Adding rocprofilerv2
Change-Id: Ic0cc280ba207d2b8f6ccae1cd4ac3184152fc1ad
[ROCm/rocprofiler commit: 8032adb64f]
This commit is contained in:
@@ -32,10 +32,10 @@ THE SOFTWARE.
|
||||
#include <string>
|
||||
|
||||
// Tracer messages protocol
|
||||
#define USE_PROF_API
|
||||
#include <prof_protocol.h>
|
||||
|
||||
#include "core/context.h"
|
||||
#include "inc/rocprofiler.h"
|
||||
#include "util/hsa_rsrc_factory.h"
|
||||
|
||||
#define PUBLIC_API __attribute__((visibility("default")))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _SRC_CORE_ACTIVITY_H
|
||||
#define _SRC_CORE_ACTIVITY_H
|
||||
|
||||
#define ROCPROFILER_V1
|
||||
|
||||
#ifdef ROCP_INTERNAL_BUILD
|
||||
#include "inc/rocprofiler.h"
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_COUNTERS_BASIC_BASIC_COUNTER_H_
|
||||
#define SRC_CORE_COUNTERS_BASIC_BASIC_COUNTER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "src/core/counters/counter.h"
|
||||
|
||||
#define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
namespace Counter {
|
||||
|
||||
class BasicCounter : Counter {
|
||||
public:
|
||||
BasicCounter(uint64_t event_id, std::string block_id, std::string name, std::string description,
|
||||
std::string gpu_name);
|
||||
~BasicCounter();
|
||||
|
||||
uint64_t GetEventId();
|
||||
std::string GetBlockId();
|
||||
std::string GetName();
|
||||
uint64_t GetBasicCounterID();
|
||||
bool GetValue(uint64_t* value, int64_t instance_id);
|
||||
uint64_t GetValue(int64_t instance_id = -1);
|
||||
|
||||
uint64_t avr(int64_t instances_count);
|
||||
uint64_t max(int64_t instances_count);
|
||||
uint64_t min(int64_t instances_count);
|
||||
uint64_t sum(int64_t instances_count);
|
||||
|
||||
private:
|
||||
void* counter_hw_info;
|
||||
std::unordered_map<int64_t, uint64_t> instances_values_;
|
||||
uint64_t event_id_;
|
||||
std::string block_id_;
|
||||
};
|
||||
|
||||
uint64_t operator+(BasicCounter counter, const uint64_t number);
|
||||
uint64_t operator*(BasicCounter counter, const uint64_t number);
|
||||
uint64_t operator/(BasicCounter counter, const uint64_t number);
|
||||
uint64_t operator-(BasicCounter counter, const uint64_t number);
|
||||
uint64_t operator^(BasicCounter counter, const uint64_t number);
|
||||
|
||||
uint64_t operator+(BasicCounter counter1, BasicCounter counter2);
|
||||
uint64_t operator*(BasicCounter counter1, BasicCounter counter2);
|
||||
uint64_t operator/(BasicCounter counter1, BasicCounter counter2);
|
||||
uint64_t operator-(BasicCounter counter1, BasicCounter counter2);
|
||||
uint64_t operator^(BasicCounter counter1, BasicCounter counter2);
|
||||
|
||||
BasicCounter* GetGeneratedBasicCounter(uint64_t id);
|
||||
void ClearBasicCounters();
|
||||
|
||||
uint64_t GetBasicCounter(const char* name, const char* gpu_name);
|
||||
|
||||
} // namespace Counter
|
||||
|
||||
#endif // SRC_CORE_COUNTERS_BASIC_BASIC_COUNTER_H_
|
||||
@@ -0,0 +1,696 @@
|
||||
<counters>
|
||||
<gfx8>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="27" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="28" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="30" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="31" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="32" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="33" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="34" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="35" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="61" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="69" descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="86" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="89" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="97" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="18" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_MC_RDREQ" block="TCC" event="35" descr="Number of 32-byte reads. The hardware actually does 64-byte reads but the number is adjusted to provide uniformity."></metric>
|
||||
<metric name="TCC_MC_WRREQ" block="TCC" event="26" descr="Number of 32-byte transactions going over the TC_MC_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests."></metric>
|
||||
<metric name="TCC_MC_WRREQ_STALL" block="TCC" event="28" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="3" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
</gfx8>
|
||||
|
||||
<gfx906>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="27" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="28" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="30" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="31" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="32" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="33" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="34" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="35" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="63" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="71" descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="84" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="85" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="93" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="20" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="22" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="29" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="30" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="33" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="41" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="42" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="TCC_EA1_WRREQ" block="TCC" event="256" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_64B" block="TCC" event="257" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_STALL" block="TCC" event="260" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA1_RDREQ" block="TCC" event="267" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA1_RDREQ_32B" block="TCC" event="268" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
</gfx906>
|
||||
|
||||
<gfx908>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="28" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="29" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="31" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="32" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="33" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="34" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="35" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="36" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="64" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="72" descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="85" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="86" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="94" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="17" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="26" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="27" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="30" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="38" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="39" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
</gfx908>
|
||||
|
||||
<gfx90a>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="91" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block="GRBM" event="3" descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block="GRBM" event="11" descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block="GRBM" event="13" descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TC_BUSY" block="GRBM" event="28" descr="Any of the Texture Cache Blocks (TCP/TCI/TCA/TCC) are busy."></metric>
|
||||
<metric name="GRBM_CPC_BUSY" block="GRBM" event="30" descr="The Command Processor Compute (CPC) is busy."></metric>
|
||||
<metric name="GRBM_CPF_BUSY" block="GRBM" event="31" descr="The Command Processor Fetchers (CPF) is busy."></metric>
|
||||
<metric name="GRBM_UTCL2_BUSY" block="GRBM" event="34" descr="The Unified Translation Cache Level-2 (UTCL2) block is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block="GRBM" event="35" descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="CPC_ME1_BUSY_FOR_PACKET_DECODE" block="CPC" event="13" descr="Me1 busy for packet decode."></metric>
|
||||
<metric name="CPC_UTCL1_STALL_ON_TRANSLATION" block="CPC" event="24" descr="One of the UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPC_CPC_STAT_BUSY" block="CPC" event="25" descr="CPC Busy."></metric>
|
||||
<metric name="CPC_CPC_STAT_IDLE" block="CPC" event="26" descr="CPC Idle."></metric>
|
||||
<metric name="CPC_CPC_STAT_STALL" block="CPC" event="27" descr="CPC Stalled."></metric>
|
||||
<metric name="CPC_CPC_TCIU_BUSY" block="CPC" event="28" descr="CPC TCIU interface Busy."></metric>
|
||||
<metric name="CPC_CPC_TCIU_IDLE" block="CPC" event="29" descr="CPC TCIU interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_BUSY" block="CPC" event="30" descr="CPC UTCL2 interface Busy."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_IDLE" block="CPC" event="31" descr="CPC UTCL2 interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_STALL" block="CPC" event="32" descr="CPC UTCL2 interface Stalled waiting on Free, Tags or Translation."></metric>
|
||||
<metric name="CPC_ME1_DC0_SPI_BUSY" block="CPC" event="33" descr="CPC Me1 Processor Busy."></metric>
|
||||
<metric name="CPF_CMP_UTCL1_STALL_ON_TRANSLATION" block="CPF" event="20" descr="One of the Compute UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPF_CPF_STAT_BUSY" block="CPF" event="23" descr="CPF Busy."></metric>
|
||||
<metric name="CPF_CPF_STAT_IDLE" block="CPF" event="24" descr="CPF Idle."></metric>
|
||||
<metric name="CPF_CPF_STAT_STALL" block="CPF" event="25" descr="CPF Stalled."></metric>
|
||||
<metric name="CPF_CPF_TCIU_BUSY" block="CPF" event="26" descr="CPF TCIU interface Busy."></metric>
|
||||
<metric name="CPF_CPF_TCIU_IDLE" block="CPF" event="27" descr="CPF TCIU interface Idle."></metric>
|
||||
<metric name="CPF_CPF_TCIU_STALL" block="CPF" event="28" descr="CPF TCIU interface Stalled waiting on Free, Tags."></metric>
|
||||
<metric name="SPI_CSN_WINDOW_VALID" block="SPI" event="47" descr="Clock count enabled by perfcounter_start event. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_BUSY" block="SPI" event="48" descr="Number of clocks with outstanding waves (SPI or SH). Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_NUM_THREADGROUPS" block="SPI" event="49" descr="Number of threadgroups launched. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_WAVE" block="SPI" event="52" descr="Number of waves. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC" block="SPI" event="79" descr="Arb cycles with requests but no allocation. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC_CSN" block="SPI" event="85" descr="Arb cycles with CSn req and no CSn alloc. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_RES_STALL_CSN" block="SPI" event="91" descr="Arb cycles with CSn req and no CSn fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TMP_STALL_CSN" block="SPI" event="97" descr="Cycles where csn wants to req but does not fit in temp space."></metric>
|
||||
<metric name="SPI_RA_WAVE_SIMD_FULL_CSN" block="SPI" event="103" descr="Sum of SIMD where WAVE can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_VGPR_SIMD_FULL_CSN" block="SPI" event="109" descr="Sum of SIMD where VGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_SGPR_SIMD_FULL_CSN" block="SPI" event="115" descr="Sum of SIMD where SGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_LDS_CU_FULL_CSN" block="SPI" event="120" descr="Sum of CU where LDS can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BAR_CU_FULL_CSN" block="SPI" event="123" descr="Sum of CU where BARRIER can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BULKY_CU_FULL_CSN" block="SPI" event="125" descr="Sum of CU where BULKY can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TGLIM_CU_FULL_CSN" block="SPI" event="127" descr="Cycles where csn wants to req but all CU are at tg_limit"></metric>
|
||||
<metric name="SPI_RA_WVLIM_STALL_CSN" block="SPI" event="133" descr="Number of clocks csn is stalled due to WAVE LIMIT."></metric>
|
||||
<metric name="SPI_SWC_CSC_WR" block="SPI" event="189" descr="Number of clocks to write CSC waves to SGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_VWC_CSC_WR" block="SPI" event="195" descr="Number of clocks to write CSC waves to VGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SQ_ACCUM_PREV" block="SQ" event="1" descr="For counter N, increment by the value of counter N-1. Only accumulates once every 4 cycles."></metric>
|
||||
<metric name="SQ_CYCLES" block="SQ" event="2" descr="Clock cycles. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_BUSY_CYCLES" block="SQ" event="3" descr="Clock cycles while SQ is reporting that it is busy. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_LEVEL_WAVES" block="SQ" event="5" descr="Track the number of waves. Set ACCUM_PREV for the next counter to use this. (level, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES_EQ_64" block="SQ" event="6" descr="Count number of waves with exactly 64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_64" block="SQ" event="7" descr="Count number of waves with smaller than 64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_48" block="SQ" event="8" descr="Count number of waves with smaller than 48 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_32" block="SQ" event="9" descr="Count number of waves sent smaller than 32 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_16" block="SQ" event="10" descr="Count number of waves sent smaller than 16 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_BUSY_CU_CYCLES" block="SQ" event="13" descr="Count quad-cycles each CU is busy. (nondeterministic, per-simd)"></metric>
|
||||
<metric name="SQ_ITEMS" block="SQ" event="14" descr="Number of valid items per wave. (per-simd, global)"></metric>
|
||||
<metric name="SQ_INSTS" block="SQ" event="25" descr="Number of instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F16" block="SQ" event="27" descr="Number of VALU ADD/SUB instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F16" block="SQ" event="28" descr="Number of VALU MUL instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F16" block="SQ" event="29" descr="Number of VALU FMA/MAD instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F16" block="SQ" event="30" descr="Number of VALU transcendental instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F32" block="SQ" event="31" descr="Number of VALU ADD/SUB instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F32" block="SQ" event="32" descr="Number of VALU MUL instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F32" block="SQ" event="33" descr="Number of VALU FMA/MAD instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F32" block="SQ" event="34" descr="Number of VALU transcendental instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F64" block="SQ" event="35" descr="Number of VALU ADD/SUB instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F64" block="SQ" event="36" descr="Number of VALU MUL instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F64" block="SQ" event="37" descr="Number of VALU FMA/MAD instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F64" block="SQ" event="38" descr="Number of VALU transcendental instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT32" block="SQ" event="39" descr="Number of VALU 32-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT64" block="SQ" event="40" descr="Number of VALU 64-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_CVT" block="SQ" event="41" descr="Number of VALU data conversion instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_I8" block="SQ" event="42" descr="Number of VALU V_MFMA_*_I8 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F16" block="SQ" event="43" descr="Number of VALU V_MFMA_*_F16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_BF16" block="SQ" event="44" descr="Number of VALU V_MFMA_*_BF16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F32" block="SQ" event="45" descr="Number of VALU V_MFMA_*_F32 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F64" block="SQ" event="46" descr="Number of VALU V_MFMA_*_F64 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_I8" block="SQ" event="47" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type I8. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F16" block="SQ" event="48" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_BF16" block="SQ" event="49" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type BF16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F32" block="SQ" event="50" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F64" block="SQ" event="51" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_MFMA" block="SQ" event="52" descr="Number of MFMA instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="53" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="54" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM" block="SQ" event="55" descr="Number of VMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="56" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="57" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="58" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="59" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="60" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="61" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_EXP_GDS" block="SQ" event="63" descr="Number of EXP and GDS instructions issued, excluding skipped export instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_BRANCH" block="SQ" event="64" descr="Number of Branch instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SENDMSG" block="SQ" event="65" descr="Number of Sendmsg instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VSKIPPED" block="SQ" event="66" descr="Number of vector instructions skipped. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_VMEM" block="SQ" event="67" descr="Number of in-flight VMEM instructions. Set next counter to ACCUM_PREV and divide by INSTS_VMEM for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_SMEM" block="SQ" event="68" descr="Number of in-flight SMEM instructions (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). Set next counter to ACCUM_PREV and divide by INSTS_SMEM for average latency per smem request. Falls slightly short of total request latency because some fetches are divided into two requests that may finish at different times and this counter collects the average latency of the two. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block="SQ" event="69" descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_VALU_MFMA_BUSY_CYCLES" block="SQ" event="72" descr="Number of cycles the MFMA ALU is busy (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block="SQ" event="74" descr="Number of wave-cycles spent by waves in the CUs (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block="SQ" event="85" descr="Number of wave-cycles spent waiting for anything (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block="SQ" event="88" descr="Number of wave-cycles spent waiting for any instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_ANY" block="SQ" event="96" descr="Number of cycles each wave is working on an instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VMEM" block="SQ" event="97" descr="Number of cycles the SQ instruction arbiter is working on a VMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_LDS" block="SQ" event="98" descr="Number of cycles the SQ instruction arbiter is working on a LDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="99" descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_SCA" block="SQ" event="100" descr="Number of cycles the SQ instruction arbiter is working on a SALU or SMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_EXP_GDS" block="SQ" event="101" descr="Number of cycles the SQ instruction arbiter is working on an EXPORT or GDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_MISC" block="SQ" event="102" descr="Number of cycles the SQ instruction aribter is working on a BRANCH or SENDMSG instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_FLAT" block="SQ" event="103" descr="Number of cycles the SQ instruction arbiter is working on a FLAT instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_WR" block="SQ" event="104" descr="Number of cycles needed to send addr and cmd data for VMEM write instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_RD" block="SQ" event="105" descr="Number of cycles needed to send addr and cmd data for VMEM read instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SMEM" block="SQ" event="111" descr="Number of cycles needed to execute scalar memory reads. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="112" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="113" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_IFETCH" block="SQ" event="115" descr="Number of instruction fetch requests from cache. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_IFETCH_LEVEL" block="SQ" event="116" descr="Number of instruction fetch requests from cache. (per-simd, level)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="121" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_ADDR_CONFLICT" block="SQ" event="122" descr="Number of cycles LDS is stalled by address conflicts. (emulated,nondeterministic)"></metric>
|
||||
<metric name="SQ_LDS_UNALIGNED_STALL" block="SQ" event="123" descr="Number of cycles LDS is stalled processing flat unaligned load/store ops. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_MEM_VIOLATIONS" block="SQ" event="124" descr="Number of threads that have a memory violation in the LDS.(emulated)"></metric>
|
||||
<metric name="SQ_LDS_ATOMIC_RETURN" block="SQ" event="125" descr="Number of atomic return cycles in LDS. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_LDS_IDX_ACTIVE" block="SQ" event="126" descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACCUM_PREV_HIRES" block="SQ" event="185" descr="For counter N, increment by the value of counter N-1."></metric>
|
||||
<metric name="SQ_WAVES_RESTORED" block="SQ" event="186" descr="Count number of context-restored waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_SAVED" block="SQ" event="187" descr="Count number of context-saved waves. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM_NORM" block="SQ" event="188" descr="Number of SMEM instructions issued normalized to match smem_level (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). (per-simd, emulated)"></metric>
|
||||
<metric name="SQC_DCACHE_INPUT_VALID_READYB" block="SQ" event="260" descr="Input stalled by SQC (per-SQ, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_TC_REQ" block="SQ" event="262" descr="Total number of TC requests that were issued by instruction and constant caches. (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_INST_REQ" block="SQ" event="263" descr="Number of insruction requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_READ_REQ" block="SQ" event="264" descr="Number of data read requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_WRITE_REQ" block="SQ" event="265" descr="Number of data write requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_ATOMIC_REQ" block="SQ" event="266" descr="Number of data atomic requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_STALL" block="SQ" event="267" descr="Valid request stalled TC request interface (no-credits). (No-Masking, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_ICACHE_REQ" block="SQ" event="270" descr="Number of requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_ICACHE_HITS" block="SQ" event="271" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES" block="SQ" event="272" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES_DUPLICATE" block="SQ" event="273" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ" block="SQ" event="290" descr="Number of requests (post-bank-serialization). (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_HITS" block="SQ" event="291" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES" block="SQ" event="292" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES_DUPLICATE" block="SQ" event="293" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_ATOMIC" block="SQ" event="298" descr="Number of atomic requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_1" block="SQ" event="323" descr="Number of constant cache 1 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_2" block="SQ" event="324" descr="Number of constant cache 2 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_4" block="SQ" event="325" descr="Number of constant cache 4 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_8" block="SQ" event="326" descr="Number of constant cache 8 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_16" block="SQ" event="327" descr="Number of constant cache 16 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS" block="TA" event="32" descr="Total number of wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS" block="TA" event="44" descr="Number of buffer wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS" block="TA" event="45" descr="Number of buffer read wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS" block="TA" event="46" descr="Number of buffer write wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS" block="TA" event="47" descr="Number of buffer atomic wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES" block="TA" event="49" descr="Number of buffer cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES" block="TA" event="52" descr="Number of buffer coalesced read cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES" block="TA" event="53" descr="Number of buffer coalesced write cycles issued to TC."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES" block="TA" event="54" descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES" block="TA" event="55" descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES" block="TA" event="56" descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS" block="TA" event="100" descr="Number of flat opcode wavfronts processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS" block="TA" event="103" descr="Number of flat opcode atomics processed by the TA."></metric>
|
||||
<metric name="TD_TD_BUSY" block="TD" event="1" descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TD_TC_STALL" block="TD" event="15" descr="TD is stalled waiting for TC data."></metric>
|
||||
<metric name="TD_SPI_STALL" block="TD" event="18" descr="TD is stalled SPI vinit"></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT" block="TD" event="25" descr="Count the wavefronts with opcode = load, include atomics and store."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT" block="TD" event="26" descr="Count the wavefronts with opcode = atomic."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT" block="TD" event="27" descr="Count the wavefronts with opcode = store."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT" block="TD" event="32" descr="Count wavefronts that TA finds coalescable."></metric>
|
||||
<metric name="TCP_GATE_EN1" block="TCP" event="0" descr="TCP interface clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_GATE_EN2" block="TCP" event="1" descr="TCP core clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES" block="TCP" event="7" descr="TD stalls TCP"></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES" block="TCP" event="8" descr="TCR stalls TCP_TCR_req interface"></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES" block="TCP" event="11" descr="Tagram conflict stall on a read"></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES" block="TCP" event="12" descr="Tagram conflict stall on a write"></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES" block="TCP" event="13" descr="Tagram conflict stall on an atomic"></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES" block="TCP" event="22" descr="Stall due to data pending from L2"></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ" block="TCP" event="27" descr="Number of state reads"></metric>
|
||||
<metric name="TCP_VOLATILE" block="TCP" event="28" descr="Total number of L1 volatile pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES" block="TCP" event="29" descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD"></metric>
|
||||
<metric name="TCP_TOTAL_READ" block="TCP" event="30" descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ"></metric>
|
||||
<metric name="TCP_TOTAL_WRITE" block="TCP" event="32" descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET" block="TCP" event="38" descr="Total number of atomic with return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET" block="TCP" event="39" descr="Total number of atomic without return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES" block="TCP" event="45" descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST" block="TCP" event="47" descr="Total CLIENT_UTCL1 NORMAL requests"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS" block="TCP" event="48" descr="Total utcl1 translation misses"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT" block="TCP" event="49" descr="Total utcl1 translation hits"></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS" block="TCP" event="50" descr="Total utcl1 permission misses"></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES" block="TCP" event="60" descr="Count of total cache line (tag) accesses (includes hits and misses)."></metric>
|
||||
<metric name="TCP_TCP_LATENCY" block="TCP" event="65" descr="Total TCP wave latency (from first clock of wave entering to first clock of wave leaving), divide by TA_TCP_STATE_READ to avg wave latency"></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_LATENCY" block="TCP" event="66" descr="Total TCP->TCC request latency for reads and atomics with return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_LATENCY" block="TCP" event="67" descr="Total TCP->TCC request latency for writes and atomics without return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ" block="TCP" event="69" descr="Total read requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ" block="TCP" event="70" descr="Total write requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ" block="TCP" event="71" descr="Total atomic with return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ" block="TCP" event="72" descr="Total atomic without return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ" block="TCP" event="75" descr="Total read requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ" block="TCP" event="76" descr="Total write requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ" block="TCP" event="77" descr="Total atomic requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ" block="TCP" event="78" descr="Total read requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ" block="TCP" event="79" descr="Total write requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ" block="TCP" event="80" descr="Total atomic requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ" block="TCP" event="81" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ" block="TCP" event="82" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ" block="TCP" event="83" descr="Total atomic requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ" block="TCP" event="85" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ" block="TCP" event="86" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ" block="TCP" event="87" descr="Total atomic requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCA_CYCLE" block="TCA" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCA_BUSY" block="TCA" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_CYCLE" block="TCC" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCC_BUSY" block="TCC" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_REQ" block="TCC" event="3" descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed."></metric>
|
||||
<metric name="TCC_STREAMING_REQ" block="TCC" event="4" descr="Number of streaming requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_NC_REQ" block="TCC" event="5" descr="The number of noncoherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_UC_REQ" block="TCC" event="6" descr="The number of uncached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_CC_REQ" block="TCC" event="7" descr="The number of coherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_RW_REQ" block="TCC" event="8" descr="The number of RW requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_PROBE" block="TCC" event="9" descr="Number of probe requests. Not windowable."></metric>
|
||||
<metric name="TCC_PROBE_ALL" block="TCC" event="10" descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable."></metric>
|
||||
<metric name="TCC_READ" block="TCC" event="12" descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included."></metric>
|
||||
<metric name="TCC_WRITE" block="TCC" event="13" descr="Number of write requests."></metric>
|
||||
<metric name="TCC_ATOMIC" block="TCC" event="14" descr="Number of atomic requests of all types."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="17" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_WRITEBACK" block="TCC" event="22" descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="26" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="27" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WR_UNCACHED_32B" block="TCC" event="29" descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="30" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_WRREQ_IO_CREDIT_STALL" block="TCC" event="31" descr="Number of cycles a EA write request was stalled because the interface was out of IO credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_GMI_CREDIT_STALL" block="TCC" event="32" descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_CREDIT_STALL" block="TCC" event="33" descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL" block="TCC" event="34" descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ_LEVEL" block="TCC" event="35" descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ."></metric>
|
||||
<metric name="TCC_EA_ATOMIC" block="TCC" event="36" descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_LEVEL" block="TCC" event="37" descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="38" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="39" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCC_EA_RD_UNCACHED_32B" block="TCC" event="40" descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_RDREQ_IO_CREDIT_STALL" block="TCC" event="41" descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_GMI_CREDIT_STALL" block="TCC" event="42" descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_CREDIT_STALL" block="TCC" event="43" descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_LEVEL" block="TCC" event="44" descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ."></metric>
|
||||
<metric name="TCC_TAG_STALL" block="TCC" event="45" descr="Number of cycles the normal request pipeline in the tag was stalled for any reason. Normally, stalls of this nature are measured exactly from one point the pipeline, but that is not the case for this counter. Probes can stall the pipeline at a variety of places, and there is no single point that can reasonably measure the total stalls accurately."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK" block="TCC" event="68" descr="Number of writebacks due to requests that are not writeback requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK" block="TCC" event="73" descr="Number of writebacks due to all TC_OP writeback requests."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT" block="TCC" event="74" descr="Number of evictions due to requests that are not invalidate or probe requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT" block="TCC" event="80" descr="Number of evictions due to all TC_OP invalidate requests."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM" block="TCC" event="102" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC)."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM" block="TCC" event="103" descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC)."></metric>
|
||||
</gfx90a>
|
||||
|
||||
<gfx940>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="96" descr="Number of quad-cycles spent waiting for LDS instruction issue. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Not Windowed."></metric>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block="GRBM" event="3" descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block="GRBM" event="11" descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block="GRBM" event="13" descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TC_BUSY" block="GRBM" event="28" descr="Any of the Texture Cache Blocks (TCP/TCI/TCA/TCC) are busy."></metric>
|
||||
<metric name="GRBM_CPC_BUSY" block="GRBM" event="30" descr="The Command Processor Compute (CPC) is busy."></metric>
|
||||
<metric name="GRBM_CPF_BUSY" block="GRBM" event="31" descr="The Command Processor Fetchers (CPF) is busy."></metric>
|
||||
<metric name="GRBM_UTCL2_BUSY" block="GRBM" event="34" descr="The Unified Translation Cache Level-2 (UTCL2) block is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block="GRBM" event="35" descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="CPC_ME1_BUSY_FOR_PACKET_DECODE" block="CPC" event="13" descr="Me1 busy for packet decode."></metric>
|
||||
<metric name="CPC_UTCL1_STALL_ON_TRANSLATION" block="CPC" event="24" descr="One of the UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPC_CPC_STAT_BUSY" block="CPC" event="25" descr="CPC Busy."></metric>
|
||||
<metric name="CPC_CPC_STAT_IDLE" block="CPC" event="26" descr="CPC Idle."></metric>
|
||||
<metric name="CPC_CPC_STAT_STALL" block="CPC" event="27" descr="CPC Stalled."></metric>
|
||||
<metric name="CPC_CPC_TCIU_BUSY" block="CPC" event="28" descr="CPC TCIU interface Busy."></metric>
|
||||
<metric name="CPC_CPC_TCIU_IDLE" block="CPC" event="29" descr="CPC TCIU interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_BUSY" block="CPC" event="30" descr="CPC UTCL2 interface Busy."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_IDLE" block="CPC" event="31" descr="CPC UTCL2 interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_STALL" block="CPC" event="32" descr="CPC UTCL2 interface Stalled waiting on Free, Tags or Translation."></metric>
|
||||
<metric name="CPC_ME1_DC0_SPI_BUSY" block="CPC" event="33" descr="CPC Me1 Processor Busy."></metric>
|
||||
<metric name="CPF_CMP_UTCL1_STALL_ON_TRANSLATION" block="CPF" event="20" descr="One of the Compute UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPF_CPF_STAT_BUSY" block="CPF" event="23" descr="CPF Busy."></metric>
|
||||
<metric name="CPF_CPF_STAT_IDLE" block="CPF" event="24" descr="CPF Idle."></metric>
|
||||
<metric name="CPF_CPF_STAT_STALL" block="CPF" event="25" descr="CPF Stalled."></metric>
|
||||
<metric name="CPF_CPF_TCIU_BUSY" block="CPF" event="26" descr="CPF TCIU interface Busy."></metric>
|
||||
<metric name="CPF_CPF_TCIU_IDLE" block="CPF" event="27" descr="CPF TCIU interface Idle."></metric>
|
||||
<metric name="CPF_CPF_TCIU_STALL" block="CPF" event="28" descr="CPF TCIU interface Stalled waiting on Free, Tags."></metric>
|
||||
<metric name="SPI_CSN_WINDOW_VALID" block="SPI" event="47" descr="Clock count enabled by perfcounter_start event. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_BUSY" block="SPI" event="48" descr="Number of clocks with outstanding waves (SPI or SH). Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_NUM_THREADGROUPS" block="SPI" event="49" descr="Number of threadgroups launched. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_WAVE" block="SPI" event="52" descr="Number of waves. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC" block="SPI" event="79" descr="Arb cycles with requests but no allocation. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC_CSN" block="SPI" event="85" descr="Arb cycles with CSn req and no CSn alloc. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_RES_STALL_CSN" block="SPI" event="91" descr="Arb cycles with CSn req and no CSn fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TMP_STALL_CSN" block="SPI" event="97" descr="Cycles where csn wants to req but does not fit in temp space."></metric>
|
||||
<metric name="SPI_RA_WAVE_SIMD_FULL_CSN" block="SPI" event="103" descr="Sum of SIMD where WAVE can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_VGPR_SIMD_FULL_CSN" block="SPI" event="109" descr="Sum of SIMD where VGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_SGPR_SIMD_FULL_CSN" block="SPI" event="115" descr="Sum of SIMD where SGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_LDS_CU_FULL_CSN" block="SPI" event="120" descr="Sum of CU where LDS can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BAR_CU_FULL_CSN" block="SPI" event="123" descr="Sum of CU where BARRIER can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BULKY_CU_FULL_CSN" block="SPI" event="125" descr="Sum of CU where BULKY can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TGLIM_CU_FULL_CSN" block="SPI" event="127" descr="Cycles where csn wants to req but all CU are at tg_limit"></metric>
|
||||
<metric name="SPI_RA_WVLIM_STALL_CSN" block="SPI" event="133" descr="Number of clocks csn is stalled due to WAVE LIMIT."></metric>
|
||||
<metric name="SPI_SWC_CSC_WR" block="SPI" event="189" descr="Number of clocks to write CSC waves to SGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_VWC_CSC_WR" block="SPI" event="195" descr="Number of clocks to write CSC waves to VGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SQ_ACCUM_PREV" block="SQ" event="1" descr="For counter N, increment by the value of counter N-1. Only accumulates once every 4 cycles."></metric>
|
||||
<metric name="SQ_CYCLES" block="SQ" event="2" descr="Clock cycles. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_BUSY_CYCLES" block="SQ" event="3" descr="Clock cycles while SQ is reporting that it is busy. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_LEVEL_WAVES" block="SQ" event="5" descr="Track the number of waves. Set ACCUM_PREV for the next counter to use this. (level, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES_EQ_64" block="SQ" event="6" descr="Count number of waves with exactly 64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_64" block="SQ" event="7" descr="Count number of waves with <64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_48" block="SQ" event="8" descr="Count number of waves with <48 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_32" block="SQ" event="9" descr="Count number of waves sent <32 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_16" block="SQ" event="10" descr="Count number of waves sent <16 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_BUSY_CU_CYCLES" block="SQ" event="13" descr="Count quad-cycles each CU is busy. (nondeterministic, per-simd)"></metric>
|
||||
<metric name="SQ_ITEMS" block="SQ" event="14" descr="Number of valid items per wave. (per-simd, global)"></metric>
|
||||
<metric name="SQ_INSTS" block="SQ" event="25" descr="Number of instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F16" block="SQ" event="27" descr="Number of VALU ADD/SUB instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F16" block="SQ" event="28" descr="Number of VALU MUL instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F16" block="SQ" event="29" descr="Number of VALU FMA/MAD instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F16" block="SQ" event="30" descr="Number of VALU transcendental instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F32" block="SQ" event="31" descr="Number of VALU ADD/SUB instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F32" block="SQ" event="32" descr="Number of VALU MUL instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F32" block="SQ" event="33" descr="Number of VALU FMA/MAD instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F32" block="SQ" event="34" descr="Number of VALU transcendental instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F64" block="SQ" event="35" descr="Number of VALU ADD/SUB instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F64" block="SQ" event="36" descr="Number of VALU MUL instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F64" block="SQ" event="37" descr="Number of VALU FMA/MAD instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F64" block="SQ" event="38" descr="Number of VALU transcendental instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT32" block="SQ" event="39" descr="Number of VALU 32-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT64" block="SQ" event="40" descr="Number of VALU 64-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_CVT" block="SQ" event="41" descr="Number of VALU data conversion instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_I8" block="SQ" event="42" descr="Number of VALU V_MFMA_*_I8 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F16" block="SQ" event="43" descr="Number of VALU V_MFMA_*_F16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_BF16" block="SQ" event="44" descr="Number of VALU V_MFMA_*_BF16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F32" block="SQ" event="45" descr="Number of VALU V_MFMA_*_F32 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F64" block="SQ" event="46" descr="Number of VALU V_MFMA_*_F64 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_I8" block="SQ" event="49" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type I8. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F16" block="SQ" event="50" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_BF16" block="SQ" event="51" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type BF16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F32" block="SQ" event="52" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F64" block="SQ" event="53" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_MFMA" block="SQ" event="56" descr="Number of MFMA instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="57" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="58" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM" block="SQ" event="59" descr="Number of VMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="60" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="61" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="62" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="65" descr="Number of LDS instructions issued (not including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="66" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_EXP_GDS" block="SQ" event="68" descr="Number of EXP and GDS instructions issued, excluding skipped export instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_BRANCH" block="SQ" event="69" descr="Number of Branch instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SENDMSG" block="SQ" event="70" descr="Number of Sendmsg instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VSKIPPED" block="SQ" event="71" descr="Number of vector instructions skipped. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_VMEM" block="SQ" event="72" descr="Number of in-flight VMEM instructions. Set next counter to ACCUM_PREV and divide by INSTS_VMEM for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_SMEM" block="SQ" event="73" descr="Number of in-flight SMEM instructions (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). Set next counter to ACCUM_PREV and divide by INSTS_SMEM for average latency per smem request. Falls slightly short of total request latency because some fetches are divided into two requests that may finish at different times and this counter collects the average latency of the two. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block="SQ" event="74" descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_VALU_MFMA_BUSY_CYCLES" block="SQ" event="77" descr="Number of cycles the MFMA ALU is busy (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block="SQ" event="79" descr="Number of quad-cycles spent by waves in the CUs. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block="SQ" event="90" descr="Number of quad-cycles spent waiting for anything. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block="SQ" event="93" descr="Number of quad-cycles spent waiting for any instruction issue. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_ANY" block="SQ" event="101" descr="Number of quad-cycles each wave is working on an instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VMEM" block="SQ" event="102" descr="Number of quad-cycles the SQ instruction arbiter is working on a VMEM instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_LDS" block="SQ" event="103" descr="Number of quad-cycles the SQ instruction arbiter is working on a LDS instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="104" descr="Number of quad-cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_SCA" block="SQ" event="105" descr="Number of quad-cycles the SQ instruction arbiter is working on a SALU or SMEM instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_EXP_GDS" block="SQ" event="106" descr="Number of quad-cycles the SQ instruction arbiter is working on an EXPORT or GDS instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_MISC" block="SQ" event="107" descr="Number of quad-cycles the SQ instruction aribter is working on a BRANCH or SENDMSG instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_FLAT" block="SQ" event="108" descr="Number of quad-cycles the SQ instruction arbiter is working on a FLAT instruction. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_WR" block="SQ" event="109" descr="Number of quad-cycles needed to send addr and cmd data for VMEM write instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_RD" block="SQ" event="110" descr="Number of quad-cycles needed to send addr and cmd data for VMEM read instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SMEM" block="SQ" event="116" descr="Number of quad-cycles needed to execute scalar memory reads. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="117" descr="Number of quad-cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="118" descr="Number of quad-cycles VALU is in used times number of active threads. (per-simd)"></metric>
|
||||
<metric name="SQ_IFETCH" block="SQ" event="120" descr="Number of instruction fetch requests from cache. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_IFETCH_LEVEL" block="SQ" event="121" descr="Number of instruction fetch requests from cache. (per-simd, level)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="126" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_ADDR_CONFLICT" block="SQ" event="127" descr="Number of cycles LDS is stalled by address conflicts. (emulated,nondeterministic)"></metric>
|
||||
<metric name="SQ_LDS_UNALIGNED_STALL" block="SQ" event="128" descr="Number of cycles LDS is stalled processing flat unaligned load/store ops. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_MEM_VIOLATIONS" block="SQ" event="129" descr="Number of threads that have a memory violation in the LDS.(emulated)"></metric>
|
||||
<metric name="SQ_LDS_ATOMIC_RETURN" block="SQ" event="130" descr="Number of atomic return cycles in LDS. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_LDS_IDX_ACTIVE" block="SQ" event="131" descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACCUM_PREV_HIRES" block="SQ" event="184" descr="For counter N, increment by the value of counter N-1."></metric>
|
||||
<metric name="SQ_WAVES_RESTORED" block="SQ" event="185" descr="Count number of context-restored waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_SAVED" block="SQ" event="186" descr="Count number of context-saved waves. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM_NORM" block="SQ" event="187" descr="Number of SMEM instructions issued normalized to match smem_level (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). (per-simd, emulated)"></metric>
|
||||
<metric name="SQC_DCACHE_INPUT_VALID_READYB" block="SQ" event="260" descr="Input stalled by SQC (per-SQ, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_TC_REQ" block="SQ" event="262" descr="Total number of TC requests that were issued by instruction and constant caches. (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_INST_REQ" block="SQ" event="263" descr="Number of insruction requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_READ_REQ" block="SQ" event="264" descr="Number of data read requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_WRITE_REQ" block="SQ" event="265" descr="Number of data write requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_ATOMIC_REQ" block="SQ" event="266" descr="Number of data atomic requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_STALL" block="SQ" event="267" descr="Valid request stalled TC request interface (no-credits). (No-Masking, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_ICACHE_REQ" block="SQ" event="270" descr="Number of requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_ICACHE_HITS" block="SQ" event="271" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES" block="SQ" event="272" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES_DUPLICATE" block="SQ" event="273" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_REQ" block="SQ" event="290" descr="Number of requests (post-bank-serialization). (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_HITS" block="SQ" event="291" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES" block="SQ" event="292" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES_DUPLICATE" block="SQ" event="293" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_ATOMIC" block="SQ" event="298" descr="Number of atomic requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_1" block="SQ" event="323" descr="Number of constant cache 1 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_2" block="SQ" event="324" descr="Number of constant cache 2 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_4" block="SQ" event="325" descr="Number of constant cache 4 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_8" block="SQ" event="326" descr="Number of constant cache 8 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_16" block="SQ" event="327" descr="Number of constant cache 16 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="13" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS" block="TA" event="29" descr="Total number of wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS" block="TA" event="32" descr="Number of buffer wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS" block="TA" event="33" descr="Number of buffer read wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS" block="TA" event="34" descr="Number of buffer write wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS" block="TA" event="35" descr="Number of buffer atomic wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES" block="TA" event="37" descr="Number of buffer cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES" block="TA" event="40" descr="Number of buffer coalesced read cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES" block="TA" event="41" descr="Number of buffer coalesced write cycles issued to TC."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES" block="TA" event="42" descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES" block="TA" event="43" descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES" block="TA" event="44" descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS" block="TA" event="51" descr="Number of flat opcode wavfronts processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="52" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="53" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS" block="TA" event="54" descr="Number of flat opcode atomics processed by the TA."></metric>
|
||||
<metric name="TD_TD_BUSY" block="TD" event="1" descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TD_TC_STALL" block="TD" event="12" descr="TD is stalled waiting for TC data."></metric>
|
||||
<metric name="TD_SPI_STALL" block="TD" event="15" descr="TD is stalled SPI vinit"></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT" block="TD" event="16" descr="Count the wavefronts with opcode = load, include atomics and store."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT" block="TD" event="17" descr="Count the wavefronts with opcode = atomic."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT" block="TD" event="18" descr="Count the wavefronts with opcode = store."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT" block="TD" event="21" descr="Count wavefronts that TA finds coalescable."></metric>
|
||||
<metric name="TCP_GATE_EN1" block="TCP" event="0" descr="TCP interface clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_GATE_EN2" block="TCP" event="1" descr="TCP core clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES" block="TCP" event="7" descr="TD stalls TCP"></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES" block="TCP" event="8" descr="TCR stalls TCP_TCR_req interface"></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES" block="TCP" event="10" descr="Tagram conflict stall on a read"></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES" block="TCP" event="11" descr="Tagram conflict stall on a write"></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES" block="TCP" event="12" descr="Tagram conflict stall on an atomic"></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES" block="TCP" event="21" descr="Stall due to data pending from L2"></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ" block="TCP" event="25" descr="Number of state reads"></metric>
|
||||
<metric name="TCP_VOLATILE" block="TCP" event="26" descr="Total number of L1 volatile pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES" block="TCP" event="27" descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD"></metric>
|
||||
<metric name="TCP_TOTAL_READ" block="TCP" event="28" descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ"></metric>
|
||||
<metric name="TCP_TOTAL_WRITE" block="TCP" event="30" descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET" block="TCP" event="36" descr="Total number of atomic with return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET" block="TCP" event="37" descr="Total number of atomic without return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES" block="TCP" event="43" descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST" block="TCP" event="45" descr="Total CLIENT_UTCL1 NORMAL requests"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS" block="TCP" event="47" descr="Total utcl1 translation misses"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT" block="TCP" event="48" descr="Total utcl1 translation hits"></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS" block="TCP" event="49" descr="Total utcl1 permission misses"></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES" block="TCP" event="60" descr="Count of total cache line (tag) accesses (includes hits and misses)."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ" block="TCP" event="65" descr="Total read requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ" block="TCP" event="66" descr="Total write requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ" block="TCP" event="67" descr="Total atomic with return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ" block="TCP" event="68" descr="Total atomic without return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ" block="TCP" event="71" descr="Total read requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ" block="TCP" event="72" descr="Total write requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ" block="TCP" event="73" descr="Total atomic requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ" block="TCP" event="74" descr="Total read requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ" block="TCP" event="75" descr="Total write requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ" block="TCP" event="76" descr="Total atomic requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ" block="TCP" event="77" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ" block="TCP" event="78" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ" block="TCP" event="79" descr="Total atomic requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ" block="TCP" event="80" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ" block="TCP" event="81" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ" block="TCP" event="82" descr="Total atomic requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCA_CYCLE" block="TCA" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCA_BUSY" block="TCA" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_CYCLE" block="TCC" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCC_BUSY" block="TCC" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_REQ" block="TCC" event="3" descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed."></metric>
|
||||
<metric name="TCC_STREAMING_REQ" block="TCC" event="4" descr="Number of streaming requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_NC_REQ" block="TCC" event="5" descr="The number of noncoherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_UC_REQ" block="TCC" event="6" descr="The number of uncached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_CC_REQ" block="TCC" event="7" descr="The number of coherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_RW_REQ" block="TCC" event="8" descr="The number of RW requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_PROBE" block="TCC" event="9" descr="Number of probe requests. Not windowable."></metric>
|
||||
<metric name="TCC_PROBE_ALL" block="TCC" event="10" descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable."></metric>
|
||||
<metric name="TCC_READ" block="TCC" event="12" descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included."></metric>
|
||||
<metric name="TCC_WRITE" block="TCC" event="13" descr="Number of write requests."></metric>
|
||||
<metric name="TCC_ATOMIC" block="TCC" event="14" descr="Number of atomic requests of all types."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="17" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_WRITEBACK" block="TCC" event="22" descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests."></metric>
|
||||
<metric name="TCC_EA0_WRREQ" block="TCC" event="26" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_64B" block="TCC" event="27" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA0_WR_UNCACHED_32B" block="TCC" event="29" descr="Number of 32/64-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_STALL" block="TCC" event="30" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_IO_CREDIT_STALL" block="TCC" event="31" descr="Number of cycles a EA write request was stalled because the interface was out of IO credits."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_GMI_CREDIT_STALL" block="TCC" event="32" descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM_CREDIT_STALL" block="TCC" event="33" descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL" block="TCC" event="34" descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_LEVEL" block="TCC" event="35" descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC" block="TCC" event="36" descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC_LEVEL" block="TCC" event="37" descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC."></metric>
|
||||
<metric name="TCC_EA0_RDREQ" block="TCC" event="38" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA0_RDREQ_32B" block="TCC" event="39" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCC_EA0_RD_UNCACHED_32B" block="TCC" event="40" descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA0_RDREQ_IO_CREDIT_STALL" block="TCC" event="41" descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_GMI_CREDIT_STALL" block="TCC" event="42" descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM_CREDIT_STALL" block="TCC" event="43" descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_LEVEL" block="TCC" event="44" descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ."></metric>
|
||||
<metric name="TCC_TAG_STALL" block="TCC" event="45" descr="Number of cycles the normal request pipeline in the tag was stalled for any reason. Normally, stalls of this nature are measured exactly from one point the pipeline, but that is not the case for this counter. Probes can stall the pipeline at a variety of places, and there is no single point that can reasonably measure the total stalls accurately."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK" block="TCC" event="68" descr="Number of writebacks due to requests that are not writeback requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK" block="TCC" event="73" descr="Number of writebacks due to all TC_OP writeback requests."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT" block="TCC" event="74" descr="Number of evictions due to requests that are not invalidate or probe requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT" block="TCC" event="80" descr="Number of evictions due to all TC_OP invalidate requests."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM" block="TCC" event="102" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC)."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM" block="TCC" event="103" descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC)."></metric>
|
||||
</gfx940>
|
||||
|
||||
<gfx9>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="27" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="28" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="30" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="31" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="32" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="33" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="34" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="35" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="63" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="71" descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="84" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="85" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="93" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="20" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="22" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="29" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="30" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="33" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="41" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="42" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
</gfx9>
|
||||
|
||||
<gfx10>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block="GRBM" event="3" descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block="GRBM" event="11" descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block="GRBM" event="13" descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_GDS_BUSY" block="GRBM" event="25" descr="The Global Data Share (GDS) is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block="GRBM" event="35" descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="GRBM_GL2CC_BUSY" block="GRBM" event="40" descr="The GL2CC block is busy."></metric>
|
||||
<metric name="GL2C_HIT" block="GL2C" event="42" descr="Number of cache hits"></metric>
|
||||
<metric name="GL2C_MISS" block="GL2C" event="43" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="GL2C_MC_WRREQ" block="GL2C" event="83" descr="Number of transactions (either 32-byte or 64-byte) going over the GL2C_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands"></metric>
|
||||
<metric name="GL2C_EA_WRREQ_64B" block="GL2C" event="85" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="GL2C_MC_WRREQ_STALL" block="GL2C" event="88" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="GL2C_MC_RDREQ" block="GL2C" event="96" descr="Number of GL2C/EA read requests (either 32-byte or 64-byte or 128-byte)."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_32B" block="GL2C" event="99" descr="Number of 32-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_64B" block="GL2C" event="100" descr="Number of 64-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_96B" block="GL2C" event="101" descr="Number of 96-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_128B" block="GL2C" event="102" descr="Number of 128-byte GL2C/EA read requests"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. {emulated, global, C1}"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block="SQ" event="26" descr="Number of clock cycles spent by waves in the SQs. Incremented by # of living (valid) waves each cycle. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block="SQ" event="28" descr="Number of clock cycles spent waiting for any instruction issue. In units of cycles. {nondeterministic}"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block="SQ" event="37" descr="Number of clock cycles spent waiting for anything. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32" block="SQ" event="71" descr="Number of wave32 instructions issued, for flat, lds, valu, tex. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_LDS" block="SQ" event="74" descr="Number of wave32 LDS indexed instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_VALU" block="SQ" event="75" descr="Number of wave32 valu instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAVE32_INSTS" block="SQ" event="84" descr="Number of instructions issued by wave32 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_WAVE64_INSTS" block="SQ" event="85" descr="Number of instructions issued by wave64 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_GDS" block="SQ" event="98" descr="Number of in-flight GDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_GDS for average latency. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block="SQ" event="99" descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM" block="SQ" event="120" descr="Number of cycles needed to send addr and data for VMEM (lds, buffer, image, flat, scratch, global) instructions, windowed by perf_en. {emulated, C1}"></metric>
|
||||
<metric name="SQC_LDS_BANK_CONFLICT" block="SQ" event="285" descr="Number of cycles LDS is stalled by bank conflicts. (emulated, C1)"></metric>
|
||||
<metric name="SQC_LDS_IDX_ACTIVE" block="SQ" event="290" descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. {per-simd, emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="64" descr="Number of VALU instructions issued excluding skipped instructions. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="60" descr="Number of SALU instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="61" descr="Number of SMEM instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="57" descr="Number of FLAT instructions issued. {emulated, C2}"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="59" descr="Number of LDS indexed instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="55" descr="Number of GDS instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="31" descr="Number of clock cycles spent waiting for LDS (indexed) instruction issue. In units of cycles. {nondeterministic, C1}"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_LOAD_WAVEFRONTS" block="TA" event="101" descr=" Number of flat load vec32 packets processed by TA, same as flat_read_wavefronts in earlier IP"></metric>
|
||||
<metric name="TA_FLAT_STORE_WAVEFRONTS" block="TA" event="102" descr="Number of flat store vec32 packets processed by TA, same as flat_write_wavefronts in earlier IP"></metric>
|
||||
</gfx10>
|
||||
|
||||
</counters>
|
||||
@@ -0,0 +1,233 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
from __future__ import print_function
|
||||
import os, sys, re
|
||||
import xml.etree.ElementTree as ET
|
||||
from lxml import etree
|
||||
import sys
|
||||
|
||||
CPP_OUT='basic_counter.cpp'
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
cpp_content = ''
|
||||
cpp_content += '/* Copyright (c) 2022 Advanced Micro Devices, Inc.\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += ' Permission is hereby granted, free of charge, to any person obtaining a copy\n'
|
||||
cpp_content += ' of this software and associated documentation files (the \"Software\"), to deal\n'
|
||||
cpp_content += ' in the Software without restriction, including without limitation the rights\n'
|
||||
cpp_content += ' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n'
|
||||
cpp_content += ' copies of the Software, and to permit persons to whom the Software is\n'
|
||||
cpp_content += ' furnished to do so, subject to the following conditions:\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += ' The above copyright notice and this permission notice shall be included in\n'
|
||||
cpp_content += ' all copies or substantial portions of the Software.\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += ' THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n'
|
||||
cpp_content += ' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n'
|
||||
cpp_content += ' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n'
|
||||
cpp_content += ' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n'
|
||||
cpp_content += ' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n'
|
||||
cpp_content += ' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n'
|
||||
cpp_content += ' THE SOFTWARE. */\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += '#include <cassert>\n'
|
||||
cpp_content += '#include "src/utils/helper.h"\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += '#include \"src/core/counters/basic/basic_counter.h\"\n'
|
||||
cpp_content += '#include \"src/core/hardware/hsa_info.h\"\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += '#define ASSERTM(exp, msg) assert(((void)msg, exp))\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += '#pragma GCC diagnostic push\n'
|
||||
cpp_content += '#pragma GCC diagnostic ignored \"-Wmaybe-uninitialized\"\n'
|
||||
cpp_content += 'namespace Counter {\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'BasicCounter::BasicCounter(uint64_t event_id, std::string block_id,\n'
|
||||
cpp_content += ' std::string name, std::string description,\n'
|
||||
cpp_content += ' std::string gpu_name)\n'
|
||||
cpp_content += ' : Counter(name, description, gpu_name),\n'
|
||||
cpp_content += ' event_id_(event_id),\n'
|
||||
cpp_content += ' block_id_(block_id) {\n'
|
||||
cpp_content += ' AddCounterToCounterMap();\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'BasicCounter::~BasicCounter() {}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'uint64_t BasicCounter::GetBasicCounterID() {\n'
|
||||
cpp_content += ' return GetCounterID();\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'uint64_t BasicCounter::GetEventId() { return event_id_; }\n'
|
||||
cpp_content += 'std::string BasicCounter::GetBlockId() { return block_id_; }\n'
|
||||
cpp_content += 'std::string BasicCounter::GetName() { return Counter::GetName(); }\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'bool BasicCounter::GetValue(uint64_t* value, int64_t instance_id = -1) {\n'
|
||||
cpp_content += ' Agent::CounterHardwareInfo* agent_info =\n'
|
||||
cpp_content += ' reinterpret_cast<Agent::CounterHardwareInfo*>(counter_hw_info);\n'
|
||||
cpp_content += ' if ((agent_info->getNumInstances() > 1 && instance_id == -1) ||\n'
|
||||
cpp_content += ' instance_id < -1 || instance_id >= agent_info->getNumInstances())\n'
|
||||
cpp_content += ' return false;\n'
|
||||
cpp_content += ' if (instance_id == -1) *value = instances_values_[0];\n'
|
||||
cpp_content += ' *value = instances_values_[instance_id];\n'
|
||||
cpp_content += ' return true;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'uint64_t BasicCounter::GetValue(int64_t instance_id) {\n'
|
||||
cpp_content += ' Agent::CounterHardwareInfo* agent_info =\n'
|
||||
cpp_content += ' reinterpret_cast<Agent::CounterHardwareInfo*>(counter_hw_info);\n'
|
||||
cpp_content += ' if ((agent_info->getNumInstances() > 1 && instance_id == -1) ||\n'
|
||||
cpp_content += ' instance_id < -1 || instance_id >= agent_info->getNumInstances())\n'
|
||||
cpp_content += ' throw(std::string(\"Error: Wrong number of instances (\") +\n'
|
||||
cpp_content += ' std::to_string(agent_info->getNumInstances()) +\n'
|
||||
cpp_content += ' \") OR Instance ID is less than 0 \");\n'
|
||||
cpp_content += ' if (instance_id == -1) return instances_values_[0];\n'
|
||||
cpp_content += ' return instances_values_[instance_id];\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'uint64_t BasicCounter::avr(int64_t instances_count) {\n'
|
||||
cpp_content += ' Agent::CounterHardwareInfo* agent_info =\n'
|
||||
cpp_content += ' reinterpret_cast<Agent::CounterHardwareInfo*>(counter_hw_info);\n'
|
||||
cpp_content += ' if (agent_info->getNumInstances() > instances_count)\n'
|
||||
cpp_content += ' throw(std::string(\"Error: Number of instances (\") +\n'
|
||||
cpp_content += ' std::to_string(agent_info->getNumInstances()) +\n'
|
||||
cpp_content += ' \") is greater than the given instance count(\" +\n'
|
||||
cpp_content += ' std::to_string(instances_count) + \")\");\n'
|
||||
cpp_content += ' uint64_t result = 0;\n'
|
||||
cpp_content += ' int64_t instance_id;\n'
|
||||
cpp_content += ' for (instance_id = 0; instance_id < instances_count; instance_id++) {\n'
|
||||
cpp_content += ' uint64_t value;\n'
|
||||
cpp_content += ' if (GetValue(&value, instance_id)) result += value;\n'
|
||||
cpp_content += ' }\n'
|
||||
cpp_content += ' return result / instances_count;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t BasicCounter::max(int64_t instances_count) {\n'
|
||||
cpp_content += ' uint64_t result = 0;\n'
|
||||
cpp_content += ' int64_t instance_id;\n'
|
||||
cpp_content += ' for (instance_id = 0; instance_id < instances_count; instance_id++) {\n'
|
||||
cpp_content += ' uint64_t value;\n'
|
||||
cpp_content += ' if (GetValue(&value, instance_id) && result < value) result = value;\n'
|
||||
cpp_content += ' }\n'
|
||||
cpp_content += ' return result;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t BasicCounter::min(int64_t instances_count) {\n'
|
||||
cpp_content += ' int64_t instance_id;\n'
|
||||
cpp_content += ' uint64_t result = 0;\n'
|
||||
cpp_content += ' for (instance_id = 0; instance_id < instances_count; instance_id++) {\n'
|
||||
cpp_content += ' uint64_t value;\n'
|
||||
cpp_content += ' if (GetValue(&value, instance_id) && result > value) result = value;\n'
|
||||
cpp_content += ' }\n'
|
||||
cpp_content += ' return result;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t BasicCounter::sum(int64_t instances_count) {\n'
|
||||
cpp_content += ' int64_t instance_id;\n'
|
||||
cpp_content += ' uint64_t result = 0;\n'
|
||||
cpp_content += ' for (instance_id = 0; instance_id < instances_count; instance_id++) {\n'
|
||||
cpp_content += ' uint64_t value;\n'
|
||||
cpp_content += ' if (GetValue(&value, instance_id)) result += value;\n'
|
||||
cpp_content += ' }\n'
|
||||
cpp_content += ' return result;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'uint64_t operator+(BasicCounter counter, const uint64_t number) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter.GetValue(&value), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return number + value;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator-(BasicCounter counter, const uint64_t number) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter.GetValue(&value), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return number - value;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator*(BasicCounter counter, const uint64_t number) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter.GetValue(&value), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return number * value;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator/(BasicCounter counter, const uint64_t number) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter.GetValue(&value), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return number / value;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator^(BasicCounter counter, const uint64_t number) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter.GetValue(&value), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return number ^ value;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'uint64_t operator+(BasicCounter counter1, BasicCounter counter2) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value1 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter1.GetValue(&value1), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value2 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter2.GetValue(&value2), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return value1 + value2;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator-(BasicCounter counter1, BasicCounter counter2) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value1 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter1.GetValue(&value1), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value2 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter2.GetValue(&value2), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return value1 - value2;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator*(BasicCounter counter1, BasicCounter counter2) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value1 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter1.GetValue(&value1), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value2 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter2.GetValue(&value2), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return value1 * value2;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator/(BasicCounter counter1, BasicCounter counter2) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value1 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter1.GetValue( & value1), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value2 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter2.GetValue( & value2), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return value1 / value2;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += 'uint64_t operator^(BasicCounter counter1, BasicCounter counter2) {\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value1 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter1.GetValue(&value1), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' [[maybe_unused]] uint64_t value2 = 0;\n'
|
||||
cpp_content += ' ASSERTM(counter2.GetValue(&value2), \"Error: Counter has no value!\");\n'
|
||||
cpp_content += ' return value1 ^ value2;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'static std::map<uint64_t, BasicCounter> basic_counters;\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'BasicCounter* GetGeneratedBasicCounter(uint64_t id) {\n'
|
||||
cpp_content += ' return &basic_counters.at(id);\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += 'void ClearBasicCounters() {\n'
|
||||
cpp_content += ' basic_counters.clear();\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += '/**\n'
|
||||
cpp_content += ' * @brief Basic Counters\n'
|
||||
cpp_content += ' *\n'
|
||||
cpp_content += ' * @{\n'
|
||||
cpp_content += ' */\n'
|
||||
cpp_content += 'uint64_t GetBasicCounter(const char* name, const char* gpu_name) {\n'
|
||||
cpp_content += ' std::string gpu;\n'
|
||||
parser=etree.XMLParser(recover=True, encoding='utf-8')
|
||||
xml_file=ET.parse(sys.argv[1] + '/gfx_metrics.xml', parser=parser)
|
||||
root=xml_file.getroot()
|
||||
for gpu in root:
|
||||
cpp_content += "\n\t/**\n\t * @brief Basic " + gpu.tag + " counters\n\t *\n\t * @{\n\t */\n"
|
||||
cpp_content += "\tgpu = \"" + gpu.tag + "\";\n\n"
|
||||
cpp_content += "\tif (strncmp(gpu_name, gpu.c_str(), gpu.length())==0) {\n"
|
||||
for child in gpu:
|
||||
cpp_content += "\t/**\n\t * Basic Counter: " + child.attrib['name'] + "\n\t *\n\t * " + child.attrib['descr'] + "\n\t */\n\tif (strcmp(name, \"" + child.attrib['name'] + "\")==0) {\n\t\tbasic_counters.emplace(" + child.attrib['event'] + ", BasicCounter{" + child.attrib['event'] + ", \"" + child.attrib['block'] + "\", \"" + child.attrib['name'] + "\", \"" + child.attrib['descr'] + "\", \"" + gpu.tag + "\"});\n\t\treturn " + child.attrib['event'] + ";\n\t}\n"
|
||||
cpp_content += "\t}\n\n\t/**\n\t * @}\n\t */\n"
|
||||
cpp_content += ' throw(\"Couldn\'t find the required Counter name for the mentioned GPU!\");\n'
|
||||
cpp_content += ' return 0;\n'
|
||||
cpp_content += '}\n'
|
||||
cpp_content += '/**\n'
|
||||
cpp_content += ' * @}\n'
|
||||
cpp_content += ' */\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += '} // namespace Counter\n'
|
||||
cpp_content += '\n'
|
||||
cpp_content += '#pragma GCC diagnostic pop\n'
|
||||
print ('Generating "' + sys.argv[2] + '"')
|
||||
f = open(sys.argv[2], 'w')
|
||||
f.write(cpp_content[:-1])
|
||||
f.close()
|
||||
@@ -0,0 +1,46 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "counter.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "src/api/rocmtool.h"
|
||||
|
||||
namespace Counter {
|
||||
|
||||
std::atomic<uint64_t> COUNTER_COUNT{1};
|
||||
|
||||
Counter::Counter(std::string name, std::string description, std::string gpu_name)
|
||||
: name_(name), description_(description), gpu_name_(gpu_name) {}
|
||||
|
||||
Counter::~Counter() {}
|
||||
|
||||
void Counter::AddCounterToCounterMap() { GenerateCounterID(); }
|
||||
|
||||
uint64_t Counter::GetCounterID() { return counter_id_; }
|
||||
void Counter::GenerateCounterID() {
|
||||
counter_id_ = COUNTER_COUNT.fetch_add(1, std::memory_order_release);
|
||||
}
|
||||
|
||||
std::string Counter::GetName() { return name_; }
|
||||
std::string Counter::GetDescription() { return description_; }
|
||||
|
||||
} // namespace Counter
|
||||
@@ -0,0 +1,52 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_COUNTERS_COUNTER_H_
|
||||
#define SRC_CORE_COUNTERS_COUNTER_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Counter {
|
||||
|
||||
class Counter {
|
||||
public:
|
||||
Counter(std::string name, std::string description, std::string gpu_name);
|
||||
~Counter();
|
||||
void AddCounterToCounterMap();
|
||||
uint64_t GetCounterID();
|
||||
void GenerateCounterID();
|
||||
std::string GetName();
|
||||
std::string GetDescription();
|
||||
|
||||
private:
|
||||
uint64_t counter_id_;
|
||||
std::string name_;
|
||||
std::string description_;
|
||||
std::string gpu_name_;
|
||||
};
|
||||
|
||||
std::string GetCounterName(uint64_t descriptor);
|
||||
|
||||
} // namespace Counter
|
||||
|
||||
#endif // SRC_CORE_COUNTERS_COUNTER_H_
|
||||
@@ -0,0 +1,61 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "src/core/counters/derived/derived_counter.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
|
||||
namespace Counter {
|
||||
|
||||
static std::atomic<uint64_t> COUNTER_COUNTER{0};
|
||||
|
||||
DerivedCounter::DerivedCounter(std::string name, std::string description,
|
||||
std::string gpu_name)
|
||||
: Counter(name, description, gpu_name) {
|
||||
metric_id_ = COUNTER_COUNTER.fetch_add(1, std::memory_order_release);
|
||||
addCounterToCounterMap();
|
||||
}
|
||||
|
||||
DerivedCounter::~DerivedCounter() {
|
||||
for (auto& it : counters_) delete it.second;
|
||||
counters_.clear();
|
||||
}
|
||||
|
||||
uint64_t DerivedCounter::getMetricId() { return metric_id_; }
|
||||
|
||||
std::map<uint64_t, BasicCounter*> *DerivedCounter::getAllCounters() {
|
||||
return &counters_;
|
||||
}
|
||||
|
||||
BasicCounter *DerivedCounter::getBasicCounterFromDerived(uint64_t counter_id) {
|
||||
return counters_[counter_id];
|
||||
}
|
||||
|
||||
void DerivedCounter::addBasicCounter(uint64_t counter_id,
|
||||
BasicCounter *counter) {
|
||||
counters_.emplace(counter_id, counter);
|
||||
}
|
||||
|
||||
@DERIVED_XML_PARSE_RESULT@
|
||||
|
||||
} // namespace Counter
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -0,0 +1,64 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_COUNTERS_DERIVED_DERIVED_COUNTER_H_
|
||||
#define SRC_CORE_COUNTERS_DERIVED_DERIVED_COUNTER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "src/core/counters/basic/basic_counter.h"
|
||||
|
||||
namespace Counter {
|
||||
|
||||
class DerivedCounter : Counter {
|
||||
public:
|
||||
std::function<uint64_t()> evaluate_metric;
|
||||
DerivedCounter(std::string name, std::string description,
|
||||
std::string gpu_name);
|
||||
~DerivedCounter();
|
||||
|
||||
uint64_t getMetricId();
|
||||
uint64_t getValue();
|
||||
std::map<uint64_t, BasicCounter*>* getAllCounters();
|
||||
void addBasicCounter(uint64_t counter_id, BasicCounter* counter);
|
||||
BasicCounter* getBasicCounterFromDerived(uint64_t counter_id);
|
||||
|
||||
private:
|
||||
uint64_t metric_id_;
|
||||
uint64_t value_;
|
||||
std::map<uint64_t, BasicCounter*> counters_;
|
||||
};
|
||||
|
||||
static std::map<uint64_t, DerivedCounter> derived_counters;
|
||||
|
||||
uint64_t getDerivedCounter(const char* name, const char* gpu_name);
|
||||
|
||||
} // namespace Counter
|
||||
|
||||
#endif // SRC_CORE_COUNTERS_DERIVED_DERIVED_COUNTER_H_
|
||||
+427
@@ -0,0 +1,427 @@
|
||||
<metrics>
|
||||
|
||||
<gfx8>
|
||||
<metric name="GPUBusy" expr="100*GRBM_GUI_ACTIVE/GRBM_COUNT" descr="The percentage of time GPU was busy."></metric>
|
||||
<metric name="Wavefronts" expr="SQ_WAVES" descr="Total wavefronts."></metric>
|
||||
<metric name="VALUInsts" expr="SQ_INSTS_VALU/SQ_WAVES" descr="The average number of vector ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SALUInsts" expr="SQ_INSTS_SALU/SQ_WAVES" descr="The average number of scalar ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SFetchInsts" expr="SQ_INSTS_SMEM/SQ_WAVES" descr="The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="GDSInsts" expr="SQ_INSTS_GDS/SQ_WAVES" descr="The average number of GDS read or GDS write instructions executed per work item (affected by flow control)."></metric>
|
||||
<metric name="MemUnitBusy" expr="100*max(TA_TA_BUSY,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound)."></metric>
|
||||
<metric name="ALUStalledByLDS" expr="100*SQ_WAIT_INST_LDS*4/SQ_WAVES/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TA_BUSY_avr" expr="avr(TA_TA_BUSY,16)" descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr="max(TA_TA_BUSY,16)" descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr="min(TA_TA_BUSY,16)" descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr="sum(TA_FLAT_READ_WAVEFRONTS,16)" descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr="sum(TA_FLAT_WRITE_WAVEFRONTS,16)" descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TCC_HIT_sum" expr="sum(TCC_HIT,16)" descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr="sum(TCC_MISS,16)" descr="Number of cache misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MC_RDREQ_sum" expr="sum(TCC_MC_RDREQ,16)" descr="Number of 32-byte reads. Sum over TCC instaces."></metric>
|
||||
<metric name="TCC_MC_WRREQ_sum" expr="sum(TCC_MC_WRREQ,16)" descr="Number of 32-byte transactions going over the TC_MC_wrreq interface. Sum over TCC instaces."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr="max(TCC_MC_WRREQ_STALL,16)" descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
<metric name="FETCH_SIZE" expr="(TCC_MC_RDREQ_sum*32)/1024" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr="(TCC_MC_WRREQ_sum*32)/1024" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr="TCC_MC_WRREQ_sum" descr="The total number of 32-byte effective memory writes."></metric>
|
||||
<metric name="VFetchInsts" expr="(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr="(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="FlatVMemInsts" expr="(SQ_INSTS_FLAT-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of FLAT instructions that read from or write to the video memory executed per work item (affected by flow control). Includes FLAT instructions that read from or write to scratch."></metric>
|
||||
<metric name="LDSInsts" expr="(SQ_INSTS_LDS-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of LDS read or LDS write instructions executed per work item (affected by flow control). Excludes FLAT instructions that read from or write to LDS."></metric>
|
||||
<metric name="FlatLDSInsts" expr="SQ_INSTS_FLAT_LDS_ONLY/SQ_WAVES" descr="The average number of FLAT instructions that read or write to LDS executed per work item (affected by flow control)."></metric>
|
||||
<metric name="VALUUtilization" expr="100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE)" descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr="100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr="100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr="FETCH_SIZE" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr="WRITE_SIZE" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr="WRITE_REQ_32B" descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="L2CacheHit" expr="100*sum(TCC_HIT,16)/(sum(TCC_HIT,16)+sum(TCC_MISS,16))" descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="MemUnitStalled" expr="100*max(TCP_TCP_TA_DATA_STALL_CYCLES,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="WriteUnitStalled" expr="100*TCC_WRREQ_STALL_max/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
<metric name="LDSBankConflict" expr="100*SQ_LDS_BANK_CONFLICT/GRBM_GUI_ACTIVE/CU_NUM" descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
</gfx8>
|
||||
|
||||
<gfx906>
|
||||
<metric name="GPUBusy" expr="100*GRBM_GUI_ACTIVE/GRBM_COUNT" descr="The percentage of time GPU was busy."></metric>
|
||||
<metric name="Wavefronts" expr="SQ_WAVES" descr="Total wavefronts."></metric>
|
||||
<metric name="VALUInsts" expr="SQ_INSTS_VALU/SQ_WAVES" descr="The average number of vector ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SALUInsts" expr="SQ_INSTS_SALU/SQ_WAVES" descr="The average number of scalar ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SFetchInsts" expr="SQ_INSTS_SMEM/SQ_WAVES" descr="The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="GDSInsts" expr="SQ_INSTS_GDS/SQ_WAVES" descr="The average number of GDS read or GDS write instructions executed per work item (affected by flow control)."></metric>
|
||||
<metric name="MemUnitBusy" expr="100*max(TA_TA_BUSY,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound)."></metric>
|
||||
<metric name="ALUStalledByLDS" expr="100*SQ_WAIT_INST_LDS*4/SQ_WAVES/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TA_BUSY_avr" expr="avr(TA_TA_BUSY,16)" descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr="max(TA_TA_BUSY,16)" descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr="min(TA_TA_BUSY,16)" descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr="sum(TA_FLAT_READ_WAVEFRONTS,16)" descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr="sum(TA_FLAT_WRITE_WAVEFRONTS,16)" descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TCC_HIT_sum" expr="sum(TCC_HIT,16)" descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr="sum(TCC_MISS,16)" descr="Number of cache misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B_sum" expr="sum(TCC_EA_RDREQ_32B,16)" descr="Number of 32-byte TCC/EA read requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_sum" expr="sum(TCC_EA_RDREQ,16)" descr="Number of TCC/EA read requests (either 32-byte or 64-byte). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_sum" expr="sum(TCC_EA_WRREQ,16)" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B_sum" expr="sum(TCC_EA_WRREQ_64B,16)" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr="max(TCC_EA_WRREQ_STALL,16)" descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
<metric name="VFetchInsts" expr="(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr="(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="FlatVMemInsts" expr="(SQ_INSTS_FLAT-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of FLAT instructions that read from or write to the video memory executed per work item (affected by flow control). Includes FLAT instructions that read from or write to scratch."></metric>
|
||||
<metric name="LDSInsts" expr="(SQ_INSTS_LDS-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of LDS read or LDS write instructions executed per work item (affected by flow control). Excludes FLAT instructions that read from or write to LDS."></metric>
|
||||
<metric name="FlatLDSInsts" expr="SQ_INSTS_FLAT_LDS_ONLY/SQ_WAVES" descr="The average number of FLAT instructions that read or write to LDS executed per work item (affected by flow control)."></metric>
|
||||
<metric name="VALUUtilization" expr="100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE)" descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr="100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr="100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr="FETCH_SIZE" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr="WRITE_SIZE" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr="WRITE_REQ_32B" descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="L2CacheHit" expr="100*sum(TCC_HIT,16)/(sum(TCC_HIT,16)+sum(TCC_MISS,16))" descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="MemUnitStalled" expr="100*max(TCP_TCP_TA_DATA_STALL_CYCLES,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="WriteUnitStalled" expr="100*TCC_WRREQ_STALL_max/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
<metric name="LDSBankConflict" expr="100*SQ_LDS_BANK_CONFLICT/GRBM_GUI_ACTIVE/CU_NUM" descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TCC_EA1_RDREQ_32B_sum" expr="sum(TCC_EA1_RDREQ_32B,16)" descr="Number of 32-byte TCC/EA read requests. Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_EA1_RDREQ_sum" expr="sum(TCC_EA1_RDREQ,16)" descr="Number of TCC/EA read requests (either 32-byte or 64-byte). Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_sum" expr="sum(TCC_EA1_WRREQ,16)" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_64B_sum" expr="sum(TCC_EA1_WRREQ_64B,16)" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_WRREQ1_STALL_max" expr="max(TCC_EA1_WRREQ_STALL,16)" descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
<metric name="RDATA1_SIZE" expr="(TCC_EA1_RDREQ_32B_sum*32+(TCC_EA1_RDREQ_sum-TCC_EA1_RDREQ_32B_sum)*64)" descr="The total kilobytes fetched from the video memory. This is measured on EA1s."></metric>
|
||||
<metric name="WDATA1_SIZE" expr="((TCC_EA1_WRREQ_sum-TCC_EA1_WRREQ_64B_sum)*32+TCC_EA1_WRREQ_64B_sum*64)" descr="The total kilobytes written to the video memory. This is measured on EA1s."></metric>
|
||||
<metric name="FETCH_SIZE" expr="(TCC_EA_RDREQ_32B_sum*32+(TCC_EA_RDREQ_sum-TCC_EA_RDREQ_32B_sum)*64+RDATA1_SIZE)/1024" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr="((TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)*32+TCC_EA_WRREQ_64B_sum*64+WDATA1_SIZE)/1024" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr="(TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)+(TCC_EA1_WRREQ_sum-TCC_EA1_WRREQ_64B_sum)+(TCC_EA_WRREQ_64B_sum+TCC_EA1_WRREQ_64B_sum)*2" descr="The total number of 32-byte effective memory writes."></metric>
|
||||
</gfx906>
|
||||
|
||||
<gfx908>
|
||||
<metric name="GPUBusy" expr="100*GRBM_GUI_ACTIVE/GRBM_COUNT" descr="The percentage of time GPU was busy."></metric>
|
||||
<metric name="Wavefronts" expr="SQ_WAVES" descr="Total wavefronts."></metric>
|
||||
<metric name="VALUInsts" expr="SQ_INSTS_VALU/SQ_WAVES" descr="The average number of vector ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SALUInsts" expr="SQ_INSTS_SALU/SQ_WAVES" descr="The average number of scalar ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SFetchInsts" expr="SQ_INSTS_SMEM/SQ_WAVES" descr="The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="GDSInsts" expr="SQ_INSTS_GDS/SQ_WAVES" descr="The average number of GDS read or GDS write instructions executed per work item (affected by flow control)."></metric>
|
||||
<metric name="MemUnitBusy" expr="100*max(TA_TA_BUSY,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound)."></metric>
|
||||
<metric name="ALUStalledByLDS" expr="100*SQ_WAIT_INST_LDS*4/SQ_WAVES/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TA_BUSY_avr" expr="avr(TA_TA_BUSY,16)" descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr="max(TA_TA_BUSY,16)" descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr="min(TA_TA_BUSY,16)" descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr="sum(TA_FLAT_READ_WAVEFRONTS,16)" descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr="sum(TA_FLAT_WRITE_WAVEFRONTS,16)" descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="FETCH_SIZE" expr="(TCC_EA_RDREQ_32B_sum*32+(TCC_EA_RDREQ_sum-TCC_EA_RDREQ_32B_sum)*64)/1024" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr="((TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)*32+TCC_EA_WRREQ_64B_sum*64)/1024" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr="TCC_EA_WRREQ_64B_sum*2+(TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)" descr="The total number of 32-byte effective memory writes."></metric>
|
||||
<metric name="VFetchInsts" expr="(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr="(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="FlatVMemInsts" expr="(SQ_INSTS_FLAT-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of FLAT instructions that read from or write to the video memory executed per work item (affected by flow control). Includes FLAT instructions that read from or write to scratch."></metric>
|
||||
<metric name="LDSInsts" expr="(SQ_INSTS_LDS-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of LDS read or LDS write instructions executed per work item (affected by flow control). Excludes FLAT instructions that read from or write to LDS."></metric>
|
||||
<metric name="FlatLDSInsts" expr="SQ_INSTS_FLAT_LDS_ONLY/SQ_WAVES" descr="The average number of FLAT instructions that read or write to LDS executed per work item (affected by flow control)."></metric>
|
||||
<metric name="VALUUtilization" expr="100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE)" descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr="100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr="100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr="FETCH_SIZE" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr="WRITE_SIZE" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr="WRITE_REQ_32B" descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="L2CacheHit" expr="100*sum(TCC_HIT,16)/(sum(TCC_HIT,16)+sum(TCC_MISS,16))" descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="MemUnitStalled" expr="100*max(TCP_TCP_TA_DATA_STALL_CYCLES,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="WriteUnitStalled" expr="100*TCC_WRREQ_STALL_max/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
<metric name="LDSBankConflict" expr="100*SQ_LDS_BANK_CONFLICT/GRBM_GUI_ACTIVE/CU_NUM" descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TCC_HIT_sum" expr="sum(TCC_HIT,32)" descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr="sum(TCC_MISS,32)" descr="Number of cache misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B_sum" expr="sum(TCC_EA_RDREQ_32B,32)" descr="Number of 32-byte TCC/EA read requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_sum" expr="sum(TCC_EA_RDREQ,32)" descr="Number of TCC/EA read requests (either 32-byte or 64-byte). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_sum" expr="sum(TCC_EA_WRREQ,32)" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B_sum" expr="sum(TCC_EA_WRREQ_64B,32)" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr="max(TCC_EA_WRREQ_STALL,32)" descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
</gfx908>
|
||||
|
||||
<gfx90a>
|
||||
<metric name="GPUBusy" expr="100*GRBM_GUI_ACTIVE/GRBM_COUNT" descr="The percentage of time GPU was busy."></metric>
|
||||
<metric name="Wavefronts" expr="SQ_WAVES" descr="Total wavefronts."></metric>
|
||||
<metric name="VALUInsts" expr="SQ_INSTS_VALU/SQ_WAVES" descr="The average number of vector ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SALUInsts" expr="SQ_INSTS_SALU/SQ_WAVES" descr="The average number of scalar ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SFetchInsts" expr="SQ_INSTS_SMEM/SQ_WAVES" descr="The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="GDSInsts" expr="SQ_INSTS_GDS/SQ_WAVES" descr="The average number of GDS read or GDS write instructions executed per work item (affected by flow control)."></metric>
|
||||
<metric name="MemUnitBusy" expr="100*max(TA_TA_BUSY,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound)."></metric>
|
||||
<metric name="ALUStalledByLDS" expr="100*SQ_WAIT_INST_LDS*4/SQ_WAVES/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="VFetchInsts" expr="(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr="(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="FlatVMemInsts" expr="(SQ_INSTS_FLAT-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of FLAT instructions that read from or write to the video memory executed per work item (affected by flow control). Includes FLAT instructions that read from or write to scratch."></metric>
|
||||
<metric name="LDSInsts" expr="(SQ_INSTS_LDS-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES" descr="The average number of LDS read or LDS write instructions executed per work item (affected by flow control). Excludes FLAT instructions that read from or write to LDS."></metric>
|
||||
<metric name="FlatLDSInsts" expr="SQ_INSTS_FLAT_LDS_ONLY/SQ_WAVES" descr="The average number of FLAT instructions that read or write to LDS executed per work item (affected by flow control)."></metric>
|
||||
<metric name="VALUUtilization" expr="100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE)" descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr="100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr="100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr="FETCH_SIZE" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr="WRITE_SIZE" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr="WRITE_REQ_32B" descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="L2CacheHit" expr="100*sum(TCC_HIT,16)/(sum(TCC_HIT,16)+sum(TCC_MISS,16))" descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="MemUnitStalled" expr="100*max(TCP_TCP_TA_DATA_STALL_CYCLES,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="WriteUnitStalled" expr="100*TCC_WRREQ_STALL_max/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
<metric name="LDSBankConflict" expr="100*SQ_LDS_BANK_CONFLICT/GRBM_GUI_ACTIVE/CU_NUM" descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TA_BUSY_avr" expr="avr(TA_TA_BUSY,16)" descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr="max(TA_TA_BUSY,16)" descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr="min(TA_TA_BUSY,16)" descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_TA_BUSY_sum" expr="sum(TA_TA_BUSY,16)" descr="TA block is busy. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS_sum" expr="sum(TA_TOTAL_WAVEFRONTS,16)" descr="Total number of wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES_sum" expr="sum(TA_ADDR_STALLED_BY_TC_CYCLES,16)" descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES_sum" expr="sum(TA_ADDR_STALLED_BY_TD_CYCLES,16)" descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES_sum" expr="sum(TA_DATA_STALLED_BY_TC_CYCLES,16)" descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS_sum" expr="sum(TA_FLAT_WAVEFRONTS,16)" descr="Number of flat opcode wavfronts processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr="sum(TA_FLAT_READ_WAVEFRONTS,16)" descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr="sum(TA_FLAT_WRITE_WAVEFRONTS,16)" descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS_sum" expr="sum(TA_FLAT_ATOMIC_WAVEFRONTS,16)" descr="Number of flat opcode atomics processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS_sum" expr="sum(TA_BUFFER_WAVEFRONTS,16)" descr="Number of buffer wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS_sum" expr="sum(TA_BUFFER_READ_WAVEFRONTS,16)" descr="Number of buffer read wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS_sum" expr="sum(TA_BUFFER_WRITE_WAVEFRONTS,16)" descr="Number of buffer write wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS_sum" expr="sum(TA_BUFFER_ATOMIC_WAVEFRONTS,16)" descr="Number of buffer atomic wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES_sum" expr="sum(TA_BUFFER_TOTAL_CYCLES,16)" descr="Number of buffer cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES_sum" expr="sum(TA_BUFFER_COALESCED_READ_CYCLES,16)" descr="Number of buffer coalesced read cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES_sum" expr="sum(TA_BUFFER_COALESCED_WRITE_CYCLES,16)" descr="Number of buffer coalesced write cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TD_TD_BUSY_sum" expr="sum(TD_TD_BUSY,16)" descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter. Sum over TD instances."></metric>
|
||||
<metric name="TD_TC_STALL_sum" expr="sum(TD_TC_STALL,16)" descr="TD is stalled waiting for TC data. Sum over TD instances."></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT_sum" expr="sum(TD_LOAD_WAVEFRONT,16)" descr="Count the wavefronts with opcode = load, include atomics and store. Sum over TD instances."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT_sum" expr="sum(TD_ATOMIC_WAVEFRONT,16)" descr="Count the wavefronts with opcode = atomic. Sum over TD instances."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT_sum" expr="sum(TD_STORE_WAVEFRONT,16)" descr="Count the wavefronts with opcode = store. Sum over TD instances."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT_sum" expr="sum(TD_COALESCABLE_WAVEFRONT,16)" descr="Count wavefronts that TA finds coalescable. Sum over TD instances."></metric>
|
||||
<metric name="TD_SPI_STALL_sum" expr="sum(TD_SPI_STALL,16)" descr="TD is stalled SPI vinit, sum of TCP instances"></metric>
|
||||
<metric name="TCP_GATE_EN1_sum" expr="sum(TCP_GATE_EN1,16)" descr="TCP interface clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_GATE_EN2_sum" expr="sum(TCP_GATE_EN2,16)" descr="TCP core clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES_sum" expr="sum(TCP_TD_TCP_STALL_CYCLES,16)" descr="TD stalls TCP. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES_sum" expr="sum(TCP_TCR_TCP_STALL_CYCLES,16)" descr="TCR stalls TCP_TCR_req interface. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES_sum" expr="sum(TCP_READ_TAGCONFLICT_STALL_CYCLES,16)" descr="Tagram conflict stall on a read. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES_sum" expr="sum(TCP_WRITE_TAGCONFLICT_STALL_CYCLES,16)" descr="Tagram conflict stall on a write. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES_sum" expr="sum(TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES,16)" descr="Tagram conflict stall on an atomic. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_VOLATILE_sum" expr="sum(TCP_VOLATILE,16)" descr="Total number of L1 volatile pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES_sum" expr="sum(TCP_TOTAL_ACCESSES,16)" descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_READ_sum" expr="sum(TCP_TOTAL_READ,16)" descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITE_sum" expr="sum(TCP_TOTAL_WRITE,16)" descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET_sum" expr="sum(TCP_TOTAL_ATOMIC_WITH_RET,16)" descr="Total number of atomic with return pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET_sum" expr="sum(TCP_TOTAL_ATOMIC_WITHOUT_RET,16)" descr="Total number of atomic without return pixels/buffers from TA Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES_sum" expr="sum(TCP_TOTAL_WRITEBACK_INVALIDATES,16)" descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST_sum" expr="sum(TCP_UTCL1_REQUEST,16)" descr="Total CLIENT_UTCL1 NORMAL requests Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS_sum" expr="sum(TCP_UTCL1_TRANSLATION_MISS,16)" descr="Total utcl1 translation misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT_sum" expr="sum(TCP_UTCL1_TRANSLATION_HIT,16)" descr="Total utcl1 translation hits Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS_sum" expr="sum(TCP_UTCL1_PERMISSION_MISS,16)" descr="Total utcl1 permission misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES_sum" expr="sum(TCP_TOTAL_CACHE_ACCESSES,16)" descr="Count of total cache line (tag) accesses (includes hits and misses). Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCP_LATENCY_sum" expr="sum(TCP_TCP_LATENCY,16)" descr="Total TCP wave latency (from first clock of wave entering to first clock of wave leaving), divide by TA_TCP_STATE_READ to avg wave latency Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ_sum" expr="sum(TCP_TA_TCP_STATE_READ,16)" descr="Number of state reads Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_LATENCY_sum" expr="sum(TCP_TCC_READ_REQ_LATENCY,16)" descr="Total TCP->TCC request latency for reads and atomics with return. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_LATENCY_sum" expr="sum(TCP_TCC_WRITE_REQ_LATENCY,16)" descr="Total TCP->TCC request latency for writes and atomics without return. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_sum" expr="sum(TCP_TCC_READ_REQ,16)" descr="Total read requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_sum" expr="sum(TCP_TCC_WRITE_REQ,16)" descr="Total write requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ_sum" expr="sum(TCP_TCC_ATOMIC_WITH_RET_REQ,16)" descr="Total atomic with return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ_sum" expr="sum(TCP_TCC_ATOMIC_WITHOUT_RET_REQ,16)" descr="Total atomic without return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ_sum" expr="sum(TCP_TCC_NC_READ_REQ,16)" descr="Total read requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_RWriteUnitStalledQ_sum" expr="sum(TCP_TCC_RW_READ_REQ,16)" descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ_sum" expr="sum(TCP_TCC_RW_WRITE_REQ,16)" descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ_sum" expr="sum(TCP_TCC_RW_ATOMIC_REQ,16)" descr="Total atomic requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES_sum" expr="sum(TCP_PENDING_STALL_CYCLES,16)" descr="Stall due to data pending from L2. Sum over TCP instances."></metric>
|
||||
<metric name="TCA_CYCLE_sum" expr="sum(TCA_CYCLE,16)" descr="Number of cycles. Sum over all TCA instances "></metric>
|
||||
<metric name="TCA_BUSY_sum" expr="sum(TCA_BUSY,16)" descr="Number of cycles we have a request pending. Sum over all TCA instances."></metric>
|
||||
<metric name="TCC_BUSY_avr" expr="avr(TCC_BUSY,32)" descr="TCC_BUSY avr over all memory channels."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr="max(TCC_EA_WRREQ_STALL,32)" descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
<metric name="TCC_CYCLE_sum" expr="sum(TCC_CYCLE,32)" descr="Number of cycles. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_BUSY_sum" expr="sum(TCC_BUSY,32)" descr="Number of cycles we have a request pending. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_REQ_sum" expr="sum(TCC_REQ,32)" descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_STREAMING_REQ_sum" expr="sum(TCC_STREAMING_REQ,32)" descr="Number of streaming requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NC_REQ_sum" expr="sum(TCC_NC_REQ,32)" descr="The number of noncoherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_UC_REQ_sum" expr="sum(TCC_UC_REQ,32)" descr="The number of uncached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_CC_REQ_sum" expr="sum(TCC_CC_REQ,32)" descr="The number of coherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_RW_REQ_sum" expr="sum(TCC_RW_REQ,32)" descr="The number of RW requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_sum" expr="sum(TCC_PROBE,32)" descr="Number of probe requests. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_ALL_sum" expr="sum(TCC_PROBE_ALL,32)" descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_READ_sum" expr="sum(TCC_READ,32)" descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITE_sum" expr="sum(TCC_WRITE,32)" descr="Number of write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ATOMIC_sum" expr="sum(TCC_ATOMIC,32)" descr="Number of atomic requests of all types. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_HIT_sum" expr="sum(TCC_HIT,32)" descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr="sum(TCC_MISS,32)" descr="Number of cache misses. UC reads count as misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITEBACK_sum" expr="sum(TCC_WRITEBACK,32)" descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_sum" expr="sum(TCC_EA_WRREQ,32)" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B_sum" expr="sum(TCC_EA_WRREQ_64B,32)" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WR_UNCACHED_32B_sum" expr="sum(TCC_EA_WR_UNCACHED_32B,32)" descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL_sum" expr="sum(TCC_EA_WRREQ_STALL,32)" descr="Number of cycles a write request was stalled. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_IO_CREDIT_STALL_sum" expr="sum(TCC_EA_WRREQ_IO_CREDIT_STALL,32)" descr="Number of cycles a EA write request was stalled because the interface was out of IO credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_GMI_CREDIT_STALL_sum" expr="sum(TCC_EA_WRREQ_GMI_CREDIT_STALL,32)" descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_CREDIT_STALL_sum" expr="sum(TCC_EA_WRREQ_DRAM_CREDIT_STALL,32)" descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL_sum" expr="sum(TCC_TOO_MANY_EA_WRREQS_STALL,32)" descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_LEVEL_sum" expr="sum(TCC_EA_WRREQ_LEVEL,32)" descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_LEVEL_sum" expr="sum(TCC_EA_RDREQ_LEVEL,32)" descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_sum" expr="sum(TCC_EA_ATOMIC,32)" descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_LEVEL_sum" expr="sum(TCC_EA_ATOMIC_LEVEL,32)" descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_sum" expr="sum(TCC_EA_RDREQ,32)" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B_sum" expr="sum(TCC_EA_RDREQ_32B,32)" descr="Number of 32-byte TCC/EA read requests Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RD_UNCACHED_32B_sum" expr="sum(TCC_EA_RD_UNCACHED_32B,32)" descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2 Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_IO_CREDIT_STALL_sum" expr="sum(TCC_EA_RDREQ_IO_CREDIT_STALL,32)" descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_GMI_CREDIT_STALL_sum" expr="sum(TCC_EA_RDREQ_GMI_CREDIT_STALL,32)" descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_CREDIT_STALL_sum" expr="sum(TCC_EA_RDREQ_DRAM_CREDIT_STALL,32)" descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TAG_STALL_sum" expr="sum(TCC_TAG_STALL,32)" descr="."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK_sum" expr="sum(TCC_NORMAL_WRITEBACK,32)" descr="Number of writebacks due to requests that are not writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK_sum" expr="sum(TCC_ALL_TC_OP_WB_WRITEBACK,32)" descr="Number of writebacks due to all TC_OP writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT_sum" expr="sum(TCC_NORMAL_EVICT,32)" descr="Number of evictions due to requests that are not invalidate or probe requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT_sum" expr="sum(TCC_ALL_TC_OP_INV_EVICT,32)" descr="Number of evictions due to all TC_OP invalidate requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_sum" expr="sum(TCC_EA_RDREQ_DRAM,32)" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_sum" expr="sum(TCC_EA_WRREQ_DRAM,32)" descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
<metric name="FETCH_SIZE" expr="(TCC_EA_RDREQ_32B_sum*32+(TCC_EA_RDREQ_sum-TCC_EA_RDREQ_32B_sum)*64)/1024" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr="((TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)*32+TCC_EA_WRREQ_64B_sum*64)/1024" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr="TCC_EA_WRREQ_64B_sum*2+(TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)" descr="The total number of 32-byte effective memory writes."></metric>
|
||||
</gfx90a>
|
||||
|
||||
<gfx940>
|
||||
<metric name="GPUBusy" expr="100*GRBM_GUI_ACTIVE/GRBM_COUNT" descr="The percentage of time GPU was busy."></metric>
|
||||
<metric name="Wavefronts" expr="SQ_WAVES" descr="Total wavefronts."></metric>
|
||||
<metric name="VALUInsts" expr="SQ_INSTS_VALU/SQ_WAVES" descr="The average number of vector ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SALUInsts" expr="SQ_INSTS_SALU/SQ_WAVES" descr="The average number of scalar ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SFetchInsts" expr="SQ_INSTS_SMEM/SQ_WAVES" descr="The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="GDSInsts" expr="SQ_INSTS_GDS/SQ_WAVES" descr="The average number of GDS read or GDS write instructions executed per work item (affected by flow control)."></metric>
|
||||
<metric name="MemUnitBusy" expr="100*max(TA_TA_BUSY,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound)."></metric>
|
||||
<metric name="ALUStalledByLDS" expr="100*SQ_WAIT_INST_LDS*4/SQ_WAVES/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="VFetchInsts" expr="(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr="(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES" descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="VALUUtilization" expr="100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE)" descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr="100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr="100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr="FETCH_SIZE" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr="WRITE_SIZE" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr="WRITE_REQ_32B" descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="L2CacheHit" expr="100*sum(TCC_HIT,16)/(sum(TCC_HIT,16)+sum(TCC_MISS,16))" descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="MemUnitStalled" expr="100*max(TCP_TCP_TA_DATA_STALL_CYCLES,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="WriteUnitStalled" expr="100*TCC_WRREQ_STALL_max/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
<metric name="LDSBankConflict" expr="100*SQ_LDS_BANK_CONFLICT/GRBM_GUI_ACTIVE/CU_NUM" descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TA_BUSY_avr" expr="avr(TA_TA_BUSY,16)" descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr="max(TA_TA_BUSY,16)" descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr="min(TA_TA_BUSY,16)" descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_TA_BUSY_sum" expr="sum(TA_TA_BUSY,16)" descr="TA block is busy. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS_sum" expr="sum(TA_TOTAL_WAVEFRONTS,16)" descr="Total number of wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES_sum" expr="sum(TA_ADDR_STALLED_BY_TC_CYCLES,16)" descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES_sum" expr="sum(TA_ADDR_STALLED_BY_TD_CYCLES,16)" descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES_sum" expr="sum(TA_DATA_STALLED_BY_TC_CYCLES,16)" descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS_sum" expr="sum(TA_FLAT_WAVEFRONTS,16)" descr="Number of flat opcode wavfronts processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr="sum(TA_FLAT_READ_WAVEFRONTS,16)" descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr="sum(TA_FLAT_WRITE_WAVEFRONTS,16)" descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS_sum" expr="sum(TA_FLAT_ATOMIC_WAVEFRONTS,16)" descr="Number of flat opcode atomics processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS_sum" expr="sum(TA_BUFFER_WAVEFRONTS,16)" descr="Number of buffer wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS_sum" expr="sum(TA_BUFFER_READ_WAVEFRONTS,16)" descr="Number of buffer read wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS_sum" expr="sum(TA_BUFFER_WRITE_WAVEFRONTS,16)" descr="Number of buffer write wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS_sum" expr="sum(TA_BUFFER_ATOMIC_WAVEFRONTS,16)" descr="Number of buffer atomic wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES_sum" expr="sum(TA_BUFFER_TOTAL_CYCLES,16)" descr="Number of buffer cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES_sum" expr="sum(TA_BUFFER_COALESCED_READ_CYCLES,16)" descr="Number of buffer coalesced read cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES_sum" expr="sum(TA_BUFFER_COALESCED_WRITE_CYCLES,16)" descr="Number of buffer coalesced write cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TD_TD_BUSY_sum" expr="sum(TD_TD_BUSY,16)" descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter. Sum over TD instances."></metric>
|
||||
<metric name="TD_TC_STALL_sum" expr="sum(TD_TC_STALL,16)" descr="TD is stalled waiting for TC data. Sum over TD instances."></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT_sum" expr="sum(TD_LOAD_WAVEFRONT,16)" descr="Count the wavefronts with opcode = load, include atomics and store. Sum over TD instances."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT_sum" expr="sum(TD_ATOMIC_WAVEFRONT,16)" descr="Count the wavefronts with opcode = atomic. Sum over TD instances."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT_sum" expr="sum(TD_STORE_WAVEFRONT,16)" descr="Count the wavefronts with opcode = store. Sum over TD instances."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT_sum" expr="sum(TD_COALESCABLE_WAVEFRONT,16)" descr="Count wavefronts that TA finds coalescable. Sum over TD instances."></metric>
|
||||
<metric name="TD_SPI_STALL_sum" expr="sum(TD_SPI_STALL,16)" descr="TD is stalled SPI vinit, sum of TCP instances"></metric>
|
||||
<metric name="TCP_GATE_EN1_sum" expr="sum(TCP_GATE_EN1,16)" descr="TCP interface clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_GATE_EN2_sum" expr="sum(TCP_GATE_EN2,16)" descr="TCP core clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES_sum" expr="sum(TCP_TD_TCP_STALL_CYCLES,16)" descr="TD stalls TCP. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES_sum" expr="sum(TCP_TCR_TCP_STALL_CYCLES,16)" descr="TCR stalls TCP_TCR_req interface. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES_sum" expr="sum(TCP_READ_TAGCONFLICT_STALL_CYCLES,16)" descr="Tagram conflict stall on a read. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES_sum" expr="sum(TCP_WRITE_TAGCONFLICT_STALL_CYCLES,16)" descr="Tagram conflict stall on a write. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES_sum" expr="sum(TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES,16)" descr="Tagram conflict stall on an atomic. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_VOLATILE_sum" expr="sum(TCP_VOLATILE,16)" descr="Total number of L1 volatile pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES_sum" expr="sum(TCP_TOTAL_ACCESSES,16)" descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_READ_sum" expr="sum(TCP_TOTAL_READ,16)" descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITE_sum" expr="sum(TCP_TOTAL_WRITE,16)" descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET_sum" expr="sum(TCP_TOTAL_ATOMIC_WITH_RET,16)" descr="Total number of atomic with return pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET_sum" expr="sum(TCP_TOTAL_ATOMIC_WITHOUT_RET,16)" descr="Total number of atomic without return pixels/buffers from TA Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES_sum" expr="sum(TCP_TOTAL_WRITEBACK_INVALIDATES,16)" descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST_sum" expr="sum(TCP_UTCL1_REQUEST,16)" descr="Total CLIENT_UTCL1 NORMAL requests Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS_sum" expr="sum(TCP_UTCL1_TRANSLATION_MISS,16)" descr="Total utcl1 translation misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT_sum" expr="sum(TCP_UTCL1_TRANSLATION_HIT,16)" descr="Total utcl1 translation hits Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS_sum" expr="sum(TCP_UTCL1_PERMISSION_MISS,16)" descr="Total utcl1 permission misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES_sum" expr="sum(TCP_TOTAL_CACHE_ACCESSES,16)" descr="Count of total cache line (tag) accesses (includes hits and misses). Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ_sum" expr="sum(TCP_TA_TCP_STATE_READ,16)" descr="Number of state reads Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_sum" expr="sum(TCP_TCC_READ_REQ,16)" descr="Total read requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_sum" expr="sum(TCP_TCC_WRITE_REQ,16)" descr="Total write requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ_sum" expr="sum(TCP_TCC_ATOMIC_WITH_RET_REQ,16)" descr="Total atomic with return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ_sum" expr="sum(TCP_TCC_ATOMIC_WITHOUT_RET_REQ,16)" descr="Total atomic without return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ_sum" expr="sum(TCP_TCC_NC_READ_REQ,16)" descr="Total read requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_RWriteUnitStalledQ_sum" expr="sum(TCP_TCC_RW_READ_REQ,16)" descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ_sum" expr="sum(TCP_TCC_RW_WRITE_REQ,16)" descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ_sum" expr="sum(TCP_TCC_RW_ATOMIC_REQ,16)" descr="Total atomic requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES_sum" expr="sum(TCP_PENDING_STALL_CYCLES,16)" descr="Stall due to data pending from L2. Sum over TCP instances."></metric>
|
||||
<metric name="TCA_CYCLE_sum" expr="sum(TCA_CYCLE,16)" descr="Number of cycles. Sum over all TCA instances "></metric>
|
||||
<metric name="TCA_BUSY_sum" expr="sum(TCA_BUSY,16)" descr="Number of cycles we have a request pending. Sum over all TCA instances."></metric>
|
||||
<metric name="TCC_BUSY_avr" expr="avr(TCC_BUSY,32)" descr="TCC_BUSY avr over all memory channels."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr="max(TCC_EA0_WRREQ_STALL,32)" descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
<metric name="TCC_CYCLE_sum" expr="sum(TCC_CYCLE,32)" descr="Number of cycles. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_BUSY_sum" expr="sum(TCC_BUSY,32)" descr="Number of cycles we have a request pending. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_REQ_sum" expr="sum(TCC_REQ,32)" descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_STREAMING_REQ_sum" expr="sum(TCC_STREAMING_REQ,32)" descr="Number of streaming requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NC_REQ_sum" expr="sum(TCC_NC_REQ,32)" descr="The number of noncoherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_UC_REQ_sum" expr="sum(TCC_UC_REQ,32)" descr="The number of uncached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_CC_REQ_sum" expr="sum(TCC_CC_REQ,32)" descr="The number of coherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_RW_REQ_sum" expr="sum(TCC_RW_REQ,32)" descr="The number of RW requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_sum" expr="sum(TCC_PROBE,32)" descr="Number of probe requests. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_ALL_sum" expr="sum(TCC_PROBE_ALL,32)" descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_READ_sum" expr="sum(TCC_READ,32)" descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITE_sum" expr="sum(TCC_WRITE,32)" descr="Number of write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ATOMIC_sum" expr="sum(TCC_ATOMIC,32)" descr="Number of atomic requests of all types. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_HIT_sum" expr="sum(TCC_HIT,32)" descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr="sum(TCC_MISS,32)" descr="Number of cache misses. UC reads count as misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITEBACK_sum" expr="sum(TCC_WRITEBACK,32)" descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_sum" expr="sum(TCC_EA0_WRREQ,32)" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_64B_sum" expr="sum(TCC_EA0_WRREQ_64B,32)" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WR_UNCACHED_32B_sum" expr="sum(TCC_EA0_WR_UNCACHED_32B,32)" descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_STALL_sum" expr="sum(TCC_EA0_WRREQ_STALL,32)" descr="Number of cycles a write request was stalled. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_IO_CREDIT_STALL_sum" expr="sum(TCC_EA0_WRREQ_IO_CREDIT_STALL,32)" descr="Number of cycles a EA write request was stalled because the interface was out of IO credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_GMI_CREDIT_STALL_sum" expr="sum(TCC_EA0_WRREQ_GMI_CREDIT_STALL,32)" descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM_CREDIT_STALL_sum" expr="sum(TCC_EA0_WRREQ_DRAM_CREDIT_STALL,32)" descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL_sum" expr="sum(TCC_TOO_MANY_EA_WRREQS_STALL,32)" descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_LEVEL_sum" expr="sum(TCC_EA0_WRREQ_LEVEL,32)" descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_LEVEL_sum" expr="sum(TCC_EA0_RDREQ_LEVEL,32)" descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC_sum" expr="sum(TCC_EA0_ATOMIC,32)" descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC_LEVEL_sum" expr="sum(TCC_EA0_ATOMIC_LEVEL,32)" descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_sum" expr="sum(TCC_EA0_RDREQ,32)" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_32B_sum" expr="sum(TCC_EA0_RDREQ_32B,32)" descr="Number of 32-byte TCC/EA read requests Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RD_UNCACHED_32B_sum" expr="sum(TCC_EA0_RD_UNCACHED_32B,32)" descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2 Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_IO_CREDIT_STALL_sum" expr="sum(TCC_EA0_RDREQ_IO_CREDIT_STALL,32)" descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_GMI_CREDIT_STALL_sum" expr="sum(TCC_EA0_RDREQ_GMI_CREDIT_STALL,32)" descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM_CREDIT_STALL_sum" expr="sum(TCC_EA0_RDREQ_DRAM_CREDIT_STALL,32)" descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TAG_STALL_sum" expr="sum(TCC_TAG_STALL,32)" descr="."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK_sum" expr="sum(TCC_NORMAL_WRITEBACK,32)" descr="Number of writebacks due to requests that are not writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK_sum" expr="sum(TCC_ALL_TC_OP_WB_WRITEBACK,32)" descr="Number of writebacks due to all TC_OP writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT_sum" expr="sum(TCC_NORMAL_EVICT,32)" descr="Number of evictions due to requests that are not invalidate or probe requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT_sum" expr="sum(TCC_ALL_TC_OP_INV_EVICT,32)" descr="Number of evictions due to all TC_OP invalidate requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM_sum" expr="sum(TCC_EA0_RDREQ_DRAM,32)" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM_sum" expr="sum(TCC_EA0_WRREQ_DRAM,32)" descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
<metric name="FETCH_SIZE" expr="(TCC_EA0_RDREQ_32B_sum*32+(TCC_EA0_RDREQ_sum-TCC_EA0_RDREQ_32B_sum)*64)/1024" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr="((TCC_EA0_WRREQ_sum-TCC_EA0_WRREQ_64B_sum)*32+TCC_EA0_WRREQ_64B_sum*64)/1024" descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr="TCC_EA0_WRREQ_64B_sum*2+(TCC_EA0_WRREQ_sum-TCC_EA0_WRREQ_64B_sum)" descr="The total number of 32-byte effective memory writes."></metric>
|
||||
</gfx940>
|
||||
|
||||
<gfx10>
|
||||
<metric name="GPUBusy" expr="100*GRBM_GUI_ACTIVE/GRBM_COUNT" descr="The percentage of time GPU was busy."></metric>
|
||||
<metric name="Wavefronts" expr="SQ_WAVES" descr="Total wavefronts."></metric>
|
||||
<metric name="VALUInsts" expr="SQ_INSTS_VALU/SQ_WAVES" descr="The average number of vector ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SALUInsts" expr="SQ_INSTS_SALU/SQ_WAVES" descr="The average number of scalar ALU instructions executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="SFetchInsts" expr="SQ_INSTS_SMEM/SQ_WAVES" descr="The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control)."></metric>
|
||||
<metric name="GDSInsts" expr="SQ_INSTS_GDS/SQ_WAVES" descr="The average number of GDS read or GDS write instructions executed per work item (affected by flow control)."></metric>
|
||||
<metric name="MemUnitBusy" expr="100*max(TA_TA_BUSY,16)/GRBM_GUI_ACTIVE/SE_NUM" descr="The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound)."></metric>
|
||||
<metric name="ALUStalledByLDS" expr="100*SQ_WAIT_INST_LDS*4/SQ_WAVES/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="GPU_UTIL" expr="100*GRBM_GUI_ACTIVE/GRBM_COUNT" descr="Percentage of the time that GUI is active"></metric>
|
||||
<metric name="CP_UTIL" expr="100*GRBM_CP_BUSY/GRBM_GUI_ACTIVE" descr="Percentage of the GRBM_GUI_ACTIVE time that any of the Command Processor (CPG/CPC/CPF) blocks are busy"></metric>
|
||||
<metric name="SPI_UTIL" expr="100*GRBM_SPI_BUSY/GRBM_GUI_ACTIVE" descr="Percentage of the GRBM_GUI_ACTIVE time that any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)"></metric>
|
||||
<metric name="TA_UTIL" expr="100*GRBM_TA_BUSY/GRBM_GUI_ACTIVE" descr="Percentage of the GRBM_GUI_ACTIVE time that any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GDS_UTIL" expr="100*GRBM_GDS_BUSY/GRBM_GUI_ACTIVE" descr="Percentage of the GRBM_GUI_ACTIVE time that the Global Data Share (GDS) is busy."></metric>
|
||||
<metric name="EA_UTIL" expr="100*GRBM_EA_BUSY/GRBM_GUI_ACTIVE" descr="Percentage of the GRBM_GUI_ACTIVE time that the Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="WAVE_DEP_WAIT" expr="100*SQ_WAIT_ANY/SQ_WAVE_CYCLES" descr="Percentage of the SQ_WAVE_CYCLE time spent waiting for anything."></metric>
|
||||
<metric name="WAVE_ISSUE_WAIT" expr="100*SQ_WAIT_INST_ANY/SQ_WAVE_CYCLES" descr="Percentage of the SQ_WAVE_CYCLE time spent waiting for any instruction issue."></metric>
|
||||
<metric name="TA_BUSY_avr" expr="avr(TA_TA_BUSY,16)" descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr="max(TA_TA_BUSY,16)" descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr="min(TA_TA_BUSY,16)" descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_FLAT_LOAD_WAVEFRONTS_sum" expr="sum(TA_FLAT_LOAD_WAVEFRONTS,16)" descr="Number of flat load vec32 packets processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_STORE_WAVEFRONTS_sum" expr="sum(TA_FLAT_STORE_WAVEFRONTS,16)" descr="Number of flat store vec32 packets processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="GL2C_HIT_sum" expr="sum(GL2C_HIT,16)" descr="Number of cache hits. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_MISS_sum" expr="sum(GL2C_MISS,16)" descr="Number of cache misses. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_32B_sum" expr="sum(GL2C_EA_RDREQ_32B,16)" descr="Number of 32-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_64B_sum" expr="sum(GL2C_EA_RDREQ_64B,16)" descr="Number of 64-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_96B_sum" expr="sum(GL2C_EA_RDREQ_96B,16)" descr="Number of 96-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_128B_sum" expr="sum(GL2C_EA_RDREQ_128B,16)" descr="Number of 128-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_MC_RDREQ_sum" expr="sum(GL2C_MC_RDREQ,16)" descr="Number of GL2C/EA read requests (either 32-byte or 64-byte or 128-byte). Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_MC_WRREQ_sum" expr="sum(GL2C_MC_WRREQ,16)" descr="Number of transactions (either 32-byte or 64-byte) going over the GL2C_MC_wrreq interface. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_WRREQ_64B_sum" expr="sum(GL2C_EA_WRREQ_64B,16)" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the GL2C_EA_wrreq interface. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_WRREQ_STALL_max" expr="max(GL2C_MC_WRREQ_STALL,16)" descr="Number of cycles a write request was stalled. Max over GL2C instances."></metric>
|
||||
<metric name="L2CacheHit" expr="100*sum(GL2C_HIT,16)/(sum(GL2C_HIT,16)+sum(GL2C_MISS,16))" descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="FETCH_SIZE" expr="(GL2C_EA_RDREQ_32B_sum*32+GL2C_EA_RDREQ_64B_sum*64+GL2C_EA_RDREQ_96B_sum*96+GL2C_EA_RDREQ_128B_sum*128)/1024" descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteUnitStalled" expr="100*GL2C_WRREQ_STALL_max/GRBM_GUI_ACTIVE" descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
<metric name="LDSBankConflict" expr="100*SQC_LDS_BANK_CONFLICT/SQC_LDS_IDX_ACTIVE" descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
</gfx10>
|
||||
|
||||
</metrics>
|
||||
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
from collections import deque
|
||||
from re import sub
|
||||
import xml.etree.ElementTree as ET
|
||||
from lxml import etree
|
||||
import ast
|
||||
import sys
|
||||
|
||||
ops = {'Div': '/', 'Mult': '*', 'Add': '+', 'Sub': '-'}
|
||||
calls = {'avr', 'max', 'min', 'sum'}
|
||||
|
||||
def parse_expr(gpu_tag, data):
|
||||
global exprs_counters
|
||||
global exprs_counters_init
|
||||
global expr_print
|
||||
global counter_count
|
||||
global counters_dictionary
|
||||
expr_queue = deque()
|
||||
for line in data.split('\n'):
|
||||
if 'Constant' in line:
|
||||
number = line.split('(')[1].split(')')[0]
|
||||
expr_queue.append('(uint64_t)' + number)
|
||||
if 'Name' in line:
|
||||
name = line.split('\'')[1]
|
||||
if name in calls:
|
||||
expr_queue.append(name)
|
||||
else:
|
||||
if not name in exprs_counters:
|
||||
exprs_counters += "getGeneratedBasicCounter(" + name + "_id), "
|
||||
exprs_counters_init += "\n\t\tuint64_t " + name + "_id = getBasicCounter(\"" + name + "\", \"" + gpu_tag + "\");"
|
||||
counters_dictionary[name] = counter_count
|
||||
counter_count+=1
|
||||
expr_queue.append("counter.getBasicCounterFromDerived(" + str(counters_dictionary[name]) + ")")
|
||||
op = line.split('(')[0]
|
||||
if op in ops:
|
||||
expr_queue.append(ops[op])
|
||||
expr_print += "\n\t\t\t\treturn "
|
||||
i = 0
|
||||
for element in expr_queue:
|
||||
if element in calls:
|
||||
i = 1
|
||||
call = element
|
||||
elif i == 1:
|
||||
expr_print += element + "." + call + "("
|
||||
call = ""
|
||||
i = 2
|
||||
elif i == 2:
|
||||
expr_print += element + ")"
|
||||
i = 0
|
||||
else:
|
||||
expr_print += element
|
||||
if "counter.getBasicCounterFromDerived" == element[0:34]:
|
||||
expr_print += "->getValue()"
|
||||
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
global exprs_counters
|
||||
global exprs_counters_init
|
||||
global expr_print
|
||||
global counter_count
|
||||
parser = etree.XMLParser(recover=True, encoding='utf-8')
|
||||
xml_file = ET.parse(sys.argv[1] + '/metrics.xml', parser=parser)
|
||||
root = xml_file.getroot()
|
||||
print(
|
||||
"uint64_t getDerivedCounter(const char* name, const char* gpu_name) {")
|
||||
for gpu in root:
|
||||
print("\n\t/**\n\t * @brief Derived " + gpu.tag + " counters\n\t *\n\t * @{\n\t */")
|
||||
print("\tif (strcmp(gpu_name, \"" + gpu.tag + "\")==0) {")
|
||||
for child in gpu:
|
||||
exprs_counters = ""
|
||||
exprs_counters_init = ""
|
||||
expr_print = ""
|
||||
counter_count = 0
|
||||
counters_dictionary = {}
|
||||
parse_expr(gpu.tag.split("_")[0], ast.dump(ast.parse(
|
||||
child.attrib['expr'], mode='eval'), annotate_fields=False, include_attributes=False, indent=0))
|
||||
print("\t/**\n\t * Derived Counter: " + child.attrib['name'] + "\n\t *\n\t * " + child.attrib['descr'] + "\n\t */\n\tif (strcmp(name, \"" +
|
||||
child.attrib['name'] + "\")==0) {" + exprs_counters_init + "\n\t\tDerivedCounter counter = DerivedCounter(\"" + child.attrib['name'] +
|
||||
"\", \"" + child.attrib['descr'] + "\", \"" + gpu.tag.split("_")[0] + "\");")
|
||||
exprs_counter_count = 0
|
||||
for expr_counter in exprs_counters[0:-2].split(", "):
|
||||
print("\n\t\tcounter.addBasicCounter(" + str(exprs_counter_count) + ", " + expr_counter + ");")
|
||||
exprs_counter_count += 1
|
||||
# print("\n\t\tcounter.evaluate_metric = [counter]() {" + expr_print + ";\n\t\t\t};")
|
||||
print("\n\t\tderived_counters.emplace(counter.getMetricId(), counter);\n\t\treturn counter.getMetricId();\n\t}")
|
||||
print("\t}\n\n\t/**\n\t * @}\n\t */")
|
||||
print("\n\treturn 0;\n}\n")
|
||||
@@ -0,0 +1,683 @@
|
||||
<gfx8>
|
||||
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
|
||||
|
||||
<metric name="SQ_WAVES" block=SQ event=4 descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block=SQ event=26 descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block=SQ event=27 descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block=SQ event=28 descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block=SQ event=30 descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block=SQ event=31 descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block=SQ event=32 descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block=SQ event=33 descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block=SQ event=34 descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block=SQ event=35 descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
|
||||
<metric name="SQ_WAIT_INST_LDS" block=SQ event=61 descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block=SQ event=69 descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block=SQ event=86 descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block=SQ event=89 descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block=SQ event=97 descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
|
||||
<metric name="TA_TA_BUSY" block=TA event=15 descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block=TA event=101 descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block=TA event=102 descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
|
||||
<metric name="TCC_HIT" block=TCC event=18 descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block=TCC event=19 descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_MC_RDREQ" block=TCC event=35 descr="Number of 32-byte reads. The hardware actually does 64-byte reads but the number is adjusted to provide uniformity."></metric>
|
||||
<metric name="TCC_MC_WRREQ" block=TCC event=26 descr="Number of 32-byte transactions going over the TC_MC_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests."></metric>
|
||||
<metric name="TCC_MC_WRREQ_STALL" block=TCC event=28 descr="Number of cycles a write request was stalled."></metric>
|
||||
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block=TCP event=3 descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
</gfx8>
|
||||
|
||||
<gfx9>
|
||||
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
|
||||
|
||||
<metric name="SQ_WAVES" block=SQ event=4 descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block=SQ event=26 descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block=SQ event=27 descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block=SQ event=28 descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block=SQ event=30 descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block=SQ event=31 descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block=SQ event=32 descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block=SQ event=33 descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block=SQ event=34 descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block=SQ event=35 descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
|
||||
<metric name="SQ_WAIT_INST_LDS" block=SQ event=63 descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block=SQ event=71 descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block=SQ event=84 descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block=SQ event=85 descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block=SQ event=93 descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
|
||||
<metric name="TA_TA_BUSY" block=TA event=15 descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block=TA event=101 descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block=TA event=102 descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
|
||||
<metric name="TCC_HIT" block=TCC event=20 descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block=TCC event=22 descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block=TCC event=29 descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block=TCC event=30 descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block=TCC event=33 descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block=TCC event=41 descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block=TCC event=42 descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block=TCP event=6 descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
</gfx9>
|
||||
|
||||
<gfx906 base="gfx9">
|
||||
# EA1
|
||||
<metric name="TCC_EA1_WRREQ" block=TCC event=256 descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_64B" block=TCC event=257 descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_STALL" block=TCC event=260 descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA1_RDREQ" block=TCC event=267 descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA1_RDREQ_32B" block=TCC event=268 descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
</gfx906>
|
||||
|
||||
<gfx908 base="gfx9">
|
||||
<metric name="SQ_INSTS_VMEM_WR" block=SQ event=28 descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block=SQ event=29 descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block=SQ event=31 descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block=SQ event=32 descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block=SQ event=33 descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block=SQ event=34 descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block=SQ event=35 descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block=SQ event=36 descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
|
||||
<metric name="SQ_WAIT_INST_LDS" block=SQ event=64 descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block=SQ event=72 descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block=SQ event=85 descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block=SQ event=86 descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block=SQ event=94 descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
|
||||
<metric name="TCC_HIT" block=TCC event=17 descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block=TCC event=19 descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block=TCC event=26 descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block=TCC event=27 descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block=TCC event=30 descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block=TCC event=38 descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block=TCC event=39 descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
</gfx908>
|
||||
|
||||
<gfx90a>
|
||||
<metric name="SQ_WAIT_INST_LDS" block=SQ event=91 descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block=TCP event=6 descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block=GRBM event=3 descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block=GRBM event=11 descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block=GRBM event=13 descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TC_BUSY" block=GRBM event=28 descr="Any of the Texture Cache Blocks (TCP/TCI/TCA/TCC) are busy."></metric>
|
||||
<metric name="GRBM_CPC_BUSY" block=GRBM event=30 descr="The Command Processor Compute (CPC) is busy."></metric>
|
||||
<metric name="GRBM_CPF_BUSY" block=GRBM event=31 descr="The Command Processor Fetchers (CPF) is busy."></metric>
|
||||
<metric name="GRBM_UTCL2_BUSY" block=GRBM event=34 descr="The Unified Translation Cache Level-2 (UTCL2) block is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block=GRBM event=35 descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="CPC_ME1_BUSY_FOR_PACKET_DECODE" block=CPC event=13 descr="Me1 busy for packet decode."></metric>
|
||||
<metric name="CPC_UTCL1_STALL_ON_TRANSLATION" block=CPC event=24 descr="One of the UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPC_CPC_STAT_BUSY" block=CPC event=25 descr="CPC Busy."></metric>
|
||||
<metric name="CPC_CPC_STAT_IDLE" block=CPC event=26 descr="CPC Idle."></metric>
|
||||
<metric name="CPC_CPC_STAT_STALL" block=CPC event=27 descr="CPC Stalled."></metric>
|
||||
<metric name="CPC_CPC_TCIU_BUSY" block=CPC event=28 descr="CPC TCIU interface Busy."></metric>
|
||||
<metric name="CPC_CPC_TCIU_IDLE" block=CPC event=29 descr="CPC TCIU interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_BUSY" block=CPC event=30 descr="CPC UTCL2 interface Busy."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_IDLE" block=CPC event=31 descr="CPC UTCL2 interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_STALL" block=CPC event=32 descr="CPC UTCL2 interface Stalled waiting on Free, Tags or Translation."></metric>
|
||||
<metric name="CPC_ME1_DC0_SPI_BUSY" block=CPC event=33 descr="CPC Me1 Processor Busy."></metric>
|
||||
<metric name="CPF_CMP_UTCL1_STALL_ON_TRANSLATION" block=CPF event=20 descr="One of the Compute UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPF_CPF_STAT_BUSY" block=CPF event=23 descr="CPF Busy."></metric>
|
||||
<metric name="CPF_CPF_STAT_IDLE" block=CPF event=24 descr="CPF Idle."></metric>
|
||||
<metric name="CPF_CPF_STAT_STALL" block=CPF event=25 descr="CPF Stalled."></metric>
|
||||
<metric name="CPF_CPF_TCIU_BUSY" block=CPF event=26 descr="CPF TCIU interface Busy."></metric>
|
||||
<metric name="CPF_CPF_TCIU_IDLE" block=CPF event=27 descr="CPF TCIU interface Idle."></metric>
|
||||
<metric name="CPF_CPF_TCIU_STALL" block=CPF event=28 descr="CPF TCIU interface Stalled waiting on Free, Tags."></metric>
|
||||
<metric name="SPI_CSN_WINDOW_VALID" block=SPI event=47 descr="Clock count enabled by perfcounter_start event. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_BUSY" block=SPI event=48 descr="Number of clocks with outstanding waves (SPI or SH). Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_NUM_THREADGROUPS" block=SPI event=49 descr="Number of threadgroups launched. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_WAVE" block=SPI event=52 descr="Number of waves. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC" block=SPI event=79 descr="Arb cycles with requests but no allocation. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC_CSN" block=SPI event=85 descr="Arb cycles with CSn req and no CSn alloc. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_RES_STALL_CSN" block=SPI event=91 descr="Arb cycles with CSn req and no CSn fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TMP_STALL_CSN" block=SPI event=97 descr="Cycles where csn wants to req but does not fit in temp space."></metric>
|
||||
<metric name="SPI_RA_WAVE_SIMD_FULL_CSN" block=SPI event=103 descr="Sum of SIMD where WAVE can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_VGPR_SIMD_FULL_CSN" block=SPI event=109 descr="Sum of SIMD where VGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_SGPR_SIMD_FULL_CSN" block=SPI event=115 descr="Sum of SIMD where SGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_LDS_CU_FULL_CSN" block=SPI event=120 descr="Sum of CU where LDS can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BAR_CU_FULL_CSN" block=SPI event=123 descr="Sum of CU where BARRIER can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BULKY_CU_FULL_CSN" block=SPI event=125 descr="Sum of CU where BULKY can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TGLIM_CU_FULL_CSN" block=SPI event=127 descr="Cycles where csn wants to req but all CU are at tg_limit"></metric>
|
||||
<metric name="SPI_RA_WVLIM_STALL_CSN" block=SPI event=133 descr="Number of clocks csn is stalled due to WAVE LIMIT."></metric>
|
||||
<metric name="SPI_SWC_CSC_WR" block=SPI event=189 descr="Number of clocks to write CSC waves to SGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_VWC_CSC_WR" block=SPI event=195 descr="Number of clocks to write CSC waves to VGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SQ_ACCUM_PREV" block=SQ event=1 descr="For counter N, increment by the value of counter N-1. Only accumulates once every 4 cycles."></metric>
|
||||
<metric name="SQ_CYCLES" block=SQ event=2 descr="Clock cycles. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_BUSY_CYCLES" block=SQ event=3 descr="Clock cycles while SQ is reporting that it is busy. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES" block=SQ event=4 descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_LEVEL_WAVES" block=SQ event=5 descr="Track the number of waves. Set ACCUM_PREV for the next counter to use this. (level, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES_EQ_64" block=SQ event=6 descr="Count number of waves with exactly 64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_64" block=SQ event=7 descr="Count number of waves with <64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_48" block=SQ event=8 descr="Count number of waves with <48 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_32" block=SQ event=9 descr="Count number of waves sent <32 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_16" block=SQ event=10 descr="Count number of waves sent <16 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_BUSY_CU_CYCLES" block=SQ event=13 descr="Count quad-cycles each CU is busy. (nondeterministic, per-simd)"></metric>
|
||||
<metric name="SQ_ITEMS" block=SQ event=14 descr="Number of valid items per wave. (per-simd, global)"></metric>
|
||||
<metric name="SQ_INSTS" block=SQ event=25 descr="Number of instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block=SQ event=26 descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F16" block=SQ event=27 descr="Number of VALU ADD/SUB instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F16" block=SQ event=28 descr="Number of VALU MUL instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F16" block=SQ event=29 descr="Number of VALU FMA/MAD instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F16" block=SQ event=30 descr="Number of VALU transcendental instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F32" block=SQ event=31 descr="Number of VALU ADD/SUB instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F32" block=SQ event=32 descr="Number of VALU MUL instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F32" block=SQ event=33 descr="Number of VALU FMA/MAD instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F32" block=SQ event=34 descr="Number of VALU transcendental instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F64" block=SQ event=35 descr="Number of VALU ADD/SUB instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F64" block=SQ event=36 descr="Number of VALU MUL instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F64" block=SQ event=37 descr="Number of VALU FMA/MAD instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F64" block=SQ event=38 descr="Number of VALU transcendental instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT32" block=SQ event=39 descr="Number of VALU 32-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT64" block=SQ event=40 descr="Number of VALU 64-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_CVT" block=SQ event=41 descr="Number of VALU data conversion instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_I8" block=SQ event=42 descr="Number of VALU V_MFMA_*_I8 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F16" block=SQ event=43 descr="Number of VALU V_MFMA_*_F16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_BF16" block=SQ event=44 descr="Number of VALU V_MFMA_*_BF16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F32" block=SQ event=45 descr="Number of VALU V_MFMA_*_F32 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F64" block=SQ event=46 descr="Number of VALU V_MFMA_*_F64 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_I8" block=SQ event=47 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type I8. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F16" block=SQ event=48 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_BF16" block=SQ event=49 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type BF16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F32" block=SQ event=50 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F64" block=SQ event=51 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_MFMA" block=SQ event=52 descr="Number of MFMA instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block=SQ event=53 descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block=SQ event=54 descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM" block=SQ event=55 descr="Number of VMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block=SQ event=56 descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block=SQ event=57 descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block=SQ event=58 descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block=SQ event=59 descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block=SQ event=60 descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block=SQ event=61 descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_EXP_GDS" block=SQ event=63 descr="Number of EXP and GDS instructions issued, excluding skipped export instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_BRANCH" block=SQ event=64 descr="Number of Branch instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SENDMSG" block=SQ event=65 descr="Number of Sendmsg instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VSKIPPED" block=SQ event=66 descr="Number of vector instructions skipped. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_VMEM" block=SQ event=67 descr="Number of in-flight VMEM instructions. Set next counter to ACCUM_PREV and divide by INSTS_VMEM for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_SMEM" block=SQ event=68 descr="Number of in-flight SMEM instructions (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). Set next counter to ACCUM_PREV and divide by INSTS_SMEM for average latency per smem request. Falls slightly short of total request latency because some fetches are divided into two requests that may finish at different times and this counter collects the average latency of the two. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block=SQ event=69 descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_VALU_MFMA_BUSY_CYCLES" block=SQ event=72 descr="Number of cycles the MFMA ALU is busy (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block=SQ event=74 descr="Number of wave-cycles spent by waves in the CUs (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block=SQ event=85 descr="Number of wave-cycles spent waiting for anything (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block=SQ event=88 descr="Number of wave-cycles spent waiting for any instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_ANY" block=SQ event=96 descr="Number of cycles each wave is working on an instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VMEM" block=SQ event=97 descr="Number of cycles the SQ instruction arbiter is working on a VMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_LDS" block=SQ event=98 descr="Number of cycles the SQ instruction arbiter is working on a LDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block=SQ event=99 descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_SCA" block=SQ event=100 descr="Number of cycles the SQ instruction arbiter is working on a SALU or SMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_EXP_GDS" block=SQ event=101 descr="Number of cycles the SQ instruction arbiter is working on an EXPORT or GDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_MISC" block=SQ event=102 descr="Number of cycles the SQ instruction aribter is working on a BRANCH or SENDMSG instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_FLAT" block=SQ event=103 descr="Number of cycles the SQ instruction arbiter is working on a FLAT instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_WR" block=SQ event=104 descr="Number of cycles needed to send addr and cmd data for VMEM write instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_RD" block=SQ event=105 descr="Number of cycles needed to send addr and cmd data for VMEM read instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SMEM" block=SQ event=111 descr="Number of cycles needed to execute scalar memory reads. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block=SQ event=112 descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block=SQ event=113 descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_IFETCH" block=SQ event=115 descr="Number of instruction fetch requests from cache. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_IFETCH_LEVEL" block=SQ event=116 descr="Number of instruction fetch requests from cache. (per-simd, level)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block=SQ event=121 descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_ADDR_CONFLICT" block=SQ event=122 descr="Number of cycles LDS is stalled by address conflicts. (emulated,nondeterministic)"></metric>
|
||||
<metric name="SQ_LDS_UNALIGNED_STALL" block=SQ event=123 descr="Number of cycles LDS is stalled processing flat unaligned load/store ops. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_MEM_VIOLATIONS" block=SQ event=124 descr="Number of threads that have a memory violation in the LDS.(emulated)"></metric>
|
||||
<metric name="SQ_LDS_ATOMIC_RETURN" block=SQ event=125 descr="Number of atomic return cycles in LDS. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_LDS_IDX_ACTIVE" block=SQ event=126 descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACCUM_PREV_HIRES" block=SQ event=185 descr="For counter N, increment by the value of counter N-1."></metric>
|
||||
<metric name="SQ_WAVES_RESTORED" block=SQ event=186 descr="Count number of context-restored waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_SAVED" block=SQ event=187 descr="Count number of context-saved waves. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM_NORM" block=SQ event=188 descr="Number of SMEM instructions issued normalized to match smem_level (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). (per-simd, emulated)"></metric>
|
||||
<metric name="SQC_DCACHE_INPUT_VALID_READYB" block=SQ event=260 descr="Input stalled by SQC (per-SQ, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_TC_REQ" block=SQ event=262 descr="Total number of TC requests that were issued by instruction and constant caches. (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_INST_REQ" block=SQ event=263 descr="Number of insruction requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_READ_REQ" block=SQ event=264 descr="Number of data read requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_WRITE_REQ" block=SQ event=265 descr="Number of data write requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_ATOMIC_REQ" block=SQ event=266 descr="Number of data atomic requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_STALL" block=SQ event=267 descr="Valid request stalled TC request interface (no-credits). (No-Masking, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_ICACHE_REQ" block=SQ event=270 descr="Number of requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_ICACHE_HITS" block=SQ event=271 descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES" block=SQ event=272 descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES_DUPLICATE" block=SQ event=273 descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_REQ" block=SQ event=290 descr="Number of requests (post-bank-serialization). (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_HITS" block=SQ event=291 descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES" block=SQ event=292 descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES_DUPLICATE" block=SQ event=293 descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_ATOMIC" block=SQ event=298 descr="Number of atomic requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_1" block=SQ event=323 descr="Number of constant cache 1 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_2" block=SQ event=324 descr="Number of constant cache 2 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_4" block=SQ event=325 descr="Number of constant cache 4 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_8" block=SQ event=326 descr="Number of constant cache 8 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_16" block=SQ event=327 descr="Number of constant cache 16 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="TA_TA_BUSY" block=TA event=15 descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS" block=TA event=32 descr="Total number of wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS" block=TA event=44 descr="Number of buffer wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS" block=TA event=45 descr="Number of buffer read wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS" block=TA event=46 descr="Number of buffer write wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS" block=TA event=47 descr="Number of buffer atomic wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES" block=TA event=49 descr="Number of buffer cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES" block=TA event=52 descr="Number of buffer coalesced read cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES" block=TA event=53 descr="Number of buffer coalesced write cycles issued to TC."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES" block=TA event=54 descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES" block=TA event=55 descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES" block=TA event=56 descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS" block=TA event=100 descr="Number of flat opcode wavfronts processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block=TA event=101 descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block=TA event=102 descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS" block=TA event=103 descr="Number of flat opcode atomics processed by the TA."></metric>
|
||||
<metric name="TD_TD_BUSY" block=TD event=1 descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TD_TC_STALL" block=TD event=15 descr="TD is stalled waiting for TC data."></metric>
|
||||
<metric name="TD_SPI_STALL" block=TD event=18 descr="TD is stalled SPI vinit"></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT" block=TD event=25 descr="Count the wavefronts with opcode = load, include atomics and store."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT" block=TD event=26 descr="Count the wavefronts with opcode = atomic."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT" block=TD event=27 descr="Count the wavefronts with opcode = store."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT" block=TD event=32 descr="Count wavefronts that TA finds coalescable."></metric>
|
||||
<metric name="TCP_GATE_EN1" block=TCP event=0 descr="TCP interface clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_GATE_EN2" block=TCP event=1 descr="TCP core clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES" block=TCP event=7 descr="TD stalls TCP"></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES" block=TCP event=8 descr="TCR stalls TCP_TCR_req interface"></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES" block=TCP event=11 descr="Tagram conflict stall on a read"></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES" block=TCP event=12 descr="Tagram conflict stall on a write"></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES" block=TCP event=13 descr="Tagram conflict stall on an atomic"></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES" block=TCP event=22 descr="Stall due to data pending from L2"></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ" block=TCP event=27 descr="Number of state reads"></metric>
|
||||
<metric name="TCP_VOLATILE" block=TCP event=28 descr="Total number of L1 volatile pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES" block=TCP event=29 descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD"></metric>
|
||||
<metric name="TCP_TOTAL_READ" block=TCP event=30 descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ"></metric>
|
||||
<metric name="TCP_TOTAL_WRITE" block=TCP event=32 descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET" block=TCP event=38 descr="Total number of atomic with return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET" block=TCP event=39 descr="Total number of atomic without return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES" block=TCP event=45 descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST" block=TCP event=47 descr="Total CLIENT_UTCL1 NORMAL requests"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS" block=TCP event=48 descr="Total utcl1 translation misses"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT" block=TCP event=49 descr="Total utcl1 translation hits"></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS" block=TCP event=50 descr="Total utcl1 permission misses"></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES" block=TCP event=60 descr="Count of total cache line (tag) accesses (includes hits and misses)."></metric>
|
||||
<metric name="TCP_TCP_LATENCY" block=TCP event=65 descr="Total TCP wave latency (from first clock of wave entering to first clock of wave leaving), divide by TA_TCP_STATE_READ to avg wave latency"></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_LATENCY" block=TCP event=66 descr="Total TCP->TCC request latency for reads and atomics with return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_LATENCY" block=TCP event=67 descr="Total TCP->TCC request latency for writes and atomics without return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ" block=TCP event=69 descr="Total read requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ" block=TCP event=70 descr="Total write requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ" block=TCP event=71 descr="Total atomic with return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ" block=TCP event=72 descr="Total atomic without return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ" block=TCP event=75 descr="Total read requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ" block=TCP event=76 descr="Total write requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ" block=TCP event=77 descr="Total atomic requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ" block=TCP event=78 descr="Total read requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ" block=TCP event=79 descr="Total write requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ" block=TCP event=80 descr="Total atomic requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ" block=TCP event=81 descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ" block=TCP event=82 descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ" block=TCP event=83 descr="Total atomic requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ" block=TCP event=85 descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ" block=TCP event=86 descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ" block=TCP event=87 descr="Total atomic requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCA_CYCLE" block=TCA event=1 descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCA_BUSY" block=TCA event=2 descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_CYCLE" block=TCC event=1 descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCC_BUSY" block=TCC event=2 descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_REQ" block=TCC event=3 descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed."></metric>
|
||||
<metric name="TCC_STREAMING_REQ" block=TCC event=4 descr="Number of streaming requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_NC_REQ" block=TCC event=5 descr="The number of noncoherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_UC_REQ" block=TCC event=6 descr="The number of uncached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_CC_REQ" block=TCC event=7 descr="The number of coherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_RW_REQ" block=TCC event=8 descr="The number of RW requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_PROBE" block=TCC event=9 descr="Number of probe requests. Not windowable."></metric>
|
||||
<metric name="TCC_PROBE_ALL" block=TCC event=10 descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable."></metric>
|
||||
<metric name="TCC_READ" block=TCC event=12 descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included."></metric>
|
||||
<metric name="TCC_WRITE" block=TCC event=13 descr="Number of write requests."></metric>
|
||||
<metric name="TCC_ATOMIC" block=TCC event=14 descr="Number of atomic requests of all types."></metric>
|
||||
<metric name="TCC_HIT" block=TCC event=17 descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block=TCC event=19 descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_WRITEBACK" block=TCC event=22 descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block=TCC event=26 descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block=TCC event=27 descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WR_UNCACHED_32B" block=TCC event=29 descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block=TCC event=30 descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_WRREQ_IO_CREDIT_STALL" block=TCC event=31 descr="Number of cycles a EA write request was stalled because the interface was out of IO credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_GMI_CREDIT_STALL" block=TCC event=32 descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_CREDIT_STALL" block=TCC event=33 descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL" block=TCC event=34 descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ_LEVEL" block=TCC event=35 descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ."></metric>
|
||||
<metric name="TCC_EA_ATOMIC" block=TCC event=36 descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_LEVEL" block=TCC event=37 descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block=TCC event=38 descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block=TCC event=39 descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCC_EA_RD_UNCACHED_32B" block=TCC event=40 descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_RDREQ_IO_CREDIT_STALL" block=TCC event=41 descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_GMI_CREDIT_STALL" block=TCC event=42 descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_CREDIT_STALL" block=TCC event=43 descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_LEVEL" block=TCC event=44 descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ."></metric>
|
||||
<metric name="TCC_TAG_STALL" block=TCC event=45 descr="Number of cycles the normal request pipeline in the tag was stalled for any reason. Normally, stalls of this nature are measured exactly from one point the pipeline, but that is not the case for this counter. Probes can stall the pipeline at a variety of places, and there is no single point that can reasonably measure the total stalls accurately."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK" block=TCC event=68 descr="Number of writebacks due to requests that are not writeback requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK" block=TCC event=73 descr="Number of writebacks due to all TC_OP writeback requests."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT" block=TCC event=74 descr="Number of evictions due to requests that are not invalidate or probe requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT" block=TCC event=80 descr="Number of evictions due to all TC_OP invalidate requests."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM" block=TCC event=102 descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC)."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM" block=TCC event=103 descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC)."></metric>
|
||||
</gfx90a>
|
||||
|
||||
<gfx940>
|
||||
<metric name="SQ_WAIT_INST_LDS" block=SQ event=96 descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block=TCP event=6 descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block=GRBM event=3 descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block=GRBM event=11 descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block=GRBM event=13 descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TC_BUSY" block=GRBM event=28 descr="Any of the Texture Cache Blocks (TCP/TCI/TCA/TCC) are busy."></metric>
|
||||
<metric name="GRBM_CPC_BUSY" block=GRBM event=30 descr="The Command Processor Compute (CPC) is busy."></metric>
|
||||
<metric name="GRBM_CPF_BUSY" block=GRBM event=31 descr="The Command Processor Fetchers (CPF) is busy."></metric>
|
||||
<metric name="GRBM_UTCL2_BUSY" block=GRBM event=34 descr="The Unified Translation Cache Level-2 (UTCL2) block is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block=GRBM event=35 descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="CPC_ME1_BUSY_FOR_PACKET_DECODE" block=CPC event=13 descr="Me1 busy for packet decode."></metric>
|
||||
<metric name="CPC_UTCL1_STALL_ON_TRANSLATION" block=CPC event=24 descr="One of the UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPC_CPC_STAT_BUSY" block=CPC event=25 descr="CPC Busy."></metric>
|
||||
<metric name="CPC_CPC_STAT_IDLE" block=CPC event=26 descr="CPC Idle."></metric>
|
||||
<metric name="CPC_CPC_STAT_STALL" block=CPC event=27 descr="CPC Stalled."></metric>
|
||||
<metric name="CPC_CPC_TCIU_BUSY" block=CPC event=28 descr="CPC TCIU interface Busy."></metric>
|
||||
<metric name="CPC_CPC_TCIU_IDLE" block=CPC event=29 descr="CPC TCIU interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_BUSY" block=CPC event=30 descr="CPC UTCL2 interface Busy."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_IDLE" block=CPC event=31 descr="CPC UTCL2 interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_STALL" block=CPC event=32 descr="CPC UTCL2 interface Stalled waiting on Free, Tags or Translation."></metric>
|
||||
<metric name="CPC_ME1_DC0_SPI_BUSY" block=CPC event=33 descr="CPC Me1 Processor Busy."></metric>
|
||||
<metric name="CPF_CMP_UTCL1_STALL_ON_TRANSLATION" block=CPF event=20 descr="One of the Compute UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPF_CPF_STAT_BUSY" block=CPF event=23 descr="CPF Busy."></metric>
|
||||
<metric name="CPF_CPF_STAT_IDLE" block=CPF event=24 descr="CPF Idle."></metric>
|
||||
<metric name="CPF_CPF_STAT_STALL" block=CPF event=25 descr="CPF Stalled."></metric>
|
||||
<metric name="CPF_CPF_TCIU_BUSY" block=CPF event=26 descr="CPF TCIU interface Busy."></metric>
|
||||
<metric name="CPF_CPF_TCIU_IDLE" block=CPF event=27 descr="CPF TCIU interface Idle."></metric>
|
||||
<metric name="CPF_CPF_TCIU_STALL" block=CPF event=28 descr="CPF TCIU interface Stalled waiting on Free, Tags."></metric>
|
||||
<metric name="SPI_CSN_WINDOW_VALID" block=SPI event=47 descr="Clock count enabled by perfcounter_start event. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_BUSY" block=SPI event=48 descr="Number of clocks with outstanding waves (SPI or SH). Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_NUM_THREADGROUPS" block=SPI event=49 descr="Number of threadgroups launched. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_WAVE" block=SPI event=52 descr="Number of waves. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC" block=SPI event=79 descr="Arb cycles with requests but no allocation. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC_CSN" block=SPI event=85 descr="Arb cycles with CSn req and no CSn alloc. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_RES_STALL_CSN" block=SPI event=91 descr="Arb cycles with CSn req and no CSn fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TMP_STALL_CSN" block=SPI event=97 descr="Cycles where csn wants to req but does not fit in temp space."></metric>
|
||||
<metric name="SPI_RA_WAVE_SIMD_FULL_CSN" block=SPI event=103 descr="Sum of SIMD where WAVE can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_VGPR_SIMD_FULL_CSN" block=SPI event=109 descr="Sum of SIMD where VGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_SGPR_SIMD_FULL_CSN" block=SPI event=115 descr="Sum of SIMD where SGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_LDS_CU_FULL_CSN" block=SPI event=120 descr="Sum of CU where LDS can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BAR_CU_FULL_CSN" block=SPI event=123 descr="Sum of CU where BARRIER can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BULKY_CU_FULL_CSN" block=SPI event=125 descr="Sum of CU where BULKY can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TGLIM_CU_FULL_CSN" block=SPI event=127 descr="Cycles where csn wants to req but all CU are at tg_limit"></metric>
|
||||
<metric name="SPI_RA_WVLIM_STALL_CSN" block=SPI event=133 descr="Number of clocks csn is stalled due to WAVE LIMIT."></metric>
|
||||
<metric name="SPI_SWC_CSC_WR" block=SPI event=189 descr="Number of clocks to write CSC waves to SGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_VWC_CSC_WR" block=SPI event=195 descr="Number of clocks to write CSC waves to VGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SQ_ACCUM_PREV" block=SQ event=1 descr="For counter N, increment by the value of counter N-1. Only accumulates once every 4 cycles."></metric>
|
||||
<metric name="SQ_CYCLES" block=SQ event=2 descr="Clock cycles. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_BUSY_CYCLES" block=SQ event=3 descr="Clock cycles while SQ is reporting that it is busy. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES" block=SQ event=4 descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_LEVEL_WAVES" block=SQ event=5 descr="Track the number of waves. Set ACCUM_PREV for the next counter to use this. (level, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES_EQ_64" block=SQ event=6 descr="Count number of waves with exactly 64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_64" block=SQ event=7 descr="Count number of waves with <64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_48" block=SQ event=8 descr="Count number of waves with <48 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_32" block=SQ event=9 descr="Count number of waves sent <32 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_16" block=SQ event=10 descr="Count number of waves sent <16 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_BUSY_CU_CYCLES" block=SQ event=13 descr="Count quad-cycles each CU is busy. (nondeterministic, per-simd)"></metric>
|
||||
<metric name="SQ_ITEMS" block=SQ event=14 descr="Number of valid items per wave. (per-simd, global)"></metric>
|
||||
<metric name="SQ_INSTS" block=SQ event=25 descr="Number of instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block=SQ event=26 descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F16" block=SQ event=27 descr="Number of VALU ADD/SUB instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F16" block=SQ event=28 descr="Number of VALU MUL instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F16" block=SQ event=29 descr="Number of VALU FMA/MAD instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F16" block=SQ event=30 descr="Number of VALU transcendental instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F32" block=SQ event=31 descr="Number of VALU ADD/SUB instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F32" block=SQ event=32 descr="Number of VALU MUL instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F32" block=SQ event=33 descr="Number of VALU FMA/MAD instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F32" block=SQ event=34 descr="Number of VALU transcendental instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F64" block=SQ event=35 descr="Number of VALU ADD/SUB instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F64" block=SQ event=36 descr="Number of VALU MUL instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F64" block=SQ event=37 descr="Number of VALU FMA/MAD instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F64" block=SQ event=38 descr="Number of VALU transcendental instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT32" block=SQ event=39 descr="Number of VALU 32-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT64" block=SQ event=40 descr="Number of VALU 64-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_CVT" block=SQ event=41 descr="Number of VALU data conversion instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_I8" block=SQ event=42 descr="Number of VALU V_MFMA_*_I8 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F16" block=SQ event=43 descr="Number of VALU V_MFMA_*_F16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_BF16" block=SQ event=44 descr="Number of VALU V_MFMA_*_BF16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F32" block=SQ event=45 descr="Number of VALU V_MFMA_*_F32 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F64" block=SQ event=46 descr="Number of VALU V_MFMA_*_F64 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_I8" block=SQ event=49 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type I8. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F16" block=SQ event=50 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_BF16" block=SQ event=51 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type BF16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F32" block=SQ event=52 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F64" block=SQ event=53 descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_MFMA" block=SQ event=56 descr="Number of MFMA instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block=SQ event=57 descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block=SQ event=58 descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM" block=SQ event=59 descr="Number of VMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block=SQ event=60 descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block=SQ event=61 descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block=SQ event=62 descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block=SQ event=65 descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block=SQ event=66 descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_EXP_GDS" block=SQ event=68 descr="Number of EXP and GDS instructions issued, excluding skipped export instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_BRANCH" block=SQ event=69 descr="Number of Branch instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SENDMSG" block=SQ event=70 descr="Number of Sendmsg instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VSKIPPED" block=SQ event=71 descr="Number of vector instructions skipped. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_VMEM" block=SQ event=72 descr="Number of in-flight VMEM instructions. Set next counter to ACCUM_PREV and divide by INSTS_VMEM for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_SMEM" block=SQ event=73 descr="Number of in-flight SMEM instructions (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). Set next counter to ACCUM_PREV and divide by INSTS_SMEM for average latency per smem request. Falls slightly short of total request latency because some fetches are divided into two requests that may finish at different times and this counter collects the average latency of the two. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block=SQ event=74 descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_VALU_MFMA_BUSY_CYCLES" block=SQ event=77 descr="Number of cycles the MFMA ALU is busy (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block=SQ event=79 descr="Number of wave-cycles spent by waves in the CUs (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block=SQ event=90 descr="Number of wave-cycles spent waiting for anything (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block=SQ event=93 descr="Number of wave-cycles spent waiting for any instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_ANY" block=SQ event=101 descr="Number of cycles each wave is working on an instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VMEM" block=SQ event=102 descr="Number of cycles the SQ instruction arbiter is working on a VMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_LDS" block=SQ event=103 descr="Number of cycles the SQ instruction arbiter is working on a LDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block=SQ event=104 descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_SCA" block=SQ event=105 descr="Number of cycles the SQ instruction arbiter is working on a SALU or SMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_EXP_GDS" block=SQ event=106 descr="Number of cycles the SQ instruction arbiter is working on an EXPORT or GDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_MISC" block=SQ event=107 descr="Number of cycles the SQ instruction aribter is working on a BRANCH or SENDMSG instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_FLAT" block=SQ event=108 descr="Number of cycles the SQ instruction arbiter is working on a FLAT instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_WR" block=SQ event=109 descr="Number of cycles needed to send addr and cmd data for VMEM write instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_RD" block=SQ event=110 descr="Number of cycles needed to send addr and cmd data for VMEM read instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SMEM" block=SQ event=116 descr="Number of cycles needed to execute scalar memory reads. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block=SQ event=117 descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block=SQ event=118 descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_IFETCH" block=SQ event=120 descr="Number of instruction fetch requests from cache. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_IFETCH_LEVEL" block=SQ event=121 descr="Number of instruction fetch requests from cache. (per-simd, level)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block=SQ event=126 descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_ADDR_CONFLICT" block=SQ event=127 descr="Number of cycles LDS is stalled by address conflicts. (emulated,nondeterministic)"></metric>
|
||||
<metric name="SQ_LDS_UNALIGNED_STALL" block=SQ event=128 descr="Number of cycles LDS is stalled processing flat unaligned load/store ops. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_MEM_VIOLATIONS" block=SQ event=129 descr="Number of threads that have a memory violation in the LDS.(emulated)"></metric>
|
||||
<metric name="SQ_LDS_ATOMIC_RETURN" block=SQ event=130 descr="Number of atomic return cycles in LDS. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_LDS_IDX_ACTIVE" block=SQ event=131 descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACCUM_PREV_HIRES" block=SQ event=184 descr="For counter N, increment by the value of counter N-1."></metric>
|
||||
<metric name="SQ_WAVES_RESTORED" block=SQ event=185 descr="Count number of context-restored waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_SAVED" block=SQ event=186 descr="Count number of context-saved waves. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM_NORM" block=SQ event=187 descr="Number of SMEM instructions issued normalized to match smem_level (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). (per-simd, emulated)"></metric>
|
||||
<metric name="SQC_DCACHE_INPUT_VALID_READYB" block=SQ event=260 descr="Input stalled by SQC (per-SQ, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_TC_REQ" block=SQ event=262 descr="Total number of TC requests that were issued by instruction and constant caches. (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_INST_REQ" block=SQ event=263 descr="Number of insruction requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_READ_REQ" block=SQ event=264 descr="Number of data read requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_WRITE_REQ" block=SQ event=265 descr="Number of data write requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_ATOMIC_REQ" block=SQ event=266 descr="Number of data atomic requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_STALL" block=SQ event=267 descr="Valid request stalled TC request interface (no-credits). (No-Masking, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_ICACHE_REQ" block=SQ event=270 descr="Number of requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_ICACHE_HITS" block=SQ event=271 descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES" block=SQ event=272 descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES_DUPLICATE" block=SQ event=273 descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_REQ" block=SQ event=290 descr="Number of requests (post-bank-serialization). (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_HITS" block=SQ event=291 descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES" block=SQ event=292 descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES_DUPLICATE" block=SQ event=293 descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_ATOMIC" block=SQ event=298 descr="Number of atomic requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_1" block=SQ event=323 descr="Number of constant cache 1 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_2" block=SQ event=324 descr="Number of constant cache 2 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_4" block=SQ event=325 descr="Number of constant cache 4 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_8" block=SQ event=326 descr="Number of constant cache 8 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_16" block=SQ event=327 descr="Number of constant cache 16 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="TA_TA_BUSY" block=TA event=13 descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS" block=TA event=29 descr="Total number of wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS" block=TA event=32 descr="Number of buffer wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS" block=TA event=33 descr="Number of buffer read wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS" block=TA event=34 descr="Number of buffer write wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS" block=TA event=35 descr="Number of buffer atomic wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES" block=TA event=37 descr="Number of buffer cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES" block=TA event=40 descr="Number of buffer coalesced read cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES" block=TA event=41 descr="Number of buffer coalesced write cycles issued to TC."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES" block=TA event=42 descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES" block=TA event=43 descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES" block=TA event=44 descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS" block=TA event=51 descr="Number of flat opcode wavfronts processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block=TA event=52 descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block=TA event=53 descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS" block=TA event=54 descr="Number of flat opcode atomics processed by the TA."></metric>
|
||||
<metric name="TD_TD_BUSY" block=TD event=1 descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TD_TC_STALL" block=TD event=12 descr="TD is stalled waiting for TC data."></metric>
|
||||
<metric name="TD_SPI_STALL" block=TD event=15 descr="TD is stalled SPI vinit"></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT" block=TD event=16 descr="Count the wavefronts with opcode = load, include atomics and store."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT" block=TD event=17 descr="Count the wavefronts with opcode = atomic."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT" block=TD event=18 descr="Count the wavefronts with opcode = store."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT" block=TD event=21 descr="Count wavefronts that TA finds coalescable."></metric>
|
||||
<metric name="TCP_GATE_EN1" block=TCP event=0 descr="TCP interface clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_GATE_EN2" block=TCP event=1 descr="TCP core clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES" block=TCP event=7 descr="TD stalls TCP"></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES" block=TCP event=8 descr="TCR stalls TCP_TCR_req interface"></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES" block=TCP event=10 descr="Tagram conflict stall on a read"></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES" block=TCP event=11 descr="Tagram conflict stall on a write"></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES" block=TCP event=12 descr="Tagram conflict stall on an atomic"></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES" block=TCP event=21 descr="Stall due to data pending from L2"></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ" block=TCP event=25 descr="Number of state reads"></metric>
|
||||
<metric name="TCP_VOLATILE" block=TCP event=26 descr="Total number of L1 volatile pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES" block=TCP event=27 descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD"></metric>
|
||||
<metric name="TCP_TOTAL_READ" block=TCP event=28 descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ"></metric>
|
||||
<metric name="TCP_TOTAL_WRITE" block=TCP event=30 descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET" block=TCP event=36 descr="Total number of atomic with return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET" block=TCP event=37 descr="Total number of atomic without return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES" block=TCP event=43 descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST" block=TCP event=45 descr="Total CLIENT_UTCL1 NORMAL requests"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS" block=TCP event=47 descr="Total utcl1 translation misses"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT" block=TCP event=48 descr="Total utcl1 translation hits"></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS" block=TCP event=49 descr="Total utcl1 permission misses"></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES" block=TCP event=60 descr="Count of total cache line (tag) accesses (includes hits and misses)."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ" block=TCP event=65 descr="Total read requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ" block=TCP event=66 descr="Total write requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ" block=TCP event=67 descr="Total atomic with return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ" block=TCP event=68 descr="Total atomic without return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ" block=TCP event=71 descr="Total read requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ" block=TCP event=72 descr="Total write requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ" block=TCP event=73 descr="Total atomic requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ" block=TCP event=74 descr="Total read requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ" block=TCP event=75 descr="Total write requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ" block=TCP event=76 descr="Total atomic requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ" block=TCP event=77 descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ" block=TCP event=78 descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ" block=TCP event=79 descr="Total atomic requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ" block=TCP event=80 descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ" block=TCP event=81 descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ" block=TCP event=82 descr="Total atomic requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCA_CYCLE" block=TCA event=1 descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCA_BUSY" block=TCA event=2 descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_CYCLE" block=TCC event=1 descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCC_BUSY" block=TCC event=2 descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_REQ" block=TCC event=3 descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed."></metric>
|
||||
<metric name="TCC_STREAMING_REQ" block=TCC event=4 descr="Number of streaming requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_NC_REQ" block=TCC event=5 descr="The number of noncoherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_UC_REQ" block=TCC event=6 descr="The number of uncached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_CC_REQ" block=TCC event=7 descr="The number of coherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_RW_REQ" block=TCC event=8 descr="The number of RW requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_PROBE" block=TCC event=9 descr="Number of probe requests. Not windowable."></metric>
|
||||
<metric name="TCC_PROBE_ALL" block=TCC event=10 descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable."></metric>
|
||||
<metric name="TCC_READ" block=TCC event=12 descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included."></metric>
|
||||
<metric name="TCC_WRITE" block=TCC event=13 descr="Number of write requests."></metric>
|
||||
<metric name="TCC_ATOMIC" block=TCC event=14 descr="Number of atomic requests of all types."></metric>
|
||||
<metric name="TCC_HIT" block=TCC event=17 descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block=TCC event=19 descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_WRITEBACK" block=TCC event=22 descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests."></metric>
|
||||
<metric name="TCC_EA0_WRREQ" block=TCC event=26 descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_64B" block=TCC event=27 descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA0_WR_UNCACHED_32B" block=TCC event=29 descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA0_WRREQ_STALL" block=TCC event=30 descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_IO_CREDIT_STALL" block=TCC event=31 descr="Number of cycles a EA write request was stalled because the interface was out of IO credits."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_GMI_CREDIT_STALL" block=TCC event=32 descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM_CREDIT_STALL" block=TCC event=33 descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL" block=TCC event=34 descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_LEVEL" block=TCC event=35 descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC" block=TCC event=36 descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC_LEVEL" block=TCC event=37 descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC."></metric>
|
||||
<metric name="TCC_EA0_RDREQ" block=TCC event=38 descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA0_RDREQ_32B" block=TCC event=39 descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCC_EA0_RD_UNCACHED_32B" block=TCC event=40 descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA0_RDREQ_IO_CREDIT_STALL" block=TCC event=41 descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_GMI_CREDIT_STALL" block=TCC event=42 descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM_CREDIT_STALL" block=TCC event=43 descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_LEVEL" block=TCC event=44 descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ."></metric>
|
||||
<metric name="TCC_TAG_STALL" block=TCC event=45 descr="Number of cycles the normal request pipeline in the tag was stalled for any reason. Normally, stalls of this nature are measured exactly from one point the pipeline, but that is not the case for this counter. Probes can stall the pipeline at a variety of places, and there is no single point that can reasonably measure the total stalls accurately."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK" block=TCC event=68 descr="Number of writebacks due to requests that are not writeback requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK" block=TCC event=73 descr="Number of writebacks due to all TC_OP writeback requests."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT" block=TCC event=74 descr="Number of evictions due to requests that are not invalidate or probe requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT" block=TCC event=80 descr="Number of evictions due to all TC_OP invalidate requests."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM" block=TCC event=102 descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC)."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM" block=TCC event=103 descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC)."></metric>
|
||||
</gfx940>
|
||||
|
||||
<gfx10>
|
||||
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block=GRBM event=3 descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block=GRBM event=11 descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block=GRBM event=13 descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_GDS_BUSY" block=GRBM event=25 descr="The Global Data Share (GDS) is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block=GRBM event=35 descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="GRBM_GL2CC_BUSY" block=GRBM event=40 descr="The GL2CC block is busy."></metric>
|
||||
|
||||
<metric name="GL2C_HIT" block=GL2C event=42 descr="Number of cache hits"></metric>
|
||||
<metric name="GL2C_MISS" block=GL2C event=43 descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="GL2C_MC_WRREQ" block=GL2C event=83 descr="Number of transactions (either 32-byte or 64-byte) going over the GL2C_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands"></metric>
|
||||
<metric name="GL2C_EA_WRREQ_64B" block=GL2C event=85 descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="GL2C_MC_WRREQ_STALL" block=GL2C event=88 descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="GL2C_MC_RDREQ" block=GL2C event=96 descr="Number of GL2C/EA read requests (either 32-byte or 64-byte or 128-byte)."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_32B" block=GL2C event=99 descr="Number of 32-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_64B" block=GL2C event=100 descr="Number of 64-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_96B" block=GL2C event=101 descr="Number of 96-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_128B" block=GL2C event=102 descr="Number of 128-byte GL2C/EA read requests"></metric>
|
||||
|
||||
<metric name="SQ_WAVES" block=SQ event=4 descr="Count number of waves sent to SQs. {emulated, global, C1}"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block=SQ event=26 descr="Number of clock cycles spent by waves in the SQs. Incremented by # of living (valid) waves each cycle. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block=SQ event=28 descr="Number of clock cycles spent waiting for any instruction issue. In units of cycles. {nondeterministic}"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block=SQ event=37 descr="Number of clock cycles spent waiting for anything. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32" block=SQ event=71 descr="Number of wave32 instructions issued, for flat, lds, valu, tex. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_LDS" block=SQ event=74 descr="Number of wave32 LDS indexed instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_VALU" block=SQ event=75 descr="Number of wave32 valu instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAVE32_INSTS" block=SQ event=84 descr="Number of instructions issued by wave32 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_WAVE64_INSTS" block=SQ event=85 descr="Number of instructions issued by wave64 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_GDS" block=SQ event=98 descr="Number of in-flight GDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_GDS for average latency. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block=SQ event=99 descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM" block=SQ event=120 descr="Number of cycles needed to send addr and data for VMEM (lds, buffer, image, flat, scratch, global) instructions, windowed by perf_en. {emulated, C1}"></metric>
|
||||
<metric name="SQC_LDS_BANK_CONFLICT" block=SQ event=285 descr="Number of cycles LDS is stalled by bank conflicts. (emulated, C1)"></metric>
|
||||
<metric name="SQC_LDS_IDX_ACTIVE" block=SQ event=290 descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. {per-simd, emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block=SQ event=64 descr="Number of VALU instructions issued excluding skipped instructions. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block=SQ event=60 descr="Number of SALU instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block=SQ event=61 descr="Number of SMEM instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block=SQ event=57 descr="Number of FLAT instructions issued. {emulated, C2}"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block=SQ event=59 descr="Number of LDS indexed instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block=SQ event=55 descr="Number of GDS instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block=SQ event=31 descr="Number of clock cycles spent waiting for LDS (indexed) instruction issue. In units of cycles. {nondeterministic, C1}"></metric>
|
||||
|
||||
<metric name="TA_TA_BUSY" block=TA event=15 descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_LOAD_WAVEFRONTS" block=TA event=101 descr=" Number of flat load vec32 packets processed by TA, same as flat_read_wavefronts in earlier IP"></metric>
|
||||
<metric name="TA_FLAT_STORE_WAVEFRONTS" block=TA event=102 descr="Number of flat store vec32 packets processed by TA, same as flat_write_wavefronts in earlier IP"></metric>
|
||||
</gfx10>
|
||||
|
||||
<gfx1030 base="gfx10">
|
||||
</gfx1030>
|
||||
|
||||
<gfx1031 base="gfx10">
|
||||
</gfx1031>
|
||||
|
||||
<gfx1032 base="gfx10">
|
||||
</gfx1032>
|
||||
|
||||
@@ -0,0 +1,538 @@
|
||||
#include "basic_counters.xml"
|
||||
|
||||
<gfx8_expr>
|
||||
<metric name="TA_BUSY_avr" expr=avr(TA_TA_BUSY,16) descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr=max(TA_TA_BUSY,16) descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr=min(TA_TA_BUSY,16) descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr=sum(TA_FLAT_READ_WAVEFRONTS,16) descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr=sum(TA_FLAT_WRITE_WAVEFRONTS,16) descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
|
||||
<metric name="TCC_HIT_sum" expr=sum(TCC_HIT,16) descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr=sum(TCC_MISS,16) descr="Number of cache misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MC_RDREQ_sum" expr=sum(TCC_MC_RDREQ,16) descr="Number of 32-byte reads. Sum over TCC instaces."></metric>
|
||||
<metric name="TCC_MC_WRREQ_sum" expr=sum(TCC_MC_WRREQ,16) descr="Number of 32-byte transactions going over the TC_MC_wrreq interface. Sum over TCC instaces."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr=max(TCC_MC_WRREQ_STALL,16) descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
|
||||
<metric name="FETCH_SIZE" expr=(TCC_MC_RDREQ_sum*32)/1024 descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr=(TCC_MC_WRREQ_sum*32)/1024 descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr=TCC_MC_WRREQ_sum descr="The total number of 32-byte effective memory writes."></metric>
|
||||
<metric name="VFetchInsts" expr=(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr=(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="FlatVMemInsts" expr=(SQ_INSTS_FLAT-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES descr="The average number of FLAT instructions that read from or write to the video memory executed per work item (affected by flow control). Includes FLAT instructions that read from or write to scratch."></metric>
|
||||
<metric name="LDSInsts" expr=(SQ_INSTS_LDS-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES descr="The average number of LDS read or LDS write instructions executed per work item (affected by flow control). Excludes FLAT instructions that read from or write to LDS."></metric>
|
||||
<metric name="FlatLDSInsts" expr=SQ_INSTS_FLAT_LDS_ONLY/SQ_WAVES descr="The average number of FLAT instructions that read or write to LDS executed per work item (affected by flow control)."></metric>
|
||||
<metric name="VALUUtilization" expr=100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE) descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr=100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr=100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr=FETCH_SIZE descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr=WRITE_SIZE descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr=WRITE_REQ_32B descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="L2CacheHit" expr=100*sum(TCC_HIT,16)/(sum(TCC_HIT,16)+sum(TCC_MISS,16)) descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="MemUnitStalled" expr=100*max(TCP_TCP_TA_DATA_STALL_CYCLES,16)/GRBM_GUI_ACTIVE/SE_NUM descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="WriteUnitStalled" expr=100*TCC_WRREQ_STALL_max/GRBM_GUI_ACTIVE descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
# LDSBankConflict The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad).
|
||||
<metric name="LDSBankConflict" expr=100*SQ_LDS_BANK_CONFLICT/GRBM_GUI_ACTIVE/CU_NUM descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
</gfx8_expr>
|
||||
|
||||
<gfx9_expr>
|
||||
<metric name="TA_BUSY_avr" expr=avr(TA_TA_BUSY,16) descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr=max(TA_TA_BUSY,16) descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr=min(TA_TA_BUSY,16) descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr=sum(TA_FLAT_READ_WAVEFRONTS,16) descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr=sum(TA_FLAT_WRITE_WAVEFRONTS,16) descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
|
||||
<metric name="TCC_HIT_sum" expr=sum(TCC_HIT,16) descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr=sum(TCC_MISS,16) descr="Number of cache misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B_sum" expr=sum(TCC_EA_RDREQ_32B,16) descr="Number of 32-byte TCC/EA read requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_sum" expr=sum(TCC_EA_RDREQ,16) descr="Number of TCC/EA read requests (either 32-byte or 64-byte). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_sum" expr=sum(TCC_EA_WRREQ,16) descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B_sum" expr=sum(TCC_EA_WRREQ_64B,16) descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr=max(TCC_EA_WRREQ_STALL,16) descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES_sum" expr=sum(TCP_TCP_TA_DATA_STALL_CYCLES,16) decr="Total number of TCP stalls TA data interface."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES_max" expr=max(TCP_TCP_TA_DATA_STALL_CYCLES,16) decr="Maximum number of TCP stalls TA data interface."></metric>
|
||||
|
||||
<metric name="FETCH_SIZE" expr=(TCC_EA_RDREQ_32B_sum*32+(TCC_EA_RDREQ_sum-TCC_EA_RDREQ_32B_sum)*64)/1024 descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr=((TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)*32+TCC_EA_WRREQ_64B_sum*64)/1024 descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr=TCC_EA_WRREQ_64B_sum*2+(TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum) descr="The total number of 32-byte effective memory writes."></metric>
|
||||
<metric name="VFetchInsts" expr=(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr=(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="FlatVMemInsts" expr=(SQ_INSTS_FLAT-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES descr="The average number of FLAT instructions that read from or write to the video memory executed per work item (affected by flow control). Includes FLAT instructions that read from or write to scratch."></metric>
|
||||
<metric name="LDSInsts" expr=(SQ_INSTS_LDS-SQ_INSTS_FLAT_LDS_ONLY)/SQ_WAVES descr="The average number of LDS read or LDS write instructions executed per work item (affected by flow control). Excludes FLAT instructions that read from or write to LDS."></metric>
|
||||
<metric name="FlatLDSInsts" expr=SQ_INSTS_FLAT_LDS_ONLY/SQ_WAVES descr="The average number of FLAT instructions that read or write to LDS executed per work item (affected by flow control)."></metric>
|
||||
<metric name="VALUUtilization" expr=100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE) descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr=100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr=100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr=FETCH_SIZE descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr=WRITE_SIZE descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr=WRITE_REQ_32B descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="L2CacheHit" expr=100*sum(TCC_HIT,16)/(sum(TCC_HIT,16)+sum(TCC_MISS,16)) descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="MemUnitStalled" expr=100*TCP_TCP_TA_DATA_STALL_CYCLES_max/GRBM_GUI_ACTIVE/SE_NUM descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="WriteUnitStalled" expr=100*TCC_WRREQ_STALL_max/GRBM_GUI_ACTIVE descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
# LDSBankConflict The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad).
|
||||
<metric name="LDSBankConflict" expr=100*SQ_LDS_BANK_CONFLICT/GRBM_GUI_ACTIVE/CU_NUM descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
</gfx9_expr>
|
||||
|
||||
<gfx906_expr base="gfx9_expr">
|
||||
# EA1
|
||||
<metric name="TCC_EA1_RDREQ_32B_sum" expr=sum(TCC_EA1_RDREQ_32B,16) descr="Number of 32-byte TCC/EA read requests. Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_EA1_RDREQ_sum" expr=sum(TCC_EA1_RDREQ,16) descr="Number of TCC/EA read requests (either 32-byte or 64-byte). Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_sum" expr=sum(TCC_EA1_WRREQ,16) descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_64B_sum" expr=sum(TCC_EA1_WRREQ_64B,16) descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC EA1s."></metric>
|
||||
<metric name="TCC_WRREQ1_STALL_max" expr=max(TCC_EA1_WRREQ_STALL,16) descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
|
||||
<metric name="RDATA1_SIZE" expr=(TCC_EA1_RDREQ_32B_sum*32+(TCC_EA1_RDREQ_sum-TCC_EA1_RDREQ_32B_sum)*64) descr="The total kilobytes fetched from the video memory. This is measured on EA1s."></metric>
|
||||
<metric name="WDATA1_SIZE" expr=((TCC_EA1_WRREQ_sum-TCC_EA1_WRREQ_64B_sum)*32+TCC_EA1_WRREQ_64B_sum*64) descr="The total kilobytes written to the video memory. This is measured on EA1s."></metric>
|
||||
|
||||
# both EA0 and EA1 should be included
|
||||
<metric name="FETCH_SIZE" expr=(TCC_EA_RDREQ_32B_sum*32+(TCC_EA_RDREQ_sum-TCC_EA_RDREQ_32B_sum)*64+RDATA1_SIZE)/1024 descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr=((TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)*32+TCC_EA_WRREQ_64B_sum*64+WDATA1_SIZE)/1024 descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr=(TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)+(TCC_EA1_WRREQ_sum-TCC_EA1_WRREQ_64B_sum)+(TCC_EA_WRREQ_64B_sum+TCC_EA1_WRREQ_64B_sum)*2 descr="The total number of 32-byte effective memory writes."></metric>
|
||||
</gfx906_expr>
|
||||
|
||||
<gfx908_expr base="gfx9_expr">
|
||||
<metric name="TCC_HIT_sum" expr=sum(TCC_HIT,32) descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr=sum(TCC_MISS,32) descr="Number of cache misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B_sum" expr=sum(TCC_EA_RDREQ_32B,32) descr="Number of 32-byte TCC/EA read requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_sum" expr=sum(TCC_EA_RDREQ,32) descr="Number of TCC/EA read requests (either 32-byte or 64-byte). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_sum" expr=sum(TCC_EA_WRREQ,32) descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B_sum" expr=sum(TCC_EA_WRREQ_64B,32) descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr=max(TCC_EA_WRREQ_STALL,32) descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
|
||||
<metric name="CU_UTILIZATION" expr=GRBM_GUI_ACTIVE/GRBM_COUNT descr="The total number of active cycles divided by total number of elapsed cycles"></metric>
|
||||
</gfx908_expr>
|
||||
|
||||
<gfx90a_expr base="gfx9_expr">
|
||||
<metric name="TA_BUSY_avr" expr=avr(TA_TA_BUSY,16) descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr=max(TA_TA_BUSY,16) descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr=min(TA_TA_BUSY,16) descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_TA_BUSY_sum" expr=sum(TA_TA_BUSY,16) descr="TA block is busy. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS_sum" expr=sum(TA_TOTAL_WAVEFRONTS,16) descr="Total number of wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES_sum" expr=sum(TA_ADDR_STALLED_BY_TC_CYCLES,16) descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES_sum" expr=sum(TA_ADDR_STALLED_BY_TD_CYCLES,16) descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES_sum" expr=sum(TA_DATA_STALLED_BY_TC_CYCLES,16) descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS_sum" expr=sum(TA_FLAT_WAVEFRONTS,16) descr="Number of flat opcode wavfronts processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr=sum(TA_FLAT_READ_WAVEFRONTS,16) descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr=sum(TA_FLAT_WRITE_WAVEFRONTS,16) descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS_sum" expr=sum(TA_FLAT_ATOMIC_WAVEFRONTS,16) descr="Number of flat opcode atomics processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS_sum" expr=sum(TA_BUFFER_WAVEFRONTS,16) descr="Number of buffer wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS_sum" expr=sum(TA_BUFFER_READ_WAVEFRONTS,16) descr="Number of buffer read wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS_sum" expr=sum(TA_BUFFER_WRITE_WAVEFRONTS,16) descr="Number of buffer write wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS_sum" expr=sum(TA_BUFFER_ATOMIC_WAVEFRONTS,16) descr="Number of buffer atomic wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES_sum" expr=sum(TA_BUFFER_TOTAL_CYCLES,16) descr="Number of buffer cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES_sum" expr=sum(TA_BUFFER_COALESCED_READ_CYCLES,16) descr="Number of buffer coalesced read cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES_sum" expr=sum(TA_BUFFER_COALESCED_WRITE_CYCLES,16) descr="Number of buffer coalesced write cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TD_TD_BUSY_sum" expr=sum(TD_TD_BUSY,16) descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter. Sum over TD instances."></metric>
|
||||
<metric name="TD_TC_STALL_sum" expr=sum(TD_TC_STALL,16) descr="TD is stalled waiting for TC data. Sum over TD instances."></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT_sum" expr=sum(TD_LOAD_WAVEFRONT,16) descr="Count the wavefronts with opcode = load, include atomics and store. Sum over TD instances."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT_sum" expr=sum(TD_ATOMIC_WAVEFRONT,16) descr="Count the wavefronts with opcode = atomic. Sum over TD instances."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT_sum" expr=sum(TD_STORE_WAVEFRONT,16) descr="Count the wavefronts with opcode = store. Sum over TD instances."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT_sum" expr=sum(TD_COALESCABLE_WAVEFRONT,16) descr="Count wavefronts that TA finds coalescable. Sum over TD instances."></metric>
|
||||
<metric name="TD_SPI_STALL_sum" expr=sum(TD_SPI_STALL,16) descr="TD is stalled SPI vinit, sum of TCP instances"></metric>
|
||||
<metric name="TCP_GATE_EN1_sum" expr=sum(TCP_GATE_EN1,16) descr="TCP interface clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_GATE_EN2_sum" expr=sum(TCP_GATE_EN2,16) descr="TCP core clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES_sum" expr=sum(TCP_TD_TCP_STALL_CYCLES,16) descr="TD stalls TCP. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES_sum" expr=sum(TCP_TCR_TCP_STALL_CYCLES,16) descr="TCR stalls TCP_TCR_req interface. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES_sum" expr=sum(TCP_READ_TAGCONFLICT_STALL_CYCLES,16) descr="Tagram conflict stall on a read. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES_sum" expr=sum(TCP_WRITE_TAGCONFLICT_STALL_CYCLES,16) descr="Tagram conflict stall on a write. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES_sum" expr=sum(TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES,16) descr="Tagram conflict stall on an atomic. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_VOLATILE_sum" expr=sum(TCP_VOLATILE,16) descr="Total number of L1 volatile pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES_sum" expr=sum(TCP_TOTAL_ACCESSES,16) descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_READ_sum" expr=sum(TCP_TOTAL_READ,16) descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITE_sum" expr=sum(TCP_TOTAL_WRITE,16) descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET_sum" expr=sum(TCP_TOTAL_ATOMIC_WITH_RET,16) descr="Total number of atomic with return pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET_sum" expr=sum(TCP_TOTAL_ATOMIC_WITHOUT_RET,16) descr="Total number of atomic without return pixels/buffers from TA Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES_sum" expr=sum(TCP_TOTAL_WRITEBACK_INVALIDATES,16) descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST_sum" expr=sum(TCP_UTCL1_REQUEST,16) descr="Total CLIENT_UTCL1 NORMAL requests Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS_sum" expr=sum(TCP_UTCL1_TRANSLATION_MISS,16) descr="Total utcl1 translation misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT_sum" expr=sum(TCP_UTCL1_TRANSLATION_HIT,16) descr="Total utcl1 translation hits Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS_sum" expr=sum(TCP_UTCL1_PERMISSION_MISS,16) descr="Total utcl1 permission misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES_sum" expr=sum(TCP_TOTAL_CACHE_ACCESSES,16) descr="Count of total cache line (tag) accesses (includes hits and misses). Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCP_LATENCY_sum" expr=sum(TCP_TCP_LATENCY,16) descr="Total TCP wave latency (from first clock of wave entering to first clock of wave leaving), divide by TA_TCP_STATE_READ to avg wave latency Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ_sum" expr=sum(TCP_TA_TCP_STATE_READ,16) descr="Number of state reads Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_LATENCY_sum" expr=sum(TCP_TCC_READ_REQ_LATENCY,16) descr="Total TCP->TCC request latency for reads and atomics with return. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_LATENCY_sum" expr=sum(TCP_TCC_WRITE_REQ_LATENCY,16) descr="Total TCP->TCC request latency for writes and atomics without return. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_sum" expr=sum(TCP_TCC_READ_REQ,16) descr="Total read requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_sum" expr=sum(TCP_TCC_WRITE_REQ,16) descr="Total write requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ_sum" expr=sum(TCP_TCC_ATOMIC_WITH_RET_REQ,16) descr="Total atomic with return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ_sum" expr=sum(TCP_TCC_ATOMIC_WITHOUT_RET_REQ,16) descr="Total atomic without return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ_sum" expr=sum(TCP_TCC_NC_READ_REQ,16) descr="Total read requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ_sum" expr=sum(TCP_TCC_NC_WRITE_REQ,16) descr="Total write requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ_sum" expr=sum(TCP_TCC_NC_ATOMIC_REQ,16) descr="Total atomic requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ_sum" expr=sum(TCP_TCC_UC_READ_REQ,16) descr="Total read requests with UC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ_sum" expr=sum(TCP_TCC_UC_WRITE_REQ,16) descr="Total write requests with UC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ_sum" expr=sum(TCP_TCC_UC_ATOMIC_REQ,16) descr="Total atomic requests with UC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ_sum" expr=sum(TCP_TCC_CC_READ_REQ,16) descr="Total write requests with CC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ_sum" expr=sum(TCP_TCC_CC_WRITE_REQ,16) descr="Total write requests with CC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ_sum" expr=sum(TCP_TCC_CC_ATOMIC_REQ,16) descr="Total atomic requests with CC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ_sum" expr=sum(TCP_TCC_RW_READ_REQ,16) descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ_sum" expr=sum(TCP_TCC_RW_WRITE_REQ,16) descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ_sum" expr=sum(TCP_TCC_RW_ATOMIC_REQ,16) descr="Total atomic requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES_sum" expr=sum(TCP_PENDING_STALL_CYCLES,16) descr="Stall due to data pending from L2. Sum over TCP instances."></metric>
|
||||
<metric name="TCA_CYCLE_sum" expr=sum(TCA_CYCLE,16) descr="Number of cycles. Sum over all TCA instances "></metric>
|
||||
<metric name="TCA_BUSY_sum" expr=sum(TCA_BUSY,16) descr="Number of cycles we have a request pending. Sum over all TCA instances."></metric>
|
||||
<metric name="TCC_BUSY_avr" expr=avr(TCC_BUSY,32) descr="TCC_BUSY avr over all memory channels."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr=max(TCC_EA_WRREQ_STALL,32) descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
<metric name="TCC_CYCLE_sum" expr=sum(TCC_CYCLE,32) descr="Number of cycles. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_BUSY_sum" expr=sum(TCC_BUSY,32) descr="Number of cycles we have a request pending. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_REQ_sum" expr=sum(TCC_REQ,32) descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_STREAMING_REQ_sum" expr=sum(TCC_STREAMING_REQ,32) descr="Number of streaming requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NC_REQ_sum" expr=sum(TCC_NC_REQ,32) descr="The number of noncoherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_UC_REQ_sum" expr=sum(TCC_UC_REQ,32) descr="The number of uncached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_CC_REQ_sum" expr=sum(TCC_CC_REQ,32) descr="The number of coherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_RW_REQ_sum" expr=sum(TCC_RW_REQ,32) descr="The number of RW requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_sum" expr=sum(TCC_PROBE,32) descr="Number of probe requests. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_ALL_sum" expr=sum(TCC_PROBE_ALL,32) descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_READ_sum" expr=sum(TCC_READ,32) descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITE_sum" expr=sum(TCC_WRITE,32) descr="Number of write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ATOMIC_sum" expr=sum(TCC_ATOMIC,32) descr="Number of atomic requests of all types. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_HIT_sum" expr=sum(TCC_HIT,32) descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr=sum(TCC_MISS,32) descr="Number of cache misses. UC reads count as misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITEBACK_sum" expr=sum(TCC_WRITEBACK,32) descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_sum" expr=sum(TCC_EA_WRREQ,32) descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B_sum" expr=sum(TCC_EA_WRREQ_64B,32) descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WR_UNCACHED_32B_sum" expr=sum(TCC_EA_WR_UNCACHED_32B,32) descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL_sum" expr=sum(TCC_EA_WRREQ_STALL,32) descr="Number of cycles a write request was stalled. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_IO_CREDIT_STALL_sum" expr=sum(TCC_EA_WRREQ_IO_CREDIT_STALL,32) descr="Number of cycles a EA write request was stalled because the interface was out of IO credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_GMI_CREDIT_STALL_sum" expr=sum(TCC_EA_WRREQ_GMI_CREDIT_STALL,32) descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_CREDIT_STALL_sum" expr=sum(TCC_EA_WRREQ_DRAM_CREDIT_STALL,32) descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL_sum" expr=sum(TCC_TOO_MANY_EA_WRREQS_STALL,32) descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_LEVEL_sum" expr=sum(TCC_EA_WRREQ_LEVEL,32) descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_LEVEL_sum" expr=sum(TCC_EA_RDREQ_LEVEL,32) descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_sum" expr=sum(TCC_EA_ATOMIC,32) descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_LEVEL_sum" expr=sum(TCC_EA_ATOMIC_LEVEL,32) descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_sum" expr=sum(TCC_EA_RDREQ,32) descr="Number of TCC/EA read requests (either 32-byte or 64-byte) Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B_sum" expr=sum(TCC_EA_RDREQ_32B,32) descr="Number of 32-byte TCC/EA read requests Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RD_UNCACHED_32B_sum" expr=sum(TCC_EA_RD_UNCACHED_32B,32) descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2 Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_IO_CREDIT_STALL_sum" expr=sum(TCC_EA_RDREQ_IO_CREDIT_STALL,32) descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_GMI_CREDIT_STALL_sum" expr=sum(TCC_EA_RDREQ_GMI_CREDIT_STALL,32) descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_CREDIT_STALL_sum" expr=sum(TCC_EA_RDREQ_DRAM_CREDIT_STALL,32) descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TAG_STALL_sum" expr=sum(TCC_TAG_STALL,32) descr="."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK_sum" expr=sum(TCC_NORMAL_WRITEBACK,32) descr="Number of writebacks due to requests that are not writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK_sum" expr=sum(TCC_ALL_TC_OP_WB_WRITEBACK,32) descr="Number of writebacks due to all TC_OP writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT_sum" expr=sum(TCC_NORMAL_EVICT,32) descr="Number of evictions due to requests that are not invalidate or probe requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT_sum" expr=sum(TCC_ALL_TC_OP_INV_EVICT,32) descr="Number of evictions due to all TC_OP invalidate requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_sum" expr=sum(TCC_EA_RDREQ_DRAM,32) descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_sum" expr=sum(TCC_EA_WRREQ_DRAM,32) descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
|
||||
<metric name="FETCH_SIZE" expr=(TCC_EA_RDREQ_32B_sum*32+(TCC_EA_RDREQ_sum-TCC_EA_RDREQ_32B_sum)*64)/1024 descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr=((TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum)*32+TCC_EA_WRREQ_64B_sum*64)/1024 descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr=TCC_EA_WRREQ_64B_sum*2+(TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum) descr="The total number of 32-byte effective memory writes."></metric>
|
||||
<metric name="CU_OCCUPANCY" expr=(SQ_CYCLES/(SQ_WAVE_CYCLES*4))/MAX_WAVE_SIZE descr="The ratio of active waves on a CU to the maximum number of active waves supported by the CU"></metric>
|
||||
<metric name="CU_UTILIZATION" expr=GRBM_GUI_ACTIVE/GRBM_COUNT descr="The total number of active cycles divided by total number of elapsed cycles"></metric>
|
||||
<metric name="TOTAL_16_OPS" expr=(SQ_INSTS_VALU_FMA_F16*2+SQ_INSTS_VALU_ADD_F16+SQ_INSTS_VALU_MUL_F16+SQ_INSTS_VALU_TRANS_F16)*64+((SQ_INSTS_VALU_MFMA_MOPS_F16+SQ_INSTS_VALU_MFMA_MOPS_BF16)*512) descr="The number of 16 bits OPS executed"></metric>
|
||||
<metric name="TOTAL_32_OPS" expr=(SQ_INSTS_VALU_FMA_F32*2+SQ_INSTS_VALU_INT32+SQ_INSTS_VALU_ADD_F32+SQ_INSTS_VALU_MUL_F32+SQ_INSTS_VALU_TRANS_F32)*64+(SQ_INSTS_VALU_MFMA_MOPS_F32*512) descr="The number of 32 bits OPS executed"></metric>
|
||||
<metric name="TOTAL_64_OPS" expr=(SQ_INSTS_VALU_FMA_F64*2+SQ_INSTS_VALU_INT64+SQ_INSTS_VALU_ADD_F64+SQ_INSTS_VALU_MUL_F64)*64+(SQ_INSTS_VALU_MFMA_MOPS_F64*512) descr="The number of 64 bits OPS executed"></metric>
|
||||
|
||||
<metric name="AggSysCycles" expr=GRBM_GUI_ACTIVE*CU_NUM descr="Unit: cycles"></metric>
|
||||
## IP Block Utilization Metrics
|
||||
<metric name="GpuUtil" expr=100*GRBM_GUI_ACTIVE/GRBM_COUNT descr="Unit: percent"></metric>
|
||||
<metric name="CpUtil" expr=100*GRBM_CP_BUSY/GRBM_GUI_ACTIVE descr="Unit: percent"></metric>
|
||||
<metric name="SpiUtil" expr=100*GRBM_SPI_BUSY/GRBM_GUI_ACTIVE descr="Unit: percent"></metric>
|
||||
<metric name="TaUtil" expr=100*GRBM_TA_BUSY/GRBM_GUI_ACTIVE descr="Unit: percent"></metric>
|
||||
<metric name="TcUtil" expr=100*GRBM_TC_BUSY/GRBM_GUI_ACTIVE descr="Unit: percent"></metric>
|
||||
<metric name="EaUtil" expr=100*GRBM_EA_BUSY/GRBM_GUI_ACTIVE descr="Unit: percent"></metric>
|
||||
## Instruction Fetch Metrics
|
||||
<metric name="InstrFetchLatency" expr=SQ_ACCUM_PREV_HIRES/SQ_IFETCH descr="Unit: cycles"></metric>
|
||||
## Wavefront Metrics
|
||||
<metric name="WaveOccupancy" expr=SQ_ACCUM_PREV_HIRES/GRBM_GUI_ACTIVE descr="Unit: wavefronts"></metric>
|
||||
<metric name="WaveDuration" expr=4*SQ_WAVE_CYCLES/SQ_WAVES descr="Unit: cycles"></metric>
|
||||
<metric name="WaveDepWait" expr=100*SQ_WAIT_ANY/SQ_WAVE_CYCLES descr="Unit: percent"></metric>
|
||||
<metric name="WaveIssueWait" expr=100*SQ_WAIT_INST_ANY/SQ_WAVE_CYCLES descr="Unit: percent"></metric>
|
||||
<metric name="WaveExec" expr=100*SQ_ACTIVE_INST_ANY/SQ_WAVE_CYCLES descr="Unit: percent"></metric>
|
||||
## Compute Unit Metrics
|
||||
<metric name="ValuIops" expr=(SQ_INSTS_VALU_INT32+SQ_INSTS_VALU_INT64)*64 descr="Unit: IOP"></metric>
|
||||
<metric name="MfmaFlops" expr=(SQ_INSTS_VALU_MFMA_MOPS_F16+SQ_INSTS_VALU_MFMA_MOPS_BF16+SQ_INSTS_VALU_MFMA_MOPS_F32+SQ_INSTS_VALU_MFMA_MOPS_F64)*512 descr="Unit: FLOP"></metric>
|
||||
<metric name="MfmaFlopsF16" expr=SQ_INSTS_VALU_MFMA_MOPS_F16*512 descr="Unit: FLOP"></metric>
|
||||
<metric name="MfmaFlopsBF16" expr=SQ_INSTS_VALU_MFMA_MOPS_BF16*512 descr="Unit: FLOP"></metric>
|
||||
<metric name="MfmaFlopsF32" expr=SQ_INSTS_VALU_MFMA_MOPS_F32*512 descr="Unit: FLOP"></metric>
|
||||
<metric name="MfmaFlopsF64" expr=SQ_INSTS_VALU_MFMA_MOPS_F64*512 descr="Unit: IOP"></metric>
|
||||
<metric name="ScaPipeIssueUtil" expr=100*SQ_ACTIVE_INST_SCA/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
|
||||
<metric name="ValuPipeIssueUtil" expr=100*SQ_ACTIVE_INST_VALU/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
|
||||
<metric name="VmemPipeIssueUtil" expr=100*4*(SQ_ACTIVE_INST_VMEM+SQ_ACTIVE_INST_FLAT)/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
|
||||
<metric name="MfmaUtil" expr=100*SQ_VALU_MFMA_BUSY_CYCLES/(GRBM_GUI_ACTIVE*CU_NUM*4) descr="Unit: percent"></metric>
|
||||
<metric name="AvgNumActiveThreads" expr=SQ_THREAD_CYCLES_VALU/SQ_ACTIVE_INST_VALU descr="Unit: percent"></metric>
|
||||
<metric name="VmemLatency" expr=SQ_ACCUM_PREV_HIRES/SQ_INSTS_VMEM descr="Unit: cycles"></metric>
|
||||
<metric name="SmemLatency" expr=SQ_ACCUM_PREV_HIRES/SQ_INSTS_SMEM_NORM descr="Unit: cycles"></metric>
|
||||
## Local Data Share (LDS) Metrics
|
||||
<metric name="LdsUtil" expr=100*SQ_LDS_IDX_ACTIVE/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
|
||||
<metric name="LdsPipeIssueUtil" expr=100*4*SQ_ACTIVE_INST_LDS/(GRBM_GUI_ACTIVE*CU_NUM*2) descr="Unit: percent"></metric>
|
||||
<metric name="LdsLatency" expr=SQ_ACCUM_PREV_HIRES/SQ_INSTS_LDS descr="Unit: cycles"></metric>
|
||||
<metric name="LdsBankConflict" expr=SQ_LDS_BANK_CONFLICT/(SQ_LDS_IDX_ACTIVE-SQ_LDS_BANK_CONFLICT) descr="Unit: conflicts/access"></metric>
|
||||
## L1I and sL1D Cache Metrics
|
||||
<metric name="L1iCacheHitRate" expr=100*SQC_ICACHE_HITS/SQC_ICACHE_REQ descr="Unit: percent"></metric>
|
||||
<metric name="sL1dCacheHitRate" expr=100*SQC_DCACHE_HITS/SQC_DCACHE_REQ descr="Unit: percent"></metric>
|
||||
## vL1D Cache Metrics
|
||||
<metric name="vL1dBufCoalesceRate" expr=100*64*TA_TOTAL_WAVEFRONTS_sum/(TCP_TOTAL_ACCESSES_sum*4) descr="Unit: percent"></metric>
|
||||
<metric name="vL1dCacheUtil" expr=100*TCP_GATE_EN2_sum/TCP_GATE_EN1_sum descr="Unit: percent"></metric>
|
||||
<metric name="vL1dCacheTcbHitRate" expr=100*TCP_UTCL1_TRANSLATION_HIT_sum/TCP_UTCL1_REQUEST_sum descr="Unit: percent"></metric>
|
||||
<metric name="vL1dCacheWaveLatency" expr=TCP_TCP_LATENCY_sum/TCP_TA_TCP_STATE_READ_sum descr="Unit: cycles"></metric>
|
||||
<metric name="vL1dReadFromL2Latency" expr=TCP_TCC_READ_REQ_LATENCY_sum/(TCP_TCC_READ_REQ_sum+TCP_TCC_ATOMIC_WITH_RET_REQ_sum) descr="Unit: cycles"></metric>
|
||||
<metric name="vL1dWriteToL2Latency" expr=TCP_TCC_WRITE_REQ_LATENCY_sum/(TCP_TCC_WRITE_REQ_sum+TCP_TCC_ATOMIC_WITHOUT_RET_REQ_sum) descr="Unit: cycles"></metric>
|
||||
<metric name="vL1dRdTagConfStallRate" expr=100*TCP_READ_TAGCONFLICT_STALL_CYCLES_sum/TCP_GATE_EN2_sum descr="Unit: percent"></metric>
|
||||
<metric name="vL1dWrTagConfStallRate" expr=100*TCP_WRITE_TAGCONFLICT_STALL_CYCLES_sum/TCP_GATE_EN2_sum descr="Unit: percent"></metric>
|
||||
<metric name="vL1dAtomicTagConfStallRate" expr=100*TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES_sum/TCP_GATE_EN2_sum descr="Unit: percent"></metric>
|
||||
<metric name="vL1dMissReqStallRate" expr=100*TCP_TCR_TCP_STALL_CYCLES_sum/TCP_GATE_EN2_sum descr="Unit: percent"></metric>
|
||||
<metric name="vL1dDataPendRate" expr=100*TCP_PENDING_STALL_CYCLES_sum/TCP_GATE_EN2_sum descr="Unit: percent"></metric>
|
||||
<metric name="vL1dDataRetStallRate" expr=100*TD_TC_STALL_sum/TD_TD_BUSY_sum descr="Unit: percent"></metric>
|
||||
## L2 Cache Metrics
|
||||
<metric name="L2CacheHitRate" expr=100*TCC_HIT_sum/(TCC_HIT_sum+TCC_MISS_sum) descr="Unit: percent"></metric>
|
||||
<metric name="L2CacheTagRamStallRate" expr=100*TCC_TAG_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaRdLatency" expr=TCC_EA_RDREQ_LEVEL_sum/TCC_EA_RDREQ_sum descr="Unit: cycles"></metric>
|
||||
<metric name="EaRdIoStallRate" expr=100*TCC_EA_RDREQ_IO_CREDIT_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaRdGmiStallRate" expr=100*TCC_EA_RDREQ_GMI_CREDIT_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaRdDramStallRate" expr=100*TCC_EA_RDREQ_DRAM_CREDIT_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaWrLatency" expr=TCC_EA_WRREQ_LEVEL_sum/TCC_EA_WRREQ_sum descr="Unit: cycles"></metric>
|
||||
<metric name="EaWrIoStallRate" expr=100*TCC_EA_WRREQ_IO_CREDIT_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaWrGmiStallRate" expr=100*TCC_EA_WRREQ_GMI_CREDIT_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaWrDramStallRate" expr=100*TCC_EA_WRREQ_DRAM_CREDIT_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaWrStarveRate" expr=100*TCC_TOO_MANY_EA_WRREQS_STALL_sum/TCC_BUSY_sum descr="Unit: percent"></metric>
|
||||
<metric name="EaAtomicLatency" expr=TCC_EA_ATOMIC_LEVEL_sum/TCC_EA_ATOMIC_sum descr="Unit: cycles"></metric>
|
||||
</gfx90a_expr>
|
||||
|
||||
<gfx940_expr>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES_sum" expr=sum(TCP_TCP_TA_DATA_STALL_CYCLES,16) decr="Total number of TCP stalls TA data interface."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES_max" expr=max(TCP_TCP_TA_DATA_STALL_CYCLES,16) decr="Maximum number of TCP stalls TA data interface."></metric>
|
||||
|
||||
<metric name="VFetchInsts" expr=(SQ_INSTS_VMEM_RD-TA_FLAT_READ_WAVEFRONTS_sum)/SQ_WAVES descr="The average number of vector fetch instructions from the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that fetch from video memory."></metric>
|
||||
<metric name="VWriteInsts" expr=(SQ_INSTS_VMEM_WR-TA_FLAT_WRITE_WAVEFRONTS_sum)/SQ_WAVES descr="The average number of vector write instructions to the video memory executed per work-item (affected by flow control). Excludes FLAT instructions that write to video memory."></metric>
|
||||
<metric name="VALUUtilization" expr=100*SQ_THREAD_CYCLES_VALU/(SQ_ACTIVE_INST_VALU*MAX_WAVE_SIZE) descr="The percentage of active vector ALU threads in a wave. A lower number can mean either more thread divergence in a wave or that the work-group size is not a multiple of 64. Value range: 0% (bad), 100% (ideal - no thread divergence)."></metric>
|
||||
<metric name="VALUBusy" expr=100*SQ_ACTIVE_INST_VALU*4/SIMD_NUM/GRBM_GUI_ACTIVE descr="The percentage of GPUTime vector ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="SALUBusy" expr=100*SQ_INST_CYCLES_SALU*4/SIMD_NUM/GRBM_GUI_ACTIVE descr="The percentage of GPUTime scalar ALU instructions are processed. Value range: 0% (bad) to 100% (optimal)."></metric>
|
||||
<metric name="FetchSize" expr=FETCH_SIZE descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteSize" expr=WRITE_SIZE descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="MemWrites32B" expr=WRITE_REQ_32B descr="The total number of effective 32B write transactions to the memory"></metric>
|
||||
<metric name="MemUnitStalled" expr=100*TCP_TCP_TA_DATA_STALL_CYCLES_max/GRBM_GUI_ACTIVE/SE_NUM descr="The percentage of GPUTime the memory unit is stalled. Try reducing the number or size of fetches and writes if possible. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
<metric name="TA_BUSY_avr" expr=avr(TA_TA_BUSY,16) descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr=max(TA_TA_BUSY,16) descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr=min(TA_TA_BUSY,16) descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_TA_BUSY_sum" expr=sum(TA_TA_BUSY,16) descr="TA block is busy. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS_sum" expr=sum(TA_TOTAL_WAVEFRONTS,16) descr="Total number of wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES_sum" expr=sum(TA_ADDR_STALLED_BY_TC_CYCLES,16) descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES_sum" expr=sum(TA_ADDR_STALLED_BY_TD_CYCLES,16) descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES_sum" expr=sum(TA_DATA_STALLED_BY_TC_CYCLES,16) descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS_sum" expr=sum(TA_FLAT_WAVEFRONTS,16) descr="Number of flat opcode wavfronts processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS_sum" expr=sum(TA_FLAT_READ_WAVEFRONTS,16) descr="Number of flat opcode reads processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS_sum" expr=sum(TA_FLAT_WRITE_WAVEFRONTS,16) descr="Number of flat opcode writes processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS_sum" expr=sum(TA_FLAT_ATOMIC_WAVEFRONTS,16) descr="Number of flat opcode atomics processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS_sum" expr=sum(TA_BUFFER_WAVEFRONTS,16) descr="Number of buffer wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS_sum" expr=sum(TA_BUFFER_READ_WAVEFRONTS,16) descr="Number of buffer read wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS_sum" expr=sum(TA_BUFFER_WRITE_WAVEFRONTS,16) descr="Number of buffer write wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS_sum" expr=sum(TA_BUFFER_ATOMIC_WAVEFRONTS,16) descr="Number of buffer atomic wavefronts processed by TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES_sum" expr=sum(TA_BUFFER_TOTAL_CYCLES,16) descr="Number of buffer cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES_sum" expr=sum(TA_BUFFER_COALESCED_READ_CYCLES,16) descr="Number of buffer coalesced read cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES_sum" expr=sum(TA_BUFFER_COALESCED_WRITE_CYCLES,16) descr="Number of buffer coalesced write cycles issued to TC. Sum over TA instances."></metric>
|
||||
<metric name="TD_TD_BUSY_sum" expr=sum(TD_TD_BUSY,16) descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter. Sum over TD instances."></metric>
|
||||
<metric name="TD_TC_STALL_sum" expr=sum(TD_TC_STALL,16) descr="TD is stalled waiting for TC data. Sum over TD instances."></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT_sum" expr=sum(TD_LOAD_WAVEFRONT,16) descr="Count the wavefronts with opcode = load, include atomics and store. Sum over TD instances."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT_sum" expr=sum(TD_ATOMIC_WAVEFRONT,16) descr="Count the wavefronts with opcode = atomic. Sum over TD instances."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT_sum" expr=sum(TD_STORE_WAVEFRONT,16) descr="Count the wavefronts with opcode = store. Sum over TD instances."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT_sum" expr=sum(TD_COALESCABLE_WAVEFRONT,16) descr="Count wavefronts that TA finds coalescable. Sum over TD instances."></metric>
|
||||
<metric name="TD_SPI_STALL_sum" expr=sum(TD_SPI_STALL,16) descr="TD is stalled SPI vinit, sum of TCP instances"></metric>
|
||||
<metric name="TCP_GATE_EN1_sum" expr=sum(TCP_GATE_EN1,16) descr="TCP interface clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_GATE_EN2_sum" expr=sum(TCP_GATE_EN2,16) descr="TCP core clocks are turned on. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES_sum" expr=sum(TCP_TD_TCP_STALL_CYCLES,16) descr="TD stalls TCP. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES_sum" expr=sum(TCP_TCR_TCP_STALL_CYCLES,16) descr="TCR stalls TCP_TCR_req interface. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES_sum" expr=sum(TCP_READ_TAGCONFLICT_STALL_CYCLES,16) descr="Tagram conflict stall on a read. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES_sum" expr=sum(TCP_WRITE_TAGCONFLICT_STALL_CYCLES,16) descr="Tagram conflict stall on a write. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES_sum" expr=sum(TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES,16) descr="Tagram conflict stall on an atomic. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_VOLATILE_sum" expr=sum(TCP_VOLATILE,16) descr="Total number of L1 volatile pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES_sum" expr=sum(TCP_TOTAL_ACCESSES,16) descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_READ_sum" expr=sum(TCP_TOTAL_READ,16) descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITE_sum" expr=sum(TCP_TOTAL_WRITE,16) descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET_sum" expr=sum(TCP_TOTAL_ATOMIC_WITH_RET,16) descr="Total number of atomic with return pixels/buffers from TA. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET_sum" expr=sum(TCP_TOTAL_ATOMIC_WITHOUT_RET,16) descr="Total number of atomic without return pixels/buffers from TA Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES_sum" expr=sum(TCP_TOTAL_WRITEBACK_INVALIDATES,16) descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST_sum" expr=sum(TCP_UTCL1_REQUEST,16) descr="Total CLIENT_UTCL1 NORMAL requests Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS_sum" expr=sum(TCP_UTCL1_TRANSLATION_MISS,16) descr="Total utcl1 translation misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT_sum" expr=sum(TCP_UTCL1_TRANSLATION_HIT,16) descr="Total utcl1 translation hits Sum over TCP instances."></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS_sum" expr=sum(TCP_UTCL1_PERMISSION_MISS,16) descr="Total utcl1 permission misses Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES_sum" expr=sum(TCP_TOTAL_CACHE_ACCESSES,16) descr="Count of total cache line (tag) accesses (includes hits and misses). Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ_sum" expr=sum(TCP_TA_TCP_STATE_READ,16) descr="Number of state reads Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_sum" expr=sum(TCP_TCC_READ_REQ,16) descr="Total read requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_sum" expr=sum(TCP_TCC_WRITE_REQ,16) descr="Total write requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ_sum" expr=sum(TCP_TCC_ATOMIC_WITH_RET_REQ,16) descr="Total atomic with return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ_sum" expr=sum(TCP_TCC_ATOMIC_WITHOUT_RET_REQ,16) descr="Total atomic without return requests from TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ_sum" expr=sum(TCP_TCC_NC_READ_REQ,16) descr="Total read requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ_sum" expr=sum(TCP_TCC_NC_WRITE_REQ,16) descr="Total write requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ_sum" expr=sum(TCP_TCC_NC_ATOMIC_REQ,16) descr="Total atomic requests with NC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ_sum" expr=sum(TCP_TCC_UC_READ_REQ,16) descr="Total read requests with UC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ_sum" expr=sum(TCP_TCC_UC_WRITE_REQ,16) descr="Total write requests with UC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ_sum" expr=sum(TCP_TCC_UC_ATOMIC_REQ,16) descr="Total atomic requests with UC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ_sum" expr=sum(TCP_TCC_CC_READ_REQ,16) descr="Total write requests with CC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ_sum" expr=sum(TCP_TCC_CC_WRITE_REQ,16) descr="Total write requests with CC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ_sum" expr=sum(TCP_TCC_CC_ATOMIC_REQ,16) descr="Total atomic requests with CC mtype from this TCP to all TCCs Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ_sum" expr=sum(TCP_TCC_RW_READ_REQ,16) descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ_sum" expr=sum(TCP_TCC_RW_WRITE_REQ,16) descr="Total write requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ_sum" expr=sum(TCP_TCC_RW_ATOMIC_REQ,16) descr="Total atomic requests with RW mtype from this TCP to all TCCs. Sum over TCP instances."></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES_sum" expr=sum(TCP_PENDING_STALL_CYCLES,16) descr="Stall due to data pending from L2. Sum over TCP instances."></metric>
|
||||
<metric name="TCA_CYCLE_sum" expr=sum(TCA_CYCLE,16) descr="Number of cycles. Sum over all TCA instances "></metric>
|
||||
<metric name="TCA_BUSY_sum" expr=sum(TCA_BUSY,16) descr="Number of cycles we have a request pending. Sum over all TCA instances."></metric>
|
||||
<metric name="TCC_BUSY_avr" expr=avr(TCC_BUSY,32) descr="TCC_BUSY avr over all memory channels."></metric>
|
||||
<metric name="TCC_WRREQ_STALL_max" expr=max(TCC_EA_WRREQ_STALL,32) descr="Number of cycles a write request was stalled. Max over TCC instances."></metric>
|
||||
<metric name="TCC_CYCLE_sum" expr=sum(TCC_CYCLE,32) descr="Number of cycles. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_BUSY_sum" expr=sum(TCC_BUSY,32) descr="Number of cycles we have a request pending. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_REQ_sum" expr=sum(TCC_REQ,32) descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_STREAMING_REQ_sum" expr=sum(TCC_STREAMING_REQ,32) descr="Number of streaming requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NC_REQ_sum" expr=sum(TCC_NC_REQ,32) descr="The number of noncoherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_UC_REQ_sum" expr=sum(TCC_UC_REQ,32) descr="The number of uncached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_CC_REQ_sum" expr=sum(TCC_CC_REQ,32) descr="The number of coherently cached requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_RW_REQ_sum" expr=sum(TCC_RW_REQ,32) descr="The number of RW requests. This is measured at the tag block. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_sum" expr=sum(TCC_PROBE,32) descr="Number of probe requests. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_PROBE_ALL_sum" expr=sum(TCC_PROBE_ALL,32) descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_READ_sum" expr=sum(TCC_READ,32) descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITE_sum" expr=sum(TCC_WRITE,32) descr="Number of write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ATOMIC_sum" expr=sum(TCC_ATOMIC,32) descr="Number of atomic requests of all types. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_HIT_sum" expr=sum(TCC_HIT,32) descr="Number of cache hits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_MISS_sum" expr=sum(TCC_MISS,32) descr="Number of cache misses. UC reads count as misses. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_WRITEBACK_sum" expr=sum(TCC_WRITEBACK,32) descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_sum" expr=sum(TCC_EA0_WRREQ,32) descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_64B_sum" expr=sum(TCC_EA0_WRREQ_64B,32) descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WR_UNCACHED_32B_sum" expr=sum(TCC_EA0_WR_UNCACHED_32B,32) descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_STALL_sum" expr=sum(TCC_EA0_WRREQ_STALL,32) descr="Number of cycles a write request was stalled. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_IO_CREDIT_STALL_sum" expr=sum(TCC_EA0_WRREQ_IO_CREDIT_STALL,32) descr="Number of cycles a EA write request was stalled because the interface was out of IO credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_GMI_CREDIT_STALL_sum" expr=sum(TCC_EA0_WRREQ_GMI_CREDIT_STALL,32) descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM_CREDIT_STALL_sum" expr=sum(TCC_EA0_WRREQ_DRAM_CREDIT_STALL,32) descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL_sum" expr=sum(TCC_TOO_MANY_EA_WRREQS_STALL,32) descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_LEVEL_sum" expr=sum(TCC_EA0_WRREQ_LEVEL,32) descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_LEVEL_sum" expr=sum(TCC_EA0_RDREQ_LEVEL,32) descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC_sum" expr=sum(TCC_EA0_ATOMIC,32) descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_ATOMIC_LEVEL_sum" expr=sum(TCC_EA0_ATOMIC_LEVEL,32) descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_sum" expr=sum(TCC_EA0_RDREQ,32) descr="Number of TCC/EA read requests (either 32-byte or 64-byte) Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_32B_sum" expr=sum(TCC_EA0_RDREQ_32B,32) descr="Number of 32-byte TCC/EA read requests Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RD_UNCACHED_32B_sum" expr=sum(TCC_EA0_RD_UNCACHED_32B,32) descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2 Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_IO_CREDIT_STALL_sum" expr=sum(TCC_EA0_RDREQ_IO_CREDIT_STALL,32) descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_GMI_CREDIT_STALL_sum" expr=sum(TCC_EA0_RDREQ_GMI_CREDIT_STALL,32) descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM_CREDIT_STALL_sum" expr=sum(TCC_EA0_RDREQ_DRAM_CREDIT_STALL,32) descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_TAG_STALL_sum" expr=sum(TCC_TAG_STALL,32) descr="."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK_sum" expr=sum(TCC_NORMAL_WRITEBACK,32) descr="Number of writebacks due to requests that are not writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK_sum" expr=sum(TCC_ALL_TC_OP_WB_WRITEBACK,32) descr="Number of writebacks due to all TC_OP writeback requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT_sum" expr=sum(TCC_NORMAL_EVICT,32) descr="Number of evictions due to requests that are not invalidate or probe requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT_sum" expr=sum(TCC_ALL_TC_OP_INV_EVICT,32) descr="Number of evictions due to all TC_OP invalidate requests. Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_RDREQ_DRAM_sum" expr=sum(TCC_EA0_RDREQ_DRAM,32) descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
<metric name="TCC_EA0_WRREQ_DRAM_sum" expr=sum(TCC_EA0_WRREQ_DRAM,32) descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC). Sum over TCC instances."></metric>
|
||||
<metric name="FETCH_SIZE" expr=(TCC_EA0_RDREQ_32B_sum*32+(TCC_EA_RDREQ_sum-TCC_EA_RDREQ_32B_sum)*64)/1024 descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_SIZE" expr=((TCC_EA0_WRREQ_sum-TCC_EA_WRREQ_64B_sum)*32+TCC_EA_WRREQ_64B_sum*64)/1024 descr="The total kilobytes written to the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WRITE_REQ_32B" expr=TCC_EA0_WRREQ_64B_sum*2+(TCC_EA_WRREQ_sum-TCC_EA_WRREQ_64B_sum) descr="The total number of 32-byte effective memory writes."></metric>
|
||||
<metric name="CU_OCCUPANCY" expr=(SQ_CYCLES/(SQ_WAVE_CYCLES*4))/MAX_WAVE_SIZE descr="The ratio of active waves on a CU to the maximum number of active waves supported by the CU"></metric>
|
||||
<metric name="CU_UTILIZATION" expr=GRBM_GUI_ACTIVE/GRBM_COUNT descr="The total number of active cycles divided by total number of elapsed cycles"></metric>
|
||||
<metric name="TOTAL_16_OPS" expr=(SQ_INSTS_VALU_FMA_F16*2+SQ_INSTS_VALU_ADD_F16+SQ_INSTS_VALU_MUL_F16+SQ_INSTS_VALU_TRANS_F16)*64+((SQ_INSTS_VALU_MFMA_MOPS_F16+SQ_INSTS_VALU_MFMA_MOPS_BF16)*512) descr="The number of 16 bits OPS executed"></metric>
|
||||
<metric name="TOTAL_32_OPS" expr=(SQ_INSTS_VALU_FMA_F32*2+SQ_INSTS_VALU_INT32+SQ_INSTS_VALU_ADD_F32+SQ_INSTS_VALU_MUL_F32+SQ_INSTS_VALU_TRANS_F32)*64+(SQ_INSTS_VALU_MFMA_MOPS_F32*512) descr="The number of 32 bits OPS executed"></metric>
|
||||
<metric name="TOTAL_64_OPS" expr=(SQ_INSTS_VALU_FMA_F64*2+SQ_INSTS_VALU_INT64+SQ_INSTS_VALU_ADD_F64+SQ_INSTS_VALU_MUL_F64)*64+(SQ_INSTS_VALU_MFMA_MOPS_F64*512) descr="The number of 64 bits OPS executed"></metric>
|
||||
</gfx940_expr>
|
||||
|
||||
<gfx10_expr>
|
||||
<metric name="GPU_UTIL" expr=100*GRBM_GUI_ACTIVE/GRBM_COUNT descr="Percentage of the time that GUI is active"></metric>
|
||||
<metric name="CP_UTIL" expr=100*GRBM_CP_BUSY/GRBM_GUI_ACTIVE descr="Percentage of the GRBM_GUI_ACTIVE time that any of the Command Processor (CPG/CPC/CPF) blocks are busy"></metric>
|
||||
<metric name="SPI_UTIL" expr=100*GRBM_SPI_BUSY/GRBM_GUI_ACTIVE descr="Percentage of the GRBM_GUI_ACTIVE time that any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)"></metric>
|
||||
<metric name="TA_UTIL" expr=100*GRBM_TA_BUSY/GRBM_GUI_ACTIVE descr="Percentage of the GRBM_GUI_ACTIVE time that any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GDS_UTIL" expr=100*GRBM_GDS_BUSY/GRBM_GUI_ACTIVE descr="Percentage of the GRBM_GUI_ACTIVE time that the Global Data Share (GDS) is busy."></metric>
|
||||
<metric name="EA_UTIL" expr=100*GRBM_EA_BUSY/GRBM_GUI_ACTIVE descr="Percentage of the GRBM_GUI_ACTIVE time that the Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="WAVE_DEP_WAIT" expr=100*SQ_WAIT_ANY/SQ_WAVE_CYCLES descr="Percentage of the SQ_WAVE_CYCLE time spent waiting for anything."></metric>
|
||||
<metric name="WAVE_ISSUE_WAIT" expr=100*SQ_WAIT_INST_ANY/SQ_WAVE_CYCLES descr="Percentage of the SQ_WAVE_CYCLE time spent waiting for any instruction issue."></metric>
|
||||
|
||||
<metric name="TA_BUSY_avr" expr=avr(TA_TA_BUSY,16) descr="TA block is busy. Average over TA instances."></metric>
|
||||
<metric name="TA_BUSY_max" expr=max(TA_TA_BUSY,16) descr="TA block is busy. Max over TA instances."></metric>
|
||||
<metric name="TA_BUSY_min" expr=min(TA_TA_BUSY,16) descr="TA block is busy. Min over TA instances."></metric>
|
||||
<metric name="TA_FLAT_LOAD_WAVEFRONTS_sum" expr=sum(TA_FLAT_LOAD_WAVEFRONTS,16) descr="Number of flat load vec32 packets processed by the TA. Sum over TA instances."></metric>
|
||||
<metric name="TA_FLAT_STORE_WAVEFRONTS_sum" expr=sum(TA_FLAT_STORE_WAVEFRONTS,16) descr="Number of flat store vec32 packets processed by the TA. Sum over TA instances."></metric>
|
||||
|
||||
<metric name="GL2C_HIT_sum" expr=sum(GL2C_HIT,16) descr="Number of cache hits. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_MISS_sum" expr=sum(GL2C_MISS,16) descr="Number of cache misses. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_32B_sum" expr=sum(GL2C_EA_RDREQ_32B,16) descr="Number of 32-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_64B_sum" expr=sum(GL2C_EA_RDREQ_64B,16) descr="Number of 64-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_96B_sum" expr=sum(GL2C_EA_RDREQ_96B,16) descr="Number of 96-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_128B_sum" expr=sum(GL2C_EA_RDREQ_128B,16) descr="Number of 128-byte GL2C/EA read requests. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_MC_RDREQ_sum" expr=sum(GL2C_MC_RDREQ,16) descr="Number of GL2C/EA read requests (either 32-byte or 64-byte or 128-byte). Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_MC_WRREQ_sum" expr=sum(GL2C_MC_WRREQ,16) descr="Number of transactions (either 32-byte or 64-byte) going over the GL2C_MC_wrreq interface. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_EA_WRREQ_64B_sum" expr=sum(GL2C_EA_WRREQ_64B,16) descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the GL2C_EA_wrreq interface. Sum over GL2C instances."></metric>
|
||||
<metric name="GL2C_WRREQ_STALL_max" expr=max(GL2C_MC_WRREQ_STALL,16) descr="Number of cycles a write request was stalled. Max over GL2C instances."></metric>
|
||||
<metric name="L2CacheHit" expr=100*sum(GL2C_HIT,16)/(sum(GL2C_HIT,16)+sum(GL2C_MISS,16)) descr="The percentage of fetch, write, atomic, and other instructions that hit the data in L2 cache. Value range: 0% (no hit) to 100% (optimal)."></metric>
|
||||
<metric name="FETCH_SIZE" expr=(GL2C_EA_RDREQ_32B_sum*32+GL2C_EA_RDREQ_64B_sum*64+GL2C_EA_RDREQ_96B_sum*96+GL2C_EA_RDREQ_128B_sum*128)/1024 descr="The total kilobytes fetched from the video memory. This is measured with all extra fetches and any cache or memory effects taken into account."></metric>
|
||||
<metric name="WriteUnitStalled" expr=100*GL2C_WRREQ_STALL_max/GRBM_GUI_ACTIVE descr="The percentage of GPUTime the Write unit is stalled. Value range: 0% to 100% (bad)."></metric>
|
||||
<metric name="LDSBankConflict" expr=100*SQC_LDS_BANK_CONFLICT/SQC_LDS_IDX_ACTIVE descr="The percentage of GPUTime LDS is stalled by bank conflicts. Value range: 0% (optimal) to 100% (bad)."></metric>
|
||||
</gfx10_expr>
|
||||
|
||||
<gfx1030_expr base="gfx10_expr">
|
||||
</gfx1030_expr>
|
||||
|
||||
<gfx1031_expr base="gfx10_expr">
|
||||
</gfx1031_expr>
|
||||
|
||||
<gfx1032_expr base="gfx10_expr">
|
||||
</gfx1032_expr>
|
||||
|
||||
<gfx8 base="gfx8_expr"></gfx8>
|
||||
<gfx9 base="gfx9_expr"></gfx9>
|
||||
<gfx10 base="gfx10_expr"></gfx10>
|
||||
# Vega20
|
||||
<gfx906 base="gfx906_expr"></gfx906>
|
||||
# Arcturus
|
||||
<gfx908 base="gfx908_expr"></gfx908>
|
||||
# Aldebaran
|
||||
<gfx90a base="gfx90a_expr"></gfx90a>
|
||||
#Navi21
|
||||
<gfx1030 base="gfx1030_expr"></gfx1030>
|
||||
|
||||
<gfx1031 base="gfx1031_expr"></gfx1031>
|
||||
|
||||
<gfx1032 base="gfx1032_expr"></gfx1032>
|
||||
|
||||
<global>
|
||||
# GPUBusy The percentage of time GPU was busy.
|
||||
<metric
|
||||
name="GPUBusy"
|
||||
descr="The percentage of time GPU was busy."
|
||||
expr=100*GRBM_GUI_ACTIVE/GRBM_COUNT
|
||||
></metric>
|
||||
|
||||
# Wavefronts Total wavefronts.
|
||||
<metric
|
||||
name="Wavefronts"
|
||||
descr="Total wavefronts."
|
||||
expr=SQ_WAVES
|
||||
></metric>
|
||||
|
||||
# VALUInsts The average number of vector ALU instructions executed per work-item (affected by flow control).
|
||||
<metric
|
||||
name="VALUInsts"
|
||||
descr="The average number of vector ALU instructions executed per work-item (affected by flow control)."
|
||||
expr=SQ_INSTS_VALU/SQ_WAVES
|
||||
></metric>
|
||||
|
||||
# SALUInsts The average number of scalar ALU instructions executed per work-item (affected by flow control).
|
||||
<metric
|
||||
name="SALUInsts"
|
||||
descr="The average number of scalar ALU instructions executed per work-item (affected by flow control)."
|
||||
expr=SQ_INSTS_SALU/SQ_WAVES
|
||||
></metric>
|
||||
|
||||
# SFetchInsts The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control).
|
||||
<metric
|
||||
name="SFetchInsts"
|
||||
descr="The average number of scalar fetch instructions from the video memory executed per work-item (affected by flow control)."
|
||||
expr=SQ_INSTS_SMEM/SQ_WAVES
|
||||
></metric>
|
||||
|
||||
# GDSInsts The average number of GDS read or GDS write instructions executed per work item (affected by flow control).
|
||||
<metric
|
||||
name="GDSInsts"
|
||||
descr="The average number of GDS read or GDS write instructions executed per work item (affected by flow control)."
|
||||
expr=SQ_INSTS_GDS/SQ_WAVES
|
||||
></metric>
|
||||
|
||||
# MemUnitBusy The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound).
|
||||
<metric
|
||||
name="MemUnitBusy"
|
||||
descr="The percentage of GPUTime the memory unit is active. The result includes the stall time (MemUnitStalled). This is measured with all extra fetches and writes and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound)."
|
||||
expr=100*max(TA_TA_BUSY,16)/GRBM_GUI_ACTIVE/SE_NUM
|
||||
></metric>
|
||||
|
||||
# ALUStalledByLDS The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad).
|
||||
<metric
|
||||
name="ALUStalledByLDS"
|
||||
descr="The percentage of GPUTime ALU units are stalled by the LDS input queue being full or the output queue being not ready. If there are LDS bank conflicts, reduce them. Otherwise, try reducing the number of LDS accesses if possible. Value range: 0% (optimal) to 100% (bad)."
|
||||
expr=100*SQ_WAIT_INST_LDS*4/SQ_WAVES/GRBM_GUI_ACTIVE
|
||||
></metric>
|
||||
|
||||
</global>
|
||||
@@ -0,0 +1,199 @@
|
||||
#include "eval_metrics.h"
|
||||
#include "src/utils/helper.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
using namespace rocmtools;
|
||||
|
||||
|
||||
struct block_des_t {
|
||||
uint32_t id;
|
||||
uint32_t index;
|
||||
};
|
||||
struct lt_block_des {
|
||||
bool operator()(const block_des_t& a1, const block_des_t& a2) const {
|
||||
return (a1.id < a2.id) || ((a1.id == a2.id) && (a1.index < a2.index));
|
||||
}
|
||||
};
|
||||
|
||||
struct block_status_t {
|
||||
uint32_t max_counters;
|
||||
uint32_t counter_index;
|
||||
uint32_t group_index;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
std::vector<results_t*>* results;
|
||||
size_t index;
|
||||
} callback_data_t;
|
||||
|
||||
static inline bool IsEventMatch(const hsa_ven_amd_aqlprofile_event_t& event1,
|
||||
const hsa_ven_amd_aqlprofile_event_t& event2) {
|
||||
return (event1.block_name == event2.block_name) && (event1.block_index == event2.block_index) &&
|
||||
(event1.counter_id == event2.counter_id);
|
||||
}
|
||||
|
||||
hsa_status_t pmcCallback(hsa_ven_amd_aqlprofile_info_type_t info_type,
|
||||
hsa_ven_amd_aqlprofile_info_data_t* info_data, void* data) {
|
||||
hsa_status_t status = HSA_STATUS_SUCCESS;
|
||||
callback_data_t* passed_data = reinterpret_cast<callback_data_t*>(data);
|
||||
passed_data->index += 1;
|
||||
|
||||
for (auto data_it = passed_data->results->begin(); data_it != passed_data->results->end();
|
||||
++data_it) {
|
||||
if (info_type == HSA_VEN_AMD_AQLPROFILE_INFO_PMC_DATA) {
|
||||
if (IsEventMatch(info_data->pmc_data.event, (*data_it)->event)) {
|
||||
(*data_it)->val_double += info_data->pmc_data.result; // TODO: += or =
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
template <class Map> class MetricArgs : public xml::args_cache_t {
|
||||
public:
|
||||
MetricArgs(const Map* map) : map_(map) {}
|
||||
~MetricArgs() {}
|
||||
bool Lookup(const std::string& name, double& result) const {
|
||||
results_t* counter_result = NULL;
|
||||
auto it = map_->find(name);
|
||||
if (it == map_->end()) std::cout << "var '" << name << "' is not found" << std::endl;
|
||||
counter_result = it->second;
|
||||
if (counter_result) {
|
||||
result = counter_result->val_double;
|
||||
} else
|
||||
std::cout << "var '" << name << "' info is NULL" << std::endl;
|
||||
return (counter_result != NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
const Map* map_;
|
||||
};
|
||||
|
||||
static std::mutex extract_metric_events_lock;
|
||||
|
||||
bool metrics::ExtractMetricEvents(
|
||||
std::vector<std::string>& metric_names, hsa_agent_t gpu_agent, MetricsDict* metrics_dict,
|
||||
std::map<std::string, results_t*>& results_map, std::vector<event_t>& events_list,
|
||||
std::vector<results_t*>& results_list,
|
||||
std::map<std::pair<uint32_t, uint32_t>, uint64_t>& event_to_max_block_count,
|
||||
std::map<std::string, std::set<std::string>>& metrics_counters) {
|
||||
std::map<block_des_t, block_status_t, lt_block_des> groups_map;
|
||||
|
||||
/* brief:
|
||||
results_map holds the result objects for each metric name(basic or derived)
|
||||
events_list holds the list of unique events from all the metrics entered
|
||||
results_list holds the result objects for each event (which means, basic counters only)
|
||||
*/
|
||||
try {
|
||||
for (size_t i = 0; i < metric_names.size(); i++) {
|
||||
counters_vec_t counters_vec;
|
||||
// TODO: saurabh
|
||||
// const Metric* metric = metrics_dict->GetMetricByName(metric_names[i]);
|
||||
const Metric* metric = metrics_dict->Get(metric_names[i]);
|
||||
if (metric == nullptr) fatal("input metric'%s' not found", metric_names[i].c_str());
|
||||
|
||||
// adding result object for derived metric
|
||||
std::lock_guard<std::mutex> lock(extract_metric_events_lock);
|
||||
if (results_map.find(metric_names[i]) == results_map.end()) {
|
||||
results_map[metric_names[i]] = new results_t{metric_names[i], 0, {}};
|
||||
} // else {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
counters_vec = metric->GetCounters();
|
||||
if (counters_vec.empty())
|
||||
rocmtools::fatal("bad metric '%s' is empty", metric_names[i].c_str());
|
||||
|
||||
for (const counter_t* counter : counters_vec) {
|
||||
results_t* result = nullptr;
|
||||
if (metric->GetExpr()) {
|
||||
metrics_counters[metric->GetName()].insert(counter->name);
|
||||
// add this counter event only if it wasn't repeated before
|
||||
if (results_map.find(counter->name) != results_map.end()) {
|
||||
// std::cout << "Metric : " << metric->GetName() << " has " << counter->name
|
||||
// << " which is already part of the results map!" << std::endl;
|
||||
// continue;
|
||||
result = results_map.at(counter->name);
|
||||
} else {
|
||||
// result object for base metric
|
||||
// std::cout << "Metric : " << metric->GetName() << " : " << counter->name << std::endl;
|
||||
result = new results_t{counter->name, 0, {}}; // TODO: set correct initial value
|
||||
results_map[counter->name] = result;
|
||||
}
|
||||
} else {
|
||||
// std::cout << "Counter : " << metric->GetName() << " : " << counter->name << std::endl;
|
||||
result = results_map.at(counter->name);
|
||||
}
|
||||
// std::cout << "General Counter : " << metric->GetName() << " : " << counter->name <<
|
||||
// std::endl;
|
||||
const event_t* event = &(counter->event);
|
||||
const block_des_t block_des = {event->block_name, event->block_index};
|
||||
auto ret = groups_map.insert({block_des, {}});
|
||||
block_status_t& block_status = ret.first->second;
|
||||
if (block_status.max_counters == 0) {
|
||||
hsa_ven_amd_aqlprofile_profile_t query = {};
|
||||
query.agent = gpu_agent;
|
||||
query.type = HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_PMC;
|
||||
query.events = event;
|
||||
|
||||
uint32_t max_block_counters;
|
||||
hsa_status_t status = hsa_ven_amd_aqlprofile_get_info(
|
||||
&query, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS, &max_block_counters);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("get block_counters info failed");
|
||||
block_status.max_counters = max_block_counters;
|
||||
}
|
||||
|
||||
// std::cout << "Counter: " << result->name << ", Block Index: " <<
|
||||
// counter->event.block_index
|
||||
// << ", Counter ID: " << counter->event.counter_id
|
||||
// << "\nBlock Status Group Index: " << block_status.group_index
|
||||
// << ", Block Max Counters: " << block_status.max_counters
|
||||
// << ", Block Status Counter ID: " << block_status.counter_index << std::endl;
|
||||
|
||||
if (block_status.counter_index >= block_status.max_counters) {
|
||||
rocmtools::fatal("Metrics specified have exceeded HW limits!");
|
||||
return false;
|
||||
}
|
||||
block_status.counter_index += 1;
|
||||
events_list.push_back(counter->event);
|
||||
result->event = counter->event;
|
||||
results_list.push_back(result);
|
||||
event_to_max_block_count.emplace(
|
||||
std::make_pair(static_cast<uint32_t>(counter->event.block_name),
|
||||
static_cast<uint32_t>(counter->event.block_index)),
|
||||
block_status.max_counters);
|
||||
}
|
||||
}
|
||||
} catch (std::string ex) {
|
||||
std::cout << ex << std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool metrics::GetCounterData(hsa_ven_amd_aqlprofile_profile_t* profile,
|
||||
std::vector<results_t*>& results_list) {
|
||||
callback_data_t callback_data{&results_list, 0};
|
||||
hsa_status_t status = hsa_ven_amd_aqlprofile_iterate_data(profile, pmcCallback, &callback_data);
|
||||
return (status == HSA_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
bool metrics::GetMetricsData(std::map<std::string, results_t*>& results_map,
|
||||
std::vector<const Metric*>& metrics_list) {
|
||||
MetricArgs<std::map<std::string, results_t*>> args(&results_map);
|
||||
for (auto& metric : metrics_list) {
|
||||
const xml::Expr* expr = metric->GetExpr();
|
||||
if (expr) {
|
||||
auto it = results_map.find(metric->GetName());
|
||||
if (it == results_map.end()) rocmtools::fatal("metric results not found ");
|
||||
results_t* res = it->second;
|
||||
res->val_double = expr->Eval(args);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/******************************************************************************
|
||||
Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SRC_CORE_METRICS_EVALMETRICS_H_
|
||||
#define SRC_CORE_METRICS_EVALMETRICS_H_
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "metrics.h"
|
||||
#include <hsa/hsa.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <set>
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
typedef struct {
|
||||
std::string name;
|
||||
double val_double;
|
||||
event_t event;
|
||||
} results_t;
|
||||
|
||||
typedef struct {
|
||||
packet_t* start_packet;
|
||||
packet_t* stop_packet;
|
||||
packet_t* read_packet;
|
||||
rocmtools::MetricsDict* metrics_dict;
|
||||
std::vector<const rocmtools::Metric*> metrics_list;
|
||||
std::map<std::string, rocmtools::results_t*> results_map;
|
||||
std::vector<rocmtools::results_t*> results_list;
|
||||
std::vector<event_t> events_list;
|
||||
hsa_agent_t gpu_agent;
|
||||
hsa_signal_t begin_signal;
|
||||
std::atomic<bool> begin_completed{false};
|
||||
} profiling_context_t;
|
||||
|
||||
namespace metrics {
|
||||
bool ExtractMetricEvents(
|
||||
std::vector<std::string>& metric_names, hsa_agent_t gpu_agent, MetricsDict* metrics_dict,
|
||||
std::map<std::string, results_t*>& results_map, std::vector<event_t>& events_list,
|
||||
std::vector<results_t*>& results_list,
|
||||
std::map<std::pair<uint32_t, uint32_t>, uint64_t>& event_to_max_block_count,
|
||||
std::map<std::string, std::set<std::string>>& metrics_counters);
|
||||
|
||||
|
||||
bool GetCounterData(hsa_ven_amd_aqlprofile_profile_t* profile,
|
||||
std::vector<results_t*>& results_list);
|
||||
|
||||
bool GetMetricsData(std::map<std::string, results_t*>& results_map,
|
||||
std::vector<const Metric*>& metrics_list);
|
||||
|
||||
} // namespace metrics
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_METRICS_EVALMETRICS_H_
|
||||
@@ -0,0 +1,75 @@
|
||||
/******************************************************************************
|
||||
Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SRC_UTIL_EXCEPTION_H_
|
||||
#define SRC_UTIL_EXCEPTION_H_
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#define EXC_ABORT(error, stream) \
|
||||
do { \
|
||||
const char* hsa_err_str = NULL; \
|
||||
if (hsa_status_string(error, &hsa_err_str) != HSA_STATUS_SUCCESS) hsa_err_str = NULL; \
|
||||
std::ostringstream oss; \
|
||||
oss << "error(" << error << ") \"" << __FUNCTION__ << "(), " << stream << "\"" << std::endl; \
|
||||
if (hsa_err_str != NULL) oss << hsa_err_str << std::endl; \
|
||||
std::cout << oss.str() << std::flush; \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
#define EXC_RAISING(error, stream) \
|
||||
do { \
|
||||
std::ostringstream oss; \
|
||||
oss << __FUNCTION__ << "(), " << stream; \
|
||||
throw rocmtools::util::exception(error, oss.str()); \
|
||||
} while (0)
|
||||
|
||||
#define AQL_EXC_RAISING(error, stream) \
|
||||
do { \
|
||||
const char* error_string = NULL; \
|
||||
hsa_ven_amd_aqlprofile_error_string(&error_string); \
|
||||
EXC_RAISING(error, stream << ", " << error_string); \
|
||||
} while (0)
|
||||
|
||||
namespace rocmtools {
|
||||
namespace util {
|
||||
|
||||
class exception : public std::exception {
|
||||
public:
|
||||
explicit exception(const uint32_t& status, const std::string& msg) : status_(status), str_(msg) {}
|
||||
const char* what() const throw() { return str_.c_str(); }
|
||||
uint32_t status() const throw() { return status_; }
|
||||
|
||||
protected:
|
||||
const uint32_t status_;
|
||||
const std::string str_;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_UTIL_EXCEPTION_H_
|
||||
@@ -0,0 +1,449 @@
|
||||
/******************************************************************************
|
||||
Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef _SRC_CORE_COUNTERS_METRICS_XML_EXPR_H
|
||||
#define _SRC_CORE_COUNTERS_METRICS_XML_EXPR_H
|
||||
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
|
||||
namespace xml {
|
||||
class exception_t : public std::exception {
|
||||
public:
|
||||
explicit exception_t(const std::string& msg) : str_(msg) {}
|
||||
const char* what() const throw() { return str_.c_str(); }
|
||||
|
||||
protected:
|
||||
const std::string str_;
|
||||
};
|
||||
|
||||
class div_zero_exception_t : public exception_t {
|
||||
public:
|
||||
explicit div_zero_exception_t(const std::string& msg)
|
||||
: exception_t("Divide by zero exception " + msg) {}
|
||||
};
|
||||
|
||||
typedef double args_t;
|
||||
static const args_t ARGS_MAX = DBL_MAX;
|
||||
typedef std::map<std::string, args_t> args_map_t;
|
||||
class Expr;
|
||||
|
||||
template <class T> class any_cache_t {
|
||||
public:
|
||||
virtual ~any_cache_t() {}
|
||||
virtual bool Lookup(const std::string& name, T& result) const = 0;
|
||||
};
|
||||
|
||||
typedef any_cache_t<std::string> expr_cache_t;
|
||||
typedef any_cache_t<args_t> args_cache_t;
|
||||
|
||||
class bin_expr_t {
|
||||
public:
|
||||
static const bin_expr_t* CreateExpr(const bin_expr_t* arg1, const bin_expr_t* arg2,
|
||||
const char op);
|
||||
static const bin_expr_t* CreateArg(Expr* obj, const std::string str);
|
||||
|
||||
bin_expr_t() : arg1_(NULL), arg2_(NULL) {}
|
||||
bin_expr_t(const bin_expr_t* arg1, const bin_expr_t* arg2) : arg1_(arg1), arg2_(arg2) {}
|
||||
virtual ~bin_expr_t() {
|
||||
if (arg1_) delete arg1_;
|
||||
if (arg2_) delete arg2_;
|
||||
}
|
||||
|
||||
virtual args_t Eval(const args_cache_t& args) const = 0;
|
||||
virtual std::string Symbol() const = 0;
|
||||
|
||||
std::string String() const {
|
||||
std::string str;
|
||||
if (arg1_) {
|
||||
str = "(" + arg1_->String() + " " + Symbol() + " " + arg2_->String() + ")";
|
||||
} else
|
||||
str = Symbol();
|
||||
return str;
|
||||
}
|
||||
|
||||
protected:
|
||||
const bin_expr_t* arg1_;
|
||||
const bin_expr_t* arg2_;
|
||||
};
|
||||
|
||||
class Expr {
|
||||
public:
|
||||
explicit Expr(const std::string& expr, const expr_cache_t* cache)
|
||||
: expr_(expr), pos_(0), sub_count_(0), cache_(cache), is_sub_expr_(false) {
|
||||
sub_vec_ = new std::vector<const Expr*>;
|
||||
var_vec_ = new std::vector<std::string>;
|
||||
tree_ = ParseExpr();
|
||||
}
|
||||
|
||||
explicit Expr(const std::string& expr, const Expr* obj)
|
||||
: expr_(expr),
|
||||
pos_(0),
|
||||
sub_count_(0),
|
||||
cache_(obj->cache_),
|
||||
sub_vec_(obj->sub_vec_),
|
||||
var_vec_(obj->var_vec_),
|
||||
is_sub_expr_(true) {
|
||||
sub_vec_->push_back(this);
|
||||
tree_ = ParseExpr();
|
||||
if (!SubCheck()) throw exception_t("expr '" + expr_ + "', bad parenthesis count");
|
||||
}
|
||||
|
||||
~Expr() {
|
||||
if (!is_sub_expr_) {
|
||||
delete cache_;
|
||||
for (auto it : *sub_vec_) delete it;
|
||||
delete sub_vec_;
|
||||
delete var_vec_;
|
||||
delete tree_;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetStr() const { return expr_; }
|
||||
const expr_cache_t* GetCache() const { return cache_; }
|
||||
const bin_expr_t* GetTree() const { return tree_; }
|
||||
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
try {
|
||||
result = tree_->Eval(args);
|
||||
} catch (const div_zero_exception_t& e) {
|
||||
if (div_zero_exc_on)
|
||||
std::cout << "Expr::Eval() exc(" << e.what() << ") : " << String() << std::endl;
|
||||
} catch (const exception_t& e) {
|
||||
throw e;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Lookup(const std::string& str) const {
|
||||
std::string result;
|
||||
if (cache_ && !(cache_->Lookup(str, result)))
|
||||
throw exception_t("expr '" + expr_ + "', lookup '" + str + "' failed");
|
||||
return result;
|
||||
}
|
||||
|
||||
void AddVar(const std::string& str) {
|
||||
bool found = false;
|
||||
for (std::string s : *var_vec_)
|
||||
if (s == str) found = true;
|
||||
if (!found) var_vec_->push_back(str);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& GetVars() const { return *var_vec_; }
|
||||
|
||||
std::string String() const { return tree_->String(); }
|
||||
|
||||
private:
|
||||
const bin_expr_t* ParseExpr() {
|
||||
const bin_expr_t* expr = ParseArg();
|
||||
while (!IsEnd()) {
|
||||
const char op = Symb();
|
||||
const bin_expr_t* second_arg = NULL;
|
||||
if (IsSymb(')')) {
|
||||
Next();
|
||||
SubClose();
|
||||
break;
|
||||
}
|
||||
if (IsSymb('*') || IsSymb('/')) {
|
||||
Next();
|
||||
second_arg = ParseArg();
|
||||
expr = bin_expr_t::CreateExpr(expr, second_arg, op);
|
||||
} else if (IsSymb('+') || IsSymb('-')) {
|
||||
Next();
|
||||
second_arg = ParseExpr();
|
||||
expr = bin_expr_t::CreateExpr(expr, second_arg, op);
|
||||
break;
|
||||
} else {
|
||||
throw exception_t("expr '" + expr_ + "', bad operator '" + op + "'");
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
const bin_expr_t* ParseArg() {
|
||||
const bin_expr_t* arg = NULL;
|
||||
if (IsSymb('(')) {
|
||||
Next();
|
||||
SubOpen();
|
||||
arg = ParseExpr();
|
||||
} else {
|
||||
const unsigned pos = FindOp();
|
||||
const std::string str = CutTill(pos);
|
||||
arg = bin_expr_t::CreateArg(this, str);
|
||||
if (arg == NULL) throw exception_t("expr '" + expr_ + "', bad argument '" + str + "'");
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
char Symb() const { return Symb(pos_); }
|
||||
char Symb(const unsigned ind) const { return expr_[ind]; }
|
||||
bool IsEnd() const { return (pos_ >= expr_.length()); }
|
||||
bool IsSymb(const char c) const { return IsSymb(pos_, c); }
|
||||
bool IsSymb(const unsigned ind, const char c) const { return (expr_[ind] == c); }
|
||||
void Next() { ++pos_; }
|
||||
void SubOpen() { ++sub_count_; }
|
||||
void SubClose() { --sub_count_; }
|
||||
bool SubCheck() const { return (sub_count_ == 0); }
|
||||
unsigned FindOp() const {
|
||||
unsigned i = pos_;
|
||||
unsigned open_n = 0;
|
||||
while (i < expr_.length()) {
|
||||
switch (Symb(i)) {
|
||||
case '*':
|
||||
case '/':
|
||||
case '+':
|
||||
case '-':
|
||||
goto end;
|
||||
case '(':
|
||||
++open_n;
|
||||
break;
|
||||
case ')':
|
||||
if (open_n != 0) i += 1;
|
||||
goto end;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
end:
|
||||
return i;
|
||||
}
|
||||
std::string CutTill(const unsigned pos) {
|
||||
const std::string str = (pos > pos_) ? expr_.substr(pos_, pos - pos_) : "";
|
||||
pos_ = pos;
|
||||
return str;
|
||||
}
|
||||
|
||||
static const bool div_zero_exc_on = false;
|
||||
|
||||
const std::string expr_;
|
||||
unsigned pos_;
|
||||
unsigned sub_count_;
|
||||
const bin_expr_t* tree_;
|
||||
const expr_cache_t* const cache_;
|
||||
std::vector<const Expr*>* sub_vec_;
|
||||
std::vector<std::string>* var_vec_;
|
||||
const bool is_sub_expr_;
|
||||
};
|
||||
|
||||
class add_expr_t : public bin_expr_t {
|
||||
public:
|
||||
add_expr_t(const bin_expr_t* arg1, const bin_expr_t* arg2) : bin_expr_t(arg1, arg2) {}
|
||||
args_t Eval(const args_cache_t& args) const { return (arg1_->Eval(args) + arg2_->Eval(args)); }
|
||||
std::string Symbol() const { return "+"; }
|
||||
};
|
||||
class sub_expr_t : public bin_expr_t {
|
||||
public:
|
||||
sub_expr_t(const bin_expr_t* arg1, const bin_expr_t* arg2) : bin_expr_t(arg1, arg2) {}
|
||||
args_t Eval(const args_cache_t& args) const { return (arg1_->Eval(args) - arg2_->Eval(args)); }
|
||||
std::string Symbol() const { return "-"; }
|
||||
};
|
||||
class mul_expr_t : public bin_expr_t {
|
||||
public:
|
||||
mul_expr_t(const bin_expr_t* arg1, const bin_expr_t* arg2) : bin_expr_t(arg1, arg2) {}
|
||||
args_t Eval(const args_cache_t& args) const { return (arg1_->Eval(args) * arg2_->Eval(args)); }
|
||||
std::string Symbol() const { return "*"; }
|
||||
};
|
||||
class div_expr_t : public bin_expr_t {
|
||||
public:
|
||||
div_expr_t(const bin_expr_t* arg1, const bin_expr_t* arg2) : bin_expr_t(arg1, arg2) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
const args_t denominator = arg2_->Eval(args);
|
||||
if (denominator == 0) throw div_zero_exception_t("div_expr_t::Eval()");
|
||||
return (static_cast<double>(arg1_->Eval(args)) / denominator);
|
||||
}
|
||||
std::string Symbol() const { return "/"; }
|
||||
};
|
||||
class const_expr_t : public bin_expr_t {
|
||||
public:
|
||||
const_expr_t(const args_t value) : value_(value) {}
|
||||
args_t Eval(const args_cache_t&) const { return value_; }
|
||||
std::string Symbol() const {
|
||||
std::ostringstream os;
|
||||
os << value_;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
private:
|
||||
const args_t value_;
|
||||
};
|
||||
class var_expr_t : public bin_expr_t {
|
||||
public:
|
||||
var_expr_t(const std::string name) : name_(name) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
if (!args.Lookup(name_, result)) throw exception_t("expr arg lookup '" + name_ + "' failed");
|
||||
return result;
|
||||
}
|
||||
std::string Symbol() const { return name_; }
|
||||
|
||||
private:
|
||||
const std::string name_;
|
||||
};
|
||||
|
||||
class fun_expr_t : public bin_expr_t {
|
||||
public:
|
||||
typedef std::vector<var_expr_t> vvect_t;
|
||||
fun_expr_t(const std::string& fname, const std::string& vname, const uint32_t& vnum)
|
||||
: fname_(fname) {
|
||||
for (uint32_t i = 0; i < vnum; ++i) {
|
||||
std::ostringstream var_full_name;
|
||||
var_full_name << vname << "[" << i << "]";
|
||||
vvect.push_back(var_expr_t(var_full_name.str()));
|
||||
}
|
||||
}
|
||||
const vvect_t& GetVars() const { return vvect; }
|
||||
std::string Symbol() const {
|
||||
const std::string var = vvect[0].Symbol();
|
||||
const std::string vname = var.substr(0, var.length() - 3);
|
||||
std::ostringstream oss;
|
||||
std::string str("(");
|
||||
str.back() = ')';
|
||||
oss << fname_ << "(" << vname << "," << vvect.size() << ")";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string fname_;
|
||||
vvect_t vvect;
|
||||
};
|
||||
class sum_expr_t : public fun_expr_t {
|
||||
public:
|
||||
sum_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("sum", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
for (const auto& var : GetVars()) result += var.Eval(args);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
class avr_expr_t : public fun_expr_t {
|
||||
public:
|
||||
avr_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("avr", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
for (const auto& var : GetVars()) result += var.Eval(args);
|
||||
return result / GetVars().size();
|
||||
}
|
||||
};
|
||||
class min_expr_t : public fun_expr_t {
|
||||
public:
|
||||
min_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("min", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = ARGS_MAX;
|
||||
for (const auto& var : GetVars()) {
|
||||
args_t val = var.Eval(args);
|
||||
result = (val < result) ? val : result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
class max_expr_t : public fun_expr_t {
|
||||
public:
|
||||
max_expr_t(const std::string& vname, const uint32_t& vnum) : fun_expr_t("max", vname, vnum) {}
|
||||
args_t Eval(const args_cache_t& args) const {
|
||||
args_t result = 0;
|
||||
for (const auto& var : GetVars()) {
|
||||
args_t val = var.Eval(args);
|
||||
result = (val > result) ? val : result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
inline const bin_expr_t* bin_expr_t::CreateExpr(const bin_expr_t* arg1, const bin_expr_t* arg2,
|
||||
const char op) {
|
||||
const bin_expr_t* expr = NULL;
|
||||
switch (op) {
|
||||
case '+':
|
||||
expr = new add_expr_t(arg1, arg2);
|
||||
break;
|
||||
case '-':
|
||||
expr = new sub_expr_t(arg1, arg2);
|
||||
break;
|
||||
case '*':
|
||||
expr = new mul_expr_t(arg1, arg2);
|
||||
break;
|
||||
case '/':
|
||||
expr = new div_expr_t(arg1, arg2);
|
||||
break;
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
inline const bin_expr_t* bin_expr_t::CreateArg(Expr* obj, const std::string str) {
|
||||
const bin_expr_t* arg = NULL;
|
||||
|
||||
const unsigned i = strspn(str.c_str(), "1234567890");
|
||||
if (i == str.length()) {
|
||||
const unsigned value = atoi(str.c_str());
|
||||
arg = new const_expr_t(value);
|
||||
}
|
||||
|
||||
if (arg == NULL) {
|
||||
const std::size_t pos = str.find('(');
|
||||
if (pos != std::string::npos) {
|
||||
char* fname = NULL;
|
||||
char* vname = NULL;
|
||||
int vnum = 0;
|
||||
int ret = sscanf(str.c_str(), "%m[a-zA-Z_](%m[0-9a-zA-Z_],%d)", &fname, &vname, &vnum);
|
||||
if (ret == 3) {
|
||||
const std::string fun_name(fname);
|
||||
const fun_expr_t* farg = NULL;
|
||||
if (fun_name == "sum") {
|
||||
farg = new sum_expr_t(vname, vnum);
|
||||
} else if (fun_name == "avr") {
|
||||
farg = new avr_expr_t(vname, vnum);
|
||||
} else if (fun_name == "min") {
|
||||
farg = new min_expr_t(vname, vnum);
|
||||
} else if (fun_name == "max") {
|
||||
farg = new max_expr_t(vname, vnum);
|
||||
}
|
||||
if (farg)
|
||||
for (const auto& var : farg->GetVars()) obj->AddVar(var.Symbol());
|
||||
arg = farg;
|
||||
}
|
||||
free(fname);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
if (arg == NULL) {
|
||||
const std::string sub_expr = obj->Lookup(str);
|
||||
if (sub_expr.empty()) {
|
||||
arg = new var_expr_t(str);
|
||||
obj->AddVar(str);
|
||||
} else {
|
||||
const Expr* expr = new Expr(sub_expr, obj);
|
||||
arg = expr->GetTree();
|
||||
}
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
} // namespace xml
|
||||
|
||||
#endif // _SRC_CORE_COUNTERS_METRICS_XML_EXPR_H
|
||||
@@ -0,0 +1,28 @@
|
||||
/******************************************************************************
|
||||
Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "metrics.h"
|
||||
|
||||
namespace rocmtools {
|
||||
MetricsDict::map_t* MetricsDict::map_ = NULL;
|
||||
MetricsDict::mutex_t MetricsDict::mutex_;
|
||||
} // namespace rocmtools
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
/******************************************************************************
|
||||
Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SRC_CORE_COUNTERS_METRICS_METRICS_H_
|
||||
#define SRC_CORE_COUNTERS_METRICS_METRICS_H_
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "types.h"
|
||||
#include "exception.h"
|
||||
#include "expr.h"
|
||||
#include "xml.h"
|
||||
#include <mutex>
|
||||
#include "src/core/hardware/hsa_info.h"
|
||||
|
||||
namespace rocmtools {
|
||||
struct counter_t {
|
||||
std::string name;
|
||||
event_t event;
|
||||
};
|
||||
typedef std::vector<const counter_t*> counters_vec_t;
|
||||
|
||||
class Metric {
|
||||
public:
|
||||
Metric(const std::string& name) : name_(name) {}
|
||||
virtual ~Metric() {}
|
||||
std::string GetName() const { return name_; }
|
||||
virtual void GetCounters(counters_vec_t& vec) const = 0;
|
||||
counters_vec_t GetCounters() const {
|
||||
counters_vec_t counters;
|
||||
GetCounters(counters);
|
||||
return counters;
|
||||
}
|
||||
virtual const xml::Expr* GetExpr() const = 0;
|
||||
|
||||
private:
|
||||
const std::string name_;
|
||||
};
|
||||
|
||||
class BaseMetric : public Metric {
|
||||
public:
|
||||
BaseMetric(const std::string& name, const counter_t& counter) : Metric(name), counter_(counter) {}
|
||||
void GetCounters(counters_vec_t& vec) const { vec.push_back(&counter_); }
|
||||
const xml::Expr* GetExpr() const { return NULL; }
|
||||
|
||||
private:
|
||||
const counter_t counter_;
|
||||
};
|
||||
|
||||
class ExprMetric : public Metric {
|
||||
public:
|
||||
ExprMetric(const std::string& name, const counters_vec_t& counters, const xml::Expr* expr)
|
||||
: Metric(name), counters_(counters), expr_(expr) {}
|
||||
~ExprMetric() { delete expr_; }
|
||||
void GetCounters(counters_vec_t& vec) const {
|
||||
vec.insert(vec.end(), counters_.begin(), counters_.end());
|
||||
}
|
||||
const xml::Expr* GetExpr() const { return expr_; }
|
||||
|
||||
private:
|
||||
const counters_vec_t counters_;
|
||||
const xml::Expr* expr_;
|
||||
};
|
||||
|
||||
class MetricsDict {
|
||||
public:
|
||||
typedef std::map<std::string, const Metric*> cache_t;
|
||||
typedef cache_t::const_iterator const_iterator_t;
|
||||
typedef std::map<std::string, MetricsDict*> map_t;
|
||||
typedef std::mutex mutex_t;
|
||||
|
||||
class ExprCache : public xml::expr_cache_t {
|
||||
public:
|
||||
ExprCache(const cache_t* cache) : cache_(cache) {}
|
||||
bool Lookup(const std::string& name, std::string& result) const {
|
||||
bool ret = false;
|
||||
auto it = cache_->find(name);
|
||||
if (it != cache_->end()) {
|
||||
ret = true;
|
||||
const rocmtools::ExprMetric* expr_metric =
|
||||
dynamic_cast<const rocmtools::ExprMetric*>(it->second);
|
||||
if (expr_metric) result = expr_metric->GetExpr()->GetStr();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
const cache_t* const cache_;
|
||||
};
|
||||
|
||||
static MetricsDict* Create(const Agent::AgentInfo* agent_info) {
|
||||
std::lock_guard<mutex_t> lck(mutex_);
|
||||
if (map_ == NULL) map_ = new map_t;
|
||||
std::string name = agent_info->getGfxip();
|
||||
auto ret = map_->insert({name, NULL});
|
||||
if (ret.second) ret.first->second = new MetricsDict(agent_info);
|
||||
return ret.first->second;
|
||||
}
|
||||
|
||||
static void Destroy() {
|
||||
if (map_ != NULL) {
|
||||
for (auto& entry : *map_) delete entry.second;
|
||||
delete map_;
|
||||
map_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const Metric* Get(const std::string& name) const {
|
||||
const Metric* metric = NULL;
|
||||
|
||||
auto it = cache_.find(name);
|
||||
if (it != cache_.end())
|
||||
metric = it->second;
|
||||
else {
|
||||
const std::size_t pos = name.find(':');
|
||||
if (pos != std::string::npos) {
|
||||
std::string block_name = name.substr(0, pos);
|
||||
const std::string event_str = name.substr(pos + 1);
|
||||
|
||||
uint32_t block_index = 0;
|
||||
bool indexed = false;
|
||||
const std::size_t pos1 = block_name.find('[');
|
||||
if (pos1 != std::string::npos) {
|
||||
const std::size_t pos2 = block_name.find(']');
|
||||
if (pos2 == std::string::npos)
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "Malformed metric name '" << name << "'");
|
||||
block_name = name.substr(0, pos1);
|
||||
const std::string block_index_str = name.substr(pos1 + 1, pos2 - (pos1 + 1));
|
||||
block_index = atol(block_index_str.c_str());
|
||||
indexed = true;
|
||||
}
|
||||
|
||||
const hsa_ven_amd_aqlprofile_id_query_t query = Translate(agent_info_, block_name);
|
||||
const hsa_ven_amd_aqlprofile_block_name_t block_id =
|
||||
(hsa_ven_amd_aqlprofile_block_name_t)query.id;
|
||||
if ((query.instance_count > 1) && (indexed == false))
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "Malformed indexed metric name '" << name << "'");
|
||||
const uint32_t event_id = atol(event_str.c_str());
|
||||
const counter_t counter = {name, {block_id, block_index, event_id}};
|
||||
metric = new BaseMetric(name, counter);
|
||||
}
|
||||
}
|
||||
|
||||
return metric;
|
||||
}
|
||||
|
||||
uint32_t Size() const { return cache_.size(); }
|
||||
const_iterator_t Begin() const { return cache_.begin(); }
|
||||
const_iterator_t End() const { return cache_.end(); }
|
||||
|
||||
std::string GetAgentName() const { return agent_name_; }
|
||||
|
||||
xml::Xml::nodes_t GetNodes() const {
|
||||
auto nodes_vec = GetNodes(agent_name_);
|
||||
auto global_vec = GetNodes("global");
|
||||
nodes_vec.insert(nodes_vec.end(), global_vec.begin(), global_vec.end());
|
||||
return nodes_vec;
|
||||
}
|
||||
|
||||
private:
|
||||
xml::Xml::nodes_t GetNodes(const std::string& scope) const {
|
||||
return (xml_ != NULL) ? xml_->GetNodes("top." + scope + ".metric") : xml::Xml::nodes_t();
|
||||
}
|
||||
|
||||
MetricsDict(const Agent::AgentInfo* agent_info) : xml_(NULL), agent_info_(agent_info) {
|
||||
const char* xml_name = getenv("ROCPROFILER_METRICS_PATH");
|
||||
if (xml_name != NULL) {
|
||||
xml_ = xml::Xml::Create(xml_name);
|
||||
if (xml_ == NULL)
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "metrics .xml open error '" << xml_name << "'");
|
||||
xml_->AddConst("top.const.metric", "MAX_WAVE_SIZE", agent_info->getMaxQueueSize());
|
||||
xml_->AddConst("top.const.metric", "CU_NUM", agent_info->getCUCount());
|
||||
xml_->AddConst("top.const.metric", "SIMD_NUM",
|
||||
agent_info->getSimdCountPerCU() * agent_info->getCUCount());
|
||||
xml_->AddConst("top.const.metric", "SE_NUM", agent_info->getShaderEngineCount());
|
||||
ImportMetrics(agent_info, "const");
|
||||
agent_name_ = agent_info->getName();
|
||||
if (std::string("gfx906") == agent_name_ || std::string("gfx908") == agent_name_ ||
|
||||
std::string("gfx90a") == agent_name_ || std::string("gfx1032") == agent_name_ ||
|
||||
std::string("gfx1031") == agent_name_ || std::string("gfx1030") == agent_name_) {
|
||||
ImportMetrics(agent_info, agent_name_);
|
||||
} else {
|
||||
agent_name_ = agent_info->getGfxip();
|
||||
ImportMetrics(agent_info, agent_name_);
|
||||
}
|
||||
ImportMetrics(agent_info, "global");
|
||||
}
|
||||
}
|
||||
|
||||
~MetricsDict() {
|
||||
xml::Xml::Destroy(xml_);
|
||||
for (auto& entry : cache_) delete entry.second;
|
||||
}
|
||||
|
||||
static hsa_ven_amd_aqlprofile_id_query_t Translate(const Agent::AgentInfo* agent_info,
|
||||
const std::string& block_name) {
|
||||
hsa_ven_amd_aqlprofile_profile_t profile{};
|
||||
profile.agent = hsa_agent_t{agent_info->getHandle()};
|
||||
hsa_ven_amd_aqlprofile_id_query_t query = {block_name.c_str(), 0, 0};
|
||||
hsa_status_t status =
|
||||
hsa_ven_amd_aqlprofile_get_info(&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_ID, &query);
|
||||
if (status != HSA_STATUS_SUCCESS)
|
||||
AQL_EXC_RAISING(HSA_STATUS_ERROR, "ImportMetrics: bad block name '" << block_name << "'");
|
||||
return query;
|
||||
}
|
||||
|
||||
void ImportMetrics(const Agent::AgentInfo* agent_info, const std::string& scope) {
|
||||
auto arr = xml_->GetNodes("top." + scope + ".metric");
|
||||
xml::Xml::node_list_t metrics_list(arr.begin(), arr.end());
|
||||
uint32_t metrics_number = metrics_list.size();
|
||||
bool do_lookup = true;
|
||||
if (!metrics_list.empty()) {
|
||||
uint32_t it_number = metrics_number;
|
||||
auto it = metrics_list.begin();
|
||||
auto end = metrics_list.end();
|
||||
while (it != end) {
|
||||
auto node = *it;
|
||||
const std::string name = node->opts["name"];
|
||||
const std::string expr_str = node->opts["expr"];
|
||||
std::string descr = node->opts["descr"];
|
||||
if (descr.empty()) descr = (expr_str.empty()) ? name : expr_str;
|
||||
|
||||
if (expr_str.empty()) {
|
||||
const std::string block_name = node->opts["block"];
|
||||
const std::string event_str = node->opts["event"];
|
||||
const uint32_t event_id = atol(event_str.c_str());
|
||||
|
||||
const hsa_ven_amd_aqlprofile_id_query_t query = Translate(agent_info, block_name);
|
||||
const hsa_ven_amd_aqlprofile_block_name_t block_id =
|
||||
(hsa_ven_amd_aqlprofile_block_name_t)query.id;
|
||||
if (query.instance_count > 1) {
|
||||
for (unsigned block_index = 0; block_index < query.instance_count; ++block_index) {
|
||||
std::ostringstream full_name;
|
||||
full_name << name << '[' << block_index << ']';
|
||||
std::ostringstream block_insance;
|
||||
block_insance << block_name << "[" << block_index << "]";
|
||||
std::ostringstream alias;
|
||||
alias << block_insance.str() << ":" << event_str;
|
||||
const counter_t counter = {full_name.str(), {block_id, block_index, event_id}};
|
||||
AddMetric(full_name.str(), alias.str(), counter);
|
||||
}
|
||||
} else {
|
||||
const std::string alias = block_name + ":" + event_str;
|
||||
const counter_t counter = {name, {block_id, 0, event_id}};
|
||||
AddMetric(name, alias, counter);
|
||||
}
|
||||
} else {
|
||||
xml::Expr* expr_obj = NULL;
|
||||
try {
|
||||
expr_obj = new xml::Expr(expr_str, new ExprCache(&cache_));
|
||||
} catch (const xml::exception_t& exc) {
|
||||
if (do_lookup)
|
||||
metrics_list.push_back(node);
|
||||
else
|
||||
throw(exc);
|
||||
}
|
||||
if (expr_obj) {
|
||||
#if 0
|
||||
std::cout << "# " << descr << std::endl;
|
||||
std::cout << name << "=" << expr_obj->String() << "\n" << std::endl;
|
||||
#endif
|
||||
counters_vec_t counters_vec;
|
||||
for (const std::string& var : expr_obj->GetVars()) {
|
||||
auto it = cache_.find(var);
|
||||
if (it == cache_.end()) {
|
||||
EXC_RAISING(HSA_STATUS_ERROR,
|
||||
"Bad metric '" << name << "', var '" << var << "' is not found");
|
||||
}
|
||||
it->second->GetCounters(counters_vec);
|
||||
}
|
||||
AddMetric(name, counters_vec, expr_obj);
|
||||
}
|
||||
}
|
||||
|
||||
auto cur = it++;
|
||||
metrics_list.erase(cur);
|
||||
if (--it_number == 0) {
|
||||
it_number = metrics_list.size();
|
||||
if (it_number < metrics_number) {
|
||||
metrics_number = it_number;
|
||||
} else if (it_number == metrics_number) {
|
||||
do_lookup = false;
|
||||
} else {
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "Internal error");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Metric* AddMetric(const std::string& name, const std::string& /*alias*/,
|
||||
const counter_t& counter) {
|
||||
const Metric* metric = NULL;
|
||||
const auto ret = cache_.insert({name, NULL});
|
||||
if (ret.second) {
|
||||
metric = new BaseMetric(name, counter);
|
||||
ret.first->second = metric;
|
||||
} else
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "metric redefined '" << name << "'");
|
||||
return metric;
|
||||
}
|
||||
|
||||
const Metric* AddMetric(const std::string& name, const counters_vec_t& counters_vec,
|
||||
const xml::Expr* expr_obj) {
|
||||
const Metric* metric = NULL;
|
||||
const auto ret = cache_.insert({name, NULL});
|
||||
if (ret.second) {
|
||||
metric = new ExprMetric(name, counters_vec, expr_obj);
|
||||
ret.first->second = metric;
|
||||
} else
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "expr-metric redefined '" << name << "'");
|
||||
return metric;
|
||||
}
|
||||
|
||||
void Print() {
|
||||
for (auto& v : cache_) {
|
||||
const Metric* metric = v.second;
|
||||
counters_vec_t counters_vec;
|
||||
printf("> Metric '%s'\n", metric->GetName().c_str());
|
||||
metric->GetCounters(counters_vec);
|
||||
for (auto c : counters_vec) {
|
||||
printf(" counter %s, b(%u), i (%u), e (%u)\n", c->name.c_str(), c->event.block_name,
|
||||
c->event.block_index, c->event.counter_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xml::Xml* xml_;
|
||||
const Agent::AgentInfo* agent_info_;
|
||||
std::string agent_name_;
|
||||
cache_t cache_;
|
||||
|
||||
static map_t* map_;
|
||||
static mutex_t mutex_;
|
||||
};
|
||||
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_COUNTERS_METRICS_METRICS_H_
|
||||
@@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SRC_CORE_TYPES_H_
|
||||
#define SRC_CORE_TYPES_H_
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
|
||||
namespace rocmtools {
|
||||
typedef hsa_ven_amd_aqlprofile_pfn_t pfn_t;
|
||||
typedef hsa_ven_amd_aqlprofile_event_t event_t;
|
||||
typedef hsa_ven_amd_aqlprofile_parameter_t parameter_t;
|
||||
typedef hsa_ven_amd_aqlprofile_profile_t profile_t;
|
||||
typedef hsa_ext_amd_aql_pm4_packet_t packet_t;
|
||||
typedef uint32_t packet_word_t;
|
||||
typedef uint64_t timestamp_t;
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const event_t& event) {
|
||||
out << "[block_name(" << event.block_name << "). block_index(" << event.block_index
|
||||
<< "). counter_id(" << event.counter_id << ")]";
|
||||
return out;
|
||||
}
|
||||
inline std::ostream& operator<<(std::ostream& out, const parameter_t& parameter) {
|
||||
out << "[parameter_name(" << parameter.parameter_name << "). value(" << parameter.value << ")]";
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_TYPES_H_
|
||||
@@ -0,0 +1,512 @@
|
||||
/******************************************************************************
|
||||
Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SRC_CORE_COUNTERS_METRICS_XML_XML_H_
|
||||
#define SRC_CORE_COUNTERS_METRICS_XML_XML_H_
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace xml {
|
||||
|
||||
class Xml {
|
||||
public:
|
||||
typedef std::vector<char> token_t;
|
||||
|
||||
struct level_t;
|
||||
typedef std::vector<level_t*> node_vect_t;
|
||||
typedef std::list<level_t*> node_list_t;
|
||||
|
||||
typedef node_vect_t nodes_t;
|
||||
typedef std::map<std::string, std::string> opts_t;
|
||||
struct level_t {
|
||||
std::string tag;
|
||||
nodes_t nodes;
|
||||
opts_t opts;
|
||||
const level_t* copy;
|
||||
};
|
||||
typedef std::vector<level_t*> nodes_vec_t;
|
||||
typedef std::map<std::string, nodes_vec_t> map_t;
|
||||
|
||||
enum { DECL_STATE, BODY_STATE };
|
||||
|
||||
static Xml* Create(const std::string& file_name, const Xml* obj = NULL) {
|
||||
Xml* xml = new Xml(file_name, obj);
|
||||
if (xml != NULL) {
|
||||
if (xml->Init() == false) {
|
||||
delete xml;
|
||||
xml = NULL;
|
||||
} else {
|
||||
const std::size_t pos = file_name.rfind('/');
|
||||
const std::string path = (pos != std::string::npos) ? file_name.substr(0, pos + 1) : "";
|
||||
|
||||
xml->PreProcess();
|
||||
nodes_t incl_nodes;
|
||||
for (auto* node : xml->GetNodes("top.include")) {
|
||||
if (node->opts.find("touch") == node->opts.end()) {
|
||||
node->opts["touch"] = "";
|
||||
incl_nodes.push_back(node);
|
||||
}
|
||||
}
|
||||
for (auto* incl : incl_nodes) {
|
||||
const std::string& incl_name = path + incl->opts["file"];
|
||||
Xml* ixml = Create(incl_name, xml);
|
||||
if (ixml == NULL) {
|
||||
delete xml;
|
||||
xml = NULL;
|
||||
break;
|
||||
} else {
|
||||
delete ixml;
|
||||
}
|
||||
}
|
||||
if (xml) {
|
||||
xml->Process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
static void Destroy(Xml* xml) { delete xml; }
|
||||
|
||||
std::string GetName() { return file_name_; }
|
||||
|
||||
void AddExpr(const std::string& full_tag, const std::string& name, const std::string& expr) {
|
||||
const std::size_t pos = full_tag.rfind('.');
|
||||
const std::size_t pos1 = (pos == std::string::npos) ? 0 : pos + 1;
|
||||
const std::string level_tag = full_tag.substr(pos1);
|
||||
level_t* level = new level_t;
|
||||
(*map_)[full_tag].push_back(level);
|
||||
level->tag = level_tag;
|
||||
level->opts["name"] = name;
|
||||
level->opts["expr"] = expr;
|
||||
}
|
||||
|
||||
void AddConst(const std::string& full_tag, const std::string& name, const uint64_t& val) {
|
||||
std::ostringstream oss;
|
||||
oss << val;
|
||||
AddExpr(full_tag, name, oss.str());
|
||||
}
|
||||
|
||||
nodes_t GetNodes(const std::string& global_tag) { return (*map_)[global_tag]; }
|
||||
|
||||
template <class F> F ForEach(const F& f_i) {
|
||||
F f = f_i;
|
||||
if (map_) {
|
||||
for (auto& entry : *map_) {
|
||||
for (auto node : entry.second) {
|
||||
if (f.fun(entry.first, node) == false) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
template <class F> F ForEach(const F& f_i) const {
|
||||
F f = f_i;
|
||||
if (map_) {
|
||||
for (auto& entry : *map_) {
|
||||
for (auto node : entry.second) {
|
||||
if (f.fun(entry.first, node) == false) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
struct print_func {
|
||||
bool fun(const std::string& global_tag, level_t* node) {
|
||||
std::cout << global_tag << ":" << std::endl;
|
||||
for (auto& opt : node->opts) {
|
||||
std::cout << global_tag << "." << opt.first << " = " << opt.second << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void Print() const {
|
||||
std::cout << "XML file '" << file_name_ << "':" << std::endl;
|
||||
ForEach(print_func());
|
||||
}
|
||||
|
||||
private:
|
||||
Xml(const std::string& file_name, const Xml* obj)
|
||||
: file_name_(file_name),
|
||||
file_line_(0),
|
||||
data_size_(0),
|
||||
index_(0),
|
||||
state_(BODY_STATE),
|
||||
comment_(false),
|
||||
included_(false),
|
||||
level_(NULL),
|
||||
map_(NULL) {
|
||||
if (obj != NULL) {
|
||||
map_ = obj->map_;
|
||||
level_ = obj->level_;
|
||||
included_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
struct delete_func {
|
||||
bool fun(const std::string&, level_t* node) {
|
||||
delete node;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
~Xml() {
|
||||
if (included_ == false) {
|
||||
ForEach(delete_func());
|
||||
delete map_;
|
||||
}
|
||||
}
|
||||
|
||||
bool Init() {
|
||||
fd_ = open(file_name_.c_str(), O_RDONLY);
|
||||
if (fd_ == -1) {
|
||||
// perror((std::string("open XML file ") + file_name_).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (map_ == NULL) {
|
||||
map_ = new map_t;
|
||||
if (map_ == NULL) return false;
|
||||
AddLevel("top");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PreProcess() {
|
||||
uint32_t ind = 0;
|
||||
char buf[kBufSize];
|
||||
bool error = false;
|
||||
|
||||
while (1) {
|
||||
const uint32_t pos = lseek(fd_, 0, SEEK_CUR);
|
||||
uint32_t size = read(fd_, buf, kBufSize);
|
||||
if (size <= 0) break;
|
||||
buf[size - 1] = '\0';
|
||||
|
||||
if (strncmp(buf, "#include \"", 10) == 0) {
|
||||
for (ind = 0; (ind < size) && (buf[ind] != '\n'); ++ind) {
|
||||
}
|
||||
if (ind < size) {
|
||||
buf[ind] = '\0';
|
||||
size = ind;
|
||||
lseek(fd_, pos + ind + 1, SEEK_SET);
|
||||
}
|
||||
|
||||
for (ind = 10; (ind < size) && (buf[ind] != '"'); ++ind) {
|
||||
}
|
||||
if (ind == size) {
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
buf[ind] = '\0';
|
||||
|
||||
AddLevel("include");
|
||||
AddOption("file", &buf[10]);
|
||||
UpLevel();
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
fprintf(stderr, "XML PreProcess failed, line '%s'\n", buf);
|
||||
abort();
|
||||
}
|
||||
|
||||
lseek(fd_, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
void Process() {
|
||||
token_t remainder;
|
||||
|
||||
while (1) {
|
||||
token_t token = (remainder.size()) ? remainder : NextToken();
|
||||
remainder.clear();
|
||||
|
||||
// token_t token1 = token;
|
||||
// token1.push_back('\0');
|
||||
// std::cout << ">>> " << &token1[0] << std::endl;
|
||||
|
||||
// End of file
|
||||
if (token.size() == 0) break;
|
||||
|
||||
switch (state_) {
|
||||
case BODY_STATE:
|
||||
if (token[0] == '<') {
|
||||
bool node_begin = true;
|
||||
unsigned ind = 1;
|
||||
if (token[1] == '/') {
|
||||
node_begin = false;
|
||||
++ind;
|
||||
}
|
||||
|
||||
unsigned i = ind;
|
||||
while (i < token.size()) {
|
||||
if (token[i] == '>') break;
|
||||
++i;
|
||||
}
|
||||
for (unsigned j = i + 1; j < token.size(); ++j) remainder.push_back(token[j]);
|
||||
|
||||
if (i == token.size()) {
|
||||
if (node_begin)
|
||||
state_ = DECL_STATE;
|
||||
else
|
||||
BadFormat(token);
|
||||
token.push_back('\0');
|
||||
} else {
|
||||
token[i] = '\0';
|
||||
}
|
||||
|
||||
const char* tag = &token[ind];
|
||||
if (node_begin) {
|
||||
AddLevel(tag);
|
||||
} else {
|
||||
Inherit(GetOption("base"));
|
||||
|
||||
if (strncmp(CurrentLevel().c_str(), tag, strlen(tag)) != 0) {
|
||||
token.back() = '>';
|
||||
BadFormat(token);
|
||||
}
|
||||
UpLevel();
|
||||
}
|
||||
} else {
|
||||
BadFormat(token);
|
||||
}
|
||||
break;
|
||||
case DECL_STATE:
|
||||
if (token[0] == '>') {
|
||||
state_ = BODY_STATE;
|
||||
for (unsigned j = 1; j < token.size(); ++j) remainder.push_back(token[j]);
|
||||
continue;
|
||||
} else {
|
||||
token.push_back('\0');
|
||||
unsigned j = 0;
|
||||
for (j = 0; j < token.size(); ++j)
|
||||
if (token[j] == '=') break;
|
||||
if (j == token.size()) BadFormat(token);
|
||||
token[j] = '\0';
|
||||
const std::string key = &token[0];
|
||||
const std::string value = &token[j + 1];
|
||||
AddOption(key, value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::cout << "XML parser error: wrong state: " << state_ << std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SpaceCheck() const {
|
||||
bool cond = ((buffer_[index_] == ' ') || (buffer_[index_] == '\t'));
|
||||
return cond;
|
||||
}
|
||||
|
||||
bool LineEndCheck() {
|
||||
bool found = false;
|
||||
if (buffer_[index_] == '\n') {
|
||||
buffer_[index_] = ' ';
|
||||
++file_line_;
|
||||
found = true;
|
||||
comment_ = false;
|
||||
} else if (comment_ || (buffer_[index_] == '#')) {
|
||||
found = true;
|
||||
comment_ = true;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
token_t NextToken() {
|
||||
token_t token;
|
||||
bool in_string = false;
|
||||
bool special_symb = false;
|
||||
|
||||
while (1) {
|
||||
if (data_size_ == 0) {
|
||||
data_size_ = read(fd_, buffer_, kBufSize);
|
||||
if (data_size_ <= 0) break;
|
||||
}
|
||||
|
||||
if (token.empty()) {
|
||||
while ((index_ < data_size_) && (SpaceCheck() || LineEndCheck())) {
|
||||
++index_;
|
||||
}
|
||||
}
|
||||
while ((index_ < data_size_) && (in_string || !(SpaceCheck() || LineEndCheck()))) {
|
||||
const char symb = buffer_[index_];
|
||||
bool skip_symb = false;
|
||||
|
||||
switch (symb) {
|
||||
case '\\':
|
||||
if (special_symb) {
|
||||
special_symb = false;
|
||||
} else {
|
||||
special_symb = true;
|
||||
skip_symb = true;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
if (special_symb) {
|
||||
special_symb = false;
|
||||
} else {
|
||||
in_string = !in_string;
|
||||
if (!in_string) {
|
||||
buffer_[index_] = ' ';
|
||||
--index_;
|
||||
}
|
||||
skip_symb = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!skip_symb) token.push_back(symb);
|
||||
++index_;
|
||||
}
|
||||
|
||||
if (index_ == data_size_) {
|
||||
index_ = 0;
|
||||
data_size_ = 0;
|
||||
} else {
|
||||
if (special_symb || in_string) BadFormat(token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
void BadFormat(token_t token) {
|
||||
token.push_back('\0');
|
||||
std::cout << "Error: " << file_name_ << ", line " << file_line_ << ", bad XML token '"
|
||||
<< &token[0] << "'" << std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
void AddLevel(const std::string& tag) {
|
||||
level_t* level = new level_t{};
|
||||
level->tag = tag;
|
||||
if (level_) {
|
||||
level_->nodes.push_back(level);
|
||||
stack_.push_back(level_);
|
||||
}
|
||||
level_ = level;
|
||||
|
||||
std::string global_tag = GlobalTag(tag);
|
||||
(*map_)[global_tag].push_back(level_);
|
||||
}
|
||||
|
||||
void UpLevel() {
|
||||
level_ = stack_.back();
|
||||
stack_.pop_back();
|
||||
}
|
||||
|
||||
void Copy(const level_t* from, level_t* to) {
|
||||
level_t* level = to;
|
||||
if (level == NULL) {
|
||||
AddLevel(from->tag);
|
||||
level = level_;
|
||||
}
|
||||
level->copy = from;
|
||||
level->opts = from->opts;
|
||||
|
||||
for (auto node : from->nodes) {
|
||||
bool found = false;
|
||||
const std::string name = GetOption("name", node);
|
||||
const std::string global_tag = GlobalTag(level->tag) + "." + node->tag;
|
||||
for (auto item : (*map_)[global_tag]) {
|
||||
if ((name == GetOption("name", item)) || (node == item->copy)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == false) Copy(node, NULL);
|
||||
}
|
||||
|
||||
if (to == NULL) UpLevel();
|
||||
}
|
||||
|
||||
void Inherit(const std::string& tag) {
|
||||
if (!tag.empty()) {
|
||||
const std::string global_tag = GlobalTag(tag);
|
||||
auto it = map_->find(global_tag);
|
||||
if (it == map_->end()) {
|
||||
fprintf(stderr, "Node \"%s\": Base not found \"%s\"\n", level_->tag.c_str(), tag.c_str());
|
||||
abort();
|
||||
}
|
||||
for (auto node : it->second) {
|
||||
Copy(node, level_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string CurrentLevel() const { return level_->tag; }
|
||||
|
||||
std::string GlobalTag(const std::string& tag) const {
|
||||
std::string global_tag;
|
||||
for (level_t* level : stack_) {
|
||||
global_tag += level->tag + ".";
|
||||
}
|
||||
global_tag += tag;
|
||||
return global_tag;
|
||||
}
|
||||
|
||||
void AddOption(const std::string& key, const std::string& value) { level_->opts[key] = value; }
|
||||
std::string GetOption(const std::string& key, const level_t* level = NULL) {
|
||||
level = (level != NULL) ? level : level_;
|
||||
auto it = level->opts.find(key);
|
||||
return (it != level->opts.end()) ? it->second : "";
|
||||
}
|
||||
|
||||
const std::string file_name_;
|
||||
unsigned file_line_;
|
||||
int fd_;
|
||||
|
||||
static const size_t kBufSize = 256;
|
||||
char buffer_[kBufSize];
|
||||
|
||||
unsigned data_size_;
|
||||
unsigned index_;
|
||||
unsigned state_;
|
||||
bool comment_;
|
||||
std::vector<level_t*> stack_;
|
||||
bool included_;
|
||||
level_t* level_;
|
||||
map_t* map_;
|
||||
};
|
||||
|
||||
} // namespace xml
|
||||
|
||||
#endif // SRC_CORE_COUNTERS_METRICS_XML_XML_H_
|
||||
+405
@@ -0,0 +1,405 @@
|
||||
<gfx8>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="27" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="28" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="30" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="31" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="32" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="33" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="34" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="35" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="61" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="69" descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="86" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="89" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="97" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="18" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_MC_RDREQ" block="TCC" event="35" descr="Number of 32-byte reads. The hardware actually does 64-byte reads but the number is adjusted to provide uniformity."></metric>
|
||||
<metric name="TCC_MC_WRREQ" block="TCC" event="26" descr="Number of 32-byte transactions going over the TC_MC_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests."></metric>
|
||||
<metric name="TCC_MC_WRREQ_STALL" block="TCC" event="28" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="3" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
</gfx8>
|
||||
|
||||
<gfx906>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="27" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="28" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="30" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="31" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="32" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="33" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="34" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="35" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="63" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="71" descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="84" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="85" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="93" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="20" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="22" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="29" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="30" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="33" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="41" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="42" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="TCC_EA1_WRREQ" block="TCC" event="256" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_64B" block="TCC" event="257" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_STALL" block="TCC" event="260" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA1_RDREQ" block="TCC" event="267" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA1_RDREQ_32B" block="TCC" event="268" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
</gfx906>
|
||||
|
||||
<gfx908>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="28" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="29" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="31" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="32" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="33" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="34" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="35" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="36" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="64" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="72" descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="85" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="86" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="94" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="17" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="26" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="27" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="30" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="38" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="39" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
</gfx908>
|
||||
|
||||
<gfx90a>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="91" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block="GRBM" event="3" descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block="GRBM" event="11" descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block="GRBM" event="13" descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TC_BUSY" block="GRBM" event="28" descr="Any of the Texture Cache Blocks (TCP/TCI/TCA/TCC) are busy."></metric>
|
||||
<metric name="GRBM_CPC_BUSY" block="GRBM" event="30" descr="The Command Processor Compute (CPC) is busy."></metric>
|
||||
<metric name="GRBM_CPF_BUSY" block="GRBM" event="31" descr="The Command Processor Fetchers (CPF) is busy."></metric>
|
||||
<metric name="GRBM_UTCL2_BUSY" block="GRBM" event="34" descr="The Unified Translation Cache Level-2 (UTCL2) block is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block="GRBM" event="35" descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="CPC_ME1_BUSY_FOR_PACKET_DECODE" block="CPC" event="13" descr="Me1 busy for packet decode."></metric>
|
||||
<metric name="CPC_UTCL1_STALL_ON_TRANSLATION" block="CPC" event="24" descr="One of the UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPC_CPC_STAT_BUSY" block="CPC" event="25" descr="CPC Busy."></metric>
|
||||
<metric name="CPC_CPC_STAT_IDLE" block="CPC" event="26" descr="CPC Idle."></metric>
|
||||
<metric name="CPC_CPC_STAT_STALL" block="CPC" event="27" descr="CPC Stalled."></metric>
|
||||
<metric name="CPC_CPC_TCIU_BUSY" block="CPC" event="28" descr="CPC TCIU interface Busy."></metric>
|
||||
<metric name="CPC_CPC_TCIU_IDLE" block="CPC" event="29" descr="CPC TCIU interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_BUSY" block="CPC" event="30" descr="CPC UTCL2 interface Busy."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_IDLE" block="CPC" event="31" descr="CPC UTCL2 interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_STALL" block="CPC" event="32" descr="CPC UTCL2 interface Stalled waiting on Free, Tags or Translation."></metric>
|
||||
<metric name="CPC_ME1_DC0_SPI_BUSY" block="CPC" event="33" descr="CPC Me1 Processor Busy."></metric>
|
||||
<metric name="CPF_CMP_UTCL1_STALL_ON_TRANSLATION" block="CPF" event="20" descr="One of the Compute UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPF_CPF_STAT_BUSY" block="CPF" event="23" descr="CPF Busy."></metric>
|
||||
<metric name="CPF_CPF_STAT_IDLE" block="CPF" event="24" descr="CPF Idle."></metric>
|
||||
<metric name="CPF_CPF_STAT_STALL" block="CPF" event="25" descr="CPF Stalled."></metric>
|
||||
<metric name="CPF_CPF_TCIU_BUSY" block="CPF" event="26" descr="CPF TCIU interface Busy."></metric>
|
||||
<metric name="CPF_CPF_TCIU_IDLE" block="CPF" event="27" descr="CPF TCIU interface Idle."></metric>
|
||||
<metric name="CPF_CPF_TCIU_STALL" block="CPF" event="28" descr="CPF TCIU interface Stalled waiting on Free, Tags."></metric>
|
||||
<metric name="SPI_CSN_WINDOW_VALID" block="SPI" event="47" descr="Clock count enabled by perfcounter_start event. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_BUSY" block="SPI" event="48" descr="Number of clocks with outstanding waves (SPI or SH). Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_NUM_THREADGROUPS" block="SPI" event="49" descr="Number of threadgroups launched. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_WAVE" block="SPI" event="52" descr="Number of waves. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC" block="SPI" event="79" descr="Arb cycles with requests but no allocation. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC_CSN" block="SPI" event="85" descr="Arb cycles with CSn req and no CSn alloc. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_RES_STALL_CSN" block="SPI" event="91" descr="Arb cycles with CSn req and no CSn fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TMP_STALL_CSN" block="SPI" event="97" descr="Cycles where csn wants to req but does not fit in temp space."></metric>
|
||||
<metric name="SPI_RA_WAVE_SIMD_FULL_CSN" block="SPI" event="103" descr="Sum of SIMD where WAVE can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_VGPR_SIMD_FULL_CSN" block="SPI" event="109" descr="Sum of SIMD where VGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_SGPR_SIMD_FULL_CSN" block="SPI" event="115" descr="Sum of SIMD where SGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_LDS_CU_FULL_CSN" block="SPI" event="120" descr="Sum of CU where LDS can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BAR_CU_FULL_CSN" block="SPI" event="123" descr="Sum of CU where BARRIER can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BULKY_CU_FULL_CSN" block="SPI" event="125" descr="Sum of CU where BULKY can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TGLIM_CU_FULL_CSN" block="SPI" event="127" descr="Cycles where csn wants to req but all CU are at tg_limit"></metric>
|
||||
<metric name="SPI_RA_WVLIM_STALL_CSN" block="SPI" event="133" descr="Number of clocks csn is stalled due to WAVE LIMIT."></metric>
|
||||
<metric name="SPI_SWC_CSC_WR" block="SPI" event="189" descr="Number of clocks to write CSC waves to SGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_VWC_CSC_WR" block="SPI" event="195" descr="Number of clocks to write CSC waves to VGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SQ_ACCUM_PREV" block="SQ" event="1" descr="For counter N, increment by the value of counter N-1. Only accumulates once every 4 cycles."></metric>
|
||||
<metric name="SQ_CYCLES" block="SQ" event="2" descr="Clock cycles. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_BUSY_CYCLES" block="SQ" event="3" descr="Clock cycles while SQ is reporting that it is busy. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_LEVEL_WAVES" block="SQ" event="5" descr="Track the number of waves. Set ACCUM_PREV for the next counter to use this. (level, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES_EQ_64" block="SQ" event="6" descr="Count number of waves with exactly 64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_64" block="SQ" event="7" descr="Count number of waves with <64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_48" block="SQ" event="8" descr="Count number of waves with <48 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_32" block="SQ" event="9" descr="Count number of waves sent <32 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_16" block="SQ" event="10" descr="Count number of waves sent <16 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_BUSY_CU_CYCLES" block="SQ" event="13" descr="Count quad-cycles each CU is busy. (nondeterministic, per-simd)"></metric>
|
||||
<metric name="SQ_ITEMS" block="SQ" event="14" descr="Number of valid items per wave. (per-simd, global)"></metric>
|
||||
<metric name="SQ_INSTS" block="SQ" event="25" descr="Number of instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F16" block="SQ" event="27" descr="Number of VALU ADD/SUB instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F16" block="SQ" event="28" descr="Number of VALU MUL instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F16" block="SQ" event="29" descr="Number of VALU FMA/MAD instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F16" block="SQ" event="30" descr="Number of VALU transcendental instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F32" block="SQ" event="31" descr="Number of VALU ADD/SUB instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F32" block="SQ" event="32" descr="Number of VALU MUL instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F32" block="SQ" event="33" descr="Number of VALU FMA/MAD instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F32" block="SQ" event="34" descr="Number of VALU transcendental instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F64" block="SQ" event="35" descr="Number of VALU ADD/SUB instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F64" block="SQ" event="36" descr="Number of VALU MUL instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F64" block="SQ" event="37" descr="Number of VALU FMA/MAD instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F64" block="SQ" event="38" descr="Number of VALU transcendental instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT32" block="SQ" event="39" descr="Number of VALU 32-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT64" block="SQ" event="40" descr="Number of VALU 64-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_CVT" block="SQ" event="41" descr="Number of VALU data conversion instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_I8" block="SQ" event="42" descr="Number of VALU V_MFMA_*_I8 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F16" block="SQ" event="43" descr="Number of VALU V_MFMA_*_F16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_BF16" block="SQ" event="44" descr="Number of VALU V_MFMA_*_BF16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F32" block="SQ" event="45" descr="Number of VALU V_MFMA_*_F32 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F64" block="SQ" event="46" descr="Number of VALU V_MFMA_*_F64 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_I8" block="SQ" event="47" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type I8. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F16" block="SQ" event="48" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_BF16" block="SQ" event="49" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type BF16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F32" block="SQ" event="50" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F64" block="SQ" event="51" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_MFMA" block="SQ" event="52" descr="Number of MFMA instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="53" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="54" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM" block="SQ" event="55" descr="Number of VMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="56" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="57" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="58" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="59" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="60" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="61" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_EXP_GDS" block="SQ" event="63" descr="Number of EXP and GDS instructions issued, excluding skipped export instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_BRANCH" block="SQ" event="64" descr="Number of Branch instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SENDMSG" block="SQ" event="65" descr="Number of Sendmsg instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VSKIPPED" block="SQ" event="66" descr="Number of vector instructions skipped. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_VMEM" block="SQ" event="67" descr="Number of in-flight VMEM instructions. Set next counter to ACCUM_PREV and divide by INSTS_VMEM for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_SMEM" block="SQ" event="68" descr="Number of in-flight SMEM instructions (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). Set next counter to ACCUM_PREV and divide by INSTS_SMEM for average latency per smem request. Falls slightly short of total request latency because some fetches are divided into two requests that may finish at different times and this counter collects the average latency of the two. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block="SQ" event="69" descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_VALU_MFMA_BUSY_CYCLES" block="SQ" event="72" descr="Number of cycles the MFMA ALU is busy (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block="SQ" event="74" descr="Number of wave-cycles spent by waves in the CUs (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block="SQ" event="85" descr="Number of wave-cycles spent waiting for anything (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block="SQ" event="88" descr="Number of wave-cycles spent waiting for any instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_ANY" block="SQ" event="96" descr="Number of cycles each wave is working on an instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VMEM" block="SQ" event="97" descr="Number of cycles the SQ instruction arbiter is working on a VMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_LDS" block="SQ" event="98" descr="Number of cycles the SQ instruction arbiter is working on a LDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="99" descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_SCA" block="SQ" event="100" descr="Number of cycles the SQ instruction arbiter is working on a SALU or SMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_EXP_GDS" block="SQ" event="101" descr="Number of cycles the SQ instruction arbiter is working on an EXPORT or GDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_MISC" block="SQ" event="102" descr="Number of cycles the SQ instruction aribter is working on a BRANCH or SENDMSG instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_FLAT" block="SQ" event="103" descr="Number of cycles the SQ instruction arbiter is working on a FLAT instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_WR" block="SQ" event="104" descr="Number of cycles needed to send addr and cmd data for VMEM write instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_RD" block="SQ" event="105" descr="Number of cycles needed to send addr and cmd data for VMEM read instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SMEM" block="SQ" event="111" descr="Number of cycles needed to execute scalar memory reads. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="112" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="113" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_IFETCH" block="SQ" event="115" descr="Number of instruction fetch requests from cache. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_IFETCH_LEVEL" block="SQ" event="116" descr="Number of instruction fetch requests from cache. (per-simd, level)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="121" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_ADDR_CONFLICT" block="SQ" event="122" descr="Number of cycles LDS is stalled by address conflicts. (emulated,nondeterministic)"></metric>
|
||||
<metric name="SQ_LDS_UNALIGNED_STALL" block="SQ" event="123" descr="Number of cycles LDS is stalled processing flat unaligned load/store ops. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_MEM_VIOLATIONS" block="SQ" event="124" descr="Number of threads that have a memory violation in the LDS.(emulated)"></metric>
|
||||
<metric name="SQ_LDS_ATOMIC_RETURN" block="SQ" event="125" descr="Number of atomic return cycles in LDS. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_LDS_IDX_ACTIVE" block="SQ" event="126" descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACCUM_PREV_HIRES" block="SQ" event="185" descr="For counter N, increment by the value of counter N-1."></metric>
|
||||
<metric name="SQ_WAVES_RESTORED" block="SQ" event="186" descr="Count number of context-restored waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_SAVED" block="SQ" event="187" descr="Count number of context-saved waves. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM_NORM" block="SQ" event="188" descr="Number of SMEM instructions issued normalized to match smem_level (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). (per-simd, emulated)"></metric>
|
||||
<metric name="SQC_DCACHE_INPUT_VALID_READYB" block="SQ" event="260" descr="Input stalled by SQC (per-SQ, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_TC_REQ" block="SQ" event="262" descr="Total number of TC requests that were issued by instruction and constant caches. (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_INST_REQ" block="SQ" event="263" descr="Number of insruction requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_READ_REQ" block="SQ" event="264" descr="Number of data read requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_WRITE_REQ" block="SQ" event="265" descr="Number of data write requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_ATOMIC_REQ" block="SQ" event="266" descr="Number of data atomic requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_STALL" block="SQ" event="267" descr="Valid request stalled TC request interface (no-credits). (No-Masking, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_ICACHE_REQ" block="SQ" event="270" descr="Number of requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_ICACHE_HITS" block="SQ" event="271" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES" block="SQ" event="272" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES_DUPLICATE" block="SQ" event="273" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_REQ" block="SQ" event="290" descr="Number of requests (post-bank-serialization). (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_HITS" block="SQ" event="291" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES" block="SQ" event="292" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES_DUPLICATE" block="SQ" event="293" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_ATOMIC" block="SQ" event="298" descr="Number of atomic requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_1" block="SQ" event="323" descr="Number of constant cache 1 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_2" block="SQ" event="324" descr="Number of constant cache 2 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_4" block="SQ" event="325" descr="Number of constant cache 4 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_8" block="SQ" event="326" descr="Number of constant cache 8 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_16" block="SQ" event="327" descr="Number of constant cache 16 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS" block="TA" event="32" descr="Total number of wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS" block="TA" event="44" descr="Number of buffer wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS" block="TA" event="45" descr="Number of buffer read wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS" block="TA" event="46" descr="Number of buffer write wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS" block="TA" event="47" descr="Number of buffer atomic wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES" block="TA" event="49" descr="Number of buffer cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES" block="TA" event="52" descr="Number of buffer coalesced read cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES" block="TA" event="53" descr="Number of buffer coalesced write cycles issued to TC."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES" block="TA" event="54" descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES" block="TA" event="55" descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES" block="TA" event="56" descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS" block="TA" event="100" descr="Number of flat opcode wavfronts processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS" block="TA" event="103" descr="Number of flat opcode atomics processed by the TA."></metric>
|
||||
<metric name="TD_TD_BUSY" block="TD" event="1" descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TD_TC_STALL" block="TD" event="15" descr="TD is stalled waiting for TC data."></metric>
|
||||
<metric name="TD_SPI_STALL" block="TD" event="18" descr="TD is stalled SPI vinit"></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT" block="TD" event="25" descr="Count the wavefronts with opcode = load, include atomics and store."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT" block="TD" event="26" descr="Count the wavefronts with opcode = atomic."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT" block="TD" event="27" descr="Count the wavefronts with opcode = store."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT" block="TD" event="32" descr="Count wavefronts that TA finds coalescable."></metric>
|
||||
<metric name="TCP_GATE_EN1" block="TCP" event="0" descr="TCP interface clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_GATE_EN2" block="TCP" event="1" descr="TCP core clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES" block="TCP" event="7" descr="TD stalls TCP"></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES" block="TCP" event="8" descr="TCR stalls TCP_TCR_req interface"></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES" block="TCP" event="11" descr="Tagram conflict stall on a read"></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES" block="TCP" event="12" descr="Tagram conflict stall on a write"></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES" block="TCP" event="13" descr="Tagram conflict stall on an atomic"></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES" block="TCP" event="22" descr="Stall due to data pending from L2"></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ" block="TCP" event="27" descr="Number of state reads"></metric>
|
||||
<metric name="TCP_VOLATILE" block="TCP" event="28" descr="Total number of L1 volatile pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES" block="TCP" event="29" descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD"></metric>
|
||||
<metric name="TCP_TOTAL_READ" block="TCP" event="30" descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ"></metric>
|
||||
<metric name="TCP_TOTAL_WRITE" block="TCP" event="32" descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET" block="TCP" event="38" descr="Total number of atomic with return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET" block="TCP" event="39" descr="Total number of atomic without return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES" block="TCP" event="45" descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST" block="TCP" event="47" descr="Total CLIENT_UTCL1 NORMAL requests"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS" block="TCP" event="48" descr="Total utcl1 translation misses"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT" block="TCP" event="49" descr="Total utcl1 translation hits"></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS" block="TCP" event="50" descr="Total utcl1 permission misses"></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES" block="TCP" event="60" descr="Count of total cache line (tag) accesses (includes hits and misses)."></metric>
|
||||
<metric name="TCP_TCP_LATENCY" block="TCP" event="65" descr="Total TCP wave latency (from first clock of wave entering to first clock of wave leaving), divide by TA_TCP_STATE_READ to avg wave latency"></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_LATENCY" block="TCP" event="66" descr="Total TCP->TCC request latency for reads and atomics with return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_LATENCY" block="TCP" event="67" descr="Total TCP->TCC request latency for writes and atomics without return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ" block="TCP" event="69" descr="Total read requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ" block="TCP" event="70" descr="Total write requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ" block="TCP" event="71" descr="Total atomic with return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ" block="TCP" event="72" descr="Total atomic without return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ" block="TCP" event="75" descr="Total read requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ" block="TCP" event="76" descr="Total write requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ" block="TCP" event="77" descr="Total atomic requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ" block="TCP" event="78" descr="Total read requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ" block="TCP" event="79" descr="Total write requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ" block="TCP" event="80" descr="Total atomic requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ" block="TCP" event="81" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ" block="TCP" event="82" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ" block="TCP" event="83" descr="Total atomic requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ" block="TCP" event="85" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ" block="TCP" event="86" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ" block="TCP" event="87" descr="Total atomic requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCA_CYCLE" block="TCA" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCA_BUSY" block="TCA" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_CYCLE" block="TCC" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCC_BUSY" block="TCC" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_REQ" block="TCC" event="3" descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed."></metric>
|
||||
<metric name="TCC_STREAMING_REQ" block="TCC" event="4" descr="Number of streaming requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_NC_REQ" block="TCC" event="5" descr="The number of noncoherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_UC_REQ" block="TCC" event="6" descr="The number of uncached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_CC_REQ" block="TCC" event="7" descr="The number of coherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_RW_REQ" block="TCC" event="8" descr="The number of RW requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_PROBE" block="TCC" event="9" descr="Number of probe requests. Not windowable."></metric>
|
||||
<metric name="TCC_PROBE_ALL" block="TCC" event="10" descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable."></metric>
|
||||
<metric name="TCC_READ" block="TCC" event="12" descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included."></metric>
|
||||
<metric name="TCC_WRITE" block="TCC" event="13" descr="Number of write requests."></metric>
|
||||
<metric name="TCC_ATOMIC" block="TCC" event="14" descr="Number of atomic requests of all types."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="17" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_WRITEBACK" block="TCC" event="22" descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="26" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="27" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WR_UNCACHED_32B" block="TCC" event="29" descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="30" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_WRREQ_IO_CREDIT_STALL" block="TCC" event="31" descr="Number of cycles a EA write request was stalled because the interface was out of IO credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_GMI_CREDIT_STALL" block="TCC" event="32" descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_CREDIT_STALL" block="TCC" event="33" descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL" block="TCC" event="34" descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ_LEVEL" block="TCC" event="35" descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ."></metric>
|
||||
<metric name="TCC_EA_ATOMIC" block="TCC" event="36" descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_LEVEL" block="TCC" event="37" descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="38" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="39" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCC_EA_RD_UNCACHED_32B" block="TCC" event="40" descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_RDREQ_IO_CREDIT_STALL" block="TCC" event="41" descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_GMI_CREDIT_STALL" block="TCC" event="42" descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_CREDIT_STALL" block="TCC" event="43" descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_LEVEL" block="TCC" event="44" descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ."></metric>
|
||||
<metric name="TCC_TAG_STALL" block="TCC" event="45" descr="Number of cycles the normal request pipeline in the tag was stalled for any reason. Normally, stalls of this nature are measured exactly from one point the pipeline, but that is not the case for this counter. Probes can stall the pipeline at a variety of places, and there is no single point that can reasonably measure the total stalls accurately."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK" block="TCC" event="68" descr="Number of writebacks due to requests that are not writeback requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK" block="TCC" event="73" descr="Number of writebacks due to all TC_OP writeback requests."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT" block="TCC" event="74" descr="Number of evictions due to requests that are not invalidate or probe requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT" block="TCC" event="80" descr="Number of evictions due to all TC_OP invalidate requests."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM" block="TCC" event="102" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC)."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM" block="TCC" event="103" descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC)."></metric>
|
||||
</gfx90a>
|
||||
|
||||
<gfx10>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block="GRBM" event="3" descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block="GRBM" event="11" descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block="GRBM" event="13" descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_GDS_BUSY" block="GRBM" event="25" descr="The Global Data Share (GDS) is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block="GRBM" event="35" descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="GRBM_GL2CC_BUSY" block="GRBM" event="40" descr="The GL2CC block is busy."></metric>
|
||||
<metric name="GL2C_HIT" block="GL2C" event="42" descr="Number of cache hits"></metric>
|
||||
<metric name="GL2C_MISS" block="GL2C" event="43" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="GL2C_MC_WRREQ" block="GL2C" event="83" descr="Number of transactions (either 32-byte or 64-byte) going over the GL2C_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands"></metric>
|
||||
<metric name="GL2C_EA_WRREQ_64B" block="GL2C" event="85" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="GL2C_MC_WRREQ_STALL" block="GL2C" event="88" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="GL2C_MC_RDREQ" block="GL2C" event="96" descr="Number of GL2C/EA read requests (either 32-byte or 64-byte or 128-byte)."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_32B" block="GL2C" event="99" descr="Number of 32-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_64B" block="GL2C" event="100" descr="Number of 64-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_96B" block="GL2C" event="101" descr="Number of 96-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_128B" block="GL2C" event="102" descr="Number of 128-byte GL2C/EA read requests"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. {emulated, global, C1}"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block="SQ" event="26" descr="Number of clock cycles spent by waves in the SQs. Incremented by # of living (valid) waves each cycle. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block="SQ" event="28" descr="Number of clock cycles spent waiting for any instruction issue. In units of cycles. {nondeterministic}"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block="SQ" event="37" descr="Number of clock cycles spent waiting for anything. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32" block="SQ" event="71" descr="Number of wave32 instructions issued, for flat, lds, valu, tex. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_LDS" block="SQ" event="74" descr="Number of wave32 LDS indexed instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_VALU" block="SQ" event="75" descr="Number of wave32 valu instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAVE32_INSTS" block="SQ" event="84" descr="Number of instructions issued by wave32 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_WAVE64_INSTS" block="SQ" event="85" descr="Number of instructions issued by wave64 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_GDS" block="SQ" event="98" descr="Number of in-flight GDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_GDS for average latency. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block="SQ" event="99" descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM" block="SQ" event="120" descr="Number of cycles needed to send addr and data for VMEM (lds, buffer, image, flat, scratch, global) instructions, windowed by perf_en. {emulated, C1}"></metric>
|
||||
<metric name="SQC_LDS_BANK_CONFLICT" block="SQ" event="285" descr="Number of cycles LDS is stalled by bank conflicts. (emulated, C1)"></metric>
|
||||
<metric name="SQC_LDS_IDX_ACTIVE" block="SQ" event="290" descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. {per-simd, emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="64" descr="Number of VALU instructions issued excluding skipped instructions. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="60" descr="Number of SALU instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="61" descr="Number of SMEM instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="57" descr="Number of FLAT instructions issued. {emulated, C2}"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="59" descr="Number of LDS indexed instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="55" descr="Number of GDS instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="31" descr="Number of clock cycles spent waiting for LDS (indexed) instruction issue. In units of cycles. {nondeterministic, C1}"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_LOAD_WAVEFRONTS" block="TA" event="101" descr=" Number of flat load vec32 packets processed by TA, same as flat_read_wavefronts in earlier IP"></metric>
|
||||
<metric name="TA_FLAT_STORE_WAVEFRONTS" block="TA" event="102" descr="Number of flat store vec32 packets processed by TA, same as flat_write_wavefronts in earlier IP"></metric>
|
||||
</gfx10>
|
||||
|
||||
</counters>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="27" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="28" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="30" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="31" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="32" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="33" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="34" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="35" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="61" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="69" descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="86" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="89" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="97" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="18" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_MC_RDREQ" block="TCC" event="35" descr="Number of 32-byte reads. The hardware actually does 64-byte reads but the number is adjusted to provide uniformity."></metric>
|
||||
<metric name="TCC_MC_WRREQ" block="TCC" event="26" descr="Number of 32-byte transactions going over the TC_MC_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests."></metric>
|
||||
<metric name="TCC_MC_WRREQ_STALL" block="TCC" event="28" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="3" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
+374
@@ -0,0 +1,374 @@
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="27" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="28" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="30" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="31" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="32" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="33" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="34" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="35" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="63" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="71" descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="84" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="85" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="93" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="20" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="22" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="29" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="30" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="33" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="41" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="42" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="TCC_EA1_WRREQ" block="TCC" event="256" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_64B" block="TCC" event="257" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA1_WRREQ_STALL" block="TCC" event="260" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA1_RDREQ" block="TCC" event="267" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA1_RDREQ_32B" block="TCC" event="268" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
|
||||
<gfx908>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="28" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="29" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="31" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="32" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="33" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="34" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="35" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="36" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="64" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="72" descr="regspec 71? Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="85" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="86" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="94" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="17" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="26" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="27" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="30" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="38" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="39" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
</gfx908>
|
||||
|
||||
<gfx90a>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="91" descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block="TCP" event="6" descr="TCP stalls TA data interface. Now Windowed."></metric>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block="GRBM" event="3" descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block="GRBM" event="11" descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block="GRBM" event="13" descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TC_BUSY" block="GRBM" event="28" descr="Any of the Texture Cache Blocks (TCP/TCI/TCA/TCC) are busy."></metric>
|
||||
<metric name="GRBM_CPC_BUSY" block="GRBM" event="30" descr="The Command Processor Compute (CPC) is busy."></metric>
|
||||
<metric name="GRBM_CPF_BUSY" block="GRBM" event="31" descr="The Command Processor Fetchers (CPF) is busy."></metric>
|
||||
<metric name="GRBM_UTCL2_BUSY" block="GRBM" event="34" descr="The Unified Translation Cache Level-2 (UTCL2) block is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block="GRBM" event="35" descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="CPC_ME1_BUSY_FOR_PACKET_DECODE" block="CPC" event="13" descr="Me1 busy for packet decode."></metric>
|
||||
<metric name="CPC_UTCL1_STALL_ON_TRANSLATION" block="CPC" event="24" descr="One of the UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPC_CPC_STAT_BUSY" block="CPC" event="25" descr="CPC Busy."></metric>
|
||||
<metric name="CPC_CPC_STAT_IDLE" block="CPC" event="26" descr="CPC Idle."></metric>
|
||||
<metric name="CPC_CPC_STAT_STALL" block="CPC" event="27" descr="CPC Stalled."></metric>
|
||||
<metric name="CPC_CPC_TCIU_BUSY" block="CPC" event="28" descr="CPC TCIU interface Busy."></metric>
|
||||
<metric name="CPC_CPC_TCIU_IDLE" block="CPC" event="29" descr="CPC TCIU interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_BUSY" block="CPC" event="30" descr="CPC UTCL2 interface Busy."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_IDLE" block="CPC" event="31" descr="CPC UTCL2 interface Idle."></metric>
|
||||
<metric name="CPC_CPC_UTCL2IU_STALL" block="CPC" event="32" descr="CPC UTCL2 interface Stalled waiting on Free, Tags or Translation."></metric>
|
||||
<metric name="CPC_ME1_DC0_SPI_BUSY" block="CPC" event="33" descr="CPC Me1 Processor Busy."></metric>
|
||||
<metric name="CPF_CMP_UTCL1_STALL_ON_TRANSLATION" block="CPF" event="20" descr="One of the Compute UTCL1s is stalled waiting on translation, XNACK or PENDING response."></metric>
|
||||
<metric name="CPF_CPF_STAT_BUSY" block="CPF" event="23" descr="CPF Busy."></metric>
|
||||
<metric name="CPF_CPF_STAT_IDLE" block="CPF" event="24" descr="CPF Idle."></metric>
|
||||
<metric name="CPF_CPF_STAT_STALL" block="CPF" event="25" descr="CPF Stalled."></metric>
|
||||
<metric name="CPF_CPF_TCIU_BUSY" block="CPF" event="26" descr="CPF TCIU interface Busy."></metric>
|
||||
<metric name="CPF_CPF_TCIU_IDLE" block="CPF" event="27" descr="CPF TCIU interface Idle."></metric>
|
||||
<metric name="CPF_CPF_TCIU_STALL" block="CPF" event="28" descr="CPF TCIU interface Stalled waiting on Free, Tags."></metric>
|
||||
<metric name="SPI_CSN_WINDOW_VALID" block="SPI" event="47" descr="Clock count enabled by perfcounter_start event. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_BUSY" block="SPI" event="48" descr="Number of clocks with outstanding waves (SPI or SH). Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_NUM_THREADGROUPS" block="SPI" event="49" descr="Number of threadgroups launched. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_CSN_WAVE" block="SPI" event="52" descr="Number of waves. Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC" block="SPI" event="79" descr="Arb cycles with requests but no allocation. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_REQ_NO_ALLOC_CSN" block="SPI" event="85" descr="Arb cycles with CSn req and no CSn alloc. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_RES_STALL_CSN" block="SPI" event="91" descr="Arb cycles with CSn req and no CSn fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TMP_STALL_CSN" block="SPI" event="97" descr="Cycles where csn wants to req but does not fit in temp space."></metric>
|
||||
<metric name="SPI_RA_WAVE_SIMD_FULL_CSN" block="SPI" event="103" descr="Sum of SIMD where WAVE can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_VGPR_SIMD_FULL_CSN" block="SPI" event="109" descr="Sum of SIMD where VGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_SGPR_SIMD_FULL_CSN" block="SPI" event="115" descr="Sum of SIMD where SGPR can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_LDS_CU_FULL_CSN" block="SPI" event="120" descr="Sum of CU where LDS can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BAR_CU_FULL_CSN" block="SPI" event="123" descr="Sum of CU where BARRIER can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_BULKY_CU_FULL_CSN" block="SPI" event="125" descr="Sum of CU where BULKY can't take csn wave when !fits. Source is RA0"></metric>
|
||||
<metric name="SPI_RA_TGLIM_CU_FULL_CSN" block="SPI" event="127" descr="Cycles where csn wants to req but all CU are at tg_limit"></metric>
|
||||
<metric name="SPI_RA_WVLIM_STALL_CSN" block="SPI" event="133" descr="Number of clocks csn is stalled due to WAVE LIMIT."></metric>
|
||||
<metric name="SPI_SWC_CSC_WR" block="SPI" event="189" descr="Number of clocks to write CSC waves to SGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SPI_VWC_CSC_WR" block="SPI" event="195" descr="Number of clocks to write CSC waves to VGPRs (need to multiply this value by 4) Requires SPI_DEBUG_CNTL.DEBUG_PIPE_SEL to select source, DEBUG_PIPE_SEL = 1, source is CS1; DEBUG_PIPE_SEL = 2, source is CS2; DEBUG_PIPE_SEL = 3, source is CS3; default, source is CS0;"></metric>
|
||||
<metric name="SQ_ACCUM_PREV" block="SQ" event="1" descr="For counter N, increment by the value of counter N-1. Only accumulates once every 4 cycles."></metric>
|
||||
<metric name="SQ_CYCLES" block="SQ" event="2" descr="Clock cycles. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_BUSY_CYCLES" block="SQ" event="3" descr="Clock cycles while SQ is reporting that it is busy. (nondeterministic, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_LEVEL_WAVES" block="SQ" event="5" descr="Track the number of waves. Set ACCUM_PREV for the next counter to use this. (level, per-simd, global)"></metric>
|
||||
<metric name="SQ_WAVES_EQ_64" block="SQ" event="6" descr="Count number of waves with exactly 64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_64" block="SQ" event="7" descr="Count number of waves with <64 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_48" block="SQ" event="8" descr="Count number of waves with <48 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_32" block="SQ" event="9" descr="Count number of waves sent <32 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_LT_16" block="SQ" event="10" descr="Count number of waves sent <16 active threads sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_BUSY_CU_CYCLES" block="SQ" event="13" descr="Count quad-cycles each CU is busy. (nondeterministic, per-simd)"></metric>
|
||||
<metric name="SQ_ITEMS" block="SQ" event="14" descr="Number of valid items per wave. (per-simd, global)"></metric>
|
||||
<metric name="SQ_INSTS" block="SQ" event="25" descr="Number of instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="26" descr="Number of VALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F16" block="SQ" event="27" descr="Number of VALU ADD/SUB instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F16" block="SQ" event="28" descr="Number of VALU MUL instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F16" block="SQ" event="29" descr="Number of VALU FMA/MAD instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F16" block="SQ" event="30" descr="Number of VALU transcendental instructions on float16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F32" block="SQ" event="31" descr="Number of VALU ADD/SUB instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F32" block="SQ" event="32" descr="Number of VALU MUL instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F32" block="SQ" event="33" descr="Number of VALU FMA/MAD instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F32" block="SQ" event="34" descr="Number of VALU transcendental instructions on float32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_ADD_F64" block="SQ" event="35" descr="Number of VALU ADD/SUB instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MUL_F64" block="SQ" event="36" descr="Number of VALU MUL instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_FMA_F64" block="SQ" event="37" descr="Number of VALU FMA/MAD instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_TRANS_F64" block="SQ" event="38" descr="Number of VALU transcendental instructions on float64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT32" block="SQ" event="39" descr="Number of VALU 32-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_INT64" block="SQ" event="40" descr="Number of VALU 64-bit integer (signed or unsigned) instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_CVT" block="SQ" event="41" descr="Number of VALU data conversion instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_I8" block="SQ" event="42" descr="Number of VALU V_MFMA_*_I8 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F16" block="SQ" event="43" descr="Number of VALU V_MFMA_*_F16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_BF16" block="SQ" event="44" descr="Number of VALU V_MFMA_*_BF16 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F32" block="SQ" event="45" descr="Number of VALU V_MFMA_*_F32 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_F64" block="SQ" event="46" descr="Number of VALU V_MFMA_*_F64 instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_I8" block="SQ" event="47" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type I8. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F16" block="SQ" event="48" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_BF16" block="SQ" event="49" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type BF16. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F32" block="SQ" event="50" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F32. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VALU_MFMA_MOPS_F64" block="SQ" event="51" descr="Number of VALU matrix math operations (add or mul) performed dividied by 512, assuming a full EXEC mask, of data type F64. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_MFMA" block="SQ" event="52" descr="Number of MFMA instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_WR" block="SQ" event="53" descr="Number of VMEM write instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM_RD" block="SQ" event="54" descr="Number of VMEM read instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VMEM" block="SQ" event="55" descr="Number of VMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="56" descr="Number of SALU instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="57" descr="Number of SMEM instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="58" descr="Number of FLAT instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_FLAT_LDS_ONLY" block="SQ" event="59" descr="Number of FLAT instructions issued that read/wrote only from/to LDS (only works if EARLY_TA_DONE is enabled). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="60" descr="Number of LDS instructions issued (including FLAT). (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="61" descr="Number of GDS instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_EXP_GDS" block="SQ" event="63" descr="Number of EXP and GDS instructions issued, excluding skipped export instructions. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_BRANCH" block="SQ" event="64" descr="Number of Branch instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_SENDMSG" block="SQ" event="65" descr="Number of Sendmsg instructions issued. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INSTS_VSKIPPED" block="SQ" event="66" descr="Number of vector instructions skipped. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_VMEM" block="SQ" event="67" descr="Number of in-flight VMEM instructions. Set next counter to ACCUM_PREV and divide by INSTS_VMEM for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_SMEM" block="SQ" event="68" descr="Number of in-flight SMEM instructions (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). Set next counter to ACCUM_PREV and divide by INSTS_SMEM for average latency per smem request. Falls slightly short of total request latency because some fetches are divided into two requests that may finish at different times and this counter collects the average latency of the two. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block="SQ" event="69" descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. (per-simd, level, nondeterministic)"></metric>
|
||||
<metric name="SQ_VALU_MFMA_BUSY_CYCLES" block="SQ" event="72" descr="Number of cycles the MFMA ALU is busy (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block="SQ" event="74" descr="Number of wave-cycles spent by waves in the CUs (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block="SQ" event="85" descr="Number of wave-cycles spent waiting for anything (per-simd, nondeterministic). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block="SQ" event="88" descr="Number of wave-cycles spent waiting for any instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_ANY" block="SQ" event="96" descr="Number of cycles each wave is working on an instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VMEM" block="SQ" event="97" descr="Number of cycles the SQ instruction arbiter is working on a VMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_LDS" block="SQ" event="98" descr="Number of cycles the SQ instruction arbiter is working on a LDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_VALU" block="SQ" event="99" descr="Number of cycles the SQ instruction arbiter is working on a VALU instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_SCA" block="SQ" event="100" descr="Number of cycles the SQ instruction arbiter is working on a SALU or SMEM instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_EXP_GDS" block="SQ" event="101" descr="Number of cycles the SQ instruction arbiter is working on an EXPORT or GDS instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_MISC" block="SQ" event="102" descr="Number of cycles the SQ instruction aribter is working on a BRANCH or SENDMSG instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_ACTIVE_INST_FLAT" block="SQ" event="103" descr="Number of cycles the SQ instruction arbiter is working on a FLAT instruction. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_WR" block="SQ" event="104" descr="Number of cycles needed to send addr and cmd data for VMEM write instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM_RD" block="SQ" event="105" descr="Number of cycles needed to send addr and cmd data for VMEM read instructions. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SMEM" block="SQ" event="111" descr="Number of cycles needed to execute scalar memory reads. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_INST_CYCLES_SALU" block="SQ" event="112" descr="Number of cycles needed to execute non-memory read scalar operations. (per-simd, emulated). Units in quad-cycles(4 cycles)"></metric>
|
||||
<metric name="SQ_THREAD_CYCLES_VALU" block="SQ" event="113" descr="Number of thread-cycles used to execute VALU operations (similar to INST_CYCLES_VALU but multiplied by # of active threads). (per-simd)"></metric>
|
||||
<metric name="SQ_IFETCH" block="SQ" event="115" descr="Number of instruction fetch requests from cache. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_IFETCH_LEVEL" block="SQ" event="116" descr="Number of instruction fetch requests from cache. (per-simd, level)"></metric>
|
||||
<metric name="SQ_LDS_BANK_CONFLICT" block="SQ" event="121" descr="Number of cycles LDS is stalled by bank conflicts. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_ADDR_CONFLICT" block="SQ" event="122" descr="Number of cycles LDS is stalled by address conflicts. (emulated,nondeterministic)"></metric>
|
||||
<metric name="SQ_LDS_UNALIGNED_STALL" block="SQ" event="123" descr="Number of cycles LDS is stalled processing flat unaligned load/store ops. (emulated)"></metric>
|
||||
<metric name="SQ_LDS_MEM_VIOLATIONS" block="SQ" event="124" descr="Number of threads that have a memory violation in the LDS.(emulated)"></metric>
|
||||
<metric name="SQ_LDS_ATOMIC_RETURN" block="SQ" event="125" descr="Number of atomic return cycles in LDS. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_LDS_IDX_ACTIVE" block="SQ" event="126" descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. (per-simd, emulated)"></metric>
|
||||
<metric name="SQ_ACCUM_PREV_HIRES" block="SQ" event="185" descr="For counter N, increment by the value of counter N-1."></metric>
|
||||
<metric name="SQ_WAVES_RESTORED" block="SQ" event="186" descr="Count number of context-restored waves sent to SQs. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_WAVES_SAVED" block="SQ" event="187" descr="Count number of context-saved waves. (per-simd, emulated, global)"></metric>
|
||||
<metric name="SQ_INSTS_SMEM_NORM" block="SQ" event="188" descr="Number of SMEM instructions issued normalized to match smem_level (*2 load/store; *2 atomic; *2 memtime; *4 wb/inv). (per-simd, emulated)"></metric>
|
||||
<metric name="SQC_DCACHE_INPUT_VALID_READYB" block="SQ" event="260" descr="Input stalled by SQC (per-SQ, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_TC_REQ" block="SQ" event="262" descr="Total number of TC requests that were issued by instruction and constant caches. (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_INST_REQ" block="SQ" event="263" descr="Number of insruction requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_READ_REQ" block="SQ" event="264" descr="Number of data read requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_WRITE_REQ" block="SQ" event="265" descr="Number of data write requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_DATA_ATOMIC_REQ" block="SQ" event="266" descr="Number of data atomic requests to the TC (No-Masking, nondeterministic)"></metric>
|
||||
<metric name="SQC_TC_STALL" block="SQ" event="267" descr="Valid request stalled TC request interface (no-credits). (No-Masking, nondeterministic, unwindowed)"></metric>
|
||||
<metric name="SQC_ICACHE_REQ" block="SQ" event="270" descr="Number of requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_ICACHE_HITS" block="SQ" event="271" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES" block="SQ" event="272" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_ICACHE_MISSES_DUPLICATE" block="SQ" event="273" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_REQ" block="SQ" event="290" descr="Number of requests (post-bank-serialization). (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_HITS" block="SQ" event="291" descr="Number of cache hits. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES" block="SQ" event="292" descr="Number of cache misses, includes uncached requests. (per-SQ, per-Bank, nondeterministic)"></metric>
|
||||
<metric name="SQC_DCACHE_MISSES_DUPLICATE" block="SQ" event="293" descr="Number of misses that were duplicates (access to a non-resident, miss pending CL). (per-SQ, per-Bank, nondeterministic)" ></metric>
|
||||
<metric name="SQC_DCACHE_ATOMIC" block="SQ" event="298" descr="Number of atomic requests. (per-SQ, per-Bank)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_1" block="SQ" event="323" descr="Number of constant cache 1 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_2" block="SQ" event="324" descr="Number of constant cache 2 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_4" block="SQ" event="325" descr="Number of constant cache 4 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_8" block="SQ" event="326" descr="Number of constant cache 8 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="SQC_DCACHE_REQ_READ_16" block="SQ" event="327" descr="Number of constant cache 16 dw read requests. (per-SQ)"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_TOTAL_WAVEFRONTS" block="TA" event="32" descr="Total number of wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WAVEFRONTS" block="TA" event="44" descr="Number of buffer wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_READ_WAVEFRONTS" block="TA" event="45" descr="Number of buffer read wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_WRITE_WAVEFRONTS" block="TA" event="46" descr="Number of buffer write wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_ATOMIC_WAVEFRONTS" block="TA" event="47" descr="Number of buffer atomic wavefronts processed by TA."></metric>
|
||||
<metric name="TA_BUFFER_TOTAL_CYCLES" block="TA" event="49" descr="Number of buffer cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_READ_CYCLES" block="TA" event="52" descr="Number of buffer coalesced read cycles issued to TC."></metric>
|
||||
<metric name="TA_BUFFER_COALESCED_WRITE_CYCLES" block="TA" event="53" descr="Number of buffer coalesced write cycles issued to TC."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TC_CYCLES" block="TA" event="54" descr="Number of cycles addr path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_ADDR_STALLED_BY_TD_CYCLES" block="TA" event="55" descr="Number of cycles addr path stalled by TD. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_DATA_STALLED_BY_TC_CYCLES" block="TA" event="56" descr="Number of cycles data path stalled by TC. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_WAVEFRONTS" block="TA" event="100" descr="Number of flat opcode wavfronts processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_READ_WAVEFRONTS" block="TA" event="101" descr="Number of flat opcode reads processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_WRITE_WAVEFRONTS" block="TA" event="102" descr="Number of flat opcode writes processed by the TA."></metric>
|
||||
<metric name="TA_FLAT_ATOMIC_WAVEFRONTS" block="TA" event="103" descr="Number of flat opcode atomics processed by the TA."></metric>
|
||||
<metric name="TD_TD_BUSY" block="TD" event="1" descr="TD is processing or waiting for data. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TD_TC_STALL" block="TD" event="15" descr="TD is stalled waiting for TC data."></metric>
|
||||
<metric name="TD_SPI_STALL" block="TD" event="18" descr="TD is stalled SPI vinit"></metric>
|
||||
<metric name="TD_LOAD_WAVEFRONT" block="TD" event="25" descr="Count the wavefronts with opcode = load, include atomics and store."></metric>
|
||||
<metric name="TD_ATOMIC_WAVEFRONT" block="TD" event="26" descr="Count the wavefronts with opcode = atomic."></metric>
|
||||
<metric name="TD_STORE_WAVEFRONT" block="TD" event="27" descr="Count the wavefronts with opcode = store."></metric>
|
||||
<metric name="TD_COALESCABLE_WAVEFRONT" block="TD" event="32" descr="Count wavefronts that TA finds coalescable."></metric>
|
||||
<metric name="TCP_GATE_EN1" block="TCP" event="0" descr="TCP interface clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_GATE_EN2" block="TCP" event="1" descr="TCP core clocks are turned on. Not Windowed."></metric>
|
||||
<metric name="TCP_TD_TCP_STALL_CYCLES" block="TCP" event="7" descr="TD stalls TCP"></metric>
|
||||
<metric name="TCP_TCR_TCP_STALL_CYCLES" block="TCP" event="8" descr="TCR stalls TCP_TCR_req interface"></metric>
|
||||
<metric name="TCP_READ_TAGCONFLICT_STALL_CYCLES" block="TCP" event="11" descr="Tagram conflict stall on a read"></metric>
|
||||
<metric name="TCP_WRITE_TAGCONFLICT_STALL_CYCLES" block="TCP" event="12" descr="Tagram conflict stall on a write"></metric>
|
||||
<metric name="TCP_ATOMIC_TAGCONFLICT_STALL_CYCLES" block="TCP" event="13" descr="Tagram conflict stall on an atomic"></metric>
|
||||
<metric name="TCP_PENDING_STALL_CYCLES" block="TCP" event="22" descr="Stall due to data pending from L2"></metric>
|
||||
<metric name="TCP_TA_TCP_STATE_READ" block="TCP" event="27" descr="Number of state reads"></metric>
|
||||
<metric name="TCP_VOLATILE" block="TCP" event="28" descr="Total number of L1 volatile pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ACCESSES" block="TCP" event="29" descr="Total number of pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_READ+TCP_PERF_SEL_TOTAL_NONREAD"></metric>
|
||||
<metric name="TCP_TOTAL_READ" block="TCP" event="30" descr="Total number of read pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_HIT_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_LRU_READ + TCP_PERF_SEL_TOTAL_MISS_EVICT_READ"></metric>
|
||||
<metric name="TCP_TOTAL_WRITE" block="TCP" event="32" descr="Total number of local write pixels/buffers from TA. Equals TCP_PERF_SEL_TOTAL_MISS_LRU_WRITE+ TCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITH_RET" block="TCP" event="38" descr="Total number of atomic with return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_ATOMIC_WITHOUT_RET" block="TCP" event="39" descr="Total number of atomic without return pixels/buffers from TA"></metric>
|
||||
<metric name="TCP_TOTAL_WRITEBACK_INVALIDATES" block="TCP" event="45" descr="Total number of cache invalidates. Equals TCP_PERF_SEL_TOTAL_WBINVL1+ TCP_PERF_SEL_TOTAL_WBINVL1_VOL+ TCP_PERF_SEL_CP_TCP_INVALIDATE+ TCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL. Not Windowed."></metric>
|
||||
<metric name="TCP_UTCL1_REQUEST" block="TCP" event="47" descr="Total CLIENT_UTCL1 NORMAL requests"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_MISS" block="TCP" event="48" descr="Total utcl1 translation misses"></metric>
|
||||
<metric name="TCP_UTCL1_TRANSLATION_HIT" block="TCP" event="49" descr="Total utcl1 translation hits"></metric>
|
||||
<metric name="TCP_UTCL1_PERMISSION_MISS" block="TCP" event="50" descr="Total utcl1 permission misses"></metric>
|
||||
<metric name="TCP_TOTAL_CACHE_ACCESSES" block="TCP" event="60" descr="Count of total cache line (tag) accesses (includes hits and misses)."></metric>
|
||||
<metric name="TCP_TCP_LATENCY" block="TCP" event="65" descr="Total TCP wave latency (from first clock of wave entering to first clock of wave leaving), divide by TA_TCP_STATE_READ to avg wave latency"></metric>
|
||||
<metric name="TCP_TCC_READ_REQ_LATENCY" block="TCP" event="66" descr="Total TCP->TCC request latency for reads and atomics with return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ_LATENCY" block="TCP" event="67" descr="Total TCP->TCC request latency for writes and atomics without return. Not Windowed."></metric>
|
||||
<metric name="TCP_TCC_READ_REQ" block="TCP" event="69" descr="Total read requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_WRITE_REQ" block="TCP" event="70" descr="Total write requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITH_RET_REQ" block="TCP" event="71" descr="Total atomic with return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_ATOMIC_WITHOUT_RET_REQ" block="TCP" event="72" descr="Total atomic without return requests from TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_READ_REQ" block="TCP" event="75" descr="Total read requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_WRITE_REQ" block="TCP" event="76" descr="Total write requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_NC_ATOMIC_REQ" block="TCP" event="77" descr="Total atomic requests with NC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_READ_REQ" block="TCP" event="78" descr="Total read requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_WRITE_REQ" block="TCP" event="79" descr="Total write requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_UC_ATOMIC_REQ" block="TCP" event="80" descr="Total atomic requests with UC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_READ_REQ" block="TCP" event="81" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_WRITE_REQ" block="TCP" event="82" descr="Total write requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_CC_ATOMIC_REQ" block="TCP" event="83" descr="Total atomic requests with CC mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_READ_REQ" block="TCP" event="85" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_WRITE_REQ" block="TCP" event="86" descr="Total write requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCP_TCC_RW_ATOMIC_REQ" block="TCP" event="87" descr="Total atomic requests with RW mtype from this TCP to all TCCs"></metric>
|
||||
<metric name="TCA_CYCLE" block="TCA" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCA_BUSY" block="TCA" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_CYCLE" block="TCC" event="1" descr="Number of cycles. Not windowable."></metric>
|
||||
<metric name="TCC_BUSY" block="TCC" event="2" descr="Number of cycles we have a request pending. Not windowable."></metric>
|
||||
<metric name="TCC_REQ" block="TCC" event="3" descr="Number of requests of all types. This is measured at the tag block. This may be more than the number of requests arriving at the TCC, but it is a good indication of the total amount of work that needs to be performed."></metric>
|
||||
<metric name="TCC_STREAMING_REQ" block="TCC" event="4" descr="Number of streaming requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_NC_REQ" block="TCC" event="5" descr="The number of noncoherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_UC_REQ" block="TCC" event="6" descr="The number of uncached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_CC_REQ" block="TCC" event="7" descr="The number of coherently cached requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_RW_REQ" block="TCC" event="8" descr="The number of RW requests. This is measured at the tag block."></metric>
|
||||
<metric name="TCC_PROBE" block="TCC" event="9" descr="Number of probe requests. Not windowable."></metric>
|
||||
<metric name="TCC_PROBE_ALL" block="TCC" event="10" descr="Number of external probe requests with with EA_TCC_preq_all== 1. Not windowable."></metric>
|
||||
<metric name="TCC_READ" block="TCC" event="12" descr="Number of read requests. Compressed reads are included in this, but metadata reads are not included."></metric>
|
||||
<metric name="TCC_WRITE" block="TCC" event="13" descr="Number of write requests."></metric>
|
||||
<metric name="TCC_ATOMIC" block="TCC" event="14" descr="Number of atomic requests of all types."></metric>
|
||||
<metric name="TCC_HIT" block="TCC" event="17" descr="Number of cache hits."></metric>
|
||||
<metric name="TCC_MISS" block="TCC" event="19" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="TCC_WRITEBACK" block="TCC" event="22" descr="Number of lines written back to main memory. This includes writebacks of dirty lines and uncached write/atomic requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ" block="TCC" event="26" descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
|
||||
<metric name="TCC_EA_WRREQ_64B" block="TCC" event="27" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="TCC_EA_WR_UNCACHED_32B" block="TCC" event="29" descr="Number of 32-byte write/atomic going over the TC_EA_wrreq interface due to uncached traffic. Note that CC mtypes can produce uncached requests, and those are included in this. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_WRREQ_STALL" block="TCC" event="30" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="TCC_EA_WRREQ_IO_CREDIT_STALL" block="TCC" event="31" descr="Number of cycles a EA write request was stalled because the interface was out of IO credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_GMI_CREDIT_STALL" block="TCC" event="32" descr="Number of cycles a EA write request was stalled because the interface was out of GMI credits."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM_CREDIT_STALL" block="TCC" event="33" descr="Number of cycles a EA write request was stalled because the interface was out of DRAM credits."></metric>
|
||||
<metric name="TCC_TOO_MANY_EA_WRREQS_STALL" block="TCC" event="34" descr="Number of cycles the TCC could not send a EA write request because it already reached its maximum number of pending EA write requests."></metric>
|
||||
<metric name="TCC_EA_WRREQ_LEVEL" block="TCC" event="35" descr="The sum of the number of EA write requests in flight. This is primarily meant for measure average EA write latency. Average write latency = TCC_PERF_SEL_EA_WRREQ_LEVEL/TCC_PERF_SEL_EA_WRREQ."></metric>
|
||||
<metric name="TCC_EA_ATOMIC" block="TCC" event="36" descr="Number of transactions going over the TC_EA_wrreq interface that are actually atomic requests."></metric>
|
||||
<metric name="TCC_EA_ATOMIC_LEVEL" block="TCC" event="37" descr="The sum of the number of EA atomics in flight. This is primarily meant for measure average EA atomic latency. Average atomic latency = TCC_PERF_SEL_EA_WRREQ_ATOMIC_LEVEL/TCC_PERF_SEL_EA_WRREQ_ATOMIC."></metric>
|
||||
<metric name="TCC_EA_RDREQ" block="TCC" event="38" descr="Number of TCC/EA read requests (either 32-byte or 64-byte)"></metric>
|
||||
<metric name="TCC_EA_RDREQ_32B" block="TCC" event="39" descr="Number of 32-byte TCC/EA read requests"></metric>
|
||||
<metric name="TCC_EA_RD_UNCACHED_32B" block="TCC" event="40" descr="Number of 32-byte TCC/EA read due to uncached traffic. A 64-byte request will be counted as 2"></metric>
|
||||
<metric name="TCC_EA_RDREQ_IO_CREDIT_STALL" block="TCC" event="41" descr="Number of cycles there was a stall because the read request interface was out of IO credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_GMI_CREDIT_STALL" block="TCC" event="42" descr="Number of cycles there was a stall because the read request interface was out of GMI credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM_CREDIT_STALL" block="TCC" event="43" descr="Number of cycles there was a stall because the read request interface was out of DRAM credits. Stalls occur regardless of whether a read needed to be performed or not."></metric>
|
||||
<metric name="TCC_EA_RDREQ_LEVEL" block="TCC" event="44" descr="The sum of the number of TCC/EA read requests in flight. This is primarily meant for measure average EA read latency. Average read latency = TCC_PERF_SEL_EA_RDREQ_LEVEL/TCC_PERF_SEL_EA_RDREQ."></metric>
|
||||
<metric name="TCC_TAG_STALL" block="TCC" event="45" descr="Number of cycles the normal request pipeline in the tag was stalled for any reason. Normally, stalls of this nature are measured exactly from one point the pipeline, but that is not the case for this counter. Probes can stall the pipeline at a variety of places, and there is no single point that can reasonably measure the total stalls accurately."></metric>
|
||||
<metric name="TCC_NORMAL_WRITEBACK" block="TCC" event="68" descr="Number of writebacks due to requests that are not writeback requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_WB_WRITEBACK" block="TCC" event="73" descr="Number of writebacks due to all TC_OP writeback requests."></metric>
|
||||
<metric name="TCC_NORMAL_EVICT" block="TCC" event="74" descr="Number of evictions due to requests that are not invalidate or probe requests."></metric>
|
||||
<metric name="TCC_ALL_TC_OP_INV_EVICT" block="TCC" event="80" descr="Number of evictions due to all TC_OP invalidate requests."></metric>
|
||||
<metric name="TCC_EA_RDREQ_DRAM" block="TCC" event="102" descr="Number of TCC/EA read requests (either 32-byte or 64-byte) destined for DRAM (MC)."></metric>
|
||||
<metric name="TCC_EA_WRREQ_DRAM" block="TCC" event="103" descr="Number of TCC/EA write requests (either 32-byte of 64-byte) destined for DRAM (MC)."></metric>
|
||||
</gfx90a>
|
||||
|
||||
<gfx10>
|
||||
<metric name="GRBM_COUNT" block="GRBM" event="0" descr="Tie High - Count Number of Clocks"></metric>
|
||||
<metric name="GRBM_GUI_ACTIVE" block="GRBM" event="2" descr="The GUI is Active"></metric>
|
||||
<metric name="GRBM_CP_BUSY" block="GRBM" event="3" descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
|
||||
<metric name="GRBM_SPI_BUSY" block="GRBM" event="11" descr="Any of the Shader Pipe Interpolators (SPI) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_TA_BUSY" block="GRBM" event="13" descr="Any of the Texture Pipes (TA) are busy in the shader engine(s)."></metric>
|
||||
<metric name="GRBM_GDS_BUSY" block="GRBM" event="25" descr="The Global Data Share (GDS) is busy."></metric>
|
||||
<metric name="GRBM_EA_BUSY" block="GRBM" event="35" descr="The Efficiency Arbiter (EA) block is busy."></metric>
|
||||
<metric name="GRBM_GL2CC_BUSY" block="GRBM" event="40" descr="The GL2CC block is busy."></metric>
|
||||
<metric name="GL2C_HIT" block="GL2C" event="42" descr="Number of cache hits"></metric>
|
||||
<metric name="GL2C_MISS" block="GL2C" event="43" descr="Number of cache misses. UC reads count as misses."></metric>
|
||||
<metric name="GL2C_MC_WRREQ" block="GL2C" event="83" descr="Number of transactions (either 32-byte or 64-byte) going over the GL2C_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands"></metric>
|
||||
<metric name="GL2C_EA_WRREQ_64B" block="GL2C" event="85" descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
|
||||
<metric name="GL2C_MC_WRREQ_STALL" block="GL2C" event="88" descr="Number of cycles a write request was stalled."></metric>
|
||||
<metric name="GL2C_MC_RDREQ" block="GL2C" event="96" descr="Number of GL2C/EA read requests (either 32-byte or 64-byte or 128-byte)."></metric>
|
||||
<metric name="GL2C_EA_RDREQ_32B" block="GL2C" event="99" descr="Number of 32-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_64B" block="GL2C" event="100" descr="Number of 64-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_96B" block="GL2C" event="101" descr="Number of 96-byte GL2C/EA read requests"></metric>
|
||||
<metric name="GL2C_EA_RDREQ_128B" block="GL2C" event="102" descr="Number of 128-byte GL2C/EA read requests"></metric>
|
||||
<metric name="SQ_WAVES" block="SQ" event="4" descr="Count number of waves sent to SQs. {emulated, global, C1}"></metric>
|
||||
<metric name="SQ_WAVE_CYCLES" block="SQ" event="26" descr="Number of clock cycles spent by waves in the SQs. Incremented by # of living (valid) waves each cycle. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_ANY" block="SQ" event="28" descr="Number of clock cycles spent waiting for any instruction issue. In units of cycles. {nondeterministic}"></metric>
|
||||
<metric name="SQ_WAIT_ANY" block="SQ" event="37" descr="Number of clock cycles spent waiting for anything. {nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32" block="SQ" event="71" descr="Number of wave32 instructions issued, for flat, lds, valu, tex. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_LDS" block="SQ" event="74" descr="Number of wave32 LDS indexed instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_WAVE32_VALU" block="SQ" event="75" descr="Number of wave32 valu instructions issued. Wave64 may count 1 or 2, depending on what gets issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAVE32_INSTS" block="SQ" event="84" descr="Number of instructions issued by wave32 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_WAVE64_INSTS" block="SQ" event="85" descr="Number of instructions issued by wave64 waves. Skipped instructions are not counted. {emulated}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_GDS" block="SQ" event="98" descr="Number of in-flight GDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_GDS for average latency. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_LEVEL_LDS" block="SQ" event="99" descr="Number of in-flight LDS instructions. Set next counter to ACCUM_PREV and divide by INSTS_LDS for average latency. Includes FLAT instructions. {level, nondeterministic, C1}"></metric>
|
||||
<metric name="SQ_INST_CYCLES_VMEM" block="SQ" event="120" descr="Number of cycles needed to send addr and data for VMEM (lds, buffer, image, flat, scratch, global) instructions, windowed by perf_en. {emulated, C1}"></metric>
|
||||
<metric name="SQC_LDS_BANK_CONFLICT" block="SQ" event="285" descr="Number of cycles LDS is stalled by bank conflicts. (emulated, C1)"></metric>
|
||||
<metric name="SQC_LDS_IDX_ACTIVE" block="SQ" event="290" descr="Number of cycles LDS is used for indexed (non-direct,non-interpolation) operations. {per-simd, emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_VALU" block="SQ" event="64" descr="Number of VALU instructions issued excluding skipped instructions. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SALU" block="SQ" event="60" descr="Number of SALU instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_SMEM" block="SQ" event="61" descr="Number of SMEM instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_FLAT" block="SQ" event="57" descr="Number of FLAT instructions issued. {emulated, C2}"></metric>
|
||||
<metric name="SQ_INSTS_LDS" block="SQ" event="59" descr="Number of LDS indexed instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_INSTS_GDS" block="SQ" event="55" descr="Number of GDS instructions issued. {emulated, C1}"></metric>
|
||||
<metric name="SQ_WAIT_INST_LDS" block="SQ" event="31" descr="Number of clock cycles spent waiting for LDS (indexed) instruction issue. In units of cycles. {nondeterministic, C1}"></metric>
|
||||
<metric name="TA_TA_BUSY" block="TA" event="15" descr="TA block is busy. Perf_Windowing not supported for this counter."></metric>
|
||||
<metric name="TA_FLAT_LOAD_WAVEFRONTS" block="TA" event="101" descr=" Number of flat load vec32 packets processed by TA, same as flat_read_wavefronts in earlier IP"></metric>
|
||||
<metric name="TA_FLAT_STORE_WAVEFRONTS" block="TA" event="102" descr="Number of flat store vec32 packets processed by TA, same as flat_write_wavefronts in earlier IP"></metric>
|
||||
</gfx10>
|
||||
|
||||
</counters>
|
||||
@@ -0,0 +1,123 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "hsa_info.h"
|
||||
|
||||
#include "src/utils/helper.h"
|
||||
|
||||
#define CHECK_STATUS(msg, status) \
|
||||
do { \
|
||||
if ((status) != HSA_STATUS_SUCCESS) { \
|
||||
const char* emsg = 0; \
|
||||
hsa_status_string(status, &emsg); \
|
||||
throw(ROCPROFILER_STATUS_ERROR_HSA_SUPPORT, \
|
||||
"Error: " << msg << ": " << emsg ? emsg : "<unknown error>"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
namespace Agent {
|
||||
// AgentInfo Class
|
||||
|
||||
AgentInfo::AgentInfo() {}
|
||||
AgentInfo::AgentInfo(const hsa_agent_t agent, ::CoreApiTable* table) : handle_(agent.handle) {
|
||||
if (table->hsa_agent_get_info_fn(agent, HSA_AGENT_INFO_DEVICE, &type_) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_agent_get_info failed");
|
||||
|
||||
table->hsa_agent_get_info_fn(agent, HSA_AGENT_INFO_NAME, name_);
|
||||
|
||||
const int gfxip_label_len = std::min(strlen(name_) - 2, sizeof(gfxip_) - 1);
|
||||
memcpy(gfxip_, name_, gfxip_label_len);
|
||||
gfxip_[gfxip_label_len] = '\0';
|
||||
|
||||
if (type_ != HSA_DEVICE_TYPE_GPU) {
|
||||
return;
|
||||
}
|
||||
|
||||
table->hsa_agent_get_info_fn(agent, HSA_AGENT_INFO_WAVEFRONT_SIZE, &max_wave_size_);
|
||||
table->hsa_agent_get_info_fn(agent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &max_queue_size_);
|
||||
|
||||
table->hsa_agent_get_info_fn(
|
||||
agent, static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT), &cu_num_);
|
||||
|
||||
table->hsa_agent_get_info_fn(
|
||||
agent, static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU), &simds_per_cu_);
|
||||
|
||||
table->hsa_agent_get_info_fn(
|
||||
agent, static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_NUM_SHADER_ENGINES), &se_num_);
|
||||
|
||||
if (table->hsa_agent_get_info_fn(
|
||||
agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_NUM_SHADER_ARRAYS_PER_SE,
|
||||
&shader_arrays_per_se_) != HSA_STATUS_SUCCESS ||
|
||||
table->hsa_agent_get_info_fn(
|
||||
agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MAX_WAVES_PER_CU,
|
||||
&waves_per_cu_) != HSA_STATUS_SUCCESS)
|
||||
{
|
||||
rocmtools::fatal("hsa_agent_get_info for gfxip hardware configuration failed");
|
||||
}
|
||||
|
||||
compute_units_per_sh_ = cu_num_ / (se_num_ * shader_arrays_per_se_);
|
||||
wave_slots_per_simd_ = waves_per_cu_ / simds_per_cu_;
|
||||
|
||||
if (table->hsa_agent_get_info_fn(
|
||||
agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_DOMAIN,
|
||||
&pci_domain_) != HSA_STATUS_SUCCESS ||
|
||||
table->hsa_agent_get_info_fn(
|
||||
agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_BDFID,
|
||||
&pci_location_id_) != HSA_STATUS_SUCCESS)
|
||||
{
|
||||
rocmtools::fatal("hsa_agent_get_info for PCI info failed");
|
||||
}
|
||||
}
|
||||
|
||||
int AgentInfo::getIndex() const { return index_; }
|
||||
hsa_device_type_t AgentInfo::getType() const { return type_; }
|
||||
uint64_t AgentInfo::getHandle() const { return handle_; }
|
||||
const std::string_view AgentInfo::getName() const { return name_; }
|
||||
std::string AgentInfo::getGfxip() const { return std::string(gfxip_); }
|
||||
uint32_t AgentInfo::getMaxWaveSize() const { return max_wave_size_; }
|
||||
uint32_t AgentInfo::getMaxQueueSize() const { return max_queue_size_; }
|
||||
uint32_t AgentInfo::getCUCount() const { return cu_num_; }
|
||||
uint32_t AgentInfo::getSimdCountPerCU() const { return simds_per_cu_; }
|
||||
uint32_t AgentInfo::getShaderEngineCount() const { return se_num_; }
|
||||
uint32_t AgentInfo::getShaderArraysPerSE() const { return shader_arrays_per_se_; }
|
||||
uint32_t AgentInfo::getMaxWavesPerCU() const { return waves_per_cu_; }
|
||||
uint32_t AgentInfo::getCUCountPerSH() const { return compute_units_per_sh_; }
|
||||
uint32_t AgentInfo::getWaveSlotsPerSimd() const { return wave_slots_per_simd_; }
|
||||
uint32_t AgentInfo::getPCIDomain() const { return pci_domain_; }
|
||||
uint32_t AgentInfo::getPCILocationID() const { return pci_location_id_; }
|
||||
|
||||
void AgentInfo::setIndex(int index) { index_ = index; }
|
||||
void AgentInfo::setType(hsa_device_type_t type) { type_ = type; }
|
||||
void AgentInfo::setHandle(uint64_t handle) { handle_ = handle; }
|
||||
void AgentInfo::setName(const std::string& name) { strcpy(name_, name.c_str()); }
|
||||
|
||||
// CounterHardwareInfo Class
|
||||
|
||||
CounterHardwareInfo::CounterHardwareInfo(uint64_t event_id, const char* block_id)
|
||||
: event_id_(event_id), block_id_(block_id) {}
|
||||
int64_t CounterHardwareInfo::getNumInstances() { return num_instances_; }
|
||||
|
||||
bool getHardwareInfo(uint64_t event_id, const char* block_id,
|
||||
CounterHardwareInfo* counter_hardware_info) {
|
||||
counter_hardware_info = new CounterHardwareInfo(event_id, block_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Agent
|
||||
@@ -0,0 +1,110 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_HARDWARE_HSA_INFO_H_
|
||||
#define SRC_CORE_HARDWARE_HSA_INFO_H_
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_api_trace.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace Agent {
|
||||
|
||||
static const uint32_t LDS_BLOCK_SIZE = 128 * 4;
|
||||
|
||||
// XXX TODO: This should be merged into rocmtools::hsa_support::AgentInfo and
|
||||
// this file should be removed entirely, as it's completely redundant
|
||||
class AgentInfo {
|
||||
public:
|
||||
AgentInfo();
|
||||
AgentInfo(const hsa_agent_t agent, ::CoreApiTable* table);
|
||||
|
||||
int getIndex() const;
|
||||
hsa_device_type_t getType() const;
|
||||
uint64_t getHandle() const;
|
||||
const std::string_view getName() const;
|
||||
|
||||
std::string getGfxip() const;
|
||||
uint32_t getMaxWaveSize() const;
|
||||
uint32_t getMaxQueueSize() const;
|
||||
uint32_t getCUCount() const;
|
||||
uint32_t getSimdCountPerCU() const;
|
||||
uint32_t getShaderEngineCount() const;
|
||||
uint32_t getShaderArraysPerSE() const;
|
||||
uint32_t getMaxWavesPerCU() const;
|
||||
uint32_t getCUCountPerSH() const;
|
||||
uint32_t getWaveSlotsPerSimd() const;
|
||||
uint32_t getPCIDomain() const;
|
||||
uint32_t getPCILocationID() const;
|
||||
|
||||
void setIndex(int index);
|
||||
void setType(hsa_device_type_t type);
|
||||
void setHandle(uint64_t handle);
|
||||
void setName(const std::string& name);
|
||||
|
||||
private:
|
||||
int index_;
|
||||
hsa_device_type_t type_; // Agent type - Cpu = 0, Gpu = 1 or Dsp = 2
|
||||
uint64_t handle_;
|
||||
char name_[64];
|
||||
char gfxip_[64];
|
||||
uint32_t max_wave_size_;
|
||||
uint32_t max_queue_size_;
|
||||
uint32_t cu_num_;
|
||||
uint32_t simds_per_cu_;
|
||||
uint32_t se_num_;
|
||||
uint32_t shader_arrays_per_se_;
|
||||
uint32_t waves_per_cu_;
|
||||
// CUs per SH/SA
|
||||
uint32_t compute_units_per_sh_;
|
||||
uint32_t wave_slots_per_simd_;
|
||||
|
||||
uint32_t pci_domain_;
|
||||
uint32_t pci_location_id_;
|
||||
};
|
||||
|
||||
// XXX TODO: This should be moved somewhere else so this file can be deleted
|
||||
class CounterHardwareInfo {
|
||||
public:
|
||||
CounterHardwareInfo(uint64_t event_id, const char* block_id);
|
||||
int64_t getNumInstances();
|
||||
|
||||
private:
|
||||
uint64_t register_offset_;
|
||||
uint64_t register_address_;
|
||||
int64_t num_instances_;
|
||||
hsa_agent_t agent_;
|
||||
uint64_t event_id_;
|
||||
const char* block_id_;
|
||||
};
|
||||
|
||||
// XXX TODO: This too
|
||||
bool getHardwareInfo(uint64_t event_id, const char* block_id,
|
||||
CounterHardwareInfo* counter_hardware_info);
|
||||
|
||||
} // namespace Agent
|
||||
|
||||
#endif // SRC_CORE_HARDWARE_HSA_INFO_H_
|
||||
@@ -0,0 +1,112 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "hsa_common.h"
|
||||
|
||||
#include "src/utils/exception.h"
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
namespace hsa_support {
|
||||
|
||||
std::mutex agents_map_lock;
|
||||
std::map<decltype(hsa_agent_t::handle), Agent::AgentInfo> agent_info_map;
|
||||
Agent::AgentInfo& GetAgentInfo(decltype(hsa_agent_t::handle) handle) {
|
||||
std::lock_guard<std::mutex> lock(agents_map_lock);
|
||||
if (agent_info_map.find(handle) != agent_info_map.end())
|
||||
return agent_info_map.at(handle);
|
||||
else
|
||||
throw(std::string("Error: Can't find Agent with handle(") + std::to_string(handle) +
|
||||
") in this system");
|
||||
}
|
||||
void SetAgentInfo(decltype(hsa_agent_t::handle) handle, const Agent::AgentInfo& agent_info) {
|
||||
std::lock_guard<std::mutex> lock(agents_map_lock);
|
||||
agent_info_map.emplace(handle, agent_info);
|
||||
}
|
||||
|
||||
hsa_agent_t GetAgentByIndex(int agent_index) {
|
||||
std::lock_guard<std::mutex> lock(agents_map_lock);
|
||||
for (auto& agent_info : agent_info_map) {
|
||||
if (agent_info.second.getIndex() == agent_index) {
|
||||
return hsa_agent_t{agent_info.second.getHandle()};
|
||||
}
|
||||
}
|
||||
throw(std::string("Error: Can't find Agent with Index(") + std::to_string(agent_index) +
|
||||
") in this system");
|
||||
}
|
||||
|
||||
CoreApiTable saved_core_api{};
|
||||
CoreApiTable& GetCoreApiTable() { return saved_core_api; }
|
||||
void SetCoreApiTable(const CoreApiTable& table) { saved_core_api = table; }
|
||||
|
||||
AmdExtTable saved_amd_ext_api{};
|
||||
AmdExtTable GetAmdExtTable() { return saved_amd_ext_api; }
|
||||
void SetAmdExtTable(AmdExtTable* table) { saved_amd_ext_api = *table; }
|
||||
|
||||
hsa_ven_amd_loader_1_01_pfn_t hsa_loader_api{};
|
||||
hsa_ven_amd_loader_1_01_pfn_t GetHSALoaderApi() { return hsa_loader_api; }
|
||||
void SetHSALoaderApi() {
|
||||
hsa_status_t status = saved_core_api.hsa_system_get_major_extension_table_fn(
|
||||
HSA_EXTENSION_AMD_LOADER, 1, sizeof(hsa_ven_amd_loader_1_01_pfn_t), &hsa_loader_api);
|
||||
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("hsa_system_get_major_extension_table failed");
|
||||
}
|
||||
|
||||
void ResetMaps() {
|
||||
if (hsa_status_t status = saved_amd_ext_api.hsa_amd_profiling_async_copy_enable_fn(false);
|
||||
status != HSA_STATUS_SUCCESS)
|
||||
assert(!"hsa_amd_profiling_async_copy_enable failed");
|
||||
memset(&saved_core_api, '\0', sizeof(saved_core_api));
|
||||
memset(&saved_amd_ext_api, '\0', sizeof(saved_amd_ext_api));
|
||||
memset(&hsa_loader_api, '\0', sizeof(hsa_loader_api));
|
||||
}
|
||||
|
||||
rocprofiler_timestamp_t GetCurrentTimestampNS() {
|
||||
// If the HSA intercept is installed, then use the "original"
|
||||
// 'hsa_system_get_info' function to avoid reporting calls for internal use
|
||||
// of the HSA API by the tracer.
|
||||
auto hsa_system_get_info_fn = saved_core_api.hsa_system_get_info_fn;
|
||||
|
||||
// If the HSA intercept is not installed, use the default
|
||||
// 'hsa_system_get_info'.
|
||||
if (hsa_system_get_info_fn == nullptr) hsa_system_get_info_fn = hsa_system_get_info;
|
||||
|
||||
uint64_t sysclock;
|
||||
if (hsa_status_t status = hsa_system_get_info_fn(HSA_SYSTEM_INFO_TIMESTAMP, &sysclock);
|
||||
status == HSA_STATUS_ERROR_NOT_INITIALIZED)
|
||||
return rocprofiler_timestamp_t{0};
|
||||
else if (status != HSA_STATUS_SUCCESS)
|
||||
assert(!"hsa_system_get_info failed");
|
||||
|
||||
static uint64_t sysclock_period = [&]() {
|
||||
uint64_t sysclock_hz = 0;
|
||||
if (hsa_status_t status =
|
||||
hsa_system_get_info_fn(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &sysclock_hz);
|
||||
status != HSA_STATUS_SUCCESS)
|
||||
assert(!"hsa_system_get_info failed");
|
||||
|
||||
return (uint64_t)1000000000 / sysclock_hz;
|
||||
}();
|
||||
|
||||
return rocprofiler_timestamp_t{sysclock * sysclock_period};
|
||||
}
|
||||
|
||||
} // namespace hsa_support
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,61 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_HSA_HSA_COMMON_H_
|
||||
#define SRC_CORE_HSA_HSA_COMMON_H_
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_api_trace.h>
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
#include <hsa/hsa_ven_amd_loader.h>
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#include "rocprofiler.h"
|
||||
#include "src/core/hardware/hsa_info.h"
|
||||
|
||||
#define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
namespace rocmtools {
|
||||
namespace hsa_support {
|
||||
|
||||
Agent::AgentInfo& GetAgentInfo(decltype(hsa_agent_t::handle) handle);
|
||||
void SetAgentInfo(decltype(hsa_agent_t::handle) handle, const Agent::AgentInfo& agent_info);
|
||||
hsa_agent_t GetAgentByIndex(int agent_index);
|
||||
|
||||
CoreApiTable& GetCoreApiTable();
|
||||
void SetCoreApiTable(const CoreApiTable& table);
|
||||
|
||||
AmdExtTable GetAmdExtTable();
|
||||
void SetAmdExtTable(AmdExtTable* table);
|
||||
|
||||
hsa_ven_amd_loader_1_01_pfn_t GetHSALoaderApi();
|
||||
void SetHSALoaderApi();
|
||||
|
||||
void ResetMaps();
|
||||
|
||||
rocprofiler_timestamp_t GetCurrentTimestampNS();
|
||||
|
||||
} // namespace hsa_support
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_HSA_HSA_COMMON_H_
|
||||
@@ -0,0 +1,895 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "hsa_support.h"
|
||||
|
||||
#include <hsa/amd_hsa_signal.h>
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_ven_amd_loader.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "src/core/session/tracer/src/correlation_id.h"
|
||||
#include "src/core/session/tracer/src/exception.h"
|
||||
#include "src/core/session/tracer/src/roctracer.h"
|
||||
#include "src/utils/helper.h"
|
||||
|
||||
#include "src/core/hsa/queues/queue.h"
|
||||
#include "src/api/rocmtool.h"
|
||||
|
||||
namespace {
|
||||
|
||||
hsa_status_t hsa_executable_iteration_callback(hsa_executable_t executable, hsa_agent_t agent,
|
||||
hsa_executable_symbol_t symbol, void* args) {
|
||||
hsa_symbol_kind_t type;
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_executable_symbol_get_info_fn(
|
||||
symbol, HSA_EXECUTABLE_SYMBOL_INFO_TYPE, &type);
|
||||
if (type == HSA_SYMBOL_KIND_KERNEL) {
|
||||
uint32_t name_length;
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_executable_symbol_get_info_fn(
|
||||
symbol, HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH, &name_length);
|
||||
// TODO(aelwazir): to be removed if the HSA fixed the issue of corrupted
|
||||
// names overflowing the length given
|
||||
if (name_length > 1) {
|
||||
char name[name_length + 1];
|
||||
uint64_t kernel_object;
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_executable_symbol_get_info_fn(
|
||||
symbol, HSA_EXECUTABLE_SYMBOL_INFO_NAME, name);
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_executable_symbol_get_info_fn(
|
||||
symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &kernel_object);
|
||||
std::string kernel_name = std::string(name).substr(0, name_length);
|
||||
rocmtools::AddKernelName(kernel_object, kernel_name);
|
||||
}
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
std::atomic<int (*)(rocprofiler_tracer_activity_domain_t domain, uint32_t operation_id, void* data)>
|
||||
report_activity;
|
||||
|
||||
bool IsEnabled(rocprofiler_tracer_activity_domain_t domain, uint32_t operation_id) {
|
||||
auto report = report_activity.load(std::memory_order_relaxed);
|
||||
return report && report(domain, operation_id, nullptr) == 0;
|
||||
}
|
||||
|
||||
void ReportActivity(rocprofiler_tracer_activity_domain_t domain, uint32_t operation_id, void* data) {
|
||||
if (auto report = report_activity.load(std::memory_order_relaxed))
|
||||
report(domain, operation_id, data);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "hsa_prof_str.inline.h"
|
||||
|
||||
namespace roctracer::hsa_support {
|
||||
|
||||
namespace {
|
||||
|
||||
CoreApiTable saved_core_api{};
|
||||
AmdExtTable saved_amd_ext_api{};
|
||||
hsa_ven_amd_loader_1_01_pfn_t hsa_loader_api{};
|
||||
|
||||
struct AgentInfo {
|
||||
uint32_t id;
|
||||
hsa_device_type_t type;
|
||||
};
|
||||
std::unordered_map<decltype(hsa_agent_t::handle), AgentInfo> agent_info_map;
|
||||
|
||||
class Tracker {
|
||||
public:
|
||||
enum { ENTRY_INV = 0, ENTRY_INIT = 1, ENTRY_COMPL = 2 };
|
||||
|
||||
enum entry_type_t {
|
||||
DFLT_ENTRY_TYPE = 0,
|
||||
API_ENTRY_TYPE = 1,
|
||||
COPY_ENTRY_TYPE = 2,
|
||||
KERNEL_ENTRY_TYPE = 3,
|
||||
NUM_ENTRY_TYPE = 4
|
||||
};
|
||||
|
||||
struct entry_t {
|
||||
std::atomic<uint32_t> valid;
|
||||
entry_type_t type;
|
||||
uint64_t correlation_id;
|
||||
roctracer_timestamp_t begin; // begin timestamp, ns
|
||||
roctracer_timestamp_t end; // end timestamp, ns
|
||||
hsa_agent_t agent;
|
||||
uint32_t dev_index;
|
||||
hsa_signal_t orig;
|
||||
hsa_signal_t signal;
|
||||
void (*handler)(const entry_t*);
|
||||
union {
|
||||
struct {
|
||||
} copy;
|
||||
struct {
|
||||
const char* name;
|
||||
hsa_agent_t agent;
|
||||
uint32_t tid;
|
||||
} kernel;
|
||||
};
|
||||
};
|
||||
|
||||
// Add tracker entry
|
||||
inline static void Enable(entry_type_t type, const hsa_agent_t& agent, const hsa_signal_t& signal,
|
||||
entry_t* entry) {
|
||||
hsa_status_t status = HSA_STATUS_ERROR;
|
||||
|
||||
// Creating a new tracker entry
|
||||
entry->type = type;
|
||||
entry->agent = agent;
|
||||
entry->dev_index = 0; // hsa_rsrc->GetAgentInfo(agent)->dev_index;
|
||||
entry->orig = signal;
|
||||
entry->valid.store(ENTRY_INIT, std::memory_order_release);
|
||||
|
||||
// Creating a proxy signal
|
||||
status = rocmtools::hsa_support::GetCoreApiTable().hsa_signal_create_fn(1, 0, NULL,
|
||||
&(entry->signal));
|
||||
if (status != HSA_STATUS_SUCCESS) rocmtools::fatal("hsa_signal_create failed");
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_signal_async_handler_fn(
|
||||
entry->signal, HSA_SIGNAL_CONDITION_LT, 1, Handler, entry);
|
||||
if (status != HSA_STATUS_SUCCESS) rocmtools::fatal("hsa_amd_signal_async_handler failed");
|
||||
}
|
||||
|
||||
// Delete tracker entry
|
||||
inline static void Disable(entry_t* entry) {
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_signal_destroy_fn(entry->signal);
|
||||
entry->valid.store(ENTRY_INV, std::memory_order_release);
|
||||
}
|
||||
|
||||
private:
|
||||
// Entry completion
|
||||
inline static void Complete(hsa_signal_value_t signal_value, entry_t* entry) {
|
||||
static roctracer_timestamp_t sysclock_period = []() {
|
||||
uint64_t sysclock_hz = 0;
|
||||
hsa_status_t status = rocmtools::hsa_support::GetCoreApiTable().hsa_system_get_info_fn(
|
||||
HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &sysclock_hz);
|
||||
if (status != HSA_STATUS_SUCCESS) rocmtools::fatal("hsa_system_get_info failed");
|
||||
return (uint64_t)1000000000 / sysclock_hz;
|
||||
}();
|
||||
|
||||
if (entry->type == COPY_ENTRY_TYPE) {
|
||||
hsa_amd_profiling_async_copy_time_t async_copy_time{};
|
||||
hsa_status_t status =
|
||||
rocmtools::hsa_support::GetAmdExtTable().hsa_amd_profiling_get_async_copy_time_fn(
|
||||
entry->signal, &async_copy_time);
|
||||
if (status != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_amd_profiling_get_async_copy_time failed");
|
||||
entry->begin = async_copy_time.start * sysclock_period;
|
||||
entry->end = async_copy_time.end * sysclock_period;
|
||||
} else {
|
||||
assert(false && "should not reach here");
|
||||
}
|
||||
|
||||
hsa_signal_t orig = entry->orig;
|
||||
hsa_signal_t signal = entry->signal;
|
||||
|
||||
// Releasing completed entry
|
||||
entry->valid.store(ENTRY_COMPL, std::memory_order_release);
|
||||
|
||||
assert(entry->handler != nullptr);
|
||||
entry->handler(entry);
|
||||
|
||||
// Original intercepted signal completion
|
||||
if (orig.handle) {
|
||||
amd_signal_t* orig_signal_ptr = reinterpret_cast<amd_signal_t*>(orig.handle);
|
||||
amd_signal_t* prof_signal_ptr = reinterpret_cast<amd_signal_t*>(signal.handle);
|
||||
orig_signal_ptr->start_ts = prof_signal_ptr->start_ts;
|
||||
orig_signal_ptr->end_ts = prof_signal_ptr->end_ts;
|
||||
|
||||
[[maybe_unused]] const hsa_signal_value_t new_value =
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_signal_load_relaxed_fn(orig) - 1;
|
||||
assert(signal_value == new_value && "Tracker::Complete bad signal value");
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_signal_store_screlease_fn(orig, signal_value);
|
||||
}
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_signal_destroy_fn(signal);
|
||||
delete entry;
|
||||
}
|
||||
|
||||
// Handler for packet completion
|
||||
static bool Handler(hsa_signal_value_t signal_value, void* arg) {
|
||||
// Acquire entry
|
||||
entry_t* entry = reinterpret_cast<entry_t*>(arg);
|
||||
while (entry->valid.load(std::memory_order_acquire) != ENTRY_INIT) sched_yield();
|
||||
|
||||
// Complete entry
|
||||
Tracker::Complete(signal_value, entry);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
hsa_status_t HSA_API MemoryAllocateIntercept(hsa_region_t region, size_t size, void** ptr) {
|
||||
hsa_status_t status =
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_memory_allocate_fn(region, size, ptr);
|
||||
if (status != HSA_STATUS_SUCCESS) return status;
|
||||
|
||||
if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_ALLOCATE)) {
|
||||
hsa_evt_data_t data{};
|
||||
data.allocate.ptr = *ptr;
|
||||
data.allocate.size = size;
|
||||
if (rocmtools::hsa_support::GetCoreApiTable().hsa_region_get_info_fn(
|
||||
region, HSA_REGION_INFO_SEGMENT, &data.allocate.segment) != HSA_STATUS_SUCCESS ||
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_region_get_info_fn(
|
||||
region, HSA_REGION_INFO_GLOBAL_FLAGS, &data.allocate.global_flag) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_region_get_info failed");
|
||||
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_ALLOCATE, &data);
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t MemoryAssignAgentIntercept(void* ptr, hsa_agent_t agent,
|
||||
hsa_access_permission_t access) {
|
||||
hsa_status_t status =
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_memory_assign_agent_fn(ptr, agent, access);
|
||||
if (status != HSA_STATUS_SUCCESS) return status;
|
||||
|
||||
if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_DEVICE)) {
|
||||
hsa_evt_data_t data{};
|
||||
data.device.ptr = ptr;
|
||||
if (rocmtools::hsa_support::GetCoreApiTable().hsa_agent_get_info_fn(
|
||||
agent, HSA_AGENT_INFO_DEVICE, &data.device.type) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_agent_get_info failed");
|
||||
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_DEVICE, &data);
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t MemoryCopyIntercept(void* dst, const void* src, size_t size) {
|
||||
hsa_status_t status =
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_memory_copy_fn(dst, src, size);
|
||||
if (status != HSA_STATUS_SUCCESS) return status;
|
||||
|
||||
if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_MEMCOPY)) {
|
||||
hsa_evt_data_t data{};
|
||||
data.memcopy.dst = dst;
|
||||
data.memcopy.src = src;
|
||||
data.memcopy.size = size;
|
||||
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_MEMCOPY, &data);
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t MemoryPoolAllocateIntercept(hsa_amd_memory_pool_t pool, size_t size, uint32_t flags,
|
||||
void** ptr) {
|
||||
hsa_status_t status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_allocate_fn(
|
||||
pool, size, flags, ptr);
|
||||
if (size == 0 || status != HSA_STATUS_SUCCESS) return status;
|
||||
|
||||
if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_ALLOCATE)) {
|
||||
hsa_evt_data_t data{};
|
||||
data.allocate.ptr = *ptr;
|
||||
data.allocate.size = size;
|
||||
|
||||
if (rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_get_info_fn(
|
||||
pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &data.allocate.segment) != HSA_STATUS_SUCCESS ||
|
||||
rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_get_info_fn(
|
||||
pool, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &data.allocate.global_flag) !=
|
||||
HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_region_get_info failed");
|
||||
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_ALLOCATE, &data);
|
||||
}
|
||||
|
||||
if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_DEVICE)) {
|
||||
auto callback_data = std::make_pair(pool, ptr);
|
||||
auto agent_callback = [](hsa_agent_t agent, void* iterate_agent_callback_data) {
|
||||
auto [pool, ptr] = *reinterpret_cast<decltype(callback_data)*>(iterate_agent_callback_data);
|
||||
|
||||
if (hsa_amd_memory_pool_access_t value;
|
||||
rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agent_memory_pool_get_info_fn(
|
||||
agent, pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &value) != HSA_STATUS_SUCCESS ||
|
||||
value != HSA_AMD_MEMORY_POOL_ACCESS_ALLOWED_BY_DEFAULT)
|
||||
return HSA_STATUS_SUCCESS;
|
||||
|
||||
auto it = agent_info_map.find(agent.handle);
|
||||
if (it == agent_info_map.end()) rocmtools::fatal("agent was not found in the agent_info map");
|
||||
|
||||
hsa_evt_data_t data{};
|
||||
data.device.type = it->second.type;
|
||||
data.device.id = it->second.id;
|
||||
data.device.agent = agent;
|
||||
data.device.ptr = ptr;
|
||||
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_DEVICE, &data);
|
||||
return HSA_STATUS_SUCCESS;
|
||||
};
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_iterate_agents_fn(agent_callback, &callback_data);
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t MemoryPoolFreeIntercept(void* ptr) {
|
||||
if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_ALLOCATE)) {
|
||||
hsa_evt_data_t data{};
|
||||
data.allocate.ptr = ptr;
|
||||
data.allocate.size = 0;
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_ALLOCATE, &data);
|
||||
}
|
||||
|
||||
if (ptr)
|
||||
return rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_free_fn(ptr);
|
||||
else
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Agent allow access callback 'hsa_amd_agents_allow_access'
|
||||
hsa_status_t AgentsAllowAccessIntercept(uint32_t num_agents, const hsa_agent_t* agents,
|
||||
const uint32_t* flags, const void* ptr) {
|
||||
hsa_status_t status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agents_allow_access_fn(
|
||||
num_agents, agents, flags, ptr);
|
||||
if (status != HSA_STATUS_SUCCESS) return status;
|
||||
|
||||
if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_DEVICE)) {
|
||||
while (num_agents--) {
|
||||
hsa_agent_t agent = *agents++;
|
||||
auto it = agent_info_map.find(agent.handle);
|
||||
if (it == agent_info_map.end()) rocmtools::fatal("agent was not found in the agent_info map");
|
||||
|
||||
hsa_evt_data_t data{};
|
||||
data.device.type = it->second.type;
|
||||
data.device.id = it->second.id;
|
||||
data.device.agent = agent;
|
||||
data.device.ptr = ptr;
|
||||
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_DEVICE, &data);
|
||||
}
|
||||
}
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
struct CodeObjectCallbackArg {
|
||||
activity_rtapi_callback_t callback_fun;
|
||||
void* callback_arg;
|
||||
bool unload;
|
||||
};
|
||||
|
||||
hsa_status_t CodeObjectCallback(hsa_executable_t executable,
|
||||
hsa_loaded_code_object_t loaded_code_object, void* arg) {
|
||||
hsa_evt_data_t data{};
|
||||
|
||||
if (rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_TYPE,
|
||||
&data.codeobj.storage_type) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_ven_amd_loader_loaded_code_object_get_info failed");
|
||||
|
||||
if (data.codeobj.storage_type == HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE) {
|
||||
if (rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_FILE,
|
||||
&data.codeobj.storage_file) != HSA_STATUS_SUCCESS ||
|
||||
data.codeobj.storage_file == -1)
|
||||
rocmtools::fatal("hsa_ven_amd_loader_loaded_code_object_get_info failed");
|
||||
data.codeobj.memory_base = data.codeobj.memory_size = 0;
|
||||
} else if (data.codeobj.storage_type == HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY) {
|
||||
if (rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object,
|
||||
HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_MEMORY_BASE,
|
||||
&data.codeobj.memory_base) != HSA_STATUS_SUCCESS ||
|
||||
rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object,
|
||||
HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_MEMORY_SIZE,
|
||||
&data.codeobj.memory_size) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_ven_amd_loader_loaded_code_object_get_info failed");
|
||||
data.codeobj.storage_file = -1;
|
||||
} else if (data.codeobj.storage_type == HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE) {
|
||||
return HSA_STATUS_SUCCESS; // FIXME: do we really not care about these
|
||||
// code objects?
|
||||
} else {
|
||||
rocmtools::fatal("unknown code object storage type: %d", data.codeobj.storage_type);
|
||||
}
|
||||
|
||||
if (rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_BASE,
|
||||
&data.codeobj.load_base) != HSA_STATUS_SUCCESS ||
|
||||
rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_SIZE,
|
||||
&data.codeobj.load_size) != HSA_STATUS_SUCCESS ||
|
||||
rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_DELTA,
|
||||
&data.codeobj.load_delta) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_ven_amd_loader_loaded_code_object_get_info failed");
|
||||
|
||||
if (rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI_LENGTH,
|
||||
&data.codeobj.uri_length) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_ven_amd_loader_loaded_code_object_get_info failed");
|
||||
|
||||
std::string uri_str(data.codeobj.uri_length, '\0');
|
||||
if (rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI, uri_str.data()) !=
|
||||
HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_ven_amd_loader_loaded_code_object_get_info failed");
|
||||
|
||||
if (rocmtools::hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_loaded_code_object_get_info(
|
||||
loaded_code_object, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_AGENT,
|
||||
&data.codeobj.agent) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_ven_amd_loader_loaded_code_object_get_info failed");
|
||||
|
||||
data.codeobj.uri = uri_str.c_str();
|
||||
data.codeobj.unload = *static_cast<bool*>(arg) ? 1 : 0;
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_CODEOBJ, &data);
|
||||
|
||||
hsa_executable_iterate_agent_symbols(executable, data.codeobj.agent,
|
||||
hsa_executable_iteration_callback, nullptr);
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t ExecutableFreezeIntercept(hsa_executable_t executable, const char* options) {
|
||||
hsa_status_t status =
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_executable_freeze_fn(executable, options);
|
||||
if (status != HSA_STATUS_SUCCESS) return status;
|
||||
|
||||
// if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_CODEOBJ)) {
|
||||
bool unload = false;
|
||||
rocmtools::hsa_support::GetHSALoaderApi()
|
||||
.hsa_ven_amd_loader_executable_iterate_loaded_code_objects(executable, CodeObjectCallback,
|
||||
&unload);
|
||||
// }
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
hsa_status_t ExecutableDestroyIntercept(hsa_executable_t executable) {
|
||||
// if (IsEnabled(ACTIVITY_DOMAIN_HSA_EVT, HSA_EVT_ID_CODEOBJ)) {
|
||||
bool unload = true;
|
||||
rocmtools::hsa_support::GetHSALoaderApi()
|
||||
.hsa_ven_amd_loader_executable_iterate_loaded_code_objects(executable, CodeObjectCallback,
|
||||
&unload);
|
||||
// }
|
||||
|
||||
return rocmtools::hsa_support::GetCoreApiTable().hsa_executable_destroy_fn(executable);
|
||||
}
|
||||
|
||||
bool profiling_async_copy_enable = false;
|
||||
|
||||
hsa_status_t ProfilingAsyncCopyEnableIntercept(bool enable) {
|
||||
hsa_status_t status =
|
||||
rocmtools::hsa_support::GetAmdExtTable().hsa_amd_profiling_async_copy_enable_fn(enable);
|
||||
if (status == HSA_STATUS_SUCCESS) profiling_async_copy_enable = enable;
|
||||
return status;
|
||||
}
|
||||
|
||||
void MemoryASyncCopyHandler(const Tracker::entry_t* entry) {
|
||||
activity_record_t record{};
|
||||
record.domain = ACTIVITY_DOMAIN_HSA_OPS;
|
||||
record.op = HSA_OP_ID_COPY;
|
||||
record.begin_ns = entry->begin;
|
||||
record.end_ns = entry->end;
|
||||
record.device_id = 0;
|
||||
record.correlation_id = entry->correlation_id;
|
||||
ReportActivity(ACTIVITY_DOMAIN_HSA_OPS, HSA_OP_ID_COPY, &record);
|
||||
}
|
||||
|
||||
hsa_status_t MemoryASyncCopyIntercept(void* dst, hsa_agent_t dst_agent, const void* src,
|
||||
hsa_agent_t src_agent, size_t size, uint32_t num_dep_signals,
|
||||
const hsa_signal_t* dep_signals,
|
||||
hsa_signal_t completion_signal) {
|
||||
bool is_enabled = IsEnabled(ACTIVITY_DOMAIN_HSA_OPS, HSA_OP_ID_COPY);
|
||||
|
||||
// FIXME: what happens if the state changes before returning?
|
||||
[[maybe_unused]] hsa_status_t status =
|
||||
rocmtools::hsa_support::GetAmdExtTable().hsa_amd_profiling_async_copy_enable_fn(
|
||||
profiling_async_copy_enable | is_enabled);
|
||||
assert(status == HSA_STATUS_SUCCESS && "hsa_amd_profiling_async_copy_enable failed");
|
||||
|
||||
if (!is_enabled) {
|
||||
return rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_async_copy_fn(
|
||||
dst, dst_agent, src, src_agent, size, num_dep_signals, dep_signals, completion_signal);
|
||||
}
|
||||
|
||||
Tracker::entry_t* entry = new Tracker::entry_t();
|
||||
entry->handler = MemoryASyncCopyHandler;
|
||||
entry->correlation_id = CorrelationId();
|
||||
Tracker::Enable(Tracker::COPY_ENTRY_TYPE, hsa_agent_t{}, completion_signal, entry);
|
||||
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_async_copy_fn(
|
||||
dst, dst_agent, src, src_agent, size, num_dep_signals, dep_signals, entry->signal);
|
||||
if (status != HSA_STATUS_SUCCESS) Tracker::Disable(entry);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
hsa_status_t MemoryASyncCopyRectIntercept(const hsa_pitched_ptr_t* dst,
|
||||
const hsa_dim3_t* dst_offset,
|
||||
const hsa_pitched_ptr_t* src,
|
||||
const hsa_dim3_t* src_offset, const hsa_dim3_t* range,
|
||||
hsa_agent_t copy_agent, hsa_amd_copy_direction_t dir,
|
||||
uint32_t num_dep_signals, const hsa_signal_t* dep_signals,
|
||||
hsa_signal_t completion_signal) {
|
||||
bool is_enabled = IsEnabled(ACTIVITY_DOMAIN_HSA_OPS, HSA_OP_ID_COPY);
|
||||
|
||||
// FIXME: what happens if the state changes before returning?
|
||||
[[maybe_unused]] hsa_status_t status =
|
||||
rocmtools::hsa_support::GetAmdExtTable().hsa_amd_profiling_async_copy_enable_fn(
|
||||
profiling_async_copy_enable | is_enabled);
|
||||
assert(status == HSA_STATUS_SUCCESS && "hsa_amd_profiling_async_copy_enable failed");
|
||||
|
||||
if (!is_enabled) {
|
||||
return rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_async_copy_rect_fn(
|
||||
dst, dst_offset, src, src_offset, range, copy_agent, dir, num_dep_signals, dep_signals,
|
||||
completion_signal);
|
||||
}
|
||||
|
||||
Tracker::entry_t* entry = new Tracker::entry_t();
|
||||
entry->handler = MemoryASyncCopyHandler;
|
||||
entry->correlation_id = CorrelationId();
|
||||
Tracker::Enable(Tracker::COPY_ENTRY_TYPE, hsa_agent_t{}, completion_signal, entry);
|
||||
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_async_copy_rect_fn(
|
||||
dst, dst_offset, src, src_offset, range, copy_agent, dir, num_dep_signals, dep_signals,
|
||||
entry->signal);
|
||||
if (status != HSA_STATUS_SUCCESS) Tracker::Disable(entry);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
rocprofiler_timestamp_t timestamp_ns() {
|
||||
// If the HSA intercept is installed, then use the "original"
|
||||
// 'hsa_system_get_info' function to avoid reporting calls for internal use
|
||||
// of the HSA API by the tracer.
|
||||
auto hsa_system_get_info_fn = rocmtools::hsa_support::GetCoreApiTable().hsa_system_get_info_fn;
|
||||
|
||||
// If the HSA intercept is not installed, use the default
|
||||
// 'hsa_system_get_info'.
|
||||
if (hsa_system_get_info_fn == nullptr) hsa_system_get_info_fn = hsa_system_get_info;
|
||||
|
||||
uint64_t sysclock;
|
||||
if (hsa_status_t status = hsa_system_get_info_fn(HSA_SYSTEM_INFO_TIMESTAMP, &sysclock);
|
||||
status == HSA_STATUS_ERROR_NOT_INITIALIZED)
|
||||
return rocprofiler_timestamp_t{0};
|
||||
else if (status != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_system_get_info failed");
|
||||
|
||||
static uint64_t sysclock_period = [&]() {
|
||||
uint64_t sysclock_hz = 0;
|
||||
if (hsa_status_t status =
|
||||
hsa_system_get_info_fn(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &sysclock_hz);
|
||||
status != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_system_get_info failed");
|
||||
|
||||
return (uint64_t)1000000000 / sysclock_hz;
|
||||
}();
|
||||
|
||||
return rocprofiler_timestamp_t{sysclock * sysclock_period};
|
||||
}
|
||||
|
||||
void Initialize_roctracer(HsaApiTable* table) {
|
||||
// Save the HSA core api and amd_ext api.
|
||||
saved_core_api = rocmtools::hsa_support::GetCoreApiTable();
|
||||
saved_amd_ext_api = rocmtools::hsa_support::GetAmdExtTable();
|
||||
hsa_loader_api = rocmtools::hsa_support::GetHSALoaderApi();
|
||||
|
||||
// Enumerate the agents.
|
||||
if (rocmtools::hsa_support::GetCoreApiTable().hsa_iterate_agents_fn(
|
||||
[](hsa_agent_t agent, void* data) {
|
||||
hsa_support::AgentInfo agent_info;
|
||||
if (rocmtools::hsa_support::GetCoreApiTable().hsa_agent_get_info_fn(
|
||||
agent, HSA_AGENT_INFO_DEVICE, &agent_info.type) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_agent_get_info failed");
|
||||
switch (agent_info.type) {
|
||||
case HSA_DEVICE_TYPE_CPU:
|
||||
static int cpu_agent_count = 0;
|
||||
agent_info.id = cpu_agent_count++;
|
||||
break;
|
||||
case HSA_DEVICE_TYPE_GPU: {
|
||||
uint32_t driver_node_id;
|
||||
if (rocmtools::hsa_support::GetCoreApiTable().hsa_agent_get_info_fn(
|
||||
agent, static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_DRIVER_NODE_ID),
|
||||
&driver_node_id) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_agent_get_info failed");
|
||||
|
||||
agent_info.id = driver_node_id;
|
||||
} break;
|
||||
default:
|
||||
static int other_agent_count = 0;
|
||||
agent_info.id = other_agent_count++;
|
||||
break;
|
||||
}
|
||||
hsa_support::agent_info_map.emplace(agent.handle, agent_info);
|
||||
return HSA_STATUS_SUCCESS;
|
||||
},
|
||||
nullptr) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_iterate_agents failed");
|
||||
}
|
||||
|
||||
const char* GetApiName(uint32_t id) { return detail::GetApiName(id); }
|
||||
|
||||
const char* GetEvtName(uint32_t id) {
|
||||
switch (id) {
|
||||
case HSA_EVT_ID_ALLOCATE:
|
||||
return "ALLOCATE";
|
||||
case HSA_EVT_ID_DEVICE:
|
||||
return "DEVICE";
|
||||
case HSA_EVT_ID_MEMCOPY:
|
||||
return "MEMCOPY";
|
||||
case HSA_EVT_ID_SUBMIT:
|
||||
return "SUBMIT";
|
||||
case HSA_EVT_ID_KSYMBOL:
|
||||
return "KSYMBOL";
|
||||
case HSA_EVT_ID_CODEOBJ:
|
||||
return "CODEOBJ";
|
||||
case HSA_EVT_ID_NUMBER:
|
||||
break;
|
||||
}
|
||||
throw ApiError(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT, "invalid HSA EVT callback id");
|
||||
}
|
||||
|
||||
const char* GetOpsName(uint32_t id) {
|
||||
switch (id) {
|
||||
case HSA_OP_ID_DISPATCH:
|
||||
return "DISPATCH";
|
||||
case HSA_OP_ID_COPY:
|
||||
return "COPY";
|
||||
case HSA_OP_ID_BARRIER:
|
||||
return "BARRIER";
|
||||
case HSA_OP_ID_RESERVED1:
|
||||
return "PCSAMPLE";
|
||||
}
|
||||
throw ApiError(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT, "invalid HSA OPS callback id");
|
||||
}
|
||||
|
||||
uint32_t GetApiCode(const char* str) { return detail::GetApiCode(str); }
|
||||
|
||||
void RegisterTracerCallback(int (*function)(activity_domain_t domain, uint32_t operation_id,
|
||||
void* data)) {
|
||||
report_activity.store(function, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
} // namespace roctracer::hsa_support
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
namespace hsa_support {
|
||||
|
||||
hsa_agent_t cpu_agent;
|
||||
std::map<uint32_t, std::unique_ptr<queue::Queue>> queues;
|
||||
std::atomic<uint32_t> active_queues{0};
|
||||
|
||||
/**
|
||||
* @brief This function is a queue create interceptor. It intercepts the queue
|
||||
* creation, registers the profiler, and registers a packet write interceptor.
|
||||
* It also creates a Queue Interceptor object to store the
|
||||
* newly created queue information.
|
||||
**/
|
||||
hsa_status_t QueueCreateInterceptor(hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source,
|
||||
void* data),
|
||||
void* data, uint32_t private_segment_size,
|
||||
uint32_t group_segment_size, hsa_queue_t** queue) {
|
||||
// TODO(aelwazir): Queue ID
|
||||
static std::mutex qc_mutex;
|
||||
std::lock_guard<std::mutex> lk(qc_mutex);
|
||||
queues.emplace(active_queues.fetch_add(1, std::memory_order_release),
|
||||
std::make_unique<queue::Queue>(cpu_agent, agent, size, type, callback, data,
|
||||
private_segment_size, group_segment_size, queue));
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is a queue destroy interceptor. It intercepts the queue
|
||||
* destroy. It deletes the queue entry from the template storage and calls the
|
||||
* hsa_queue_destroy_fn.
|
||||
**/
|
||||
|
||||
hsa_status_t QueueDestroyInterceptor(hsa_queue_t* hsa_queue) {
|
||||
static std::mutex qd_mutex;
|
||||
std::lock_guard<std::mutex> lk(qd_mutex);
|
||||
ASSERTM(GetCoreApiTable().hsa_queue_destroy_fn(hsa_queue) == HSA_STATUS_SUCCESS,
|
||||
"Queue couldn't be destroyed!");
|
||||
queues.erase(active_queues.fetch_sub(1, std::memory_order_release));
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void Initialize(HsaApiTable* table) {
|
||||
InitKsymbols();
|
||||
// Save the HSA core api and amd_ext api.
|
||||
SetCoreApiTable(*table->core_);
|
||||
SetAmdExtTable(table->amd_ext_);
|
||||
// Enumerate the agents.
|
||||
if (GetCoreApiTable().hsa_iterate_agents_fn(
|
||||
[](hsa_agent_t agent, void* data) {
|
||||
Agent::AgentInfo agent_info{agent, &GetCoreApiTable()};
|
||||
static int cpu_agent_count = 0;
|
||||
static int gpu_agent_count = 0;
|
||||
static int other_agent_count = 0;
|
||||
switch (agent_info.getType()) {
|
||||
case HSA_DEVICE_TYPE_CPU:
|
||||
agent_info.setIndex(cpu_agent_count++);
|
||||
cpu_agent = agent;
|
||||
rocmtools::queue::InitializePools(cpu_agent);
|
||||
break;
|
||||
case HSA_DEVICE_TYPE_GPU:
|
||||
// XXX FIXME: When multiple ranks are used, each rank's first
|
||||
// logical device always has GPU ID 0, regardless of which
|
||||
// physical device is selected with CUDA_VISIBLE_DEVICES.
|
||||
// Because of this, when merging traces from multiple ranks,
|
||||
// GPU IDs from different processes may overlap.
|
||||
//
|
||||
// The long term solution is to use KFD's gpu_id, which is
|
||||
// stable across APIs and processes, but it isn't currently
|
||||
// exposed by ROCr. We could use the agent's
|
||||
// HSA_AMD_AGENT_INFO_DRIVER_NODE_ID in the meantime, as even
|
||||
// that would be an improvement--it's what legacy roctracer
|
||||
// is currently doing as well as the roctracer compatibility
|
||||
// code earlier in this file.
|
||||
agent_info.setIndex(gpu_agent_count++);
|
||||
break;
|
||||
default:
|
||||
agent_info.setIndex(other_agent_count++);
|
||||
break;
|
||||
}
|
||||
SetAgentInfo(agent.handle, agent_info);
|
||||
return HSA_STATUS_SUCCESS;
|
||||
},
|
||||
nullptr) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_iterate_agents failed");
|
||||
|
||||
SetHSALoaderApi();
|
||||
|
||||
roctracer::hsa_support::Initialize_roctracer(table);
|
||||
|
||||
// Install the Queue intercept
|
||||
table->core_->hsa_queue_create_fn = QueueCreateInterceptor;
|
||||
table->core_->hsa_queue_destroy_fn = QueueDestroyInterceptor;
|
||||
|
||||
// Install the HSA_OPS intercept
|
||||
table->amd_ext_->hsa_amd_memory_async_copy_fn = roctracer::hsa_support::MemoryASyncCopyIntercept;
|
||||
table->amd_ext_->hsa_amd_memory_async_copy_rect_fn =
|
||||
roctracer::hsa_support::MemoryASyncCopyRectIntercept;
|
||||
table->amd_ext_->hsa_amd_profiling_async_copy_enable_fn =
|
||||
roctracer::hsa_support::ProfilingAsyncCopyEnableIntercept;
|
||||
|
||||
// Install the HSA_EVT intercept
|
||||
table->core_->hsa_memory_allocate_fn = roctracer::hsa_support::MemoryAllocateIntercept;
|
||||
table->core_->hsa_memory_assign_agent_fn = roctracer::hsa_support::MemoryAssignAgentIntercept;
|
||||
table->core_->hsa_memory_copy_fn = roctracer::hsa_support::MemoryCopyIntercept;
|
||||
table->amd_ext_->hsa_amd_memory_pool_allocate_fn =
|
||||
roctracer::hsa_support::MemoryPoolAllocateIntercept;
|
||||
table->amd_ext_->hsa_amd_memory_pool_free_fn = roctracer::hsa_support::MemoryPoolFreeIntercept;
|
||||
table->amd_ext_->hsa_amd_agents_allow_access_fn =
|
||||
roctracer::hsa_support::AgentsAllowAccessIntercept;
|
||||
table->core_->hsa_executable_freeze_fn = roctracer::hsa_support::ExecutableFreezeIntercept;
|
||||
table->core_->hsa_executable_destroy_fn = roctracer::hsa_support::ExecutableDestroyIntercept;
|
||||
|
||||
// Install the HSA_API wrappers
|
||||
roctracer::hsa_support::detail::InstallCoreApiWrappers(table->core_);
|
||||
roctracer::hsa_support::detail::InstallAmdExtWrappers(table->amd_ext_);
|
||||
roctracer::hsa_support::detail::InstallImageExtWrappers(table->image_ext_);
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
while (active_queues.load(std::memory_order_relaxed) != 0) {
|
||||
}
|
||||
|
||||
// FinitKsymbols();
|
||||
ResetMaps();
|
||||
}
|
||||
|
||||
static std::map<uint64_t, rocmtools::MetricsDict*> metricsDicts;
|
||||
|
||||
bool IterateCounters(rocprofiler_counters_info_callback_t counters_info_callback) {
|
||||
if (GetCoreApiTable().hsa_iterate_agents_fn(
|
||||
[](hsa_agent_t agent, void* data) {
|
||||
Agent::AgentInfo agent_info{agent, &GetCoreApiTable()};
|
||||
if (agent_info.getType() == HSA_DEVICE_TYPE_GPU) {
|
||||
metricsDicts.emplace(agent.handle, rocmtools::MetricsDict::Create(&agent_info));
|
||||
}
|
||||
return HSA_STATUS_SUCCESS;
|
||||
},
|
||||
nullptr) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_iterate_agents failed");
|
||||
uint32_t gpu_counter = 0;
|
||||
for (auto metricsDictAgent : metricsDicts) {
|
||||
rocmtools::MetricsDict* metricsDict = metricsDictAgent.second;
|
||||
std::string gpu_name = metricsDict->GetAgentName();
|
||||
auto nodes_vec = metricsDict->GetNodes();
|
||||
|
||||
for (auto* node : nodes_vec) {
|
||||
const std::string& name = node->opts["name"];
|
||||
const std::string& descr = node->opts["descr"];
|
||||
const std::string& expr = node->opts["expr"];
|
||||
// Getting the block name
|
||||
const std::string block_name = node->opts["block"];
|
||||
uint32_t block_counters = 0;
|
||||
|
||||
hsa_ven_amd_aqlprofile_id_query_t query;
|
||||
|
||||
if (expr.empty()) {
|
||||
// Querying profile
|
||||
hsa_ven_amd_aqlprofile_profile_t profile = {};
|
||||
profile.agent = hsa_agent_t{metricsDictAgent.first};
|
||||
profile.type = HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_PMC;
|
||||
|
||||
// Query block id info
|
||||
query = {block_name.c_str(), 0, 0};
|
||||
hsa_status_t status =
|
||||
hsa_ven_amd_aqlprofile_get_info(&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_ID, &query);
|
||||
if (status != HSA_STATUS_SUCCESS)
|
||||
AQL_EXC_RAISING(HSA_STATUS_ERROR, "get block id info: '" << block_name << "'");
|
||||
|
||||
// Metric object
|
||||
const std::string metric_name = (query.instance_count > 1) ? name + "[0]" : name;
|
||||
const Metric* metric = metricsDict->Get(metric_name);
|
||||
if (metric == NULL) EXC_RAISING(HSA_STATUS_ERROR, "metric '" << name << "' is not found");
|
||||
|
||||
// Process metrics counters
|
||||
const counters_vec_t& counters_vec = metric->GetCounters();
|
||||
if (counters_vec.size() != 1)
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "error: '" << metric->GetName() << "' is not basic");
|
||||
|
||||
// Query block counters number
|
||||
profile.events = &(counters_vec[0]->event);
|
||||
status = hsa_ven_amd_aqlprofile_get_info(
|
||||
&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS, &block_counters);
|
||||
if (status != HSA_STATUS_SUCCESS) continue;
|
||||
}
|
||||
|
||||
const rocprofiler_counter_info_t counter_info =
|
||||
rocprofiler_counter_info_t{strdup(name.c_str()),
|
||||
strdup(descr.c_str()),
|
||||
expr.empty() ? nullptr : strdup(expr.c_str()),
|
||||
query.instance_count,
|
||||
block_name.c_str(),
|
||||
block_counters};
|
||||
counters_info_callback(counter_info, gpu_name.c_str(), gpu_counter);
|
||||
}
|
||||
gpu_counter++;
|
||||
|
||||
// auto start = metricsDict->Begin();
|
||||
// while (start != metricsDict->End()) {
|
||||
// const xml::Expr* expr = start->second->GetExpr();
|
||||
// std::string expr_str;
|
||||
// if (expr) expr_str = expr->GetStr().c_str();
|
||||
// const rocprofiler_counter_info_t counter_info =
|
||||
// rocprofiler_counter_info_t{start->first.c_str(), "", expr ? expr_str.c_str() : nullptr};
|
||||
// counters_info_callback(counter_info, gpu_name.c_str(), gpu_counter);
|
||||
// start++;
|
||||
// }
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace hsa_support
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,136 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_HSA_HSA_SUPPORT_H_
|
||||
#define SRC_CORE_HSA_HSA_SUPPORT_H_
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_api_trace.h>
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
#include <hsa/hsa_ven_amd_loader.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
#include "hsa_common.h"
|
||||
#include "src/core/hardware/hsa_info.h"
|
||||
|
||||
// HSA EVT data type
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
const void* ptr; // allocated area ptr
|
||||
size_t size; // allocated area size, zero size means 'free' callback
|
||||
hsa_amd_segment_t segment; // allocated area's memory segment type
|
||||
hsa_amd_memory_pool_global_flag_t global_flag; // allocated area's memory global flag
|
||||
int is_code; // equal to 1 if code is allocated
|
||||
} allocate;
|
||||
|
||||
struct {
|
||||
hsa_device_type_t type; // type of assigned device
|
||||
uint32_t id; // id of assigned device
|
||||
hsa_agent_t agent; // device HSA agent handle
|
||||
const void* ptr; // ptr the device is assigned to
|
||||
} device;
|
||||
|
||||
struct {
|
||||
const void* dst; // memcopy dst ptr
|
||||
const void* src; // memcopy src ptr
|
||||
size_t size; // memcopy size bytes
|
||||
} memcopy;
|
||||
|
||||
struct {
|
||||
const void* packet; // submitted to GPU packet
|
||||
const char* kernel_name; // kernel name, NULL if not a kernel dispatch packet
|
||||
hsa_queue_t* queue; // HSA queue the packet was submitted to
|
||||
uint32_t device_type; // type of device the packet is submitted to
|
||||
uint32_t device_id; // id of device the packet is submitted to
|
||||
} submit;
|
||||
|
||||
struct {
|
||||
uint64_t object; // kernel symbol object
|
||||
const char* name; // kernel symbol name
|
||||
uint32_t name_length; // kernel symbol name length
|
||||
int unload; // symbol executable destroy
|
||||
} ksymbol;
|
||||
|
||||
struct {
|
||||
uint32_t storage_type; // code object storage type
|
||||
int storage_file; // origin file descriptor
|
||||
uint64_t memory_base; // origin memory base
|
||||
uint64_t memory_size; // origin memory size
|
||||
uint64_t load_base; // code object load base
|
||||
uint64_t load_size; // code object load size
|
||||
uint64_t load_delta; // code object load size
|
||||
uint32_t uri_length; // URI string length (not including the terminating
|
||||
// NUL character)
|
||||
const char* uri; // URI string
|
||||
hsa_agent_t agent; // device HSA agent handle
|
||||
int unload; // unload flag
|
||||
} codeobj;
|
||||
};
|
||||
|
||||
} hsa_evt_data_t;
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
namespace hsa_support {
|
||||
|
||||
void Initialize(HsaApiTable* Table);
|
||||
hsa_status_t hsa_iterate_agents_cb(hsa_agent_t agent, void *data);
|
||||
void Finalize();
|
||||
|
||||
bool IterateCounters(rocprofiler_counters_info_callback_t counters_info_callback);
|
||||
|
||||
} // namespace hsa_support
|
||||
} // namespace rocmtools
|
||||
|
||||
#include "src/core/session/tracer/src/roctracer.h"
|
||||
|
||||
namespace roctracer::hsa_support {
|
||||
|
||||
struct hsa_trace_data_t {
|
||||
hsa_api_data_t api_data;
|
||||
uint64_t phase_enter_timestamp;
|
||||
uint64_t phase_data;
|
||||
|
||||
void (*phase_enter)(hsa_api_id_t operation_id, hsa_trace_data_t* data);
|
||||
void (*phase_exit)(hsa_api_id_t operation_id, hsa_trace_data_t* data);
|
||||
};
|
||||
|
||||
void Initialize(HsaApiTable* table);
|
||||
void Finalize();
|
||||
|
||||
const char* GetApiName(uint32_t id);
|
||||
const char* GetEvtName(uint32_t id);
|
||||
const char* GetOpsName(uint32_t id);
|
||||
uint32_t GetApiCode(const char* str);
|
||||
|
||||
void RegisterTracerCallback(int (*function)(rocprofiler_tracer_activity_domain_t domain,
|
||||
uint32_t operation_id, void* data));
|
||||
rocprofiler_timestamp_t timestamp_ns();
|
||||
|
||||
void Initialize_roctracer(HsaApiTable* table);
|
||||
|
||||
|
||||
} // namespace roctracer::hsa_support
|
||||
|
||||
#endif // SRC_CORE_HSA_HSA_SUPPORT_H_
|
||||
@@ -0,0 +1,489 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "packets_generator.h"
|
||||
#include "src/api/rocmtool.h"
|
||||
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "src/core/counters/basic/basic_counter.h"
|
||||
#include "src/utils/exception.h"
|
||||
#include "src/utils/logger.h"
|
||||
#include "src/core/hsa/hsa_common.h"
|
||||
|
||||
#include "src/core/counters/metrics/metrics.h"
|
||||
|
||||
|
||||
#define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
#define CHECK_HSA_STATUS(msg, status) \
|
||||
do { \
|
||||
if ((status) != HSA_STATUS_INFO_BREAK) { \
|
||||
const char* emsg = 0; \
|
||||
hsa_status_string(status, &emsg); \
|
||||
printf("%s: %s\n", msg, emsg ? emsg : "<unknown error>"); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
namespace Packet {
|
||||
|
||||
static const size_t MEM_PAGE_BYTES = 0x1000;
|
||||
static const size_t MEM_PAGE_MASK = MEM_PAGE_BYTES - 1;
|
||||
hsa_amd_memory_pool_t command_pool;
|
||||
hsa_amd_memory_pool_t output_pool;
|
||||
|
||||
hsa_amd_memory_pool_t& GetCommandPool() { return command_pool; }
|
||||
hsa_amd_memory_pool_t& GetOutputPool() { return output_pool; }
|
||||
|
||||
// This function checks to see if the provided
|
||||
// pool has the HSA_AMD_SEGMENT_GLOBAL property. If the kern_arg flag is true,
|
||||
// the function adds an additional requirement that the pool have the
|
||||
// HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT property. If kern_arg is false,
|
||||
// pools must NOT have this property.
|
||||
// Upon finding a pool that meets these conditions, HSA_STATUS_INFO_BREAK is
|
||||
// returned. HSA_STATUS_SUCCESS is returned if no errors were encountered, but
|
||||
// no pool was found meeting the requirements. If an error is encountered, we
|
||||
// return that error.
|
||||
static hsa_status_t FindGlobalPool(hsa_amd_memory_pool_t pool, void* data, bool kern_arg) {
|
||||
[[maybe_unused]] hsa_status_t err;
|
||||
hsa_amd_segment_t segment;
|
||||
uint32_t flag;
|
||||
if (nullptr == data) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
err = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_get_info_fn(
|
||||
pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);
|
||||
ASSERTM(err != HSA_STATUS_ERROR, "hsa_amd_memory_pool_get_info");
|
||||
if (HSA_AMD_SEGMENT_GLOBAL != segment) {
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
err = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_get_info_fn(
|
||||
pool, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flag);
|
||||
ASSERTM(err != HSA_STATUS_ERROR, "hsa_amd_memory_pool_get_info");
|
||||
uint32_t karg_st = flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT;
|
||||
if ((karg_st == 0 && kern_arg) || (karg_st != 0 && !kern_arg)) {
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
*(reinterpret_cast<hsa_amd_memory_pool_t*>(data)) = pool;
|
||||
return HSA_STATUS_INFO_BREAK;
|
||||
}
|
||||
|
||||
// This is the call-back function for hsa_amd_agent_iterate_memory_pools() that
|
||||
// finds a pool with the properties of HSA_AMD_SEGMENT_GLOBAL and that is NOT
|
||||
// HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT
|
||||
hsa_status_t FindStandardPool(hsa_amd_memory_pool_t pool, void* data) {
|
||||
return FindGlobalPool(pool, data, false);
|
||||
}
|
||||
|
||||
// This is the call-back function for hsa_amd_agent_iterate_memory_pools() that
|
||||
// finds a pool with the properties of HSA_AMD_SEGMENT_GLOBAL and that IS
|
||||
// HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT
|
||||
hsa_status_t FindKernArgPool(hsa_amd_memory_pool_t pool, void* data) {
|
||||
return FindGlobalPool(pool, data, true);
|
||||
}
|
||||
|
||||
void InitializePools(hsa_agent_t cpu_agent) {
|
||||
hsa_status_t status =
|
||||
rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agent_iterate_memory_pools_fn(
|
||||
cpu_agent, FindStandardPool, &command_pool);
|
||||
if ((status != HSA_STATUS_INFO_BREAK)) printf("Error: Command Buffer Pool is not initialized\n");
|
||||
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agent_iterate_memory_pools_fn(
|
||||
cpu_agent, FindKernArgPool, &output_pool);
|
||||
if ((status != HSA_STATUS_INFO_BREAK)) printf("Error: Output Buffer Pool is not initialized\n");
|
||||
}
|
||||
|
||||
struct block_des_t {
|
||||
uint32_t id;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
// Initialize the PM4 commands with having the CPU&GPU agents, the counters,
|
||||
// counters count to output three packets which are start, stop and read
|
||||
// packets
|
||||
std::vector<std::pair<rocmtools::profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*>>*
|
||||
InitializeAqlPackets(hsa_agent_t cpu_agent, hsa_agent_t gpu_agent,
|
||||
std::vector<std::string>& counter_names, bool is_spm) {
|
||||
hsa_status_t status = HSA_STATUS_SUCCESS;
|
||||
|
||||
Agent::AgentInfo& agentInfo = rocmtools::hsa_support::GetAgentInfo(gpu_agent.handle);
|
||||
// get the instance of MetricsDict
|
||||
rocmtools::MetricsDict* metricsDict = rocmtools::MetricsDict::Create(&agentInfo);
|
||||
std::map<std::string, rocmtools::results_t*> results_map;
|
||||
std::vector<rocmtools::event_t> events_list;
|
||||
std::vector<rocmtools::results_t*> results_list;
|
||||
std::map<std::pair<uint32_t, uint32_t>, uint64_t> event_to_max_block_count;
|
||||
std::map<std::string, std::set<std::string>> metrics_counters;
|
||||
uint32_t counters_count = 0;
|
||||
|
||||
for (auto& name : counter_names) {
|
||||
// std::cout << "Counter from Counter Names: " << name << std::endl;
|
||||
|
||||
if (rocmtools::GetROCMToolObj()->HasActiveSession()) {
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession(rocmtools::GetROCMToolObj()->GetCurrentSessionId())
|
||||
->GetProfiler()
|
||||
->AddCounterName(name);
|
||||
}
|
||||
|
||||
counters_count++;
|
||||
}
|
||||
|
||||
rocmtools::metrics::ExtractMetricEvents(counter_names, gpu_agent, metricsDict, results_map,
|
||||
events_list, results_list, event_to_max_block_count,
|
||||
metrics_counters);
|
||||
|
||||
// TODO: validate needs to be called on each events_list[i]
|
||||
// Validating the events array for the specified gpu agent
|
||||
bool result;
|
||||
hsa_ven_amd_aqlprofile_validate_event(gpu_agent, &events_list[0], &result);
|
||||
if (!result) {
|
||||
printf("Error: Events are not valid for the current gpu agent\n");
|
||||
throw("Error: Events are not valid for the current gpu agent");
|
||||
}
|
||||
|
||||
// std::cout << "Max Block Counters: " << max_block_counters << std::endl;
|
||||
|
||||
std::vector<std::pair<rocmtools::profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*>>*
|
||||
profiles = new std::vector<
|
||||
std::pair<rocmtools::profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*>>();
|
||||
|
||||
do {
|
||||
rocmtools::profiling_context_t* context = new rocmtools::profiling_context_t();
|
||||
context->gpu_agent = gpu_agent;
|
||||
uint64_t i = 0;
|
||||
uint32_t counter_val_iteration = 0;
|
||||
auto result = results_list.begin();
|
||||
std::map<std::pair<uint32_t, uint32_t>, uint32_t> block_max_events_count;
|
||||
std::set<hsa_ven_amd_aqlprofile_block_name_t> block_names_taken;
|
||||
for (auto event = events_list.begin(); event != events_list.end();) {
|
||||
if (block_max_events_count[std::make_pair<uint32_t, uint32_t>(
|
||||
static_cast<uint32_t>(event->block_name),
|
||||
static_cast<uint32_t>(event->block_index))] <
|
||||
event_to_max_block_count[std::make_pair<uint32_t, uint32_t>(
|
||||
static_cast<uint32_t>(event->block_name),
|
||||
static_cast<uint32_t>(event->block_index))]) {
|
||||
context->events_list.push_back(*event);
|
||||
context->results_list.emplace_back(*result);
|
||||
counter_val_iteration++;
|
||||
block_max_events_count[std::make_pair<uint32_t, uint32_t>(
|
||||
static_cast<uint32_t>(event->block_name), static_cast<uint32_t>(event->block_index))]++;
|
||||
// std::cout << "Block Name: " << event->block_name << " Block Index: " <<
|
||||
// event->block_index
|
||||
// << " Current Count: "
|
||||
// << block_max_events_count[std::make_pair<uint32_t, uint32_t>(
|
||||
// static_cast<uint32_t>(event->block_name),
|
||||
// static_cast<uint32_t>(event->block_index))]
|
||||
// << std::endl;
|
||||
// std::cout << "Counter Taken: " << event->block_index << ", " << event->counter_id << " "
|
||||
// << block_max_events_count[std::make_pair<uint32_t, uint32_t>(
|
||||
// static_cast<uint32_t>(event->block_name),
|
||||
// static_cast<uint32_t>(event->block_index))]
|
||||
// << ":"
|
||||
// << event_to_max_block_count[std::make_pair<uint32_t, uint32_t>(
|
||||
// static_cast<uint32_t>(event->block_name),
|
||||
// static_cast<uint32_t>(event->block_index))]
|
||||
// << std::endl;
|
||||
results_list.erase(result);
|
||||
events_list.erase(event);
|
||||
} else {
|
||||
// std::cout << "Counter Left: " << event->block_index << ", " << event->counter_id
|
||||
// << std::endl;
|
||||
event++;
|
||||
result++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
std::set<std::string> counters_taken;
|
||||
|
||||
std::set<std::string> metrics_counters_taken;
|
||||
|
||||
for (auto result : context->results_list) {
|
||||
rocmtools::Metric* metric;
|
||||
if (std::find(counter_names.begin(), counter_names.end(), result->name) !=
|
||||
counter_names.end()) {
|
||||
// std::cout << "Counter from Result List: " << result->name << std::endl;
|
||||
counters_taken.insert(result->name);
|
||||
metric = const_cast<rocmtools::Metric*>(metricsDict->Get(result->name));
|
||||
if (metric == nullptr) std::cout << result->name << " not found in metricsDict\n";
|
||||
context->metrics_list.push_back(metric);
|
||||
} else {
|
||||
metrics_counters_taken.insert(result->name);
|
||||
// std::cout << "Counter Added: " << result->name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> metrics_taken;
|
||||
|
||||
for (auto result : results_map) {
|
||||
if (counters_taken.find(result.first) == counters_taken.end() &&
|
||||
std::find(counter_names.begin(), counter_names.end(), result.first) !=
|
||||
counter_names.end()) {
|
||||
bool flag = true;
|
||||
for (auto result_basic : results_list) {
|
||||
if (result_basic->name.compare(result.first)) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) metrics_taken.insert(result.first);
|
||||
// std::cout << "Metric to be checked from map: " << result.first << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto metric_name : metrics_taken) {
|
||||
bool flag = true;
|
||||
if (metrics_counters.find(metric_name) == metrics_counters.end()) continue;
|
||||
for (auto metric_counter_name : metrics_counters.at(metric_name)) {
|
||||
if (metrics_counters_taken.find(metric_counter_name) == metrics_counters_taken.end() &&
|
||||
counters_taken.find(metric_counter_name) == counters_taken.end()) {
|
||||
// std::cout << metric_counter_name << " for " << metric_name << " is not found!"
|
||||
// << std::endl;
|
||||
flag = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
// std::cout << "Counter from Result Map: " << metric_name << std::endl;
|
||||
counters_taken.insert(metric_name);
|
||||
rocmtools::Metric* metric = const_cast<rocmtools::Metric*>(metricsDict->Get(metric_name));
|
||||
if (metric == nullptr) std::cout << metric_name << " not found in metricsDict\n";
|
||||
context->metrics_list.push_back(metric);
|
||||
}
|
||||
}
|
||||
|
||||
context->results_map = results_map;
|
||||
context->metrics_dict = metricsDict;
|
||||
|
||||
hsa_ven_amd_aqlprofile_parameter_t* params = {};
|
||||
|
||||
packet_t* start_packet = new packet_t();
|
||||
packet_t* stop_packet = new packet_t();
|
||||
packet_t* read_packet = new packet_t();
|
||||
|
||||
if (context->events_list.size() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Preparing the profile structure to get the packets
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wconversion-null"
|
||||
hsa_ven_amd_aqlprofile_event_type_t profile_type = HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_PMC;
|
||||
if (is_spm) profile_type = HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_TRACE;
|
||||
hsa_ven_amd_aqlprofile_profile_t* profile =
|
||||
new hsa_ven_amd_aqlprofile_profile_t{gpu_agent,
|
||||
profile_type,
|
||||
&(context->events_list[0]),
|
||||
static_cast<uint32_t>(context->events_list.size()),
|
||||
params,
|
||||
0,
|
||||
NULL,
|
||||
NULL};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// Preparing an Getting the size of the command and output buffers
|
||||
status = hsa_ven_amd_aqlprofile_start(profile, NULL);
|
||||
if (status != HSA_STATUS_SUCCESS) {
|
||||
const char* hsa_err_str = nullptr;
|
||||
if (hsa_status_string(status, &hsa_err_str) != HSA_STATUS_SUCCESS) hsa_err_str = "Unknown";
|
||||
printf("Error: %s\n", hsa_err_str);
|
||||
continue;
|
||||
} else {
|
||||
status = HSA_STATUS_ERROR;
|
||||
size_t size = profile->command_buffer.size;
|
||||
size = (size + MEM_PAGE_MASK) & ~MEM_PAGE_MASK;
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_allocate_fn(
|
||||
command_pool, size, 0, reinterpret_cast<void**>(&(profile->command_buffer.ptr)));
|
||||
|
||||
// Both the CPU and GPU can access the memory
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
hsa_agent_t ag_list[1] = {gpu_agent};
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agents_allow_access_fn(
|
||||
1, ag_list, NULL, profile->command_buffer.ptr);
|
||||
|
||||
if (status != HSA_STATUS_SUCCESS) {
|
||||
printf("Error: Can't allow access for both agents to Command Buffer\n");
|
||||
continue;
|
||||
} else if (status == HSA_STATUS_ERROR_OUT_OF_RESOURCES) {
|
||||
printf("Error: Ran out of GPU memory to allocate Command Buffer\n");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const char* hsa_err_str = NULL;
|
||||
if (hsa_status_string(status, &hsa_err_str) != HSA_STATUS_SUCCESS) hsa_err_str = "Unknown";
|
||||
printf("Error: Allocating command Buffer (Size=%lu) (%s)\n", size, hsa_err_str);
|
||||
}
|
||||
|
||||
if (!is_spm) {
|
||||
status = HSA_STATUS_ERROR;
|
||||
size = profile->output_buffer.size;
|
||||
size = (size + MEM_PAGE_MASK) & ~MEM_PAGE_MASK;
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_allocate_fn(
|
||||
output_pool, size, 0, reinterpret_cast<void**>(&profile->output_buffer.ptr));
|
||||
|
||||
if (status == HSA_STATUS_ERROR_OUT_OF_RESOURCES) {
|
||||
printf("Error: Ran out of GPU memory to allocate Output Buffer\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
hsa_agent_t ag_list[1] = {gpu_agent};
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agents_allow_access_fn(
|
||||
1, ag_list, NULL, profile->output_buffer.ptr);
|
||||
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
memset(profile->output_buffer.ptr, 0x0, profile->output_buffer.size);
|
||||
|
||||
// Creating the start/stop/read packets
|
||||
status = hsa_ven_amd_aqlprofile_start(profile, start_packet);
|
||||
status = hsa_ven_amd_aqlprofile_stop(profile, stop_packet);
|
||||
status = hsa_ven_amd_aqlprofile_read(profile, read_packet);
|
||||
|
||||
context->start_packet = start_packet;
|
||||
context->stop_packet = stop_packet;
|
||||
context->read_packet = read_packet;
|
||||
|
||||
// add profiles
|
||||
profiles->emplace_back(std::make_pair(context, profile));
|
||||
} else {
|
||||
printf("Error: Can't allow access for both agents to output Buffer\n");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const char* hsa_err_str = NULL;
|
||||
if (hsa_status_string(status, &hsa_err_str) != HSA_STATUS_SUCCESS)
|
||||
hsa_err_str = "Unknown";
|
||||
printf("Error: Allocating output Buffer (%s)\n", hsa_err_str);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
profile->output_buffer.size = 0;
|
||||
status = hsa_ven_amd_aqlprofile_start(profile, start_packet);
|
||||
status = hsa_ven_amd_aqlprofile_stop(profile, stop_packet);
|
||||
status = hsa_ven_amd_aqlprofile_read(profile, read_packet);
|
||||
|
||||
context->start_packet = start_packet;
|
||||
context->stop_packet = stop_packet;
|
||||
context->read_packet = read_packet;
|
||||
|
||||
// add profiles
|
||||
profiles->emplace_back(std::make_pair(context, profile));
|
||||
}
|
||||
}
|
||||
} while (events_list.size() > 0);
|
||||
return profiles;
|
||||
}
|
||||
|
||||
// Initialize the PM4 commands with having the CPU&GPU agents, the counters,
|
||||
// counters count to output three packets which are start, stop and read
|
||||
// packets
|
||||
hsa_ven_amd_aqlprofile_profile_t* InitializeDeviceProfilingAqlPackets(
|
||||
hsa_agent_t cpu_agent, hsa_agent_t gpu_agent, hsa_ven_amd_aqlprofile_event_t* events,
|
||||
uint32_t event_count, packet_t* start_packet, packet_t* stop_packet, packet_t* read_packet) {
|
||||
hsa_status_t status = HSA_STATUS_SUCCESS;
|
||||
|
||||
// Validating the events array for the specified gpu agent
|
||||
bool result;
|
||||
hsa_ven_amd_aqlprofile_validate_event(gpu_agent, events, &result);
|
||||
if (!result) {
|
||||
printf("Error: Events are not valid for the current gpu agent\n");
|
||||
throw("Error: Events are not valid for the current gpu agent");
|
||||
}
|
||||
|
||||
hsa_ven_amd_aqlprofile_parameter_t* params = {};
|
||||
uint8_t* command_buffer = nullptr;
|
||||
uint8_t* output_buffer = nullptr;
|
||||
|
||||
|
||||
// Preparing the profile structure to get the packets
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wconversion-null"
|
||||
hsa_ven_amd_aqlprofile_profile_t* profile = new hsa_ven_amd_aqlprofile_profile_t{
|
||||
gpu_agent, HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_PMC, events, event_count, params, 0, NULL, NULL};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// Preparing an Getting the size of the command and output buffers
|
||||
status = hsa_ven_amd_aqlprofile_start(profile, NULL);
|
||||
|
||||
// Preparing and Initializing bool of buffers for command and output buffers
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agent_iterate_memory_pools_fn(
|
||||
cpu_agent, FindStandardPool, &command_pool);
|
||||
if ((status != HSA_STATUS_INFO_BREAK)) printf("Error: Command Buffer Pool is not initialized\n");
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agent_iterate_memory_pools_fn(
|
||||
cpu_agent, FindKernArgPool, &output_pool);
|
||||
if ((status != HSA_STATUS_INFO_BREAK)) printf("Error: Output Buffer Pool is not initialized\n");
|
||||
|
||||
// Allocating Command Buffer
|
||||
status = HSA_STATUS_ERROR;
|
||||
size_t size = profile->command_buffer.size;
|
||||
size = (size + MEM_PAGE_MASK) & ~MEM_PAGE_MASK;
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_allocate_fn(
|
||||
command_pool, size, 0, reinterpret_cast<void**>(&command_buffer));
|
||||
// Both the CPU and GPU can access the memory
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
hsa_agent_t ag_list[1] = {gpu_agent};
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agents_allow_access_fn(
|
||||
1, ag_list, NULL, command_buffer);
|
||||
}
|
||||
profile->command_buffer.ptr = (status == HSA_STATUS_SUCCESS) ? command_buffer : nullptr;
|
||||
if (status != HSA_STATUS_SUCCESS) printf("Error: Allocating Command Buffer\n");
|
||||
|
||||
// Allocating Output Buffer
|
||||
status = HSA_STATUS_ERROR;
|
||||
size = profile->output_buffer.size;
|
||||
size = (size + MEM_PAGE_MASK) & ~MEM_PAGE_MASK;
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_allocate_fn(
|
||||
output_pool, size, 0, reinterpret_cast<void**>(&output_buffer));
|
||||
// Both the CPU and GPU can access the kernel arguments
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
hsa_agent_t ag_list[1] = {gpu_agent};
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agents_allow_access_fn(
|
||||
1, ag_list, NULL, output_buffer);
|
||||
}
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
profile->output_buffer.ptr = output_buffer;
|
||||
memset(profile->output_buffer.ptr, 0x0, profile->output_buffer.size);
|
||||
} else {
|
||||
profile->output_buffer.ptr = nullptr;
|
||||
}
|
||||
|
||||
// Creating the start/stop/read packets
|
||||
status = hsa_ven_amd_aqlprofile_start(profile, start_packet);
|
||||
status = hsa_ven_amd_aqlprofile_stop(profile, stop_packet);
|
||||
status = hsa_ven_amd_aqlprofile_read(profile, read_packet);
|
||||
|
||||
if (status == HSA_STATUS_ERROR) return nullptr;
|
||||
return profile;
|
||||
}
|
||||
|
||||
} // namespace Packet
|
||||
@@ -0,0 +1,59 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
#ifndef SRC_CORE_HSA_PACKETS_PACKETS_GENERATOR_H_
|
||||
#define SRC_CORE_HSA_PACKETS_PACKETS_GENERATOR_H_
|
||||
|
||||
#include "inc/rocprofiler.h"
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_api_trace.h>
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
#include <hsa/hsa_ven_amd_loader.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
#include "src/core/counters/metrics/eval_metrics.h"
|
||||
|
||||
namespace Packet {
|
||||
|
||||
static std::mutex pool_lock;
|
||||
|
||||
typedef hsa_ext_amd_aql_pm4_packet_t packet_t;
|
||||
|
||||
std::vector<std::pair<rocmtools::profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*>>*
|
||||
InitializeAqlPackets(hsa_agent_t cpu_agent, hsa_agent_t gpu_agent,
|
||||
std::vector<std::string>& counter_names, bool is_spm = false);
|
||||
uint8_t* AllocateSysMemory(hsa_agent_t gpu_agent, size_t size, hsa_amd_memory_pool_t* cpu_pool);
|
||||
void GetCommandBufferMap(std::map<size_t, uint8_t*>);
|
||||
void GetOutputBufferMap(std::map<size_t, uint8_t*>);
|
||||
void InitializePools(hsa_agent_t cpu_agent);
|
||||
hsa_ven_amd_aqlprofile_profile_t* InitializeDeviceProfilingAqlPackets(
|
||||
hsa_agent_t cpu_agent, hsa_agent_t gpu_agent, hsa_ven_amd_aqlprofile_event_t* events,
|
||||
uint32_t event_count, packet_t* start_packet, packet_t* stop_packet, packet_t* read_packet);
|
||||
hsa_amd_memory_pool_t& GetCommandPool();
|
||||
hsa_amd_memory_pool_t& GetOutputPool();
|
||||
|
||||
|
||||
} // namespace Packet
|
||||
#endif // SRC_CORE_HSA_PACKETS_PACKETS_GENERATOR_H_
|
||||
@@ -0,0 +1,705 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
#include "rocprofiler.h"
|
||||
#include "src/api/rocmtool.h"
|
||||
#include "src/core/hsa/packets/packets_generator.h"
|
||||
#include "src/core/hsa/hsa_support.h"
|
||||
#include "src/utils/helper.h"
|
||||
|
||||
#define __NR_gettid 186
|
||||
std::mutex sessions_pending_signal_lock;
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
std::atomic<uint32_t> ACTIVE_INTERRUPT_SIGNAL_COUNT{0};
|
||||
|
||||
uint32_t GetCurrentActiveInterruptSignalsCount() {
|
||||
return ACTIVE_INTERRUPT_SIGNAL_COUNT.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
typedef std::vector<hsa_ven_amd_aqlprofile_info_data_t> pmc_callback_data_t;
|
||||
|
||||
static inline bool IsEventMatch(const hsa_ven_amd_aqlprofile_event_t& event1,
|
||||
const hsa_ven_amd_aqlprofile_event_t& event2) {
|
||||
return (event1.block_name == event2.block_name) && (event1.block_index == event2.block_index) &&
|
||||
(event1.counter_id == event2.counter_id);
|
||||
}
|
||||
|
||||
static std::mutex ksymbol_map_lock;
|
||||
static std::map<uint64_t, std::string>* ksymbols;
|
||||
static std::atomic<bool> ksymbols_flag{true};
|
||||
void AddKernelName(uint64_t handle, std::string name) {
|
||||
std::lock_guard<std::mutex> lock(ksymbol_map_lock);
|
||||
ksymbols->emplace(handle, name);
|
||||
}
|
||||
std::string GetKernelNameFromKsymbols(uint64_t handle) {
|
||||
std::lock_guard<std::mutex> lock(ksymbol_map_lock);
|
||||
return ksymbols->at(handle);
|
||||
}
|
||||
void InitKsymbols() {
|
||||
if (ksymbols_flag.load(std::memory_order_relaxed)) {
|
||||
std::lock_guard<std::mutex> lock(ksymbol_map_lock);
|
||||
ksymbols = new std::map<uint64_t, std::string>();
|
||||
ksymbols_flag.exchange(false, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
void FinitKsymbols() {
|
||||
if (!ksymbols_flag.load(std::memory_order_relaxed)) {
|
||||
std::lock_guard<std::mutex> lock(ksymbol_map_lock);
|
||||
ksymbols->clear();
|
||||
delete ksymbols;
|
||||
ksymbols_flag.exchange(true, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
struct kernel_descriptor_t {
|
||||
uint8_t reserved0[16];
|
||||
int64_t kernel_code_entry_byte_offset;
|
||||
uint8_t reserved1[20];
|
||||
uint32_t compute_pgm_rsrc3;
|
||||
uint32_t compute_pgm_rsrc1;
|
||||
uint32_t compute_pgm_rsrc2;
|
||||
uint16_t kernel_code_properties;
|
||||
uint8_t reserved2[6];
|
||||
};
|
||||
// AMD Compute Program Resource Register Three.
|
||||
typedef uint32_t amd_compute_pgm_rsrc_three32_t;
|
||||
enum amd_compute_gfx9_pgm_rsrc_three_t {
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_THREE_ACCUM_OFFSET, 0, 5),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_THREE_TG_SPLIT, 16, 1)
|
||||
};
|
||||
enum amd_compute_gfx10_gfx11_pgm_rsrc_three_t {
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_THREE_SHARED_VGPR_COUNT, 0, 4),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_THREE_INST_PREF_SIZE, 4, 6),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_THREE_TRAP_ON_START, 10, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_THREE_TRAP_ON_END, 11, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_THREE_IMAGE_OP, 31, 1)
|
||||
};
|
||||
|
||||
// Kernel code properties.
|
||||
enum amd_kernel_code_property_t {
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER, 0,
|
||||
1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, 1, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, 2, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR, 3, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, 4, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT, 5, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE, 6, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_RESERVED0, 7, 3),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, 10,
|
||||
1), // GFX10+
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, 11, 1),
|
||||
AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTY_RESERVED1, 12, 4),
|
||||
};
|
||||
|
||||
static const kernel_descriptor_t* GetKernelCode(uint64_t kernel_object) {
|
||||
const kernel_descriptor_t* kernel_code = NULL;
|
||||
hsa_status_t status = hsa_support::GetHSALoaderApi().hsa_ven_amd_loader_query_host_address(
|
||||
reinterpret_cast<const void*>(kernel_object), reinterpret_cast<const void**>(&kernel_code));
|
||||
if (HSA_STATUS_SUCCESS != status) {
|
||||
kernel_code = reinterpret_cast<kernel_descriptor_t*>(kernel_object);
|
||||
}
|
||||
return kernel_code;
|
||||
}
|
||||
|
||||
static uint32_t arch_vgpr_count(Agent::AgentInfo& info, const kernel_descriptor_t& kernel_code) {
|
||||
const std::string_view& name = info.getName();
|
||||
std::string info_name(name.data(), name.size());
|
||||
if (strcmp(name.data(), "gfx90a") == 0 || strcmp(name.data(), "gfx940") == 0)
|
||||
return (AMD_HSA_BITS_GET(kernel_code.compute_pgm_rsrc3,
|
||||
AMD_COMPUTE_PGM_RSRC_THREE_ACCUM_OFFSET) +
|
||||
1) *
|
||||
4;
|
||||
|
||||
return (AMD_HSA_BITS_GET(kernel_code.compute_pgm_rsrc1,
|
||||
AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WORKITEM_VGPR_COUNT) +
|
||||
1) *
|
||||
(AMD_HSA_BITS_GET(kernel_code.kernel_code_properties,
|
||||
AMD_KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32)
|
||||
? 8
|
||||
: 4);
|
||||
}
|
||||
static uint32_t accum_vgpr_count(Agent::AgentInfo& info, const kernel_descriptor_t& kernel_code) {
|
||||
const std::string_view& name = info.getName();
|
||||
std::string info_name(name.data(), name.size());
|
||||
if (strcmp(info_name.c_str(), "gfx908") == 0) return arch_vgpr_count(info, kernel_code);
|
||||
if (strcmp(info_name.c_str(), "gfx90a") == 0 || strcmp(info_name.c_str(), "gfx940") == 0)
|
||||
return (AMD_HSA_BITS_GET(kernel_code.compute_pgm_rsrc1,
|
||||
AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WORKITEM_VGPR_COUNT) +
|
||||
1) *
|
||||
8 -
|
||||
arch_vgpr_count(info, kernel_code);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t sgpr_count(Agent::AgentInfo& info, const kernel_descriptor_t& kernel_code) {
|
||||
// GFX10 and later always allocate 128 sgprs.
|
||||
const std::string_view name = info.getName();
|
||||
// TODO(srnagara): Recheck the extraction of gfxip from gpu name
|
||||
const char* name_data = name.data();
|
||||
const size_t gfxip_label_len = std::min(name.size() - 2, size_t{63});
|
||||
if (gfxip_label_len > 0 && strlen(name_data) >= gfxip_label_len) {
|
||||
char gfxip[gfxip_label_len];
|
||||
memcpy(gfxip, name_data, gfxip_label_len);
|
||||
// TODO(srnagara): Check if it is hardcoded
|
||||
if (std::atoi(&gfxip[3]) >= 10) return 128;
|
||||
return (AMD_HSA_BITS_GET(kernel_code.compute_pgm_rsrc1,
|
||||
AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WAVEFRONT_SGPR_COUNT) /
|
||||
2 +
|
||||
1) *
|
||||
16;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
rocprofiler_kernel_properties_t set_kernel_properties(hsa_kernel_dispatch_packet_t packet,
|
||||
hsa_agent_t agent) {
|
||||
const uint64_t kernel_object = packet.kernel_object;
|
||||
rocprofiler_kernel_properties_t kernel_properties_ptr = {};
|
||||
const kernel_descriptor_t* kernel_code = GetKernelCode(kernel_object);
|
||||
uint64_t grid_size = packet.grid_size_x * packet.grid_size_y * packet.grid_size_z;
|
||||
if (grid_size > UINT32_MAX) abort();
|
||||
kernel_properties_ptr.grid_size = grid_size;
|
||||
uint64_t workgroup_size =
|
||||
packet.workgroup_size_x * packet.workgroup_size_y * packet.workgroup_size_z;
|
||||
if (workgroup_size > UINT32_MAX) abort();
|
||||
kernel_properties_ptr.workgroup_size = (uint32_t)workgroup_size;
|
||||
kernel_properties_ptr.lds_size = packet.group_segment_size;
|
||||
kernel_properties_ptr.scratch_size = packet.private_segment_size;
|
||||
Agent::AgentInfo agent_info = hsa_support::GetAgentInfo(agent.handle);
|
||||
kernel_properties_ptr.arch_vgpr_count = arch_vgpr_count(agent_info, *kernel_code);
|
||||
kernel_properties_ptr.accum_vgpr_count = accum_vgpr_count(agent_info, *kernel_code);
|
||||
kernel_properties_ptr.sgpr_count = sgpr_count(agent_info, *kernel_code);
|
||||
kernel_properties_ptr.wave_size =
|
||||
AMD_HSA_BITS_GET(kernel_code->kernel_code_properties,
|
||||
AMD_KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32)
|
||||
? 32
|
||||
: 64;
|
||||
kernel_properties_ptr.signal_handle = packet.completion_signal.handle;
|
||||
|
||||
return kernel_properties_ptr;
|
||||
}
|
||||
|
||||
namespace queue {
|
||||
|
||||
using rocmtools::GetROCMToolObj;
|
||||
|
||||
hsa_status_t pmcCallback(hsa_ven_amd_aqlprofile_info_type_t info_type,
|
||||
hsa_ven_amd_aqlprofile_info_data_t* info_data, void* data) {
|
||||
hsa_status_t status = HSA_STATUS_SUCCESS;
|
||||
pmc_callback_data_t* passed_data = reinterpret_cast<pmc_callback_data_t*>(data);
|
||||
|
||||
pmc_callback_data_t::iterator data_it;
|
||||
if (info_data->sample_id == 0) {
|
||||
passed_data->emplace_back(*info_data);
|
||||
} else {
|
||||
for (data_it = passed_data->begin(); data_it != passed_data->end(); ++data_it) {
|
||||
if (info_type == HSA_VEN_AMD_AQLPROFILE_INFO_PMC_DATA) {
|
||||
if (IsEventMatch(info_data->pmc_data.event, data_it->pmc_data.event)) {
|
||||
data_it->pmc_data.result += info_data->pmc_data.result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void AddRecordCounters(rocprofiler_record_profiler_t* record, const pending_signal_t& pending) {
|
||||
rocmtools::metrics::GetCounterData(pending.profile, pending.context->results_list);
|
||||
rocmtools::metrics::GetMetricsData(pending.context->results_map, pending.context->metrics_list);
|
||||
|
||||
std::vector<rocprofiler_record_counter_instance_t> counters_vec;
|
||||
for (size_t i = 0; i < pending.context->metrics_list.size(); i++) {
|
||||
const rocmtools::Metric* metric = pending.context->metrics_list[i];
|
||||
double value = 0;
|
||||
std::string metric_name = metric->GetName();
|
||||
auto it = pending.context->results_map.find(metric_name);
|
||||
if (it != pending.context->results_map.end()) {
|
||||
value = it->second->val_double;
|
||||
}
|
||||
counters_vec.emplace_back(rocprofiler_record_counter_instance_t{
|
||||
// TODO(aelwazir): Moving to span once C++20 is adopted, strdup can be
|
||||
// removed after that
|
||||
rocprofiler_counter_id_t{rocmtools::profiler::GetCounterID(metric_name)},
|
||||
rocprofiler_record_counter_value_t{value}});
|
||||
}
|
||||
record->counters = static_cast<rocprofiler_record_counter_instance_t*>(
|
||||
malloc(counters_vec.size() * sizeof(rocprofiler_record_counter_instance_t)));
|
||||
::memcpy(record->counters, &(counters_vec)[0],
|
||||
counters_vec.size() * sizeof(rocprofiler_record_counter_instance_t));
|
||||
record->counters_count = rocprofiler_record_counters_instances_count_t{counters_vec.size()};
|
||||
}
|
||||
|
||||
// static const size_t MEM_PAGE_BYTES = 0x1000;
|
||||
// static const size_t MEM_PAGE_MASK = MEM_PAGE_BYTES - 1;
|
||||
// static std::mutex begin_signal_lock;
|
||||
|
||||
// bool BeginSignalHandler(hsa_signal_value_t signal_value, void* data) {
|
||||
// std::lock_guard<std::mutex> lock(begin_signal_lock);
|
||||
// auto profiling_context =
|
||||
// static_cast<std::pair<rocmtools::profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*>*>(
|
||||
// data);
|
||||
// if (!profiling_context->first->begin_completed.load(std::memory_order_relaxed)) {
|
||||
// std::cout << "BeginSignalHandler is called" << std::endl;
|
||||
// hsa_status_t status = HSA_STATUS_ERROR;
|
||||
// size_t size = profiling_context->second->command_buffer.size;
|
||||
// size = (size + MEM_PAGE_MASK) & ~MEM_PAGE_MASK;
|
||||
// status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_allocate_fn(
|
||||
// Packet::GetCommandPool(), size, 0,
|
||||
// reinterpret_cast<void**>(&(profiling_context->second->command_buffer.ptr)));
|
||||
|
||||
// // Both the CPU and GPU can access the memory
|
||||
// if (status == HSA_STATUS_SUCCESS) {
|
||||
// hsa_agent_t ag_list[1] = {profiling_context->first->gpu_agent};
|
||||
// status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agents_allow_access_fn(
|
||||
// 1, ag_list, NULL, profiling_context->second->command_buffer.ptr);
|
||||
|
||||
// if (status != HSA_STATUS_SUCCESS) {
|
||||
// printf("Error: Can't allow access for both agents to Command Buffer\n");
|
||||
// }
|
||||
// } else if (status == HSA_STATUS_ERROR_OUT_OF_RESOURCES) {
|
||||
// printf("Error: Ran out of GPU memory to allocate Command Buffer\n");
|
||||
// } else {
|
||||
// const char* hsa_err_str = NULL;
|
||||
// if (hsa_status_string(status, &hsa_err_str) != HSA_STATUS_SUCCESS) hsa_err_str = "Unknown";
|
||||
// printf("Error: Allocating command Buffer (Size=%lu) (%s)\n", size, hsa_err_str);
|
||||
// }
|
||||
|
||||
// status = HSA_STATUS_ERROR;
|
||||
// size = profiling_context->second->output_buffer.size;
|
||||
// size = (size + MEM_PAGE_MASK) & ~MEM_PAGE_MASK;
|
||||
// status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_allocate_fn(
|
||||
// Packet::GetOutputPool(), size, 0,
|
||||
// reinterpret_cast<void**>(&profiling_context->second->output_buffer.ptr));
|
||||
|
||||
// if (status == HSA_STATUS_ERROR_OUT_OF_RESOURCES) {
|
||||
// printf("Error: Ran out of GPU memory to allocate Output Buffer\n");
|
||||
// }
|
||||
|
||||
// if (status == HSA_STATUS_SUCCESS) {
|
||||
// hsa_agent_t ag_list[1] = {profiling_context->first->gpu_agent};
|
||||
// status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_agents_allow_access_fn(
|
||||
// 1, ag_list, NULL, profiling_context->second->output_buffer.ptr);
|
||||
|
||||
// if (status == HSA_STATUS_SUCCESS) {
|
||||
// memset(profiling_context->second->output_buffer.ptr, 0x0,
|
||||
// profiling_context->second->output_buffer.size);
|
||||
|
||||
// // Creating the start/stop/read packets
|
||||
// status = hsa_ven_amd_aqlprofile_start(profiling_context->second,
|
||||
// profiling_context->first->start_packet);
|
||||
// status = hsa_ven_amd_aqlprofile_stop(profiling_context->second,
|
||||
// profiling_context->first->stop_packet);
|
||||
// status = hsa_ven_amd_aqlprofile_read(profiling_context->second,
|
||||
// profiling_context->first->read_packet);
|
||||
// } else {
|
||||
// printf("Error: Can't allow access for both agents to output Buffer\n");
|
||||
// }
|
||||
// } else {
|
||||
// const char* hsa_err_str = NULL;
|
||||
// if (hsa_status_string(status, &hsa_err_str) != HSA_STATUS_SUCCESS) hsa_err_str = "Unknown";
|
||||
// printf("Error: Allocating output Buffer (%s)\n", hsa_err_str);
|
||||
// }
|
||||
|
||||
// profiling_context->first->begin_completed.exchange(true, std::memory_order_relaxed);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
bool AsyncSignalHandler(hsa_signal_value_t signal_value, void* data) {
|
||||
auto queue_info_session = static_cast<queue_info_session_t*>(data);
|
||||
if (!queue_info_session || !GetROCMToolObj() ||
|
||||
!GetROCMToolObj()->GetSession(queue_info_session->session_id) ||
|
||||
!GetROCMToolObj()->GetSession(queue_info_session->session_id)->GetProfiler())
|
||||
return true;
|
||||
rocmtools::Session* session = GetROCMToolObj()->GetSession(queue_info_session->session_id);
|
||||
rocmtools::profiler::Profiler* profiler = session->GetProfiler();
|
||||
std::vector<pending_signal_t>& pending_signals = const_cast<std::vector<pending_signal_t>&>(
|
||||
profiler->GetPendingSignals(queue_info_session->writer_id));
|
||||
|
||||
if (!pending_signals.empty()) {
|
||||
for (auto it = pending_signals.begin(); it != pending_signals.end();
|
||||
it = pending_signals.erase(it)) {
|
||||
auto& pending = *it;
|
||||
std::lock_guard<std::mutex> lock(session->GetSessionLock());
|
||||
if (hsa_support::GetCoreApiTable().hsa_signal_load_relaxed_fn(pending.signal)) return true;
|
||||
hsa_amd_profiling_dispatch_time_t time;
|
||||
hsa_support::GetAmdExtTable().hsa_amd_profiling_get_dispatch_time_fn(
|
||||
queue_info_session->agent, pending.signal, &time);
|
||||
rocprofiler_record_profiler_t record{};
|
||||
record.kernel_id = rocprofiler_kernel_id_t{pending.kernel_descriptor};
|
||||
record.gpu_id = rocprofiler_agent_id_t{
|
||||
(uint64_t)hsa_support::GetAgentInfo(queue_info_session->agent.handle).getIndex()};
|
||||
record.kernel_properties = pending.kernel_properties;
|
||||
record.thread_id = rocprofiler_thread_id_t{pending.thread_id};
|
||||
record.queue_idx = rocprofiler_queue_index_t{pending.queue_index};
|
||||
record.timestamps = rocprofiler_record_header_timestamp_t{time.start, time.end};
|
||||
record.queue_id = rocprofiler_queue_id_t{queue_info_session->queue_id};
|
||||
if (pending.counters_count > 0 && pending.context->metrics_list.size() > 0 &&
|
||||
pending.profile) {
|
||||
AddRecordCounters(&record, pending);
|
||||
}
|
||||
record.header = {ROCPROFILER_PROFILER_RECORD,
|
||||
rocprofiler_record_id_t{GetROCMToolObj()->GetUniqueRecordId()}};
|
||||
|
||||
if (pending.session_id.handle == 0) {
|
||||
pending.session_id = GetROCMToolObj()->GetCurrentSessionId();
|
||||
}
|
||||
if (session->FindBuffer(pending.buffer_id)) {
|
||||
Memory::GenericBuffer* buffer = session->GetBuffer(pending.buffer_id);
|
||||
record.header.id = rocprofiler_record_id_t{GetROCMToolObj()->GetUniqueRecordId()};
|
||||
if (pending.profile && pending.counters_count > 0) {
|
||||
rocprofiler_record_counter_instance_t* record_counters = record.counters;
|
||||
buffer->AddRecord(
|
||||
record, record.counters,
|
||||
(record.counters_count.value * (sizeof(rocprofiler_record_counter_instance_t) + 1)),
|
||||
[](auto& record, const void* data) {
|
||||
record.counters = const_cast<rocprofiler_record_counter_instance_t*>(
|
||||
static_cast<const rocprofiler_record_counter_instance_t*>(data));
|
||||
});
|
||||
free(record_counters);
|
||||
} else {
|
||||
buffer->AddRecord(record);
|
||||
}
|
||||
}
|
||||
if (pending.counters_count > 0 && pending.profile && pending.profile->events) {
|
||||
// TODO(aelwazir): we need a better way of distributing events and free them
|
||||
// free(const_cast<hsa_ven_amd_aqlprofile_event_t*>(pending.profile->events));
|
||||
hsa_status_t status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_free_fn(
|
||||
(pending.profile->output_buffer.ptr));
|
||||
if (status != HSA_STATUS_SUCCESS) {
|
||||
printf("Error: Couldn't free output buffer memory\n");
|
||||
}
|
||||
status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_memory_pool_free_fn(
|
||||
(pending.profile->command_buffer.ptr));
|
||||
if (status != HSA_STATUS_SUCCESS) {
|
||||
printf("Error: Couldn't free command buffer memory\n");
|
||||
}
|
||||
delete pending.profile;
|
||||
}
|
||||
if (pending.signal.handle)
|
||||
hsa_support::GetCoreApiTable().hsa_signal_destroy_fn(pending.signal);
|
||||
if (queue_info_session->interrupt_signal.handle)
|
||||
hsa_support::GetCoreApiTable().hsa_signal_destroy_fn(queue_info_session->interrupt_signal);
|
||||
}
|
||||
}
|
||||
delete queue_info_session;
|
||||
ACTIVE_INTERRUPT_SIGNAL_COUNT.fetch_sub(1, std::memory_order_relaxed);
|
||||
return false;
|
||||
}
|
||||
|
||||
void CreateBarrierPacket(const hsa_signal_t& packet_completion_signal,
|
||||
std::vector<Packet::packet_t>* transformed_packets) {
|
||||
hsa_barrier_and_packet_t barrier{0};
|
||||
barrier.header = HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE;
|
||||
barrier.dep_signal[0] = packet_completion_signal;
|
||||
void* barrier_ptr = &barrier;
|
||||
transformed_packets->emplace_back(*reinterpret_cast<Packet::packet_t*>(barrier_ptr));
|
||||
}
|
||||
|
||||
void AddVendorSpecificPacket(const Packet::packet_t* packet,
|
||||
std::vector<Packet::packet_t>* transformed_packets,
|
||||
const hsa_signal_t& packet_completion_signal) {
|
||||
transformed_packets->emplace_back(*packet).completion_signal = packet_completion_signal;
|
||||
}
|
||||
|
||||
void SignalAsyncHandler(const hsa_signal_t& signal, void* data) {
|
||||
hsa_status_t status = hsa_support::GetAmdExtTable().hsa_amd_signal_async_handler_fn(
|
||||
signal, HSA_SIGNAL_CONDITION_EQ, 0, AsyncSignalHandler, data);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("hsa_amd_signal_async_handler failed");
|
||||
}
|
||||
|
||||
void CreateSignal(uint32_t attribute, hsa_signal_t* signal) {
|
||||
hsa_status_t status =
|
||||
hsa_support::GetAmdExtTable().hsa_amd_signal_create_fn(1, 0, nullptr, attribute, signal);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("hsa_amd_signal_create failed");
|
||||
}
|
||||
|
||||
template <typename Integral = uint64_t> constexpr Integral bit_mask(int first, int last) {
|
||||
assert(last >= first && "Error: hsa_support::bit_mask -> invalid argument");
|
||||
size_t num_bits = last - first + 1;
|
||||
return ((num_bits >= sizeof(Integral) * 8) ? ~Integral{0}
|
||||
/* num_bits exceed the size of Integral */
|
||||
: ((Integral{1} << num_bits) - 1))
|
||||
<< first;
|
||||
}
|
||||
|
||||
/* Extract bits [last:first] from t. */
|
||||
template <typename Integral> constexpr Integral bit_extract(Integral x, int first, int last) {
|
||||
return (x >> first) & bit_mask<Integral>(0, last - first);
|
||||
}
|
||||
|
||||
std::atomic<uint32_t> WRITER_ID{0};
|
||||
/**
|
||||
* @brief This function is a queue write interceptor. It intercepts the
|
||||
* packet write function. Creates an instance of packet class with the raw
|
||||
* pointer. invoke the populate function of the packet class which returns a
|
||||
* pointer to the packet. This packet is written into the queue by this
|
||||
* interceptor by invoking the writer function.
|
||||
*/
|
||||
void WriteInterceptor(const void* packets, uint64_t pkt_count, uint64_t user_pkt_index, void* data,
|
||||
hsa_amd_queue_intercept_packet_writer writer) {
|
||||
const Packet::packet_t* packets_arr = reinterpret_cast<const Packet::packet_t*>(packets);
|
||||
std::vector<Packet::packet_t> transformed_packets;
|
||||
rocprofiler_session_id_t session_id;
|
||||
if (GetROCMToolObj())
|
||||
// Getting Session ID
|
||||
session_id = GetROCMToolObj()->GetCurrentSessionId();
|
||||
else
|
||||
session_id = {0};
|
||||
|
||||
// Counter Names declaration
|
||||
std::vector<std::string> session_data;
|
||||
|
||||
rocprofiler_buffer_id_t buffer_id;
|
||||
|
||||
uint64_t session_data_count = 0;
|
||||
|
||||
bool is_counter_collection_mode = false;
|
||||
bool is_timestamp_collection_mode = false;
|
||||
bool is_pc_sampling_collection_mode = false;
|
||||
|
||||
uint32_t replay_mode_count = 0;
|
||||
|
||||
rocmtools::Session* session = nullptr;
|
||||
|
||||
// Getting Counters count from the Session
|
||||
if (session_id.handle > 0 && GetROCMToolObj()) {
|
||||
session = GetROCMToolObj()->GetSession(session_id);
|
||||
if (session && session->FindFilterWithKind(ROCPROFILER_COUNTERS_COLLECTION)) {
|
||||
rocprofiler_filter_id_t filter_id = session->GetFilterIdWithKind(ROCPROFILER_COUNTERS_COLLECTION);
|
||||
rocmtools::Filter* filter = session->GetFilter(filter_id);
|
||||
session_data = filter->GetCounterData();
|
||||
is_counter_collection_mode = true;
|
||||
session_data_count = session_data.size();
|
||||
buffer_id = filter->GetBufferId();
|
||||
} else if (session && session->FindFilterWithKind(ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION)) {
|
||||
is_timestamp_collection_mode = true;
|
||||
rocprofiler_filter_id_t filter_id =
|
||||
session->GetFilterIdWithKind(ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION);
|
||||
rocmtools::Filter* filter = session->GetFilter(filter_id);
|
||||
buffer_id = filter->GetBufferId();
|
||||
} else if (session && session->FindFilterWithKind(ROCPROFILER_PC_SAMPLING_COLLECTION)) {
|
||||
is_pc_sampling_collection_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (session_id.handle > 0 && pkt_count > 0 &&
|
||||
(is_counter_collection_mode || is_timestamp_collection_mode ||
|
||||
is_pc_sampling_collection_mode) &&
|
||||
session) {
|
||||
// Getting Queue Data and Information
|
||||
auto& queue_info = *static_cast<Queue*>(data);
|
||||
std::lock_guard<std::mutex> lk(queue_info.qw_mutex);
|
||||
|
||||
|
||||
// hsa_ven_amd_aqlprofile_profile_t* profile;
|
||||
std::vector<std::pair<rocmtools::profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*>>*
|
||||
profiles = nullptr;
|
||||
|
||||
// Searching accross all the packets given during this write
|
||||
for (size_t i = 0; i < pkt_count; ++i) {
|
||||
auto& original_packet = static_cast<const hsa_barrier_and_packet_t*>(packets)[i];
|
||||
|
||||
// Skip packets other than kernel dispatch packets.
|
||||
if (bit_extract(original_packet.header, HSA_PACKET_HEADER_TYPE,
|
||||
HSA_PACKET_HEADER_TYPE + HSA_PACKET_HEADER_WIDTH_TYPE - 1) !=
|
||||
HSA_PACKET_TYPE_KERNEL_DISPATCH) {
|
||||
transformed_packets.emplace_back(packets_arr[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If counters found in the session
|
||||
if (session_data_count > 0 && is_counter_collection_mode) {
|
||||
// Get the PM4 Packets using packets_generator
|
||||
profiles = Packet::InitializeAqlPackets(queue_info.GetCPUAgent(), queue_info.GetGPUAgent(),
|
||||
session_data);
|
||||
replay_mode_count = profiles->size();
|
||||
}
|
||||
|
||||
uint32_t profile_id = 0;
|
||||
hsa_signal_t interrupt_signal;
|
||||
do {
|
||||
std::pair<rocmtools::profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*> profile;
|
||||
if (profiles && replay_mode_count > 0) profile = profiles->at(profile_id);
|
||||
|
||||
uint32_t writer_id = WRITER_ID.fetch_add(1, std::memory_order_release);
|
||||
|
||||
if (session_data_count > 0 && is_counter_collection_mode && profiles &&
|
||||
replay_mode_count > 0) {
|
||||
// hsa_signal_t begin_signal{};
|
||||
// CreateSignal(0, &begin_signal);
|
||||
// hsa_barrier_and_packet_t barrier{0};
|
||||
// barrier.header = HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE;
|
||||
// CreateSignal(0, &barrier.completion_signal);
|
||||
// barrier.dep_signal[0] = hsa_signal_t{};
|
||||
// Packet::packet_t* __attribute__((__may_alias__)) pkt =
|
||||
// (reinterpret_cast<Packet::packet_t*>(&barrier));
|
||||
// transformed_packets.emplace_back(*pkt);
|
||||
// hsa_status_t status = hsa_support::GetAmdExtTable().hsa_amd_signal_async_handler_fn(
|
||||
// barrier.completion_signal, HSA_SIGNAL_CONDITION_GTE, 1, BeginSignalHandler,
|
||||
// &profiles->at(profile_id));
|
||||
// if (status != HSA_STATUS_SUCCESS)
|
||||
// fatal("hsa_amd_signal_async_handler failed for begin signal");
|
||||
|
||||
// Adding start packet and its barrier with a dummy signal
|
||||
hsa_signal_t dummy_signal{};
|
||||
dummy_signal.handle = 0;
|
||||
profile.first->start_packet->header = HSA_PACKET_TYPE_VENDOR_SPECIFIC
|
||||
<< HSA_PACKET_HEADER_TYPE;
|
||||
AddVendorSpecificPacket(profile.first->start_packet, &transformed_packets, dummy_signal);
|
||||
|
||||
CreateBarrierPacket(profile.first->start_packet->completion_signal, &transformed_packets);
|
||||
}
|
||||
|
||||
auto& packet = transformed_packets.emplace_back(packets_arr[i]);
|
||||
auto& dispatch_packet = reinterpret_cast<hsa_kernel_dispatch_packet_t&>(packet);
|
||||
|
||||
/*
|
||||
* Only PC sampling relies on this right now, so it would be better to
|
||||
* only generate an ID if PC sampling is active to conserve IDs, but it's
|
||||
* unlikely 64 bits' worth of identifiers will be exhausted during the
|
||||
* lifetime of the ROCMToolObj.
|
||||
*/
|
||||
dispatch_packet.reserved2 = GetROCMToolObj()->GetUniqueKernelDispatchId();
|
||||
|
||||
CreateSignal(HSA_AMD_SIGNAL_AMD_GPU_ONLY, &packet.completion_signal);
|
||||
// Adding the dispatch packet newly created signal to the pending signals
|
||||
// list to be processed by the signal interrupt
|
||||
rocprofiler_kernel_properties_t kernel_properties =
|
||||
set_kernel_properties(dispatch_packet, queue_info.GetGPUAgent());
|
||||
if (session) {
|
||||
if (profiles && replay_mode_count > 0) {
|
||||
session->GetProfiler()->AddPendingSignals(
|
||||
writer_id, dispatch_packet.kernel_object, dispatch_packet.completion_signal,
|
||||
session_id, buffer_id, profile.first, profile.first->metrics_list.size(),
|
||||
profile.second, kernel_properties, (uint32_t)syscall(__NR_gettid), user_pkt_index);
|
||||
} else {
|
||||
session->GetProfiler()->AddPendingSignals(
|
||||
writer_id, dispatch_packet.kernel_object, dispatch_packet.completion_signal,
|
||||
session_id, buffer_id, nullptr, 0, nullptr, kernel_properties,
|
||||
(uint32_t)syscall(__NR_gettid), user_pkt_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Make a copy of the original packet, adding its signal to a barrier
|
||||
// packet and create a new signal for it to get timestamps
|
||||
if (original_packet.completion_signal.handle) {
|
||||
hsa_barrier_and_packet_t barrier{0};
|
||||
barrier.header = HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE;
|
||||
Packet::packet_t* __attribute__((__may_alias__)) pkt =
|
||||
(reinterpret_cast<Packet::packet_t*>(&barrier));
|
||||
transformed_packets.emplace_back(*pkt).completion_signal =
|
||||
original_packet.completion_signal;
|
||||
}
|
||||
|
||||
// Adding a barrier packet with the original packet's completion signal.
|
||||
CreateSignal(0, &interrupt_signal);
|
||||
|
||||
// Adding Stop and Read PM4 Packets
|
||||
if (session_data_count > 0 && is_counter_collection_mode && profiles &&
|
||||
replay_mode_count > 0) {
|
||||
hsa_signal_t dummy_signal{};
|
||||
profile.first->stop_packet->header = HSA_PACKET_TYPE_VENDOR_SPECIFIC
|
||||
<< HSA_PACKET_HEADER_TYPE;
|
||||
AddVendorSpecificPacket(profile.first->stop_packet, &transformed_packets, dummy_signal);
|
||||
profile.first->read_packet->header = HSA_PACKET_TYPE_VENDOR_SPECIFIC
|
||||
<< HSA_PACKET_HEADER_TYPE;
|
||||
AddVendorSpecificPacket(profile.first->read_packet, &transformed_packets,
|
||||
interrupt_signal);
|
||||
|
||||
// Added Interrupt Signal with barrier and provided handler for it
|
||||
CreateBarrierPacket(interrupt_signal, &transformed_packets);
|
||||
} else {
|
||||
hsa_barrier_and_packet_t barrier{0};
|
||||
barrier.header = HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE;
|
||||
barrier.completion_signal = interrupt_signal;
|
||||
Packet::packet_t* __attribute__((__may_alias__)) pkt =
|
||||
(reinterpret_cast<Packet::packet_t*>(&barrier));
|
||||
transformed_packets.emplace_back(*pkt);
|
||||
}
|
||||
// Creating Async Handler to be called every time the interrupt signal is
|
||||
// marked complete
|
||||
SignalAsyncHandler(interrupt_signal,
|
||||
new queue_info_session_t{queue_info.GetGPUAgent(), session_id,
|
||||
queue_info.GetQueueID(), writer_id});
|
||||
ACTIVE_INTERRUPT_SIGNAL_COUNT.fetch_add(1, std::memory_order_relaxed);
|
||||
profile_id++;
|
||||
} while (replay_mode_count > 0 && profile_id < replay_mode_count); // Profiles loop end
|
||||
}
|
||||
/* Write the transformed packets to the hardware queue. */
|
||||
writer(&transformed_packets[0], transformed_packets.size());
|
||||
} else {
|
||||
/* Write the original packets to the hardware queue if no profiling session
|
||||
* is active */
|
||||
writer(packets, pkt_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Queue::Queue(const hsa_agent_t& cpu_agent, const hsa_agent_t& gpu_agent, uint32_t size,
|
||||
hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,
|
||||
uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue)
|
||||
: cpu_agent_(cpu_agent), gpu_agent_(gpu_agent) {
|
||||
[[maybe_unused]] hsa_status_t status =
|
||||
hsa_support::GetAmdExtTable().hsa_amd_queue_intercept_create_fn(
|
||||
gpu_agent, size, type, callback, data, private_segment_size, group_segment_size,
|
||||
&intercept_queue_);
|
||||
assert(status == HSA_STATUS_SUCCESS);
|
||||
|
||||
status = hsa_support::GetAmdExtTable().hsa_amd_profiling_set_profiler_enabled_fn(intercept_queue_,
|
||||
true);
|
||||
assert(status == HSA_STATUS_SUCCESS);
|
||||
|
||||
hsa_support::GetAmdExtTable().hsa_amd_queue_intercept_register_fn(intercept_queue_,
|
||||
WriteInterceptor, this);
|
||||
assert(status == HSA_STATUS_SUCCESS);
|
||||
|
||||
*queue = intercept_queue_;
|
||||
}
|
||||
|
||||
// Queue::~Queue() { std::lock_guard<std::mutex> lk(mutex_); }
|
||||
|
||||
hsa_queue_t* Queue::GetCurrentInterceptQueue() { return intercept_queue_; }
|
||||
|
||||
hsa_agent_t Queue::GetGPUAgent() { return gpu_agent_; }
|
||||
|
||||
hsa_agent_t Queue::GetCPUAgent() { return cpu_agent_; }
|
||||
|
||||
uint64_t Queue::GetQueueID() { return intercept_queue_->id; }
|
||||
|
||||
void InitializePools(hsa_agent_t cpu_agent) { Packet::InitializePools(cpu_agent); }
|
||||
|
||||
} // namespace queue
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,91 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_HSA_QUEUES_QUEUE_H_
|
||||
#define SRC_CORE_HSA_QUEUES_QUEUE_H_
|
||||
|
||||
#include "inc/rocprofiler.h"
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_api_trace.h>
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
#include <hsa/hsa_ven_amd_loader.h>
|
||||
#include <hsa/amd_hsa_kernel_code.h>
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "src/core/session/profiler/profiler.h"
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
void InitKsymbols();
|
||||
void FinitKsymbols();
|
||||
void AddKernelName(uint64_t handle, std::string kernel_name);
|
||||
std::string GetKernelNameFromKsymbols(uint64_t handle);
|
||||
uint32_t GetCurrentActiveInterruptSignalsCount();
|
||||
|
||||
namespace queue {
|
||||
|
||||
class Queue {
|
||||
public:
|
||||
Queue(const hsa_agent_t& cpu_agent, const hsa_agent_t& gpu_agent, uint32_t size,
|
||||
hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,
|
||||
uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue);
|
||||
~Queue() {}
|
||||
|
||||
hsa_queue_t* GetCurrentInterceptQueue();
|
||||
hsa_agent_t GetGPUAgent();
|
||||
hsa_agent_t GetCPUAgent();
|
||||
uint64_t GetQueueID();
|
||||
static void PrintCounters();
|
||||
std::mutex qw_mutex;
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
hsa_agent_t cpu_agent_;
|
||||
hsa_agent_t gpu_agent_;
|
||||
hsa_queue_t* original_queue_;
|
||||
hsa_queue_t* intercept_queue_;
|
||||
|
||||
hsa_status_t pmcCallback(hsa_ven_amd_aqlprofile_info_type_t info_type,
|
||||
hsa_ven_amd_aqlprofile_info_data_t* info_data, void* data);
|
||||
};
|
||||
|
||||
struct queue_info_session_t {
|
||||
hsa_agent_t agent;
|
||||
rocprofiler_session_id_t session_id;
|
||||
uint64_t queue_id;
|
||||
uint32_t writer_id;
|
||||
hsa_signal_t interrupt_signal;
|
||||
};
|
||||
|
||||
void AddRecordCounters(rocprofiler_record_profiler_t* record, const pending_signal_t& pending);
|
||||
|
||||
void InitializePools(hsa_agent_t cpu_agent);
|
||||
|
||||
} // namespace queue
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_HSA_QUEUES_QUEUE_H_
|
||||
@@ -0,0 +1,229 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "generic_buffer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
|
||||
#include "src/api/rocmtool.h"
|
||||
|
||||
namespace Memory {
|
||||
|
||||
void periodic_flush_buffer_fn(rocprofiler_session_id_t session_id);
|
||||
|
||||
GenericBuffer::GenericBuffer(rocprofiler_session_id_t session_id, rocprofiler_buffer_id_t id,
|
||||
size_t buffer_size, rocprofiler_buffer_callback_t flush_function)
|
||||
: buffer_size_(buffer_size),
|
||||
available_space_(buffer_size_),
|
||||
id_(id),
|
||||
flush_function_(flush_function),
|
||||
session_id_(session_id) {
|
||||
if (!is_valid_.load(std::memory_order_release)) {
|
||||
// Pool definition: The memory pool is split in 2 buffers of equal size. When
|
||||
// first initialized, the write pointer points to the first element of the
|
||||
// first buffer. When a buffer is full, or when Flush() is called, the write
|
||||
// pointer moves to the other buffer. Each buffer should be large enough to
|
||||
// hold at least 2 activity records, as record pairs may be written when
|
||||
// external correlation ids are used.
|
||||
const size_t allocation_size = 2 * std::max(2 * sizeof(rocprofiler_record_header_t), buffer_size);
|
||||
pool_begin_ = nullptr;
|
||||
AllocateMemory(&pool_begin_, allocation_size);
|
||||
assert(pool_begin_ != nullptr && "pool allocator failed");
|
||||
|
||||
pool_end_ = pool_begin_ + allocation_size;
|
||||
buffer_begin_ = pool_begin_;
|
||||
buffer_end_ = buffer_begin_ + buffer_size;
|
||||
record_ptr_ = buffer_begin_;
|
||||
data_ptr_ = buffer_end_;
|
||||
|
||||
// Create a consumer thread and wait for it to be ready to accept work.
|
||||
std::promise<void> ready;
|
||||
std::future<void> future = ready.get_future();
|
||||
consumer_thread_ = std::thread(&GenericBuffer::ConsumerThreadLoop, this, std::move(ready));
|
||||
future.wait();
|
||||
|
||||
is_valid_.exchange(true, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
GenericBuffer::~GenericBuffer() {
|
||||
if (is_valid_.load(std::memory_order_release)) {
|
||||
std::lock_guard lock(buffer_lock_);
|
||||
if (rocmtools::GetROCMToolObj()->GetSession(session_id_))
|
||||
rocmtools::GetROCMToolObj()->GetSession(session_id_)->DisableTools(id_);
|
||||
|
||||
Flush();
|
||||
|
||||
// Wait for the previous flush to complete, then send the exit signal.
|
||||
NotifyConsumerThread(nullptr, nullptr);
|
||||
consumer_thread_.join();
|
||||
|
||||
// Free the pool's buffer memory.
|
||||
AllocateMemory(&pool_begin_, 0);
|
||||
|
||||
is_valid_.exchange(false, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
bool GenericBuffer::Flush() {
|
||||
{
|
||||
std::lock_guard producer_lock(producer_mutex_);
|
||||
if (record_ptr_ == buffer_begin_) return true;
|
||||
|
||||
NotifyConsumerThread(buffer_begin_, record_ptr_);
|
||||
SwitchBuffers();
|
||||
}
|
||||
{
|
||||
// Wait for the current operation to complete.
|
||||
std::unique_lock consumer_lock(consumer_mutex_);
|
||||
consumer_cond_.wait(consumer_lock, [this]() { return !consumer_arg_.valid; });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GenericBuffer::SetProperties(rocprofiler_buffer_property_t* buffer_properties,
|
||||
uint32_t buffer_properties_count) {
|
||||
// TODO(aelwazir): Change it to do real work
|
||||
for (uint32_t i = 0; i < buffer_properties_count; i++)
|
||||
properties_.emplace_back(buffer_properties[i]);
|
||||
}
|
||||
|
||||
void GenericBuffer::SwitchBuffers() {
|
||||
buffer_begin_ = (buffer_end_ == pool_end_) ? pool_begin_ : buffer_end_;
|
||||
buffer_end_ = buffer_begin_ + buffer_size_;
|
||||
record_ptr_ = buffer_begin_;
|
||||
data_ptr_ = buffer_end_;
|
||||
}
|
||||
|
||||
void GenericBuffer::ConsumerThreadLoop(std::promise<void> ready) {
|
||||
std::unique_lock consumer_lock(consumer_mutex_);
|
||||
|
||||
// This consumer is now ready to accept work.
|
||||
ready.set_value();
|
||||
|
||||
while (true) {
|
||||
consumer_cond_.wait(consumer_lock, [this]() { return consumer_arg_.valid; });
|
||||
|
||||
// begin == end == nullptr means the thread needs to exit.
|
||||
if (consumer_arg_.begin == nullptr && consumer_arg_.end == nullptr) break;
|
||||
|
||||
flush_function_(reinterpret_cast<const rocprofiler_record_header_t*>(consumer_arg_.begin),
|
||||
reinterpret_cast<const rocprofiler_record_header_t*>(consumer_arg_.end),
|
||||
session_id_, id_);
|
||||
|
||||
// Mark this operation as complete (valid=false) and notify all producers
|
||||
// that may be waiting for this operation to finish, or to start a new
|
||||
// operation. See comment below in NotifyConsumerThread().
|
||||
consumer_arg_.valid = false;
|
||||
consumer_cond_.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void GenericBuffer::NotifyConsumerThread(const std::byte* data_begin, const std::byte* data_end) {
|
||||
std::unique_lock consumer_lock(consumer_mutex_);
|
||||
|
||||
// If consumer_arg_ is still in use (valid=true), then wait for the consumer
|
||||
// thread to finish processing the current operation. Multiple producers may
|
||||
// wait here, one will be allowed to continue once the consumer thread is
|
||||
// idle and valid=false. This prevents a race condition where operations
|
||||
// would be lost if multiple producers could enter this critical section
|
||||
// (sequentially) before the consumer thread could re-acquire the
|
||||
// consumer_mutex_ lock.
|
||||
consumer_cond_.wait(consumer_lock, [this]() { return !consumer_arg_.valid; });
|
||||
|
||||
consumer_arg_.begin = data_begin;
|
||||
consumer_arg_.end = data_end;
|
||||
|
||||
consumer_arg_.valid = true;
|
||||
consumer_cond_.notify_all();
|
||||
}
|
||||
|
||||
void GenericBuffer::AllocateMemory(std::byte** ptr, size_t size) const {
|
||||
// Allocate using the default malloc/realloc/free allocator.
|
||||
if (*ptr == nullptr && size > 0) {
|
||||
*ptr = static_cast<std::byte*>(malloc(size));
|
||||
} else if (size != 0) {
|
||||
*ptr = static_cast<std::byte*>(realloc(*ptr, size));
|
||||
} else {
|
||||
if (*ptr) free(*ptr);
|
||||
*ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
rocprofiler_session_id_t GenericBuffer::GetSessionId() {
|
||||
if (is_valid_) return session_id_;
|
||||
return rocprofiler_session_id_t{0};
|
||||
}
|
||||
|
||||
bool GenericBuffer::IsValid() { return is_valid_.load(std::memory_order_release); }
|
||||
|
||||
rocprofiler_buffer_id_t GenericBuffer::GetId() {
|
||||
if (is_valid_) return id_;
|
||||
return rocprofiler_buffer_id_t{0};
|
||||
}
|
||||
|
||||
std::mutex& GenericBuffer::GetBufferLock() { return buffer_lock_; }
|
||||
|
||||
bool GetNextRecord(const rocprofiler_record_header_t* record,
|
||||
const rocprofiler_record_header_t** next) {
|
||||
// size_t size_to_add = sizeof(rocprofiler_record_header_t);
|
||||
switch (record->kind) {
|
||||
case ROCPROFILER_PROFILER_RECORD: {
|
||||
const rocprofiler_record_profiler_t* profiler_record =
|
||||
reinterpret_cast<const rocprofiler_record_profiler_t*>(record);
|
||||
// size_to_add = sizeof(rocprofiler_record_profiler_t);
|
||||
// if (profiler_record->counters_count.value > 0) {
|
||||
// size_to_add += (profiler_record->counters_count.value *
|
||||
// sizeof(rocprofiler_record_counter_instance_t));
|
||||
// }
|
||||
*next = reinterpret_cast<const rocprofiler_record_header_t*>(profiler_record + 1);
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_SPM_RECORD: {
|
||||
const rocprofiler_record_spm_t* spm_record =
|
||||
reinterpret_cast<const rocprofiler_record_spm_t*>(record);
|
||||
*next = reinterpret_cast<const rocprofiler_record_header_t*>(spm_record + 1);
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_TRACER_RECORD: {
|
||||
const rocprofiler_record_tracer_t* tracer_record =
|
||||
reinterpret_cast<const rocprofiler_record_tracer_t*>(record);
|
||||
// size_to_add = sizeof(rocprofiler_record_tracer_t);
|
||||
// if (tracer_record->api_data_handle.size > 0) {
|
||||
// size_to_add += tracer_record->api_data_handle.size;
|
||||
// }
|
||||
// break;
|
||||
*next = reinterpret_cast<const rocprofiler_record_header_t*>(tracer_record + 1);
|
||||
}
|
||||
default:
|
||||
const rocprofiler_record_tracer_t* tracer_record =
|
||||
reinterpret_cast<const rocprofiler_record_tracer_t*>(record);
|
||||
*next = reinterpret_cast<const rocprofiler_record_header_t*>(tracer_record + 1);
|
||||
// size_to_add = sizeof(rocprofiler_record_header_t);
|
||||
}
|
||||
// const std::byte* ptr = reinterpret_cast<const std::byte*>(record);
|
||||
// ptr += size_to_add;
|
||||
// *next = reinterpret_cast<const rocprofiler_record_header_t*>(ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Memory
|
||||
@@ -0,0 +1,166 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_MEMORY_GENERIC_BUFFER_H_
|
||||
#define SRC_CORE_MEMORY_GENERIC_BUFFER_H_
|
||||
#include "inc/rocprofiler.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <condition_variable>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
namespace Memory {
|
||||
|
||||
class GenericBuffer {
|
||||
public:
|
||||
GenericBuffer(rocprofiler_session_id_t session_id, rocprofiler_buffer_id_t id, size_t buffer_size,
|
||||
rocprofiler_buffer_callback_t flush_function);
|
||||
~GenericBuffer();
|
||||
|
||||
GenericBuffer(const GenericBuffer&) = delete;
|
||||
GenericBuffer& operator=(const GenericBuffer&) = delete;
|
||||
|
||||
rocprofiler_buffer_id_t GetId();
|
||||
rocprofiler_session_id_t GetSessionId();
|
||||
|
||||
bool Flush();
|
||||
|
||||
template <typename Record, typename Functor = std::function<void(Record& record, const void*)>>
|
||||
void AddRecord(Record&& record, const void* data, size_t data_size, Functor&& store_data) {
|
||||
if (!is_valid_) return;
|
||||
assert(data != nullptr || data_size == 0); // If data is null, then data_size must be 0
|
||||
|
||||
std::lock_guard producer_lock(producer_mutex_);
|
||||
|
||||
// The amount of memory reserved in the buffer to store data. If the data
|
||||
// cannot fit because it is larger than the buffer size minus one record,
|
||||
// then the data won't be copied into the buffer.
|
||||
size_t reserve_data_size = data_size <= (buffer_size_ - sizeof(Record)) ? data_size : 0;
|
||||
|
||||
std::byte* next_record = record_ptr_ + sizeof(Record);
|
||||
if (next_record > (data_ptr_ - reserve_data_size)) {
|
||||
NotifyConsumerThread(buffer_begin_, record_ptr_);
|
||||
SwitchBuffers();
|
||||
next_record = record_ptr_ + sizeof(Record);
|
||||
assert(next_record <= buffer_end_ && "buffer size is less then the record size");
|
||||
}
|
||||
|
||||
// Store data in the record. Copy the data first if it fits in the buffer
|
||||
// (reserve_data_size != 0).
|
||||
if (reserve_data_size) {
|
||||
data_ptr_ -= data_size;
|
||||
::memcpy(data_ptr_, data, data_size);
|
||||
store_data(record, data_ptr_);
|
||||
} else if (data != nullptr) {
|
||||
store_data(record, data);
|
||||
}
|
||||
|
||||
// Store the record into the buffer, and increment the write pointer.
|
||||
::memcpy(record_ptr_, &record, sizeof(Record));
|
||||
record_ptr_ = next_record;
|
||||
|
||||
// If the data does not fit in the buffer, flush the buffer with the record
|
||||
// as is. We don't copy the data so we make sure that the record and its
|
||||
// data are processed by waiting until the flush is complete.
|
||||
if (data != nullptr && reserve_data_size == 0) {
|
||||
NotifyConsumerThread(buffer_begin_, record_ptr_);
|
||||
SwitchBuffers();
|
||||
{
|
||||
std::unique_lock consumer_lock(consumer_mutex_);
|
||||
consumer_cond_.wait(consumer_lock, [this]() { return !consumer_arg_.valid; });
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename Record> bool AddRecord(Record&& record) {
|
||||
using DataPtr = void*;
|
||||
AddRecord(std::forward<Record>(record), DataPtr(nullptr), 0, {});
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetProperties(rocprofiler_buffer_property_t* buffer_properties,
|
||||
uint32_t buffer_properties_count);
|
||||
|
||||
|
||||
bool GetPeriodicFlushFlag(rocprofiler_session_id_t session_id);
|
||||
|
||||
bool IsValid();
|
||||
|
||||
std::mutex& GetBufferLock();
|
||||
|
||||
private:
|
||||
void SwitchBuffers();
|
||||
void ConsumerThreadLoop(std::promise<void> ready);
|
||||
void NotifyConsumerThread(const std::byte* data_begin, const std::byte* data_end);
|
||||
void AllocateMemory(std::byte** ptr, size_t size) const;
|
||||
|
||||
// Memory Pool and Buffers
|
||||
size_t buffer_size_;
|
||||
size_t available_space_;
|
||||
std::byte* pool_begin_;
|
||||
std::byte* pool_end_;
|
||||
std::byte* buffer_begin_;
|
||||
std::byte* buffer_end_;
|
||||
std::byte* record_ptr_;
|
||||
std::byte* data_ptr_;
|
||||
std::mutex producer_mutex_;
|
||||
|
||||
// Session related Information
|
||||
rocprofiler_buffer_id_t id_;
|
||||
rocprofiler_buffer_callback_t flush_function_;
|
||||
rocprofiler_session_id_t session_id_;
|
||||
std::vector<rocprofiler_buffer_property_t> properties_;
|
||||
std::atomic<bool> is_valid_{false};
|
||||
|
||||
// Flush Period
|
||||
std::mutex periodic_flush_threads_map_lock_;
|
||||
std::map<uint64_t, std::thread> periodic_flush_threads_;
|
||||
std::mutex periodic_flush_flags_map_lock_;
|
||||
std::map<uint64_t, std::atomic<bool>> periodic_flush_flags_;
|
||||
|
||||
// Consumer thread
|
||||
std::thread consumer_thread_;
|
||||
struct {
|
||||
const std::byte* begin;
|
||||
const std::byte* end;
|
||||
bool valid = false;
|
||||
} consumer_arg_;
|
||||
|
||||
std::mutex consumer_mutex_;
|
||||
std::condition_variable consumer_cond_;
|
||||
|
||||
std::mutex buffer_lock_;
|
||||
};
|
||||
|
||||
bool GetNextRecord(const rocprofiler_record_header_t* record, const rocprofiler_record_header_t** next);
|
||||
|
||||
} // namespace Memory
|
||||
#endif // SRC_CORE_MEMORY_GENERIC_BUFFER_H_
|
||||
@@ -39,6 +39,8 @@ THE SOFTWARE.
|
||||
#include "util/exception.h"
|
||||
#include "util/hsa_rsrc_factory.h"
|
||||
#include "util/logger.h"
|
||||
#include "src/core/hsa/hsa_support.h"
|
||||
#include "src/utils/helper.h"
|
||||
|
||||
#define PUBLIC_API __attribute__((visibility("default")))
|
||||
#define CONSTRUCTOR_API __attribute__((constructor))
|
||||
@@ -47,7 +49,6 @@ THE SOFTWARE.
|
||||
#define API_METHOD_PREFIX \
|
||||
hsa_status_t status = HSA_STATUS_SUCCESS; \
|
||||
try {
|
||||
|
||||
#define API_METHOD_SUFFIX \
|
||||
} \
|
||||
catch (std::exception & e) { \
|
||||
@@ -56,10 +57,12 @@ THE SOFTWARE.
|
||||
} \
|
||||
return status;
|
||||
|
||||
#define ONLOAD_TRACE(str) \
|
||||
if (getenv("ROCP_ONLOAD_TRACE")) do { \
|
||||
std::cout << "PID(" << GetPid() << "): PROF_LIB::" << __FUNCTION__ << " " << str << std::endl << std::flush; \
|
||||
} while(0);
|
||||
#define ONLOAD_TRACE(str) \
|
||||
if (getenv("ROCP_ONLOAD_TRACE")) do { \
|
||||
std::cout << "PID(" << GetPid() << "): PROF_LIB::" << __FUNCTION__ << " " << str \
|
||||
<< std::endl \
|
||||
<< std::flush; \
|
||||
} while (0);
|
||||
#define ONLOAD_TRACE_BEG() ONLOAD_TRACE("begin")
|
||||
#define ONLOAD_TRACE_END() ONLOAD_TRACE("end")
|
||||
|
||||
@@ -69,15 +72,10 @@ static inline uint32_t GetPid() { return syscall(__NR_getpid); }
|
||||
// Internal library methods
|
||||
//
|
||||
namespace rocprofiler {
|
||||
hsa_status_t CreateQueuePro(
|
||||
hsa_agent_t agent,
|
||||
uint32_t size,
|
||||
hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t *source, void *data),
|
||||
void *data,
|
||||
uint32_t private_segment_size,
|
||||
uint32_t group_segment_size,
|
||||
hsa_queue_t **queue);
|
||||
hsa_status_t CreateQueuePro(hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data),
|
||||
void* data, uint32_t private_segment_size, uint32_t group_segment_size,
|
||||
hsa_queue_t** queue);
|
||||
|
||||
decltype(hsa_queue_create)* hsa_queue_create_fn;
|
||||
decltype(hsa_queue_destroy)* hsa_queue_destroy_fn;
|
||||
@@ -161,7 +159,7 @@ void StandaloneIntercept() {
|
||||
|
||||
typedef void (*tool_handler_t)();
|
||||
typedef void (*tool_handler_prop_t)(rocprofiler_settings_t*);
|
||||
void * tool_handle = NULL;
|
||||
void* tool_handle = NULL;
|
||||
|
||||
// Load profiling tool library
|
||||
// Return true if intercepting mode is enabled
|
||||
@@ -189,13 +187,17 @@ uint32_t LoadTool() {
|
||||
abort();
|
||||
}
|
||||
tool_handler_t handler = reinterpret_cast<tool_handler_t>(dlsym(tool_handle, "OnLoadTool"));
|
||||
tool_handler_prop_t handler_prop = reinterpret_cast<tool_handler_prop_t>(dlsym(tool_handle, "OnLoadToolProp"));
|
||||
tool_handler_prop_t handler_prop =
|
||||
reinterpret_cast<tool_handler_prop_t>(dlsym(tool_handle, "OnLoadToolProp"));
|
||||
if ((handler == NULL) && (handler_prop == NULL)) {
|
||||
fprintf(stderr, "ROCProfiler: tool library corrupted, OnLoadTool()/OnLoadToolProp() method is expected\n");
|
||||
fprintf(stderr,
|
||||
"ROCProfiler: tool library corrupted, OnLoadTool()/OnLoadToolProp() method is "
|
||||
"expected\n");
|
||||
fprintf(stderr, "%s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
tool_handler_t on_unload_handler = reinterpret_cast<tool_handler_t>(dlsym(tool_handle, "OnUnloadTool"));
|
||||
tool_handler_t on_unload_handler =
|
||||
reinterpret_cast<tool_handler_t>(dlsym(tool_handle, "OnUnloadTool"));
|
||||
if (on_unload_handler == NULL) {
|
||||
fprintf(stderr, "ROCProfiler: tool library corrupted, OnUnloadTool() method is expected\n");
|
||||
fprintf(stderr, "%s\n", dlerror());
|
||||
@@ -205,13 +207,15 @@ uint32_t LoadTool() {
|
||||
rocprofiler_settings_t settings{};
|
||||
settings.intercept_mode = (intercept_mode != 0) ? 1 : 0;
|
||||
settings.trace_size = TraceProfile::GetSize();
|
||||
settings.trace_local = TraceProfile::IsLocal() ? 1: 0;
|
||||
settings.trace_local = TraceProfile::IsLocal() ? 1 : 0;
|
||||
settings.timeout = util::HsaRsrcFactory::GetTimeoutNs();
|
||||
settings.timestamp_on = InterceptQueue::IsTrackerOn() ? 1 : 0;
|
||||
settings.code_obj_tracking = 1;
|
||||
|
||||
if (handler) handler();
|
||||
else if (handler_prop) handler_prop(&settings);
|
||||
if (handler)
|
||||
handler();
|
||||
else if (handler_prop)
|
||||
handler_prop(&settings);
|
||||
|
||||
TraceProfile::SetSize(settings.trace_size);
|
||||
TraceProfile::SetLocal(settings.trace_local != 0);
|
||||
@@ -266,7 +270,8 @@ void UnloadTool() {
|
||||
if (tool_handle) {
|
||||
tool_handler_t handler = reinterpret_cast<tool_handler_t>(dlsym(tool_handle, "OnUnloadTool"));
|
||||
if (handler == NULL) {
|
||||
fprintf(stderr, "ROCProfiler error: tool library corrupted, OnUnloadTool() method is expected\n");
|
||||
fprintf(stderr,
|
||||
"ROCProfiler error: tool library corrupted, OnUnloadTool() method is expected\n");
|
||||
fprintf(stderr, "%s\n", dlerror());
|
||||
abort();
|
||||
}
|
||||
@@ -305,26 +310,13 @@ hsa_status_t GetExcStatus(const std::exception& e) {
|
||||
: HSA_STATUS_ERROR;
|
||||
}
|
||||
|
||||
hsa_status_t CreateQueuePro(
|
||||
hsa_agent_t agent,
|
||||
uint32_t size,
|
||||
hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t *source, void *data),
|
||||
void *data,
|
||||
uint32_t private_segment_size,
|
||||
uint32_t group_segment_size,
|
||||
hsa_queue_t **queue)
|
||||
{
|
||||
hsa_status_t CreateQueuePro(hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data),
|
||||
void* data, uint32_t private_segment_size, uint32_t group_segment_size,
|
||||
hsa_queue_t** queue) {
|
||||
// Create HSA queue
|
||||
hsa_status_t status = hsa_queue_create_fn(
|
||||
agent,
|
||||
size,
|
||||
type,
|
||||
callback,
|
||||
data,
|
||||
private_segment_size,
|
||||
group_segment_size,
|
||||
queue);
|
||||
hsa_status_t status = hsa_queue_create_fn(agent, size, type, callback, data, private_segment_size,
|
||||
group_segment_size, queue);
|
||||
if (status != HSA_STATUS_SUCCESS) return status;
|
||||
|
||||
// Issue PMC-enable GPU command
|
||||
@@ -339,18 +331,18 @@ bool async_copy_handler(hsa_signal_value_t value, void* arg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_memory_async_copy_interceptor(
|
||||
void* dst, hsa_agent_t dst_agent, const void* src,
|
||||
hsa_agent_t src_agent, size_t size, uint32_t num_dep_signals,
|
||||
const hsa_signal_t* dep_signals, hsa_signal_t completion_signal)
|
||||
{
|
||||
hsa_status_t hsa_amd_memory_async_copy_interceptor(void* dst, hsa_agent_t dst_agent,
|
||||
const void* src, hsa_agent_t src_agent,
|
||||
size_t size, uint32_t num_dep_signals,
|
||||
const hsa_signal_t* dep_signals,
|
||||
hsa_signal_t completion_signal) {
|
||||
Tracker* tracker = &Tracker::Instance();
|
||||
Tracker::entry_t* tracker_entry = tracker->Alloc(hsa_agent_t{}, completion_signal);
|
||||
hsa_status_t status = hsa_amd_memory_async_copy_fn(dst, dst_agent, src,
|
||||
src_agent, size, num_dep_signals,
|
||||
dep_signals, tracker_entry->signal);
|
||||
hsa_status_t status = hsa_amd_memory_async_copy_fn(
|
||||
dst, dst_agent, src, src_agent, size, num_dep_signals, dep_signals, tracker_entry->signal);
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
tracker->EnableMemcopy(tracker_entry, async_copy_handler, reinterpret_cast<void*>(tracker_entry));
|
||||
tracker->EnableMemcopy(tracker_entry, async_copy_handler,
|
||||
reinterpret_cast<void*>(tracker_entry));
|
||||
} else {
|
||||
tracker->Delete(tracker_entry);
|
||||
}
|
||||
@@ -361,16 +353,15 @@ hsa_status_t hsa_amd_memory_async_copy_rect_interceptor(
|
||||
const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset, const hsa_pitched_ptr_t* src,
|
||||
const hsa_dim3_t* src_offset, const hsa_dim3_t* range, hsa_agent_t copy_agent,
|
||||
hsa_amd_copy_direction_t dir, uint32_t num_dep_signals, const hsa_signal_t* dep_signals,
|
||||
hsa_signal_t completion_signal)
|
||||
{
|
||||
hsa_signal_t completion_signal) {
|
||||
Tracker* tracker = &Tracker::Instance();
|
||||
Tracker::entry_t* tracker_entry = tracker->Alloc(hsa_agent_t{}, completion_signal);
|
||||
hsa_status_t status = hsa_amd_memory_async_copy_rect_fn(dst, dst_offset, src,
|
||||
src_offset, range, copy_agent,
|
||||
dir, num_dep_signals, dep_signals,
|
||||
tracker_entry->signal);
|
||||
hsa_status_t status =
|
||||
hsa_amd_memory_async_copy_rect_fn(dst, dst_offset, src, src_offset, range, copy_agent, dir,
|
||||
num_dep_signals, dep_signals, tracker_entry->signal);
|
||||
if (status == HSA_STATUS_SUCCESS) {
|
||||
tracker->EnableMemcopy(tracker_entry, async_copy_handler, reinterpret_cast<void*>(tracker_entry));
|
||||
tracker->EnableMemcopy(tracker_entry, async_copy_handler,
|
||||
reinterpret_cast<void*>(tracker_entry));
|
||||
} else {
|
||||
tracker->Delete(tracker_entry);
|
||||
}
|
||||
@@ -385,19 +376,31 @@ Tracker::mutex_t Tracker::glob_mutex_;
|
||||
Tracker::counter_t Tracker::counter_ = 0;
|
||||
util::Logger::mutex_t util::Logger::mutex_;
|
||||
std::atomic<util::Logger*> util::Logger::instance_{};
|
||||
}
|
||||
} // namespace rocprofiler
|
||||
|
||||
CONTEXT_INSTANTIATE();
|
||||
|
||||
static bool started{false};
|
||||
// #include "src/core/hsa/hsa_support.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public library methods
|
||||
//
|
||||
extern "C" {
|
||||
|
||||
// The HSA_AMD_TOOL_PRIORITY variable must be a constant value type
|
||||
// initialized by the loader itself, not by code during _init. 'extern const'
|
||||
// seems do that although that is not a guarantee.
|
||||
ROCPROFILER_EXPORT extern const uint32_t HSA_AMD_TOOL_PRIORITY = 25;
|
||||
|
||||
|
||||
// HSA-runtime tool on-load method
|
||||
PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t failed_tool_count,
|
||||
const char* const* failed_tool_names) {
|
||||
ONLOAD_TRACE_BEG();
|
||||
if (started) rocmtools::fatal("HSA Tool started already!");
|
||||
started = true;
|
||||
rocmtools::hsa_support::Initialize(table);
|
||||
rocprofiler::SaveHsaApi(table);
|
||||
rocprofiler::ProxyQueue::InitFactory();
|
||||
|
||||
@@ -411,17 +414,19 @@ PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t fa
|
||||
switch (intercept_env_value) {
|
||||
case 0:
|
||||
case 1:
|
||||
// 0: Intercepting disabled
|
||||
// 1: Intercepting enabled without timestamping
|
||||
// 0: Intercepting disabled
|
||||
// 1: Intercepting enabled without timestamping
|
||||
rocprofiler::InterceptQueue::TrackerOn(false);
|
||||
break;
|
||||
case 2:
|
||||
// Intercepting enabled with timestamping
|
||||
// Intercepting enabled with timestamping
|
||||
rocprofiler::InterceptQueue::TrackerOn(true);
|
||||
break;
|
||||
default:
|
||||
ERR_LOGGING("Bad ROCP_HSA_INTERCEPT env var value (" << intercept_env << "): " <<
|
||||
"valid values are 0 (standalone), 1 (intercepting without timestamp), 2 (intercepting with timestamp)");
|
||||
ERR_LOGGING("Bad ROCP_HSA_INTERCEPT env var value ("
|
||||
<< intercept_env << "): "
|
||||
<< "valid values are 0 (standalone), 1 (intercepting without timestamp), 2 "
|
||||
"(intercepting with timestamp)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -436,9 +441,12 @@ PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t fa
|
||||
hsa_status_t status = hsa_amd_profiling_async_copy_enable(true);
|
||||
if (status != HSA_STATUS_SUCCESS) EXC_ABORT(status, "hsa_amd_profiling_async_copy_enable");
|
||||
rocprofiler::hsa_amd_memory_async_copy_fn = table->amd_ext_->hsa_amd_memory_async_copy_fn;
|
||||
rocprofiler::hsa_amd_memory_async_copy_rect_fn = table->amd_ext_->hsa_amd_memory_async_copy_rect_fn;
|
||||
table->amd_ext_->hsa_amd_memory_async_copy_fn = rocprofiler::hsa_amd_memory_async_copy_interceptor;
|
||||
table->amd_ext_->hsa_amd_memory_async_copy_rect_fn = rocprofiler::hsa_amd_memory_async_copy_rect_interceptor;
|
||||
rocprofiler::hsa_amd_memory_async_copy_rect_fn =
|
||||
table->amd_ext_->hsa_amd_memory_async_copy_rect_fn;
|
||||
table->amd_ext_->hsa_amd_memory_async_copy_fn =
|
||||
rocprofiler::hsa_amd_memory_async_copy_interceptor;
|
||||
table->amd_ext_->hsa_amd_memory_async_copy_rect_fn =
|
||||
rocprofiler::hsa_amd_memory_async_copy_rect_interceptor;
|
||||
}
|
||||
if (intercept_mode_mask & rocprofiler::HSA_INTERCEPT_MODE) {
|
||||
if (intercept_mode_mask & rocprofiler::MEMCOPY_INTERCEPT_MODE) {
|
||||
@@ -456,23 +464,22 @@ PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t fa
|
||||
rocprofiler::StandaloneIntercept();
|
||||
}
|
||||
|
||||
ONLOAD_TRACE("end intercept_mode(" << std::hex << intercept_env_value << ")" <<
|
||||
" intercept_mode_mask(" << std::hex << intercept_mode_mask << ")" << std::dec);
|
||||
ONLOAD_TRACE("end intercept_mode(" << std::hex << intercept_env_value << ")"
|
||||
<< " intercept_mode_mask(" << std::hex << intercept_mode_mask
|
||||
<< ")" << std::dec);
|
||||
return true;
|
||||
}
|
||||
|
||||
// HSA-runtime tool on-unload method
|
||||
PUBLIC_API void OnUnload() {
|
||||
ONLOAD_TRACE_BEG();
|
||||
if (!started) rocmtools::fatal("HSA Tool hasn't started yet!");
|
||||
rocmtools::hsa_support::Finalize();
|
||||
rocprofiler::UnloadTool();
|
||||
rocprofiler::RestoreHsaApi();
|
||||
ONLOAD_TRACE_END();
|
||||
}
|
||||
|
||||
// Returns library vesrion
|
||||
PUBLIC_API uint32_t rocprofiler_version_major() { return ROCPROFILER_VERSION_MAJOR; }
|
||||
PUBLIC_API uint32_t rocprofiler_version_minor() { return ROCPROFILER_VERSION_MINOR; }
|
||||
|
||||
// Returns the last error message
|
||||
PUBLIC_API hsa_status_t rocprofiler_error_string(const char** str) {
|
||||
API_METHOD_PREFIX
|
||||
@@ -482,8 +489,8 @@ PUBLIC_API hsa_status_t rocprofiler_error_string(const char** str) {
|
||||
|
||||
// Create new profiling context
|
||||
PUBLIC_API hsa_status_t rocprofiler_open(hsa_agent_t agent, rocprofiler_feature_t* features,
|
||||
uint32_t feature_count, rocprofiler_t** handle, uint32_t mode,
|
||||
rocprofiler_properties_t* properties) {
|
||||
uint32_t feature_count, rocprofiler_t** handle,
|
||||
uint32_t mode, rocprofiler_properties_t* properties) {
|
||||
API_METHOD_PREFIX
|
||||
rocprofiler::util::HsaRsrcFactory* hsa_rsrc = &rocprofiler::util::HsaRsrcFactory::Instance();
|
||||
const rocprofiler::util::AgentInfo* agent_info = hsa_rsrc->GetAgentInfo(agent);
|
||||
@@ -495,7 +502,8 @@ PUBLIC_API hsa_status_t rocprofiler_open(hsa_agent_t agent, rocprofiler_feature_
|
||||
if (mode != 0) {
|
||||
if (mode & ROCPROFILER_MODE_STANDALONE) {
|
||||
if (mode & ROCPROFILER_MODE_CREATEQUEUE) {
|
||||
if (hsa_rsrc->CreateQueue(agent_info, properties->queue_depth, &(properties->queue)) == false) {
|
||||
if (hsa_rsrc->CreateQueue(agent_info, properties->queue_depth, &(properties->queue)) ==
|
||||
false) {
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "CreateQueue() failed");
|
||||
}
|
||||
}
|
||||
@@ -623,7 +631,8 @@ PUBLIC_API hsa_status_t rocprofiler_get_metrics(const rocprofiler_t* handle) {
|
||||
}
|
||||
|
||||
// Set/remove queue callbacks
|
||||
PUBLIC_API hsa_status_t rocprofiler_set_queue_callbacks(rocprofiler_queue_callbacks_t callbacks, void* data) {
|
||||
PUBLIC_API hsa_status_t rocprofiler_set_queue_callbacks(rocprofiler_queue_callbacks_t callbacks,
|
||||
void* data) {
|
||||
API_METHOD_PREFIX
|
||||
rocprofiler::InterceptQueue::SetCallbacks(callbacks, data);
|
||||
API_METHOD_SUFFIX
|
||||
@@ -659,12 +668,13 @@ PUBLIC_API hsa_status_t rocprofiler_iterate_trace_data(
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Open profiling pool
|
||||
PUBLIC_API hsa_status_t rocprofiler_pool_open(hsa_agent_t agent, // GPU handle
|
||||
rocprofiler_feature_t* features, // [in] profiling features array
|
||||
uint32_t feature_count, // profiling info count
|
||||
rocprofiler_pool_t** pool, // [out] context object
|
||||
uint32_t mode, // profiling mode mask
|
||||
rocprofiler_pool_properties_t* properties) // pool properties
|
||||
PUBLIC_API hsa_status_t
|
||||
rocprofiler_pool_open(hsa_agent_t agent, // GPU handle
|
||||
rocprofiler_feature_t* features, // [in] profiling features array
|
||||
uint32_t feature_count, // profiling info count
|
||||
rocprofiler_pool_t** pool, // [out] context object
|
||||
uint32_t mode, // profiling mode mask
|
||||
rocprofiler_pool_properties_t* properties) // pool properties
|
||||
{
|
||||
API_METHOD_PREFIX
|
||||
rocprofiler::util::HsaRsrcFactory* hsa_rsrc = &rocprofiler::util::HsaRsrcFactory::Instance();
|
||||
@@ -674,14 +684,8 @@ PUBLIC_API hsa_status_t rocprofiler_pool_open(hsa_agent_t agent, // GPU h
|
||||
}
|
||||
|
||||
rocprofiler::ContextPool* obj = rocprofiler::ContextPool::Create(
|
||||
properties->num_entries,
|
||||
properties->payload_bytes,
|
||||
agent_info,
|
||||
features,
|
||||
feature_count,
|
||||
properties->handler,
|
||||
properties->handler_arg
|
||||
);
|
||||
properties->num_entries, properties->payload_bytes, agent_info, features, feature_count,
|
||||
properties->handler, properties->handler_arg);
|
||||
*pool = reinterpret_cast<rocprofiler_pool_t*>(obj);
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
@@ -696,8 +700,9 @@ PUBLIC_API hsa_status_t rocprofiler_pool_close(rocprofiler_pool_t* pool) // pro
|
||||
}
|
||||
|
||||
// Fetch profiling pool entry
|
||||
PUBLIC_API hsa_status_t rocprofiler_pool_fetch(rocprofiler_pool_t* pool, // profiling pool handle
|
||||
rocprofiler_pool_entry_t* entry) // [out] empty profling pool entry
|
||||
PUBLIC_API hsa_status_t
|
||||
rocprofiler_pool_fetch(rocprofiler_pool_t* pool, // profiling pool handle
|
||||
rocprofiler_pool_entry_t* entry) // [out] empty profling pool entry
|
||||
{
|
||||
API_METHOD_PREFIX
|
||||
rocprofiler::ContextPool* context_pool = reinterpret_cast<rocprofiler::ContextPool*>(pool);
|
||||
@@ -716,11 +721,8 @@ PUBLIC_API hsa_status_t rocprofiler_pool_flush(rocprofiler_pool_t* pool) // pro
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Return the info for a given info kind
|
||||
PUBLIC_API hsa_status_t rocprofiler_get_info(
|
||||
const hsa_agent_t *agent,
|
||||
rocprofiler_info_kind_t kind,
|
||||
void *data)
|
||||
{
|
||||
PUBLIC_API hsa_status_t rocprofiler_get_info(const hsa_agent_t* agent, rocprofiler_info_kind_t kind,
|
||||
void* data) {
|
||||
API_METHOD_PREFIX
|
||||
if (agent == NULL) EXC_RAISING(HSA_STATUS_ERROR, "NULL agent");
|
||||
uint32_t* result_32bit_ptr = reinterpret_cast<uint32_t*>(data);
|
||||
@@ -738,13 +740,11 @@ PUBLIC_API hsa_status_t rocprofiler_get_info(
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
|
||||
// Iterate over the info for a given info kind, and invoke an application-defined callback on every iteration
|
||||
// Iterate over the info for a given info kind, and invoke an application-defined callback on every
|
||||
// iteration
|
||||
PUBLIC_API hsa_status_t rocprofiler_iterate_info(
|
||||
const hsa_agent_t* agent,
|
||||
rocprofiler_info_kind_t kind,
|
||||
hsa_status_t (*callback)(const rocprofiler_info_data_t info, void* data),
|
||||
void* data)
|
||||
{
|
||||
const hsa_agent_t* agent, rocprofiler_info_kind_t kind,
|
||||
hsa_status_t (*callback)(const rocprofiler_info_data_t info, void* data), void* data) {
|
||||
API_METHOD_PREFIX
|
||||
rocprofiler::util::HsaRsrcFactory* hsa_rsrc = &rocprofiler::util::HsaRsrcFactory::Instance();
|
||||
rocprofiler_info_data_t info{};
|
||||
@@ -763,8 +763,7 @@ PUBLIC_API hsa_status_t rocprofiler_iterate_info(
|
||||
info.agent_index = agent_idx;
|
||||
|
||||
switch (kind) {
|
||||
case ROCPROFILER_INFO_KIND_METRIC:
|
||||
{
|
||||
case ROCPROFILER_INFO_KIND_METRIC: {
|
||||
const rocprofiler::MetricsDict* dict = rocprofiler::GetMetrics(agent_info->dev_id);
|
||||
auto nodes_vec = dict->GetNodes();
|
||||
|
||||
@@ -788,24 +787,31 @@ PUBLIC_API hsa_status_t rocprofiler_iterate_info(
|
||||
|
||||
// Query block id info
|
||||
hsa_ven_amd_aqlprofile_id_query_t query = {block_name.c_str(), 0, 0};
|
||||
hsa_status_t status = rocprofiler::util::HsaRsrcFactory::Instance().AqlProfileApi()->hsa_ven_amd_aqlprofile_get_info(
|
||||
&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_ID, &query);
|
||||
if (status != HSA_STATUS_SUCCESS) AQL_EXC_RAISING(HSA_STATUS_ERROR, "get block id info: '" << block_name << "'");
|
||||
hsa_status_t status = rocprofiler::util::HsaRsrcFactory::Instance()
|
||||
.AqlProfileApi()
|
||||
->hsa_ven_amd_aqlprofile_get_info(
|
||||
&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_ID, &query);
|
||||
if (status != HSA_STATUS_SUCCESS)
|
||||
AQL_EXC_RAISING(HSA_STATUS_ERROR, "get block id info: '" << block_name << "'");
|
||||
|
||||
// Metric object
|
||||
const std::string metric_name = (query.instance_count > 1) ? name + "[0]" : name;
|
||||
const rocprofiler::Metric* metric = dict->Get(metric_name);
|
||||
if (metric == NULL) EXC_RAISING(HSA_STATUS_ERROR, "metric '" << name << "' is not found");
|
||||
if (metric == NULL)
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "metric '" << name << "' is not found");
|
||||
|
||||
// Process metrics counters
|
||||
const rocprofiler::counters_vec_t& counters_vec = metric->GetCounters();
|
||||
if (counters_vec.size() != 1) EXC_RAISING(HSA_STATUS_ERROR, "error: '" << metric->GetName() << "' is not basic");
|
||||
if (counters_vec.size() != 1)
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "error: '" << metric->GetName() << "' is not basic");
|
||||
|
||||
// Query block counters number
|
||||
uint32_t block_counters;
|
||||
profile.events = &(counters_vec[0]->event);
|
||||
status = rocprofiler::util::HsaRsrcFactory::Instance().AqlProfileApi()->hsa_ven_amd_aqlprofile_get_info(
|
||||
&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS, &block_counters);
|
||||
status = rocprofiler::util::HsaRsrcFactory::Instance()
|
||||
.AqlProfileApi()
|
||||
->hsa_ven_amd_aqlprofile_get_info(
|
||||
&profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS, &block_counters);
|
||||
if (status != HSA_STATUS_SUCCESS) continue;
|
||||
|
||||
info.metric.instances = query.instance_count;
|
||||
@@ -818,8 +824,7 @@ PUBLIC_API hsa_status_t rocprofiler_iterate_info(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_INFO_KIND_TRACE:
|
||||
{
|
||||
case ROCPROFILER_INFO_KIND_TRACE: {
|
||||
info.trace.name = strdup("TT");
|
||||
info.trace.description = strdup("Thread Trace");
|
||||
info.trace.parameter_count = 5;
|
||||
@@ -841,13 +846,11 @@ PUBLIC_API hsa_status_t rocprofiler_iterate_info(
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
|
||||
// Iterate over the info for a given info query, and invoke an application-defined callback on every iteration
|
||||
// Iterate over the info for a given info query, and invoke an application-defined callback on every
|
||||
// iteration
|
||||
PUBLIC_API hsa_status_t rocprofiler_query_info(
|
||||
const hsa_agent_t *agent,
|
||||
rocprofiler_info_query_t query,
|
||||
hsa_status_t (*callback)(const rocprofiler_info_data_t info, void *data),
|
||||
void *data)
|
||||
{
|
||||
const hsa_agent_t* agent, rocprofiler_info_query_t query,
|
||||
hsa_status_t (*callback)(const rocprofiler_info_data_t info, void* data), void* data) {
|
||||
API_METHOD_PREFIX
|
||||
EXC_RAISING(HSA_STATUS_ERROR, "Not implemented");
|
||||
API_METHOD_SUFFIX
|
||||
@@ -856,23 +859,17 @@ PUBLIC_API hsa_status_t rocprofiler_query_info(
|
||||
// Creates a profiled queue. All dispatches on this queue will be profiled
|
||||
PUBLIC_API hsa_status_t rocprofiler_queue_create_profiled(
|
||||
hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data),
|
||||
void* data, uint32_t private_segment_size, uint32_t group_segment_size,
|
||||
hsa_queue_t** queue)
|
||||
{
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,
|
||||
uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue) {
|
||||
API_METHOD_PREFIX
|
||||
status = rocprofiler::InterceptQueue::QueueCreateTracked(
|
||||
agent, size, type, callback, data, private_segment_size, group_segment_size, queue);
|
||||
agent, size, type, callback, data, private_segment_size, group_segment_size, queue);
|
||||
API_METHOD_SUFFIX
|
||||
}
|
||||
|
||||
// Return time value for a given time ID and profiling timestamp
|
||||
PUBLIC_API hsa_status_t rocprofiler_get_time(
|
||||
rocprofiler_time_id_t time_id,
|
||||
uint64_t timestamp,
|
||||
uint64_t* value_ns,
|
||||
uint64_t* error_ns)
|
||||
{
|
||||
PUBLIC_API hsa_status_t rocprofiler_get_time(rocprofiler_time_id_t time_id, uint64_t timestamp,
|
||||
uint64_t* value_ns, uint64_t* error_ns) {
|
||||
API_METHOD_PREFIX
|
||||
if (error_ns != NULL) {
|
||||
*error_ns = 0;
|
||||
@@ -891,14 +888,16 @@ PUBLIC_API hsa_status_t rocprofiler_get_time(
|
||||
// HSA API callbacks routines
|
||||
//
|
||||
bool rocprofiler::HsaInterceptor::enable_ = false;
|
||||
thread_local bool rocprofiler::HsaInterceptor::recursion_ = false;;
|
||||
thread_local bool rocprofiler::HsaInterceptor::recursion_ = false;
|
||||
;
|
||||
rocprofiler_hsa_callbacks_t rocprofiler::HsaInterceptor::callbacks_{};
|
||||
rocprofiler::HsaInterceptor::arg_t rocprofiler::HsaInterceptor::arg_{};
|
||||
hsa_ven_amd_loader_1_01_pfn_t rocprofiler::HsaInterceptor::LoaderApiTable{};
|
||||
rocprofiler::HsaInterceptor::mutex_t rocprofiler::HsaInterceptor::mutex_;
|
||||
|
||||
// Set HSA callbacks. If a callback is NULL then it is disabled
|
||||
extern "C" PUBLIC_API hsa_status_t rocprofiler_set_hsa_callbacks(const rocprofiler_hsa_callbacks_t callbacks, void* arg) {
|
||||
extern "C" PUBLIC_API hsa_status_t
|
||||
rocprofiler_set_hsa_callbacks(const rocprofiler_hsa_callbacks_t callbacks, void* arg) {
|
||||
API_METHOD_PREFIX
|
||||
rocprofiler::HsaInterceptor::SetCallbacks(callbacks, arg);
|
||||
rocprofiler::InterceptQueue::SetSubmitCallback(callbacks.submit, arg);
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
#include "device_profiling.h"
|
||||
// #include "src/utils/debug.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sched.h>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
#include "src/utils/exception.h"
|
||||
#include "src/core/hsa/queues/queue.h"
|
||||
// #include "src/core/counters/rdc/rdc_metrics.h"
|
||||
#include "src/core/hsa/hsa_common.h"
|
||||
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
#include <stdexcept>
|
||||
|
||||
#define QUEUE_NUM_PACKETS 64
|
||||
static const size_t CMD_SLOT_SIZE_B = 0x40;
|
||||
|
||||
using namespace rocmtools;
|
||||
|
||||
typedef std::vector<hsa_ven_amd_aqlprofile_info_data_t> pmc_callback_data_t;
|
||||
|
||||
|
||||
static std::atomic<uint64_t> SESSION_COUNTER{1};
|
||||
|
||||
uint64_t GenerateUniqueSessionId() {
|
||||
return SESSION_COUNTER.fetch_add(1, std::memory_order_release);
|
||||
}
|
||||
|
||||
struct devices_t {
|
||||
std::vector<hsa_agent_t> cpu_devices;
|
||||
std::vector<hsa_agent_t> gpu_devices;
|
||||
std::vector<hsa_agent_t> other_devices;
|
||||
};
|
||||
|
||||
|
||||
bool createHsaQueue(hsa_queue_t** queue, hsa_agent_t gpu_agent) {
|
||||
// create a single-producer queue
|
||||
// TODO: check if API args are correct, especially UINT32_MAX
|
||||
hsa_status_t status;
|
||||
status = hsa_queue_create(gpu_agent, QUEUE_NUM_PACKETS, HSA_QUEUE_TYPE_SINGLE, NULL, NULL,
|
||||
UINT32_MAX, UINT32_MAX, queue);
|
||||
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("queue creation failed");
|
||||
|
||||
return (status == HSA_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
uint64_t submitPacket(hsa_queue_t* queue, const void* packet) {
|
||||
const uint32_t slot_size_b = CMD_SLOT_SIZE_B;
|
||||
|
||||
// advance command queue
|
||||
const uint64_t write_idx = hsa_queue_add_write_index_scacq_screl(queue, 1);
|
||||
while ((write_idx - hsa_queue_load_read_index_relaxed(queue)) >= queue->size) {
|
||||
sched_yield(); // TODO: remove
|
||||
}
|
||||
|
||||
const uint32_t slot_idx = (uint32_t)(write_idx % queue->size);
|
||||
uint32_t* queue_slot =
|
||||
reinterpret_cast<uint32_t*>((uintptr_t)(queue->base_address) + (slot_idx * slot_size_b));
|
||||
const uint32_t* slot_data = reinterpret_cast<const uint32_t*>(packet);
|
||||
|
||||
// Copy buffered commands into the queue slot.
|
||||
// Overwrite the AQL invalid header (first dword) last.
|
||||
// This prevents the slot from being read until it's fully written.
|
||||
memcpy(&queue_slot[1], &slot_data[1], slot_size_b - sizeof(uint32_t));
|
||||
std::atomic<uint32_t>* header_atomic_ptr =
|
||||
reinterpret_cast<std::atomic<uint32_t>*>(&queue_slot[0]);
|
||||
header_atomic_ptr->store(slot_data[0], std::memory_order_release);
|
||||
|
||||
// ringdoor bell
|
||||
hsa_signal_store_relaxed(queue->doorbell_signal, write_idx);
|
||||
|
||||
return write_idx;
|
||||
}
|
||||
|
||||
// Wait signal
|
||||
hsa_signal_value_t signalWait(const hsa_signal_t& signal, const hsa_signal_value_t& signal_value) {
|
||||
const hsa_signal_value_t exp_value = signal_value - 1;
|
||||
hsa_signal_value_t ret_value = signal_value;
|
||||
while (1) {
|
||||
// TODO: The 4th argument mentioning timeout is current set to UINT64_MAX.
|
||||
// Probably a maximum wait time should be set. We don't want application to hang because of
|
||||
// unlimited wait.
|
||||
// TODO2 : try 500000 assuming nanosecond granularity -- must be verified.
|
||||
ret_value = hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_LT, signal_value, UINT64_MAX,
|
||||
HSA_WAIT_STATE_BLOCKED);
|
||||
if (ret_value == exp_value) break;
|
||||
if (ret_value != signal_value)
|
||||
fatal("Error: signalWait: signal_value(%lu), ret_value(%lu)", signal_value, ret_value);
|
||||
}
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
bool DeviceProfileSession::generatePackets() {
|
||||
// char gpu_name[64];
|
||||
// hsa_agent_get_info(gpu_agent_, HSA_AGENT_INFO_NAME, gpu_name);
|
||||
|
||||
// Get the PM4 Packets
|
||||
// TODO: The below function is wasteful. Doesn't do resource cleanup.
|
||||
// write a function that is specific to the needs of this class
|
||||
|
||||
/*
|
||||
profiles_ = Packet::initializeAqlPackets(
|
||||
cpu_agent_, gpu_agent_, gpu_name, profiling_data_,
|
||||
profiling_data_.size());
|
||||
|
||||
if(profiles_->size() > 1)
|
||||
std::cout<<"Multiple profiles present!\n";
|
||||
|
||||
profile_ = (*profiles_)[0].second;
|
||||
start_packet_ = *(*profiles_)[0].first->start_packet;
|
||||
stop_packet_ = *(*profiles_)[0].first->stop_packet;
|
||||
read_packet_ = *(*profiles_)[0].first->read_packet;
|
||||
|
||||
counter_map_ = *(*profiles_)[0].first->counter_map; */
|
||||
|
||||
std::map<std::pair<uint32_t, uint32_t>, uint64_t> events_max_block_counters;
|
||||
std::map<std::string, std::set<std::string>> metrics_counters;
|
||||
|
||||
|
||||
metrics::ExtractMetricEvents(profiling_data_, gpu_agent_, metrics_dict_, results_map_,
|
||||
events_list_, results_list_, events_max_block_counters,
|
||||
metrics_counters);
|
||||
|
||||
profile_ = Packet::InitializeDeviceProfilingAqlPackets(cpu_agent_, gpu_agent_, &events_list_[0],
|
||||
events_list_.size(), &start_packet_,
|
||||
&stop_packet_, &read_packet_);
|
||||
|
||||
start_packet_.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE;
|
||||
|
||||
start_packet_.completion_signal = {};
|
||||
|
||||
|
||||
read_packet_.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE;
|
||||
|
||||
read_packet_.completion_signal = {};
|
||||
|
||||
stop_packet_.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE;
|
||||
|
||||
stop_packet_.completion_signal = {};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceProfileSession::createQueue() {
|
||||
// Ensuring there is only one queue per device
|
||||
hsa_queue_t* queue = DeviceProfileSession::getQueue(gpu_agent_);
|
||||
if (queue != nullptr) return true;
|
||||
if (::createHsaQueue(&queue, gpu_agent_) == false) return false;
|
||||
|
||||
std::lock_guard<std::mutex> lock(agent_queue_map_mutex_);
|
||||
agent_queue_map_.insert(std::make_pair(gpu_agent_.handle, queue));
|
||||
return true;
|
||||
}
|
||||
|
||||
hsa_queue_t* DeviceProfileSession::getQueue(hsa_agent_t gpu_agent) {
|
||||
std::lock_guard<std::mutex> lock(agent_queue_map_mutex_);
|
||||
auto it = agent_queue_map_.find(gpu_agent.handle);
|
||||
return (it != agent_queue_map_.end()) ? it->second : nullptr;
|
||||
}
|
||||
|
||||
DeviceProfileSession::DeviceProfileSession(std::vector<std::string> profiling_data,
|
||||
hsa_agent_t cpu_agent, hsa_agent_t gpu_agent,
|
||||
uint64_t* session_id)
|
||||
: profiling_data_(profiling_data), cpu_agent_(cpu_agent), gpu_agent_(gpu_agent) {
|
||||
session_id_ = GenerateUniqueSessionId();
|
||||
*session_id = session_id_;
|
||||
|
||||
// initialize packets struct
|
||||
start_packet_ = {};
|
||||
stop_packet_ = {};
|
||||
read_packet_ = {};
|
||||
|
||||
profile_ = NULL;
|
||||
|
||||
char gpu_name[64];
|
||||
if (hsa_agent_get_info(gpu_agent_, HSA_AGENT_INFO_NAME, gpu_name) != HSA_STATUS_SUCCESS)
|
||||
fatal("Agent name query failed");
|
||||
|
||||
Agent::AgentInfo* agentInfo = &(hsa_support::GetAgentInfo(gpu_agent_.handle));
|
||||
metrics_dict_ = MetricsDict::Create(agentInfo);
|
||||
|
||||
for (auto& d : profiling_data_) {
|
||||
Metric* metric = const_cast<Metric*>(metrics_dict_->Get(d));
|
||||
if (metric == NULL) std::cout << d << " not found in metrics_dict\n";
|
||||
metrics_list_.push_back(metric);
|
||||
}
|
||||
|
||||
createQueue();
|
||||
generatePackets();
|
||||
|
||||
// create signals
|
||||
hsa_status_t status = hsa_signal_create(1, 0, NULL, &start_signal_);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("start signal creation failed");
|
||||
|
||||
status = hsa_signal_create(1, 0, NULL, &completion_signal_);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("completion signal creation failed");
|
||||
|
||||
status = hsa_signal_create(1, 0, NULL, &stop_signal_);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("stop signal creation failed");
|
||||
}
|
||||
|
||||
DeviceProfileSession::~DeviceProfileSession() {
|
||||
// TODO:
|
||||
// delete queue
|
||||
// delete signals
|
||||
// free command buffer/output buffer
|
||||
}
|
||||
|
||||
void DeviceProfileSession::StartSession() {
|
||||
// TODO: check if session was already started. Don't allow start twice
|
||||
|
||||
// Set completion signal
|
||||
start_packet_.completion_signal = start_signal_;
|
||||
|
||||
// Place the "Start" packet in the Queue
|
||||
submitPacket(DeviceProfileSession::getQueue(gpu_agent_), &start_packet_);
|
||||
|
||||
// Wait for the completion signal of the packet
|
||||
::signalWait(start_packet_.completion_signal, 1);
|
||||
|
||||
// restore signal to a value of 1
|
||||
hsa_signal_store_screlease(start_signal_, 1);
|
||||
|
||||
// set a variable that this session has started
|
||||
}
|
||||
|
||||
void DeviceProfileSession::PollMetrics(rocprofiler_device_profile_metric_t* data) {
|
||||
// TODO: check if session was already started
|
||||
// TODO: can't poll if stopped
|
||||
// Reset the completion signal value for read packet
|
||||
// TODO: clear profile output buffer
|
||||
|
||||
// Set completion signal
|
||||
read_packet_.completion_signal = completion_signal_;
|
||||
|
||||
// Place the "Read" packet in the Queue
|
||||
::submitPacket(DeviceProfileSession::getQueue(gpu_agent_), &read_packet_);
|
||||
|
||||
// Wait for the completion signal of the packet
|
||||
::signalWait(read_packet_.completion_signal, 1);
|
||||
|
||||
// Collect counter values for events
|
||||
metrics::GetCounterData(profile_, results_list_);
|
||||
|
||||
// evaluate metrics based on collected counter values
|
||||
metrics::GetMetricsData(results_map_, metrics_list_);
|
||||
|
||||
for (size_t i = 0; i < profiling_data_.size(); i++) {
|
||||
auto it = results_map_.find(profiling_data_[i]);
|
||||
if (it != results_map_.end()) {
|
||||
strcpy(data[i].metric_name, it->first.c_str());
|
||||
data[i].value.value = it->second->val_double;
|
||||
}
|
||||
}
|
||||
|
||||
// restore signal to a value of 1
|
||||
hsa_signal_store_screlease(completion_signal_, 1);
|
||||
}
|
||||
|
||||
void DeviceProfileSession::StopSession() {
|
||||
// TODO: check if session was already started
|
||||
|
||||
// Set completion signal
|
||||
stop_packet_.completion_signal = stop_signal_;
|
||||
|
||||
// Place the "Stop" packet in the Queue
|
||||
submitPacket(DeviceProfileSession::getQueue(gpu_agent_), &stop_packet_);
|
||||
|
||||
// Wait for the completion signal of the packet
|
||||
// What is the correct value to wait for?
|
||||
signalWait(stop_packet_.completion_signal, 1);
|
||||
|
||||
// restore signal to a value of 1
|
||||
hsa_signal_store_screlease(stop_signal_, 1);
|
||||
}
|
||||
|
||||
hsa_status_t device_cb(hsa_agent_t agent, void* data) {
|
||||
hsa_device_type_t device_type;
|
||||
devices_t* devices = reinterpret_cast<devices_t*>(data);
|
||||
if (hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type) != HSA_STATUS_SUCCESS)
|
||||
fatal("hsa_agent_get_info failed");
|
||||
switch (device_type) {
|
||||
case HSA_DEVICE_TYPE_CPU:
|
||||
devices->cpu_devices.push_back(agent);
|
||||
break;
|
||||
case HSA_DEVICE_TYPE_GPU:
|
||||
devices->gpu_devices.push_back(agent);
|
||||
break;
|
||||
default:
|
||||
devices->other_devices.push_back(agent);
|
||||
break;
|
||||
}
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void get_hsa_agents_list(devices_t* device_list) {
|
||||
// Enumerate the agents.
|
||||
if (hsa_iterate_agents(device_cb, device_list) != HSA_STATUS_SUCCESS)
|
||||
fatal("hsa_iterate_agents failed");
|
||||
}
|
||||
|
||||
|
||||
bool rocmtools::find_hsa_agent_cpu(uint64_t index, hsa_agent_t* agent) {
|
||||
devices_t device_list;
|
||||
get_hsa_agents_list(&device_list);
|
||||
|
||||
if (index > device_list.cpu_devices.size()) return false;
|
||||
|
||||
*agent = device_list.cpu_devices[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rocmtools::find_hsa_agent_gpu(uint64_t index, hsa_agent_t* agent) {
|
||||
devices_t device_list;
|
||||
get_hsa_agents_list(&device_list);
|
||||
|
||||
if (index > device_list.gpu_devices.size()) return false;
|
||||
|
||||
*agent = device_list.gpu_devices[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<uint64_t, hsa_queue_t*> DeviceProfileSession::agent_queue_map_;
|
||||
std::mutex DeviceProfileSession::agent_queue_map_mutex_;
|
||||
@@ -0,0 +1,87 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_SESSION_DEVICE_PROFILING_H_
|
||||
#define SRC_CORE_SESSION_DEVICE_PROFILING_H_
|
||||
|
||||
#include <rocprofiler.h>
|
||||
#include "src/core/hsa/packets/packets_generator.h"
|
||||
#include <mutex>
|
||||
// #include "src/core/counters/rdc/rdc_metrics.h"
|
||||
#include "src/core/counters/metrics/metrics.h"
|
||||
#include "src/core/counters/metrics/eval_metrics.h"
|
||||
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
class DeviceProfileSession {
|
||||
public:
|
||||
void StartSession();
|
||||
void PollMetrics(rocprofiler_device_profile_metric_t* data);
|
||||
void StopSession();
|
||||
|
||||
DeviceProfileSession(std::vector<std::string> counters, hsa_agent_t cpu_agent,
|
||||
hsa_agent_t gpu_agent, uint64_t* session_id);
|
||||
|
||||
~DeviceProfileSession();
|
||||
|
||||
private:
|
||||
bool createQueue();
|
||||
bool generatePackets();
|
||||
bool readPmcCounters();
|
||||
|
||||
static hsa_queue_t* getQueue(hsa_agent_t);
|
||||
|
||||
uint64_t session_id_;
|
||||
|
||||
std::vector<std::string> profiling_data_;
|
||||
|
||||
hsa_agent_t cpu_agent_;
|
||||
hsa_agent_t gpu_agent_;
|
||||
|
||||
static std::map<uint64_t, hsa_queue_t*> agent_queue_map_;
|
||||
static std::mutex agent_queue_map_mutex_;
|
||||
|
||||
Packet::packet_t start_packet_;
|
||||
Packet::packet_t stop_packet_;
|
||||
Packet::packet_t read_packet_;
|
||||
|
||||
MetricsDict* metrics_dict_;
|
||||
std::vector<const Metric*> metrics_list_;
|
||||
std::map<std::string, results_t*> results_map_;
|
||||
std::vector<event_t> events_list_;
|
||||
std::vector<results_t*> results_list_;
|
||||
|
||||
hsa_signal_t completion_signal_;
|
||||
hsa_signal_t start_signal_;
|
||||
hsa_signal_t stop_signal_;
|
||||
|
||||
// TODO: remove this or do actual cleanup
|
||||
hsa_ven_amd_aqlprofile_profile_t* profile_;
|
||||
};
|
||||
|
||||
bool find_hsa_agent_cpu(uint64_t index, hsa_agent_t* agent);
|
||||
bool find_hsa_agent_gpu(uint64_t index, hsa_agent_t* agent);
|
||||
|
||||
|
||||
} // namespace rocmtools
|
||||
|
||||
|
||||
#endif // SRC_CORE_SESSION_DEVICE_PROFILING_H_
|
||||
@@ -0,0 +1,217 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "src/core/session/filter.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "src/utils/helper.h"
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
Filter::Filter(rocprofiler_filter_id_t id, rocprofiler_filter_kind_t filter_kind,
|
||||
rocprofiler_filter_data_t filter_data, uint64_t data_count)
|
||||
: id_(id), kind_(filter_kind) {
|
||||
switch (filter_kind) {
|
||||
case ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION: {
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_COUNTERS_COLLECTION: {
|
||||
profiler_counter_names_.clear();
|
||||
for (uint32_t j = 0; j < data_count; j++)
|
||||
profiler_counter_names_.emplace_back(filter_data.counters_names[j]);
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_PC_SAMPLING_COLLECTION:
|
||||
case ROCPROFILER_ATT_TRACE: {
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_SPM_COLLECTION: {
|
||||
spm_parameter_ = filter_data.spm_parameters;
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_API_TRACE: {
|
||||
tracer_apis_.clear();
|
||||
for (uint32_t j = 0; j < data_count; j++)
|
||||
tracer_apis_.emplace_back(filter_data.trace_apis[j]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
warning(
|
||||
"Error: ROCMtools filter specified is not supported for "
|
||||
"profiler mode!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Filter::~Filter() {}
|
||||
|
||||
rocprofiler_filter_id_t Filter::GetId() { return id_; }
|
||||
|
||||
void Filter::SetBufferId(rocprofiler_buffer_id_t buffer_id) { buffer_id_ = buffer_id; }
|
||||
rocprofiler_buffer_id_t Filter::GetBufferId() { return buffer_id_; }
|
||||
bool Filter::HasBuffer() { return (buffer_id_.value > 0); }
|
||||
|
||||
rocprofiler_filter_kind_t Filter::GetKind() { return kind_; }
|
||||
|
||||
std::mutex counter_data_lock;
|
||||
std::vector<std::string> Filter::GetCounterData() {
|
||||
if (kind_ == ROCPROFILER_COUNTERS_COLLECTION) {
|
||||
std::lock_guard<std::mutex> lock(counter_data_lock);
|
||||
return profiler_counter_names_;
|
||||
}
|
||||
fatal(
|
||||
"Error: ROCMtools filter specified is not supported for "
|
||||
"Counter Collection Filter!\n");
|
||||
}
|
||||
|
||||
std::vector<rocprofiler_tracer_activity_domain_t> Filter::GetTraceData() {
|
||||
if (kind_ == ROCPROFILER_API_TRACE) {
|
||||
return tracer_apis_;
|
||||
}
|
||||
fatal(
|
||||
"Error: ROCMtools filter specified is not supported for "
|
||||
"profiler mode!\n");
|
||||
}
|
||||
rocprofiler_spm_parameter_t* Filter::GetSpmParameterData() {
|
||||
if (kind_ == ROCPROFILER_SPM_COLLECTION) {
|
||||
return spm_parameter_;
|
||||
}
|
||||
fatal(
|
||||
"Error: ROCMtools filter specified is not supported for "
|
||||
"SPM collection mode!\n");
|
||||
}
|
||||
void Filter::SetProperty(rocprofiler_filter_property_t property) {
|
||||
switch (property.kind) {
|
||||
case ROCPROFILER_FILTER_HSA_TRACER_API_FUNCTIONS: {
|
||||
if (kind_ == ROCPROFILER_API_TRACE) {
|
||||
hsa_tracer_api_calls_.clear();
|
||||
for (uint32_t j = 0; j < property.data_count; j++)
|
||||
hsa_tracer_api_calls_.emplace_back(property.hsa_functions_names[j]);
|
||||
} else {
|
||||
throw(ROCPROFILER_STATUS_ERROR_SESSION_FILTER_DATA_MISMATCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_FILTER_HIP_TRACER_API_FUNCTIONS: {
|
||||
if (kind_ == ROCPROFILER_API_TRACE) {
|
||||
hip_tracer_api_calls_.clear();
|
||||
for (uint32_t j = 0; j < property.data_count; j++)
|
||||
hip_tracer_api_calls_.emplace_back(property.hip_functions_names[j]);
|
||||
} else {
|
||||
throw(ROCPROFILER_STATUS_ERROR_SESSION_FILTER_DATA_MISMATCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_FILTER_GPU_NAME: {
|
||||
if (kind_ == ROCPROFILER_COUNTERS_COLLECTION ||
|
||||
kind_ == ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION) {
|
||||
agent_names_.clear();
|
||||
for (uint32_t j = 0; j < property.data_count; j++)
|
||||
agent_names_.emplace_back(property.name_regex[j]);
|
||||
} else {
|
||||
throw(ROCPROFILER_STATUS_ERROR_SESSION_FILTER_DATA_MISMATCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_FILTER_RANGE: {
|
||||
if (kind_ == ROCPROFILER_COUNTERS_COLLECTION ||
|
||||
kind_ == ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION) {
|
||||
dispatch_range_[0] = property.range[0];
|
||||
dispatch_range_[1] = property.range[1];
|
||||
} else {
|
||||
throw(ROCPROFILER_STATUS_ERROR_SESSION_FILTER_DATA_MISMATCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ROCPROFILER_FILTER_KERNEL_NAMES: {
|
||||
if (kind_ == ROCPROFILER_COUNTERS_COLLECTION ||
|
||||
kind_ == ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION) {
|
||||
kernel_names_.clear();
|
||||
for (uint32_t j = 0; j < property.data_count; j++)
|
||||
kernel_names_.emplace_back(property.name_regex[j]);
|
||||
} else {
|
||||
throw(ROCPROFILER_STATUS_ERROR_SESSION_FILTER_DATA_MISMATCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
// TODO(aelwazir): Check for empty property
|
||||
// warning(
|
||||
// "Error: ROCMtools filter specified is not supported for "
|
||||
// "profiler mode!\n");
|
||||
}
|
||||
}
|
||||
std::variant<std::vector<std::string>, uint32_t*> Filter::GetProperty(
|
||||
rocprofiler_filter_property_kind_t kind) {
|
||||
std::variant<std::vector<std::string>, uint32_t*> property;
|
||||
switch (kind) {
|
||||
case ROCPROFILER_FILTER_GPU_NAME: {
|
||||
property = agent_names_;
|
||||
}
|
||||
case ROCPROFILER_FILTER_RANGE: {
|
||||
property = static_cast<uint32_t*>(dispatch_range_);
|
||||
}
|
||||
case ROCPROFILER_FILTER_KERNEL_NAMES: {
|
||||
property = kernel_names_;
|
||||
}
|
||||
case ROCPROFILER_FILTER_HSA_TRACER_API_FUNCTIONS: {
|
||||
property = hsa_tracer_api_calls_;
|
||||
}
|
||||
case ROCPROFILER_FILTER_HIP_TRACER_API_FUNCTIONS: {
|
||||
property = hip_tracer_api_calls_;
|
||||
}
|
||||
default:
|
||||
fatal(
|
||||
"Error: ROCMtools filter specified is not supported for the given "
|
||||
"kind!");
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
void Filter::SetCallback(rocprofiler_sync_callback_t& callback) { callback_ = callback; }
|
||||
|
||||
rocprofiler_sync_callback_t& Filter::GetCallback() { return callback_; }
|
||||
|
||||
size_t Filter::GetPropertiesCount(rocprofiler_filter_property_kind_t kind) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_FILTER_GPU_NAME: {
|
||||
return agent_names_.size();
|
||||
}
|
||||
case ROCPROFILER_FILTER_RANGE: {
|
||||
return 2;
|
||||
}
|
||||
case ROCPROFILER_FILTER_KERNEL_NAMES: {
|
||||
return kernel_names_.size();
|
||||
}
|
||||
case ROCPROFILER_FILTER_HSA_TRACER_API_FUNCTIONS: {
|
||||
return hsa_tracer_api_calls_.size();
|
||||
}
|
||||
case ROCPROFILER_FILTER_HIP_TRACER_API_FUNCTIONS: {
|
||||
return hip_tracer_api_calls_.size();
|
||||
}
|
||||
}
|
||||
fatal(
|
||||
"Error: ROCMtools filter specified is not supported for the given "
|
||||
"kind!");
|
||||
}
|
||||
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,80 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_SESSION_FILTER_H_
|
||||
#define SRC_CORE_SESSION_FILTER_H_
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "inc/rocprofiler.h"
|
||||
|
||||
#define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
class Filter {
|
||||
public:
|
||||
Filter(rocprofiler_filter_id_t id, rocprofiler_filter_kind_t filter_kind,
|
||||
rocprofiler_filter_data_t filter_data, uint64_t data_count);
|
||||
~Filter();
|
||||
|
||||
rocprofiler_filter_id_t GetId();
|
||||
|
||||
void SetBufferId(rocprofiler_buffer_id_t buffer_id);
|
||||
rocprofiler_buffer_id_t GetBufferId();
|
||||
bool HasBuffer();
|
||||
|
||||
rocprofiler_filter_kind_t GetKind();
|
||||
|
||||
std::vector<std::string> GetCounterData();
|
||||
std::vector<rocprofiler_tracer_activity_domain_t> GetTraceData();
|
||||
|
||||
void SetCallback(rocprofiler_sync_callback_t& callback);
|
||||
rocprofiler_sync_callback_t& GetCallback();
|
||||
|
||||
void SetProperty(rocprofiler_filter_property_t property);
|
||||
std::variant<std::vector<std::string>, uint32_t*> GetProperty(
|
||||
rocprofiler_filter_property_kind_t kind);
|
||||
size_t GetPropertiesCount(rocprofiler_filter_property_kind_t kind);
|
||||
rocprofiler_spm_parameter_t* GetSpmParameterData();
|
||||
|
||||
private:
|
||||
rocprofiler_filter_id_t id_;
|
||||
rocprofiler_filter_kind_t kind_;
|
||||
rocprofiler_buffer_id_t buffer_id_{0};
|
||||
|
||||
std::vector<std::string> agent_names_; // GPU name filter
|
||||
std::vector<std::string> hsa_tracer_api_calls_; // HSA API Functions
|
||||
std::vector<std::string> hip_tracer_api_calls_; // HIP API Functions
|
||||
std::vector<std::string> kernel_names_; // HIP/HSA API Functions
|
||||
uint32_t dispatch_range_[2]; // Kernel Dispatches OR API Range
|
||||
|
||||
std::vector<std::string> profiler_counter_names_; // Counter Names to collect
|
||||
std::vector<rocprofiler_tracer_activity_domain_t> tracer_apis_; // ROCTX/HIP/HSA API
|
||||
rocprofiler_spm_parameter_t* spm_parameter_; // spm parameter
|
||||
|
||||
rocprofiler_sync_callback_t callback_;
|
||||
};
|
||||
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_SESSION_FILTER_H_
|
||||
@@ -0,0 +1,145 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "profiler.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "src/core/counters/basic/basic_counter.h"
|
||||
#include "src/utils/helper.h"
|
||||
#include "src/utils/logger.h"
|
||||
|
||||
#define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
namespace rocmtools {
|
||||
namespace profiler {
|
||||
|
||||
uint64_t GetCounterID(std::string& counter_name) {
|
||||
static auto counter_hash_fn = std::hash<std::string>{};
|
||||
return counter_hash_fn(counter_name);
|
||||
}
|
||||
|
||||
Profiler::Profiler(rocprofiler_buffer_id_t buffer_id, rocprofiler_filter_id_t filter_id,
|
||||
rocprofiler_session_id_t session_id)
|
||||
: buffer_id_(buffer_id), filter_id_(filter_id), session_id_(session_id) {}
|
||||
Profiler::~Profiler() {}
|
||||
|
||||
void Profiler::AddCounterName(rocprofiler_counter_id_t counter_id, std::string counter_name) {
|
||||
std::lock_guard<std::mutex> lock(counter_names_lock_);
|
||||
counter_names_.emplace(counter_id.handle, counter_name);
|
||||
}
|
||||
|
||||
void Profiler::AddCounterName(std::string& counter_name) {
|
||||
std::lock_guard<std::mutex> lock(counter_names_lock_);
|
||||
counter_names_.emplace(GetCounterID(counter_name), counter_name);
|
||||
}
|
||||
|
||||
std::string& Profiler::GetCounterName(rocprofiler_counter_id_t counter_id) {
|
||||
std::lock_guard<std::mutex> lock(counter_names_lock_);
|
||||
auto it = counter_names_.find(counter_id.handle);
|
||||
ASSERTM(it != counter_names_.end(), "Error: couldn't find kernel name with given descriptor!");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool Profiler::FindCounter(rocprofiler_counter_id_t counter_id) {
|
||||
std::lock_guard<std::mutex> lock(counter_names_lock_);
|
||||
return counter_names_.find(counter_id.handle) != counter_names_.end();
|
||||
}
|
||||
size_t Profiler::GetCounterInfoSize(rocprofiler_counter_info_kind_t kind,
|
||||
rocprofiler_counter_id_t counter_id) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_COUNTER_NAME: {
|
||||
std::lock_guard<std::mutex> lock(counter_names_lock_);
|
||||
return counter_names_.at(counter_id.handle).size();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
warning("Not yet Supported!");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* Profiler::GetCounterInfo(rocprofiler_counter_info_kind_t kind,
|
||||
rocprofiler_counter_id_t counter_id) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_COUNTER_NAME: {
|
||||
std::lock_guard<std::mutex> lock(counter_names_lock_);
|
||||
return counter_names_.at(counter_id.handle).c_str();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
warning("Not yet Supported!");
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Profiler::StartReplayPass(rocprofiler_session_id_t session_id) { warning("Not yet supported!"); }
|
||||
void Profiler::EndReplayPass() { warning("Not yet supported!"); }
|
||||
bool Profiler::HasActivePass() {
|
||||
warning("Not yet supported!");
|
||||
return true;
|
||||
}
|
||||
|
||||
void Profiler::AddPendingSignals(uint32_t writer_id, uint64_t kernel_object,
|
||||
const hsa_signal_t& completion_signal,
|
||||
rocprofiler_session_id_t session_id, rocprofiler_buffer_id_t buffer_id,
|
||||
rocmtools::profiling_context_t* context,
|
||||
uint64_t session_data_count,
|
||||
hsa_ven_amd_aqlprofile_profile_t* profile,
|
||||
rocprofiler_kernel_properties_t kernel_properties,
|
||||
uint32_t thread_id, uint64_t queue_index) {
|
||||
std::lock_guard<std::mutex> lock(sessions_pending_signals_lock_);
|
||||
if (sessions_pending_signals_.find(writer_id) == sessions_pending_signals_.end())
|
||||
sessions_pending_signals_.emplace(writer_id, std::vector<pending_signal_t>());
|
||||
sessions_pending_signals_.at(writer_id).emplace_back(
|
||||
pending_signal_t{kernel_object, completion_signal, session_id_, buffer_id, context,
|
||||
session_data_count, profile});
|
||||
}
|
||||
|
||||
const std::vector<pending_signal_t>& Profiler::GetPendingSignals(uint32_t writer_id) {
|
||||
std::lock_guard<std::mutex> lock(sessions_pending_signals_lock_);
|
||||
assert(sessions_pending_signals_.find(writer_id) != sessions_pending_signals_.end() &&
|
||||
"writer_id is not found in the pending_signals");
|
||||
return sessions_pending_signals_.at(writer_id);
|
||||
}
|
||||
|
||||
bool Profiler::CheckPendingSignalsIsEmpty() {
|
||||
std::lock_guard<std::mutex> lock(sessions_pending_signals_lock_);
|
||||
return sessions_pending_signals_.empty();
|
||||
}
|
||||
|
||||
} // namespace profiler
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,106 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_TOOLS_PROFILER_PROFILER_H_
|
||||
#define SRC_TOOLS_PROFILER_PROFILER_H_
|
||||
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "inc/rocprofiler.h"
|
||||
#include "src/core/counters/basic/basic_counter.h"
|
||||
#include "src/core/counters/metrics/eval_metrics.h"
|
||||
|
||||
typedef void (*rocprofiler_add_profiler_record_t)(rocprofiler_record_profiler_t&& record,
|
||||
rocprofiler_session_id_t session_id);
|
||||
|
||||
typedef rocprofiler_timestamp_t (*rocprofiler_get_timestamp_t)();
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
typedef struct {
|
||||
uint64_t kernel_descriptor;
|
||||
hsa_signal_t signal;
|
||||
rocprofiler_session_id_t session_id;
|
||||
rocprofiler_buffer_id_t buffer_id;
|
||||
rocmtools::profiling_context_t* context;
|
||||
uint64_t counters_count;
|
||||
hsa_ven_amd_aqlprofile_profile_t* profile;
|
||||
rocprofiler_kernel_properties_t kernel_properties;
|
||||
uint32_t thread_id;
|
||||
uint64_t queue_index;
|
||||
} pending_signal_t;
|
||||
|
||||
namespace profiler {
|
||||
|
||||
uint64_t GetCounterID(std::string& counter_name);
|
||||
|
||||
class Profiler {
|
||||
public:
|
||||
Profiler(rocprofiler_buffer_id_t buffer_id, rocprofiler_filter_id_t filter_id,
|
||||
rocprofiler_session_id_t session_id);
|
||||
~Profiler();
|
||||
|
||||
void AddPendingSignals(uint32_t writer_id, uint64_t kernel_object,
|
||||
const hsa_signal_t& completion_signal, rocprofiler_session_id_t session_id,
|
||||
rocprofiler_buffer_id_t buffer_id,
|
||||
rocmtools::profiling_context_t* context, uint64_t session_data_count,
|
||||
hsa_ven_amd_aqlprofile_profile_t* profile,
|
||||
rocprofiler_kernel_properties_t kernel_properties, uint32_t thread_id,
|
||||
uint64_t queue_index);
|
||||
|
||||
const std::vector<pending_signal_t>& GetPendingSignals(uint32_t writer_id);
|
||||
bool CheckPendingSignalsIsEmpty();
|
||||
|
||||
void AddCounterName(rocprofiler_counter_id_t handler, std::string counter_name);
|
||||
void AddCounterName(std::string& counter_name);
|
||||
std::string& GetCounterName(rocprofiler_counter_id_t handler);
|
||||
|
||||
bool FindCounter(rocprofiler_counter_id_t counter_id);
|
||||
size_t GetCounterInfoSize(rocprofiler_counter_info_kind_t kind, rocprofiler_counter_id_t counter_id);
|
||||
const char* GetCounterInfo(rocprofiler_counter_info_kind_t kind, rocprofiler_counter_id_t counter_id);
|
||||
|
||||
void StartReplayPass(rocprofiler_session_id_t session_id);
|
||||
void EndReplayPass();
|
||||
bool HasActivePass();
|
||||
|
||||
private:
|
||||
std::mutex counter_names_lock_;
|
||||
std::map<uint64_t, std::string> counter_names_;
|
||||
rocprofiler_get_timestamp_t get_timestamp_fn_;
|
||||
rocprofiler_buffer_id_t buffer_id_;
|
||||
rocprofiler_filter_id_t filter_id_;
|
||||
rocprofiler_session_id_t session_id_;
|
||||
|
||||
std::mutex sessions_pending_signals_lock_;
|
||||
std::map<uint32_t, std::vector<pending_signal_t>> sessions_pending_signals_;
|
||||
};
|
||||
|
||||
} // namespace profiler
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_TOOLS_PROFILER_PROFILER_H_
|
||||
@@ -0,0 +1,345 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "session.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "rocprofiler.h"
|
||||
#include "src/pcsampler/session/pc_sampler.h"
|
||||
#include "src/utils/helper.h"
|
||||
#include "src/core/hsa/queues/queue.h"
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
Session::Session(rocprofiler_replay_mode_t replay_mode, rocprofiler_session_id_t session_id)
|
||||
: session_id_(session_id), is_active_(false), replay_mode_(replay_mode) {}
|
||||
|
||||
Session::~Session() {
|
||||
while (GetCurrentActiveInterruptSignalsCount() > 0) {
|
||||
}
|
||||
if (profiler_started_.load(std::memory_order_release)) {
|
||||
delete profiler_;
|
||||
profiler_started_.exchange(false, std::memory_order_release);
|
||||
}
|
||||
// if (tracer_started_.load(std::memory_order_release)) {
|
||||
// delete tracer_;
|
||||
// tracer_started_.exchange(false, std::memory_order_release);
|
||||
// }
|
||||
// {
|
||||
// std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
// buffers_.clear();
|
||||
// }
|
||||
}
|
||||
|
||||
void Session::DisableTools(rocprofiler_buffer_id_t buffer_id) {
|
||||
if ((FindFilterWithKind(ROCPROFILER_COUNTERS_COLLECTION) &&
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_COUNTERS_COLLECTION))->GetBufferId().value ==
|
||||
buffer_id.value) ||
|
||||
(FindFilterWithKind(ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION) &&
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION))
|
||||
->GetBufferId()
|
||||
.value == buffer_id.value)) {
|
||||
if (profiler_started_.load(std::memory_order_release)) {
|
||||
// Implement Disable Profiling
|
||||
}
|
||||
}
|
||||
if (FindFilterWithKind(ROCPROFILER_API_TRACE) &&
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_API_TRACE))->GetBufferId().value == buffer_id.value) {
|
||||
if (tracer_started_.load(std::memory_order_release)) {
|
||||
tracer_->DisableRoctracer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::Start() {
|
||||
std::lock_guard<std::mutex> lock(session_lock_);
|
||||
if (!is_active_) {
|
||||
if (FindFilterWithKind(ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION)) {
|
||||
if (profiler_started_.load(std::memory_order_release)) delete profiler_;
|
||||
profiler_ = new profiler::Profiler(
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION))->GetBufferId(),
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_DISPATCH_TIMESTAMPS_COLLECTION))->GetId(),
|
||||
session_id_);
|
||||
profiler_started_.exchange(true, std::memory_order_release);
|
||||
}
|
||||
|
||||
if (FindFilterWithKind(ROCPROFILER_COUNTERS_COLLECTION)) {
|
||||
if (profiler_started_.load(std::memory_order_release)) delete profiler_;
|
||||
profiler_ = new profiler::Profiler(
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_COUNTERS_COLLECTION))->GetBufferId(),
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_COUNTERS_COLLECTION))->GetId(), session_id_);
|
||||
profiler_started_.exchange(true, std::memory_order_release);
|
||||
}
|
||||
|
||||
if (FindFilterWithKind(ROCPROFILER_SPM_COLLECTION)) {
|
||||
if (spm_started_.load(std::memory_order_release)) delete spmcounter_;
|
||||
rocprofiler_spm_parameter_t* spmparameter =
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_SPM_COLLECTION))->GetSpmParameterData();
|
||||
spmcounter_ = new spm::SpmCounters(
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_SPM_COLLECTION))->GetBufferId(),
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_SPM_COLLECTION))->GetId(), spmparameter,
|
||||
session_id_);
|
||||
if (profiler_started_.load(std::memory_order_release)) delete profiler_;
|
||||
profiler_ = new profiler::Profiler(
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_SPM_COLLECTION))->GetBufferId(),
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_SPM_COLLECTION))->GetId(), session_id_);
|
||||
profiler_started_.exchange(true, std::memory_order_release);
|
||||
}
|
||||
|
||||
if (FindFilterWithKind(ROCPROFILER_API_TRACE)) {
|
||||
std::vector<rocprofiler_tracer_activity_domain_t> domains =
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_API_TRACE))->GetTraceData();
|
||||
if (!tracer_started_.load(std::memory_order_release)) {
|
||||
tracer_ = new tracer::Tracer(
|
||||
session_id_, GetFilter(GetFilterIdWithKind(ROCPROFILER_API_TRACE))->GetCallback(),
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_API_TRACE))->GetBufferId(), domains);
|
||||
tracer_started_.exchange(true, std::memory_order_release);
|
||||
}
|
||||
tracer_->StartRoctracer();
|
||||
}
|
||||
|
||||
if (FindFilterWithKind(ROCPROFILER_PC_SAMPLING_COLLECTION)) {
|
||||
if (!pc_sampler_started_.load(std::memory_order_release)) {
|
||||
pc_sampler_ = new pc_sampler::PCSampler(
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_PC_SAMPLING_COLLECTION))->GetBufferId(),
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_PC_SAMPLING_COLLECTION))->GetId(), session_id_);
|
||||
pc_sampler_started_.exchange(true, std::memory_order_release);
|
||||
}
|
||||
pc_sampler_->Start();
|
||||
}
|
||||
|
||||
is_active_ = true;
|
||||
if (FindFilterWithKind(ROCPROFILER_SPM_COLLECTION)) startSpm();
|
||||
}
|
||||
}
|
||||
|
||||
void Session::Terminate() {
|
||||
if (is_active_) {
|
||||
std::lock_guard<std::mutex> lock(session_lock_);
|
||||
if (FindFilterWithKind(ROCPROFILER_SPM_COLLECTION)) {
|
||||
{
|
||||
stopSpm();
|
||||
delete spmcounter_;
|
||||
}
|
||||
}
|
||||
if (FindFilterWithKind(ROCPROFILER_API_TRACE)) {
|
||||
std::vector<rocprofiler_tracer_activity_domain_t> domains =
|
||||
GetFilter(GetFilterIdWithKind(ROCPROFILER_API_TRACE))->GetTraceData();
|
||||
if (tracer_started_.load(std::memory_order_release)) {
|
||||
tracer_->StopRoctracer();
|
||||
delete tracer_;
|
||||
tracer_started_.exchange(false, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
if (FindFilterWithKind(ROCPROFILER_PC_SAMPLING_COLLECTION)) {
|
||||
if (pc_sampler_started_.load(std::memory_order_release)) {
|
||||
pc_sampler_->Stop();
|
||||
delete pc_sampler_;
|
||||
pc_sampler_started_.exchange(false, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
is_active_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
rocprofiler_session_id_t Session::GetId() { return session_id_; }
|
||||
bool Session::IsActive() { return is_active_; }
|
||||
|
||||
profiler::Profiler* Session::GetProfiler() { return profiler_; }
|
||||
tracer::Tracer* Session::GetTracer() { return tracer_; }
|
||||
spm::SpmCounters* Session::GetSpmCounter() { return spmcounter_; }
|
||||
pc_sampler::PCSampler* Session::GetPCSampler() { return pc_sampler_; }
|
||||
|
||||
rocprofiler_filter_id_t Session::CreateFilter(rocprofiler_filter_kind_t filter_kind,
|
||||
rocprofiler_filter_data_t filter_data,
|
||||
uint64_t data_count,
|
||||
rocprofiler_filter_property_t property) {
|
||||
rocprofiler_filter_id_t id =
|
||||
rocprofiler_filter_id_t{filters_counter_.fetch_add(1, std::memory_order_release)};
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
filters_.emplace_back(new Filter{id, filter_kind, filter_data, data_count});
|
||||
filters_.back()->SetProperty(property);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
bool Session::FindFilter(rocprofiler_filter_id_t filter_id) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
for (auto& filter : filters_) {
|
||||
if (filter->GetId().value == filter_id.value) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Session::DestroyFilter(rocprofiler_filter_id_t filter_id) {
|
||||
{
|
||||
std::vector<Filter*>::iterator filter;
|
||||
std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
for (filter = filters_.begin(); filter != filters_.end(); ++filter) {
|
||||
if ((*filter) && (*filter)->GetId().value == filter_id.value) filters_.erase(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Filter* Session::GetFilter(rocprofiler_filter_id_t filter_id) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
for (auto& filter : filters_) {
|
||||
if (filter->GetId().value == filter_id.value) return filter;
|
||||
}
|
||||
}
|
||||
fatal("Filter is not found!");
|
||||
}
|
||||
|
||||
bool Session::CheckFilterBufferSize(rocprofiler_filter_id_t filter_id,
|
||||
rocprofiler_buffer_id_t buffer_id) {
|
||||
// TODO(aelwazir): To be implemented
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Session::HasFilter() { return filters_.size() > 0; }
|
||||
|
||||
bool Session::FindFilterWithKind(rocprofiler_filter_kind_t kind) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
for (auto& filter : filters_) {
|
||||
if (filter->GetKind() == kind) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
rocprofiler_filter_id_t Session::GetFilterIdWithKind(rocprofiler_filter_kind_t kind) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
for (auto& filter : filters_) {
|
||||
if (filter->GetKind() == kind) return filter->GetId();
|
||||
}
|
||||
}
|
||||
return rocprofiler_filter_id_t{0};
|
||||
}
|
||||
|
||||
bool Session::HasBuffer() { return buffers_.size() > 0; }
|
||||
|
||||
rocprofiler_buffer_id_t Session::CreateBuffer(rocprofiler_buffer_callback_t buffer_callback,
|
||||
size_t buffer_size) {
|
||||
rocprofiler_buffer_id_t id =
|
||||
rocprofiler_buffer_id_t{buffers_counter_.fetch_add(1, std::memory_order_release)};
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(buffers_lock_);
|
||||
buffers_.emplace(id.value,
|
||||
new Memory::GenericBuffer(session_id_, id, buffer_size, buffer_callback));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
bool Session::FindBuffer(rocprofiler_buffer_id_t buffer_id) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(buffers_lock_);
|
||||
return buffers_.find(buffer_id.value) != buffers_.end();
|
||||
}
|
||||
}
|
||||
|
||||
void Session::DestroyTracer() { /* tracer_.reset(); */
|
||||
}
|
||||
|
||||
void Session::DestroyBuffer(rocprofiler_buffer_id_t buffer_id) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(filters_lock_);
|
||||
delete buffers_.at(buffer_id.value);
|
||||
buffers_.erase(buffer_id.value);
|
||||
// if (buffers_.find(buffer_id.value) != buffers_.end() &&
|
||||
// buffers_.at(buffer_id.value)->IsValid())
|
||||
// buffers_.at(buffer_id.value).reset();
|
||||
}
|
||||
}
|
||||
|
||||
rocprofiler_status_t Session::startSpm() {
|
||||
if (spmcounter_) {
|
||||
spm_started_.exchange(true, std::memory_order_release);
|
||||
return spmcounter_->startSpm();
|
||||
} else {
|
||||
std::cout << "Apply the SPM Filter" << std::endl;
|
||||
return ROCPROFILER_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
rocprofiler_status_t Session::stopSpm() {
|
||||
if (spmcounter_ && spm_started_.load()) {
|
||||
spm_started_.exchange(false, std::memory_order_release);
|
||||
return spmcounter_->stopSpm();
|
||||
} else {
|
||||
std::cout << "SPM not started" << std::endl;
|
||||
return ROCPROFILER_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
Memory::GenericBuffer* Session::GetBuffer(rocprofiler_buffer_id_t buffer_id) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(buffers_lock_);
|
||||
return buffers_.at(buffer_id.value);
|
||||
}
|
||||
}
|
||||
|
||||
void Session::PushRangeLabels(const std::string label) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(range_labels_lock_);
|
||||
range_labels_.push(label);
|
||||
}
|
||||
current_range_label_ = label;
|
||||
}
|
||||
bool Session::PopRangeLabels() {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(range_labels_lock_);
|
||||
if (range_labels_.empty()) {
|
||||
return false;
|
||||
}
|
||||
range_labels_.pop();
|
||||
}
|
||||
current_range_label_ = "";
|
||||
return true;
|
||||
}
|
||||
std::string& Session::GetCurrentRangeLabel() { return current_range_label_; }
|
||||
|
||||
std::mutex& Session::GetSessionLock() { return session_lock_; }
|
||||
|
||||
static std::atomic<uint64_t> SESSION_COUNTER{1};
|
||||
|
||||
// use some util function to generate a unique id
|
||||
uint64_t GenerateUniqueSessionId() {
|
||||
return SESSION_COUNTER.fetch_add(1, std::memory_order_release);
|
||||
}
|
||||
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,131 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_CORE_SESSION_SESSION_H_
|
||||
#define SRC_CORE_SESSION_SESSION_H_
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "inc/rocprofiler.h"
|
||||
#include "src/core/memory/generic_buffer.h"
|
||||
#include "src/core/session/filter.h"
|
||||
#include "profiler/profiler.h"
|
||||
#include "tracer/tracer.h"
|
||||
#include "spm/spm.h"
|
||||
#include "src/pcsampler/session/pc_sampler.h"
|
||||
|
||||
#define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
class Session {
|
||||
public:
|
||||
Session(rocprofiler_replay_mode_t replay_mode, rocprofiler_session_id_t session_id);
|
||||
~Session();
|
||||
void DisableTools(rocprofiler_buffer_id_t buffer_id);
|
||||
void Start();
|
||||
void Terminate();
|
||||
rocprofiler_session_id_t GetId();
|
||||
bool IsActive();
|
||||
|
||||
void DestroyTracer();
|
||||
|
||||
profiler::Profiler* GetProfiler();
|
||||
tracer::Tracer* GetTracer();
|
||||
spm::SpmCounters* GetSpmCounter();
|
||||
pc_sampler::PCSampler* GetPCSampler();
|
||||
|
||||
// Filter
|
||||
rocprofiler_filter_id_t CreateFilter(rocprofiler_filter_kind_t filter_kind,
|
||||
rocprofiler_filter_data_t filter_data, uint64_t data_count,
|
||||
rocprofiler_filter_property_t property);
|
||||
bool FindFilter(rocprofiler_filter_id_t filter_id);
|
||||
void DestroyFilter(rocprofiler_filter_id_t filter_id);
|
||||
Filter* GetFilter(rocprofiler_filter_id_t filter_id);
|
||||
bool HasFilter();
|
||||
|
||||
bool FindFilterWithKind(rocprofiler_filter_kind_t kind);
|
||||
rocprofiler_filter_id_t GetFilterIdWithKind(rocprofiler_filter_kind_t kind);
|
||||
|
||||
std::mutex& GetSessionLock();
|
||||
|
||||
bool CheckFilterBufferSize(rocprofiler_filter_id_t filter_id, rocprofiler_buffer_id_t buffer_id);
|
||||
|
||||
// Buffer
|
||||
rocprofiler_buffer_id_t CreateBuffer(rocprofiler_buffer_callback_t buffer_callback,
|
||||
size_t buffer_size);
|
||||
bool FindBuffer(rocprofiler_buffer_id_t buffer_id);
|
||||
void DestroyBuffer(rocprofiler_buffer_id_t buffer_id);
|
||||
Memory::GenericBuffer* GetBuffer(rocprofiler_buffer_id_t buffer_id);
|
||||
bool HasBuffer();
|
||||
|
||||
rocprofiler_status_t startSpm();
|
||||
rocprofiler_status_t stopSpm();
|
||||
// Range Labels
|
||||
void PushRangeLabels(const std::string label);
|
||||
bool PopRangeLabels();
|
||||
std::string& GetCurrentRangeLabel();
|
||||
|
||||
private:
|
||||
rocprofiler_session_id_t session_id_;
|
||||
std::atomic<bool> is_active_;
|
||||
rocprofiler_replay_mode_t replay_mode_;
|
||||
std::mutex session_lock_;
|
||||
|
||||
std::atomic<uint64_t> filters_counter_{1};
|
||||
std::mutex filters_lock_;
|
||||
std::vector<Filter*> filters_;
|
||||
|
||||
std::atomic<bool> profiler_started_{false};
|
||||
std::atomic<bool> tracer_started_{false};
|
||||
std::atomic<bool> spm_started_{false};
|
||||
|
||||
profiler::Profiler* profiler_;
|
||||
tracer::Tracer* tracer_;
|
||||
spm::SpmCounters* spmcounter_;
|
||||
|
||||
std::atomic<bool> pc_sampler_started_{false};
|
||||
pc_sampler::PCSampler* pc_sampler_;
|
||||
|
||||
std::atomic<uint64_t> buffers_counter_{1};
|
||||
std::mutex buffers_lock_;
|
||||
std::map<uint64_t, Memory::GenericBuffer*> buffers_;
|
||||
std::atomic<uint64_t> records_counter_{1};
|
||||
|
||||
|
||||
std::mutex range_labels_lock_;
|
||||
std::stack<std::string> range_labels_;
|
||||
std::string current_range_label_;
|
||||
};
|
||||
|
||||
uint64_t GenerateUniqueSessionId();
|
||||
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_SESSION_SESSION_H_
|
||||
@@ -0,0 +1,425 @@
|
||||
#include "spm.h"
|
||||
#include "src/core/hsa/hsa_support.h"
|
||||
#include "src/utils/helper.h"
|
||||
#include "src/api/rocmtool.h"
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#define QUEUE_NUM_PACKETS 64
|
||||
static const size_t CMD_SLOT_SIZE_B = 0x40;
|
||||
// #define ASSERTM(exp, msg) assert(((void)msg, exp))
|
||||
#define DEST_BUFFER_MAX 4
|
||||
|
||||
namespace {
|
||||
struct devices_t {
|
||||
std::vector<hsa_agent_t> cpu_devices;
|
||||
std::vector<hsa_agent_t> gpu_devices;
|
||||
std::vector<hsa_agent_t> other_devices;
|
||||
};
|
||||
typedef struct {
|
||||
uint32_t size; // size of buffer in bytes
|
||||
uint32_t timeout;
|
||||
uint32_t len; // len of streamed data in spm buffer
|
||||
void* addr; // address of spm buffer
|
||||
bool data_loss; // OUT
|
||||
} spm_buffer_params_t;
|
||||
|
||||
typedef struct spm_data_buffer {
|
||||
char* addr;
|
||||
uint32_t buffSize;
|
||||
// spm_data_buffer(char * data, uint32_t len) :
|
||||
// addr{data}, buffSize{len} {}
|
||||
} spm_data_buffer_t;
|
||||
|
||||
std::queue<spm_data_buffer_t> process_queue;
|
||||
// spm_buffer_params_t spm_buffer_params[3];
|
||||
|
||||
std::atomic<bool> is_started;
|
||||
std::atomic<bool> buffer_read_flag;
|
||||
std::atomic<uint32_t> spm_buffer_idx;
|
||||
|
||||
|
||||
std::thread thread_buffer_setup;
|
||||
std::thread thread_spm_data_parse;
|
||||
|
||||
// std::atomic<uint32_t> currIndex;
|
||||
// std::atomic<uint32_t> preIndex;
|
||||
std::mutex processQueueLock;
|
||||
// void spmDataParse();
|
||||
// void spmBufferSetup(hsa_agent_t preferredGpuNode);
|
||||
// FILE* fd;
|
||||
|
||||
// rocprofiler_status_t setSpmDestBuffer(hsa_agent_t preferred_agent, size_t size_in_bytes,
|
||||
// uint32_t* timeout, uint32_t* size_copied, void* dest,
|
||||
// bool* is_data_loss) {
|
||||
// [[maybe_unused]] hsa_status_t status = HSA_STATUS_SUCCESS;
|
||||
// #if 0
|
||||
// status = rocmtools::hsa_support::GetAmdExtTable().hsa_amd_spm_set_dest_buffer_fn(
|
||||
// preferred_agent, size_in_bytes, timeout, size_copied, dest, is_data_loss);
|
||||
// ASSERTM(status == HSA_STATUS_SUCCESS, "ERROR: SPM set buffer failed");
|
||||
// #endif
|
||||
// return ROCPROFILER_STATUS_SUCCESS;
|
||||
// }
|
||||
|
||||
// rocprofiler_status_t SetDestBuffer(hsa_agent_t GPUNode, uint32_t size, uint32_t timeout) {
|
||||
// rocprofiler_status_t ret;
|
||||
// uint32_t idx = currIndex.load(std::memory_order_release);
|
||||
// if (size) {
|
||||
// // Check if user buffer in using
|
||||
// if (spm_buffer_params[idx].addr != NULL) {
|
||||
// std::cout << "Buffer in use ." << std::endl;
|
||||
// return ROCPROFILER_STATUS_ERROR;
|
||||
// }
|
||||
|
||||
// spm_buffer_params[idx].addr = malloc(size);
|
||||
// if (spm_buffer_params[idx].addr == NULL) {
|
||||
// std::cout << "Malloc(size) Failed." << std::endl;
|
||||
// return ROCPROFILER_STATUS_ERROR;
|
||||
// }
|
||||
// } else {
|
||||
// spm_buffer_params[idx].addr = NULL;
|
||||
// }
|
||||
|
||||
// spm_buffer_params[idx].timeout = timeout;
|
||||
// spm_buffer_params[idx].data_loss = 0;
|
||||
|
||||
// ret = setSpmDestBuffer(GPUNode, spm_buffer_params[idx].size, &spm_buffer_params[idx].timeout,
|
||||
// &spm_buffer_params[idx].len, spm_buffer_params[idx].addr,
|
||||
// &spm_buffer_params[idx].data_loss);
|
||||
// if (ret != ROCPROFILER_STATUS_SUCCESS) {
|
||||
// std::cout << "Fail to set Dest Buf "
|
||||
// << "ret " << ret << std::endl;
|
||||
// return ROCPROFILER_STATUS_ERROR;
|
||||
// }
|
||||
// if (spm_buffer_params[idx].data_loss) std::cout << "Data Loss" << std::endl;
|
||||
// if (spm_buffer_params[idx].len) {
|
||||
// uint32_t pidx = preIndex.load(std::memory_order_release);
|
||||
// if (spm_buffer_params[idx].len == spm_buffer_params[pidx].size) {
|
||||
// std::cout << "Buffer completely filled with bytes" << spm_buffer_params[idx].len << std::endl;
|
||||
// fd = fopen("SPM_rocmtool_data.txt", "wb");
|
||||
// size_t retele = fwrite(spm_buffer_params[pidx].addr, 1, spm_buffer_params[idx].len, fd);
|
||||
// if (retele <= 0) rocmtools::warning("SPM Data is wrong!");
|
||||
// fclose(fd);
|
||||
// } else {
|
||||
// std::cout << "Buffer partially filled with %d bytes" << spm_buffer_params[idx].len
|
||||
// << std::endl;
|
||||
// }
|
||||
// if (timeout)
|
||||
// if (spm_buffer_params[idx].timeout == timeout) std::cout << "Timeout occurred" << std::endl;
|
||||
// ret = ROCPROFILER_STATUS_SUCCESS;
|
||||
// } else {
|
||||
// std::cout << "Data collection failed" << std::endl;
|
||||
// ret = ROCPROFILER_STATUS_SUCCESS;
|
||||
// }
|
||||
// spm_buffer_params[idx].addr = NULL;
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// void spmBufferSetup(hsa_agent_t GPUNode) {
|
||||
// rocprofiler_status_t ret;
|
||||
// if (is_started.load(std::memory_order_release)) {
|
||||
// uint32_t idx = currIndex.load(std::memory_order_release);
|
||||
// ret = SetDestBuffer(GPUNode, spm_buffer_params[idx].size, spm_buffer_params[idx].timeout);
|
||||
// if (ret != ROCPROFILER_STATUS_SUCCESS) {
|
||||
// std::cout << "Fail to set Dest Buf 2 "
|
||||
// << "ret " << ret << std::endl;
|
||||
// return;
|
||||
// }
|
||||
// usleep(5 * 1000);
|
||||
// // Set blocking dest buff
|
||||
// currIndex.store(1, std::memory_order_release);
|
||||
// preIndex.store(0, std::memory_order_release);
|
||||
// spm_buffer_params[idx].timeout = 1000;
|
||||
|
||||
// ret = SetDestBuffer(GPUNode, spm_buffer_params[idx].size, spm_buffer_params[idx].timeout);
|
||||
// if (ret != ROCPROFILER_STATUS_SUCCESS) {
|
||||
// std::cout << "Fail to set Dest Buf 1"
|
||||
// << "ret " << ret << std::endl;
|
||||
// }
|
||||
// usleep(5 * 1000);
|
||||
|
||||
// currIndex.store(0, std::memory_order_release);
|
||||
// preIndex.store(1, std::memory_order_release);
|
||||
// spm_buffer_params[idx].timeout = 80;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void AddSpmRecords(std::vector<uint16_t>& sample) {
|
||||
// // Getting timestamps
|
||||
// int index = 0;
|
||||
// int nSample = 0;
|
||||
// int se = 0;
|
||||
// uint64_t count = 0;
|
||||
// std::vector<uint64_t> timestamp_vec;
|
||||
// // Get Buffer
|
||||
// rocmtools::Session* session =
|
||||
// rocmtools::GetROCMToolObj()->GetSession(rocmtools::GetROCMToolObj()->GetCurrentSessionId());
|
||||
// rocprofiler_filter_id_t filter_id = session->GetFilterIdWithKind(ROCPROFILER_SPM_COLLECTION);
|
||||
// rocmtools::Filter* filter = session->GetFilter(filter_id);
|
||||
// rocprofiler_buffer_id_t buffer_id = filter->GetBufferId();
|
||||
// Memory::GenericBuffer* buffer = session->GetBuffer(buffer_id);
|
||||
// // Getting timestamps
|
||||
|
||||
// while (static_cast<size_t>(index) < sample.size()) {
|
||||
// int64_t timestamp = sample[index] >> 16 | sample[index + 1];
|
||||
// timestamp = timestamp >> 16 | sample[index + 2];
|
||||
// timestamp = timestamp >> 16 | sample[index + 3];
|
||||
// timestamp_vec.emplace_back(timestamp);
|
||||
// index = index + 160;
|
||||
// }
|
||||
|
||||
// index = 32;
|
||||
|
||||
// while (static_cast<size_t>(index) < sample.size()) {
|
||||
// se = 0;
|
||||
// rocprofiler_record_spm_t record = {};
|
||||
// record.timestamps = rocprofiler_record_header_timestamp_t{timestamp_vec[nSample]};
|
||||
// while (se < 4) {
|
||||
// count = 0;
|
||||
// while (count < 15) {
|
||||
// record.shader_engine_data[se].counters_data[count].value = sample[index];
|
||||
// record.shader_engine_data[se].counters_data[count + 15].value = sample[index + 15];
|
||||
|
||||
// count++;
|
||||
// }
|
||||
// se++;
|
||||
// }
|
||||
// record.header.id = rocprofiler_record_id_t{rocmtools::GetROCMToolObj()->GetUniqueRecordId()};
|
||||
// buffer->AddRecord(record);
|
||||
// nSample++;
|
||||
// index += 160;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void spmDataParse() {
|
||||
// std::vector<uint16_t> lines;
|
||||
// fd = fopen("SPM_rocmtool_data.txt", "rb");
|
||||
// while (!feof(fd)) {
|
||||
// char bytes[2];
|
||||
// size_t size = fread(&bytes, 1, 2, fd);
|
||||
// if (size) {
|
||||
// uint16_t value;
|
||||
// memcpy(&value, bytes, 2);
|
||||
// lines.push_back(value);
|
||||
// }
|
||||
// }
|
||||
// AddSpmRecords(lines);
|
||||
// }
|
||||
|
||||
hsa_status_t device_cb(hsa_agent_t agent, void* data) {
|
||||
hsa_device_type_t device_type;
|
||||
devices_t* devices = reinterpret_cast<devices_t*>(data);
|
||||
if (hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type) != HSA_STATUS_SUCCESS)
|
||||
rocmtools::fatal("hsa_agent_get_info failed");
|
||||
switch (device_type) {
|
||||
case HSA_DEVICE_TYPE_CPU:
|
||||
devices->cpu_devices.push_back(agent);
|
||||
break;
|
||||
case HSA_DEVICE_TYPE_GPU:
|
||||
devices->gpu_devices.push_back(agent);
|
||||
break;
|
||||
default:
|
||||
devices->other_devices.push_back(agent);
|
||||
break;
|
||||
}
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void get_hsa_agents_list(devices_t* device_list) {
|
||||
hsa_status_t status;
|
||||
// Enumerate the agents.
|
||||
status = hsa_iterate_agents(device_cb, device_list);
|
||||
if (status != HSA_STATUS_SUCCESS) rocmtools::fatal("hsa_iterate_agents failed");
|
||||
}
|
||||
uint64_t submitPacket(hsa_queue_t* queue, const void* packet) {
|
||||
const uint32_t slot_size_b = CMD_SLOT_SIZE_B;
|
||||
|
||||
// advance command queue
|
||||
const uint64_t write_idx =
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_queue_add_write_index_scacq_screl_fn(queue, 1);
|
||||
while ((write_idx -
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_queue_load_read_index_relaxed_fn(queue)) >=
|
||||
queue->size) {
|
||||
sched_yield(); // TODO: remove
|
||||
}
|
||||
|
||||
const uint32_t slot_idx = (uint32_t)(write_idx % queue->size);
|
||||
uint32_t* queue_slot =
|
||||
reinterpret_cast<uint32_t*>((uintptr_t)(queue->base_address) + (slot_idx * slot_size_b));
|
||||
const uint32_t* slot_data = reinterpret_cast<const uint32_t*>(packet);
|
||||
|
||||
// Copy buffered commands into the queue slot.
|
||||
// Overwrite the AQL invalid header (first dword) last.
|
||||
// This prevents the slot from being read until it's fully written.
|
||||
memcpy(&queue_slot[1], &slot_data[1], slot_size_b - sizeof(uint32_t));
|
||||
std::atomic<uint32_t>* header_atomic_ptr =
|
||||
reinterpret_cast<std::atomic<uint32_t>*>(&queue_slot[0]);
|
||||
header_atomic_ptr->store(slot_data[0], std::memory_order_release);
|
||||
|
||||
// ringdoor bell
|
||||
rocmtools::hsa_support::GetCoreApiTable().hsa_signal_store_relaxed_fn(queue->doorbell_signal,
|
||||
write_idx);
|
||||
|
||||
return write_idx;
|
||||
}
|
||||
|
||||
// bool createHsaQueue(hsa_queue_t** queue, hsa_agent_t gpu_agent) {
|
||||
// // create a single-producer queue
|
||||
// // TODO: check if API args are correct, especially UINT32_MAX
|
||||
// hsa_status_t status;
|
||||
// status = rocmtools::hsa_support::GetCoreApiTable().hsa_queue_create_fn(
|
||||
// gpu_agent, QUEUE_NUM_PACKETS, HSA_QUEUE_TYPE_SINGLE, nullptr, nullptr, UINT32_MAX, UINT32_MAX,
|
||||
// queue);
|
||||
|
||||
// if (status != HSA_STATUS_SUCCESS) rocmtools::fatal("queue creation failed");
|
||||
|
||||
// return (status == HSA_STATUS_SUCCESS);
|
||||
// }
|
||||
|
||||
hsa_signal_value_t signalWait(const hsa_signal_t& signal, const hsa_signal_value_t& signal_value) {
|
||||
const hsa_signal_value_t exp_value = signal_value - 1;
|
||||
hsa_signal_value_t ret_value = signal_value;
|
||||
while (1) {
|
||||
// TODO: The 4th argument mentioning timeout is current set to UINT64_MAX.
|
||||
// Probably a maximum wait time should be set. We don't want application to hang because of
|
||||
// unlimited wait.
|
||||
// TODO2 : try 500000 assuming nanosecond granularity -- must be verified.
|
||||
ret_value = rocmtools::hsa_support::GetCoreApiTable().hsa_signal_wait_scacquire_fn(
|
||||
signal, HSA_SIGNAL_CONDITION_LT, signal_value, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);
|
||||
|
||||
if (ret_value == exp_value) break;
|
||||
if (ret_value != signal_value)
|
||||
rocmtools::fatal("Error: signalWait: signal_value(%lu), ret_value(%lu)", signal_value,
|
||||
ret_value);
|
||||
}
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
namespace rocmtools {
|
||||
|
||||
|
||||
spm::SpmCounters::SpmCounters(rocprofiler_buffer_id_t buffer_id, rocprofiler_filter_id_t filter_id,
|
||||
rocprofiler_spm_parameter_t* spmparameter,
|
||||
rocprofiler_session_id_t session_id)
|
||||
: buffer_id_(buffer_id),
|
||||
filter_id_(filter_id),
|
||||
spmparameter_(spmparameter),
|
||||
session_id_(session_id) {
|
||||
queue_ = nullptr;
|
||||
devices_t* device_list_ = new devices_t;
|
||||
get_hsa_agents_list(device_list_);
|
||||
defaultGpuNode_ = device_list_->gpu_devices[0];
|
||||
defaultCpuNode_ = device_list_->cpu_devices[0];
|
||||
|
||||
// create signals
|
||||
hsa_status_t status =
|
||||
hsa_support::GetCoreApiTable().hsa_signal_create_fn(1, 0, NULL, &start_signal_);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("start signal creation failed");
|
||||
status = hsa_support::GetCoreApiTable().hsa_signal_create_fn(1, 0, NULL, &stop_signal_);
|
||||
if (status != HSA_STATUS_SUCCESS) fatal("start signal creation failed");
|
||||
is_started.store(false, std::memory_order_relaxed);
|
||||
buffer_read_flag.store(false, std::memory_order_relaxed);
|
||||
spm_buffer_idx.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
rocprofiler_status_t spm::SpmCounters::startSpm() {
|
||||
if (spmparameter_->gpu_agent_id != NULL)
|
||||
preferredGpuNode_.handle = spmparameter_->gpu_agent_id->handle;
|
||||
else
|
||||
// else choose the default node to collect SPM
|
||||
preferredGpuNode_ = defaultGpuNode_;
|
||||
// hsa_agent_t preferred_cpu_agent = defaultCpuNode_;
|
||||
// int counter_count = spmparameter_->counters_count;
|
||||
// Packet::packet_t start_packet;
|
||||
#if 0
|
||||
hsa_status_t hsa_status = hsa_support::GetAmdExtTable().hsa_amd_spm_acquire_fn(preferredGpuNode_);
|
||||
if (hsa_status == HSA_STATUS_SUCCESS) {
|
||||
if (!createHsaQueue(&queue_, preferredGpuNode_))
|
||||
std::cout << "Create queue is failed" << std::endl;
|
||||
agent_queue_map_.insert(std::make_pair(preferredGpuNode_.handle, queue_));
|
||||
// Generate the start and stop packets
|
||||
char gpu_name[64];
|
||||
hsa_agent_get_info(preferredGpuNode_, HSA_AGENT_INFO_NAME, &gpu_name);
|
||||
std::vector<std::string> counter_names;
|
||||
for (int i = 0; i < counter_count; i++) {
|
||||
counter_names.push_back(std::string(spmparameter_->counters_names[i]));
|
||||
}
|
||||
profiles_ =
|
||||
Packet::InitializeAqlPackets(preferred_cpu_agent, preferredGpuNode_, counter_names, true);
|
||||
// Submit the start packet
|
||||
start_packet = *(*profiles_)[0].first->start_packet;
|
||||
start_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE;
|
||||
start_packet.completion_signal = {};
|
||||
start_packet.completion_signal = start_signal_;
|
||||
submitPacket(queue_, &start_packet);
|
||||
signalWait(start_packet.completion_signal, 1);
|
||||
// restore signal to a value of 1
|
||||
hsa_signal_store_screlease(start_signal_, 1);
|
||||
is_started.exchange(true, std::memory_order_release);
|
||||
uint32_t timeout = 10000;
|
||||
const uint32_t spm_buffer_size = 0x2000000;
|
||||
spm_buffer_params[0].size = spm_buffer_size;
|
||||
spm_buffer_params[0].timeout = timeout;
|
||||
spm_buffer_params[0].len = 0;
|
||||
spm_buffer_params[0].addr = nullptr;
|
||||
spm_buffer_params[0].data_loss = false;
|
||||
spm_buffer_params[1].size = spm_buffer_size;
|
||||
spm_buffer_params[1].timeout = timeout;
|
||||
spm_buffer_params[1].len = 0;
|
||||
spm_buffer_params[1].addr = nullptr;
|
||||
spm_buffer_params[1].data_loss = false;
|
||||
spm_buffer_params[2].size = spm_buffer_size;
|
||||
spm_buffer_params[2].timeout = timeout;
|
||||
spm_buffer_params[2].len = 0;
|
||||
spm_buffer_params[2].addr = malloc(spm_buffer_size);
|
||||
spm_buffer_params[2].data_loss = false;
|
||||
setSpmDestBuffer(preferredGpuNode_, spm_buffer_params[2].size, &timeout,
|
||||
&spm_buffer_params[2].len, &spm_buffer_params[2].addr,
|
||||
&spm_buffer_params[2].data_loss);
|
||||
currIndex.store(0, std::memory_order_release);
|
||||
preIndex.store(0, std::memory_order_release);
|
||||
// thread_buffer_setup = std::thread(spmBufferSetup, preferredGpuNode_);
|
||||
// thread_spm_data_parse = std::thread(spmDataParse);
|
||||
spmBufferSetup(preferredGpuNode_);
|
||||
spmDataParse();
|
||||
return ROCPROFILER_STATUS_SUCCESS;
|
||||
} else {
|
||||
std::cout << "SPM acquire failed\n" << std::endl;
|
||||
return ROCPROFILER_STATUS_ERROR;
|
||||
}
|
||||
#endif
|
||||
return ROCPROFILER_STATUS_SUCCESS; //delete this line with if 0
|
||||
}
|
||||
|
||||
rocprofiler_status_t spm::SpmCounters::stopSpm() {
|
||||
Packet::packet_t stop_packet;
|
||||
// submit the start packet
|
||||
is_started.exchange(false, std::memory_order_release);
|
||||
// thread_buffer_setup.join();
|
||||
|
||||
// thread_spm_data_parse.join();
|
||||
stop_packet = *(*profiles_)[0].first->stop_packet;
|
||||
buffer_read_flag.exchange(false, std::memory_order_release);
|
||||
stop_packet.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE;
|
||||
stop_packet.completion_signal = {};
|
||||
stop_packet.completion_signal = stop_signal_;
|
||||
submitPacket(queue_, &stop_packet);
|
||||
signalWait(stop_packet.completion_signal, 1);
|
||||
// restore signal to a value of 1
|
||||
hsa_signal_store_screlease(stop_signal_, 1);
|
||||
hsa_status_t status = HSA_STATUS_SUCCESS;
|
||||
if (queue_ != nullptr) {
|
||||
status = hsa_support::GetCoreApiTable().hsa_queue_destroy_fn(queue_);
|
||||
queue_ = nullptr;
|
||||
}
|
||||
if (status != HSA_STATUS_SUCCESS) rocmtools::warning("Queue destroy failed");
|
||||
return ROCPROFILER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef SRC_CORE_SESSION_SPM_H_
|
||||
#define SRC_CORE_SESSION_SPM_H_
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include "hsa/hsa_ext_amd.h"
|
||||
#include "src/core/hsa/packets/packets_generator.h"
|
||||
#include "src/utils/exception.h"
|
||||
#include "inc/rocprofiler.h"
|
||||
|
||||
|
||||
namespace rocmtools {
|
||||
|
||||
namespace spm {
|
||||
|
||||
|
||||
class SpmCounters {
|
||||
private:
|
||||
rocprofiler_buffer_id_t buffer_id_;
|
||||
rocprofiler_filter_id_t filter_id_;
|
||||
rocprofiler_spm_parameter_t* spmparameter_;
|
||||
rocprofiler_session_id_t session_id_;
|
||||
std::map<uint64_t, hsa_queue_t*> agent_queue_map_;
|
||||
typedef std::vector<std::pair<profiling_context_t*, hsa_ven_amd_aqlprofile_profile_t*>>
|
||||
profile_vector_t;
|
||||
|
||||
profile_vector_t* profiles_;
|
||||
hsa_queue_t* queue_;
|
||||
hsa_agent_t defaultGpuNode_;
|
||||
hsa_agent_t defaultCpuNode_;
|
||||
hsa_agent_t preferredGpuNode_;
|
||||
hsa_signal_t start_signal_;
|
||||
hsa_signal_t stop_signal_;
|
||||
|
||||
public:
|
||||
SpmCounters(rocprofiler_buffer_id_t buffer_id, rocprofiler_filter_id_t filter_id,
|
||||
rocprofiler_spm_parameter_t* spmparameter, rocprofiler_session_id_t session_id);
|
||||
~SpmCounters(){};
|
||||
|
||||
rocprofiler_status_t startSpm();
|
||||
rocprofiler_status_t stopSpm();
|
||||
|
||||
|
||||
}; // class SpmCounters
|
||||
|
||||
} // namespace spm
|
||||
|
||||
bool find_hsa_agent_cpu(uint64_t index, hsa_agent_t* agent);
|
||||
bool find_hsa_agent_gpu(uint64_t index, hsa_agent_t* agent);
|
||||
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_CORE_SESSION_SPM_H_
|
||||
@@ -0,0 +1,99 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "correlation_id.h"
|
||||
#include "roctracer.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// A stack that can be used for TLS variables. TLS destructors are invoked before global destructors
|
||||
// which is a problem if operations invoked by global destructors use TLS variables. If the TLS
|
||||
// stack is destructed, it still has well defined behavior by always returning a dummy element.
|
||||
template <typename T> class Stack : std::stack<T, std::vector<T>> {
|
||||
using parent_type = typename std::stack<T, std::vector<T>>;
|
||||
|
||||
public:
|
||||
Stack() { valid_.store(true, std::memory_order_relaxed); }
|
||||
~Stack() { valid_.store(false, std::memory_order_relaxed); }
|
||||
|
||||
template <class... Args> auto& emplace(Args&&... args) {
|
||||
return is_valid() ? parent_type::emplace(std::forward<Args>(args)...)
|
||||
: dummy_element_ = T(std::forward<Args>(args)...);
|
||||
}
|
||||
void push(const T& v) {
|
||||
if (is_valid()) parent_type::push(v);
|
||||
}
|
||||
void push(T&& v) {
|
||||
if (is_valid()) parent_type::push(std::move(v));
|
||||
}
|
||||
void pop() {
|
||||
if (is_valid()) parent_type::pop();
|
||||
}
|
||||
const auto& top() const { return is_valid() ? parent_type::top() : dummy_element_; }
|
||||
auto& top() { return is_valid() ? parent_type::top() : (dummy_element_ = {}); }
|
||||
|
||||
bool is_valid() const { return valid_.load(std::memory_order_relaxed); }
|
||||
size_t size() const { return is_valid() ? parent_type::size() : 0; }
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
private:
|
||||
std::atomic<bool> valid_{false};
|
||||
T dummy_element_; // Dummy element used when the stack is not valid.
|
||||
};
|
||||
|
||||
thread_local Stack<activity_correlation_id_t> correlation_id_stack{};
|
||||
thread_local Stack<activity_correlation_id_t> external_id_stack{};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace roctracer {
|
||||
|
||||
activity_correlation_id_t CorrelationIdPush() {
|
||||
static std::atomic<uint64_t> counter{1};
|
||||
return correlation_id_stack.emplace(counter.fetch_add(1, std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
void CorrelationIdPop() { correlation_id_stack.pop(); }
|
||||
|
||||
activity_correlation_id_t CorrelationId() {
|
||||
return correlation_id_stack.empty() ? 0 : correlation_id_stack.top();
|
||||
}
|
||||
|
||||
void ExternalCorrelationIdPush(activity_correlation_id_t external_id) {
|
||||
external_id_stack.push(external_id);
|
||||
}
|
||||
|
||||
std::optional<activity_correlation_id_t> ExternalCorrelationIdPop() {
|
||||
if (external_id_stack.empty()) return std::nullopt;
|
||||
|
||||
auto external_id = external_id_stack.top();
|
||||
external_id_stack.pop();
|
||||
return std::make_optional(external_id);
|
||||
}
|
||||
|
||||
std::optional<activity_correlation_id_t> ExternalCorrelationId() {
|
||||
return external_id_stack.empty() ? std::nullopt : std::make_optional(external_id_stack.top());
|
||||
}
|
||||
|
||||
} // namespace roctracer
|
||||
@@ -0,0 +1,50 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "roctracer.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace roctracer {
|
||||
|
||||
// Start a new correlation ID region and push it onto the thread local stack. Correlation ID
|
||||
// regions are nested and per-thread.
|
||||
activity_correlation_id_t CorrelationIdPush();
|
||||
|
||||
// Stop the current correlation ID region and pop it from the thread local stack.
|
||||
void CorrelationIdPop();
|
||||
|
||||
// Return the ID currently active correlation ID region, or 0 if no regin is active.
|
||||
activity_correlation_id_t CorrelationId();
|
||||
|
||||
// Start a new external correlation ID region for the given \p external_id. As for the internal
|
||||
// correlation ID regions, external correlation ID regions are nested and per-thread.
|
||||
void ExternalCorrelationIdPush(activity_correlation_id_t external_id);
|
||||
|
||||
// Stop the current external correlation ID region and return the external_id used to start the
|
||||
// region. Return a nullopt if no region was active.
|
||||
std::optional<activity_correlation_id_t> ExternalCorrelationIdPop();
|
||||
|
||||
// Return the current external correlation ID or nullopt is no region is active.
|
||||
std::optional<activity_correlation_id_t> ExternalCorrelationId();
|
||||
|
||||
} // namespace roctracer
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2018-2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef EXCEPTION_H_
|
||||
#define EXCEPTION_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace roctracer {
|
||||
|
||||
class ApiError : public std::runtime_error {
|
||||
public:
|
||||
explicit ApiError(roctracer_status_t status, const std::string& what_arg)
|
||||
: std::runtime_error(what_arg), status_(status) {}
|
||||
|
||||
roctracer_status_t status() const noexcept { return status_; }
|
||||
|
||||
private:
|
||||
const roctracer_status_t status_;
|
||||
};
|
||||
|
||||
} // namespace roctracer
|
||||
|
||||
#endif // EXCEPTION_H_
|
||||
@@ -0,0 +1,194 @@
|
||||
/* Copyright (c) 2018-2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef ROCTRACER_LOADER_H_
|
||||
#define ROCTRACER_LOADER_H_
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
#include <link.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include "src/utils/helper.h"
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
namespace roctracer {
|
||||
|
||||
// Base loader class
|
||||
template <typename Loader> class BaseLoader {
|
||||
protected:
|
||||
BaseLoader(const char* pattern) {
|
||||
// Iterate through the process' loaded shared objects and try to dlopen the
|
||||
// first entry with a file name starting with the given 'pattern'. This
|
||||
// allows the loader to acquire a handle to the target library iff it is
|
||||
// already loaded. The handle is used to query symbols exported by that
|
||||
// library.
|
||||
|
||||
auto callback = [this, pattern](dl_phdr_info* info) {
|
||||
if (handle_ == nullptr &&
|
||||
fs::path(info->dlpi_name).filename().string().rfind(pattern, 0) == 0)
|
||||
handle_ = ::dlopen(info->dlpi_name, RTLD_LAZY);
|
||||
};
|
||||
dl_iterate_phdr(
|
||||
[](dl_phdr_info* info, size_t size, void* data) {
|
||||
(*reinterpret_cast<decltype(callback)*>(data))(info);
|
||||
return 0;
|
||||
},
|
||||
&callback);
|
||||
}
|
||||
|
||||
~BaseLoader() {
|
||||
if (handle_ != nullptr) ::dlclose(handle_);
|
||||
}
|
||||
|
||||
BaseLoader(const BaseLoader&) = delete;
|
||||
BaseLoader& operator=(const BaseLoader&) = delete;
|
||||
|
||||
public:
|
||||
bool IsEnabled() const { return handle_ != nullptr; }
|
||||
|
||||
template <typename FunctionPtr> FunctionPtr GetFun(const char* symbol) const {
|
||||
assert(IsEnabled());
|
||||
|
||||
auto function_ptr = reinterpret_cast<FunctionPtr>(::dlsym(handle_, symbol));
|
||||
if (function_ptr == nullptr)
|
||||
rocmtools::fatal("symbol lookup '%s' failed: %s", symbol, ::dlerror());
|
||||
return function_ptr;
|
||||
}
|
||||
|
||||
static inline Loader& Instance() {
|
||||
static Loader instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
private:
|
||||
void* handle_;
|
||||
};
|
||||
|
||||
} // namespace roctracer
|
||||
|
||||
// HIP runtime library loader class
|
||||
namespace roctracer {
|
||||
#if STATIC_BUILD
|
||||
__attribute__((weak)) const char* hipKernelNameRef(const hipFunction_t f) { return nullptr; }
|
||||
__attribute__((weak)) const char* hipKernelNameRefByPtr(const void* hostFunction,
|
||||
hipStream_t stream) {
|
||||
return nullptr;
|
||||
}
|
||||
__attribute__((weak)) int hipGetStreamDeviceId(hipStream_t stream) { return 0; }
|
||||
__attribute__((weak)) const char* hipGetCmdName(unsigned op) { return nullptr; }
|
||||
__attribute__((weak)) const char* hipApiName(uint32_t id) { return nullptr; }
|
||||
__attribute__((weak)) void hipRegisterTracerCallback(int (*function)(activity_domain_t domain,
|
||||
uint32_t operation_id,
|
||||
void* data)) {}
|
||||
|
||||
class HipLoader {
|
||||
private:
|
||||
HipLoader() {}
|
||||
|
||||
public:
|
||||
bool IsEnabled() const { return true; }
|
||||
|
||||
int GetStreamDeviceId(hipStream_t stream) const { return hipGetStreamDeviceId(stream); }
|
||||
|
||||
const char* KernelNameRef(const hipFunction_t f) const { return hipKernelNameRef(f); }
|
||||
|
||||
const char* KernelNameRefByPtr(const void* host_function, hipStream_t stream = nullptr) const {
|
||||
return hipKernelNameRefByPtr(host_function, stream);
|
||||
}
|
||||
|
||||
const char* GetOpName(unsigned op) const { return hipGetCmdName(op); }
|
||||
|
||||
const char* ApiName(uint32_t id) const { return hipApiName(id); }
|
||||
|
||||
void RegisterTracerCallback(int (*callback)(activity_domain_t domain, uint32_t operation_id,
|
||||
void* data)) const {
|
||||
return hipRegisterTracerCallback(callback);
|
||||
}
|
||||
|
||||
static inline HipLoader& Instance() {
|
||||
static HipLoader instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
#else
|
||||
class HipLoader : public BaseLoader<HipLoader> {
|
||||
private:
|
||||
friend HipLoader& BaseLoader::Instance();
|
||||
HipLoader() : BaseLoader("libamdhip64.so") {}
|
||||
|
||||
public:
|
||||
int GetStreamDeviceId(hipStream_t stream) const {
|
||||
static auto function = GetFun<int (*)(hipStream_t stream)>("hipGetStreamDeviceId");
|
||||
return function(stream);
|
||||
}
|
||||
|
||||
const char* KernelNameRef(const hipFunction_t f) const {
|
||||
static auto function = GetFun<const char* (*)(const hipFunction_t f)>("hipKernelNameRef");
|
||||
return function(f);
|
||||
}
|
||||
|
||||
const char* KernelNameRefByPtr(const void* host_function, hipStream_t stream = nullptr) const {
|
||||
static auto function = GetFun<const char* (*)(const void* hostFunction, hipStream_t stream)>(
|
||||
"hipKernelNameRefByPtr");
|
||||
return function(host_function, stream);
|
||||
}
|
||||
|
||||
const char* GetOpName(unsigned op) const {
|
||||
static auto function = GetFun<const char* (*)(unsigned op)>("hipGetCmdName");
|
||||
return function(op);
|
||||
}
|
||||
|
||||
const char* ApiName(uint32_t id) const {
|
||||
static auto function = GetFun<const char* (*)(uint32_t id)>("hipApiName");
|
||||
return function(id);
|
||||
}
|
||||
|
||||
void RegisterTracerCallback(int (*callback)(activity_domain_t domain, uint32_t operation_id,
|
||||
void* data)) const {
|
||||
static auto function = GetFun<void (*)(int (*callback)(
|
||||
activity_domain_t domain, uint32_t operation_id, void* data))>("hipRegisterTracerCallback");
|
||||
return function(callback);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// ROCTX library loader class
|
||||
class RocTxLoader : public BaseLoader<RocTxLoader> {
|
||||
private:
|
||||
friend RocTxLoader& BaseLoader::Instance();
|
||||
RocTxLoader() : BaseLoader("libroctx64.so") {}
|
||||
|
||||
public:
|
||||
void RegisterTracerCallback(int (*callback)(activity_domain_t domain, uint32_t operation_id,
|
||||
void* data)) const {
|
||||
static auto function =
|
||||
GetFun<void (*)(int (*callback)(activity_domain_t domain, uint32_t operation_id,
|
||||
void* data))>("roctxRegisterTracerCallback");
|
||||
return function(callback);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace roctracer
|
||||
|
||||
#endif // ROCTRACER_LOADER_H_
|
||||
@@ -0,0 +1,101 @@
|
||||
/* Copyright (c) 2018-2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef UTIL_CALLBACK_TABLE_H_
|
||||
#define UTIL_CALLBACK_TABLE_H_
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <utility>
|
||||
|
||||
#include "roctracer.h"
|
||||
|
||||
namespace roctracer::util {
|
||||
|
||||
#if __GNUC__ == 11 || __GNUCC__ == 12
|
||||
// Starting with gcc-11 (verified with gcc-12 as well), an array out-of-bounds
|
||||
// subscript error is reported for accessing the registration table element at
|
||||
// the operation ID index. Validating the index in the function calling
|
||||
// Register/Unregister does not quiet the warning/error in release builds, so,
|
||||
// for gcc-11 and gcc-12, we disable that warning just for this class.
|
||||
#define IGNORE_GCC_ARRAY_BOUNDS_ERROR 1
|
||||
#endif // __GNUC__ == 11 || __GNUCC__ == 12
|
||||
|
||||
#if IGNORE_GCC_ARRAY_BOUNDS_ERROR
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif // IGNORE_GCC_ARRAY_BOUNDS_ERROR
|
||||
|
||||
namespace detail {
|
||||
struct False {
|
||||
constexpr bool operator()() { return false; }
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
// Generic callbacks table
|
||||
template <typename T, uint32_t N, typename IsStopped = detail::False> class RegistrationTable {
|
||||
public:
|
||||
template <typename... Args> void Register(uint32_t operation_id, Args... args) {
|
||||
assert(operation_id < N && "operation_id is out of range");
|
||||
auto& entry = table_[operation_id];
|
||||
std::unique_lock lock(entry.mutex);
|
||||
if (!entry.enabled.exchange(true, std::memory_order_relaxed))
|
||||
registered_count_.fetch_add(1, std::memory_order_relaxed);
|
||||
entry.data = T{std::forward<Args>(args)...};
|
||||
}
|
||||
|
||||
void Unregister(uint32_t operation_id) {
|
||||
assert(operation_id < N && "id is out of range");
|
||||
auto& entry = table_[operation_id];
|
||||
std::unique_lock lock(entry.mutex);
|
||||
if (entry.enabled.exchange(false, std::memory_order_relaxed))
|
||||
registered_count_.fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
std::optional<T> Get(uint32_t operation_id) const {
|
||||
assert(operation_id < N && "id is out of range");
|
||||
auto& entry = table_[operation_id];
|
||||
if (!entry.enabled.load(std::memory_order_relaxed) || IsStopped{}()) return std::nullopt;
|
||||
std::shared_lock lock(entry.mutex);
|
||||
return entry.enabled.load(std::memory_order_relaxed) ? std::make_optional(entry.data)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
bool IsEmpty() const { return registered_count_.load(std::memory_order_relaxed) == 0; }
|
||||
|
||||
private:
|
||||
std::atomic<size_t> registered_count_{0};
|
||||
struct {
|
||||
std::atomic<bool> enabled{false};
|
||||
mutable std::shared_mutex mutex;
|
||||
T data;
|
||||
} table_[N]{};
|
||||
};
|
||||
|
||||
#if IGNORE_GCC_ARRAY_BOUNDS_ERROR
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // IGNORE_GCC_ARRAY_BOUNDS_ERROR
|
||||
|
||||
} // namespace roctracer::util
|
||||
|
||||
#endif // UTIL_CALLBACK_TABLE_H_
|
||||
@@ -0,0 +1,847 @@
|
||||
/* Copyright (c) 2018-2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "roctracer.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <hsa/hsa_api_trace.h>
|
||||
#include <string.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <stack>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "correlation_id.h"
|
||||
#include "exception.h"
|
||||
#include "loader.h"
|
||||
#include "registration_table.h"
|
||||
#include "src/core/hsa/hsa_support.h"
|
||||
#include "src/utils/helper.h"
|
||||
#include "src/api/rocmtool.h"
|
||||
|
||||
static inline uint32_t GetPid() {
|
||||
static auto pid = syscall(__NR_getpid);
|
||||
return pid;
|
||||
}
|
||||
static inline uint32_t GetTid() {
|
||||
static thread_local auto tid = syscall(__NR_gettid);
|
||||
return tid;
|
||||
}
|
||||
|
||||
using namespace roctracer;
|
||||
|
||||
namespace {
|
||||
|
||||
session_buffer_id_t session_buffer_id{};
|
||||
|
||||
roctracer_start_cb_t roctracer_start_cb = nullptr;
|
||||
roctracer_stop_cb_t roctracer_stop_cb = nullptr;
|
||||
|
||||
std::mutex registration_mutex;
|
||||
|
||||
// Memory pool routines and primitives
|
||||
std::recursive_mutex memory_pool_mutex;
|
||||
|
||||
} // namespace
|
||||
|
||||
// Return Op code and kind by given string
|
||||
void roctracer_op_code(uint32_t domain, const char* str, uint32_t* op, uint32_t* kind) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_API: {
|
||||
*op = hsa_support::GetApiCode(str);
|
||||
if (*op == HSA_API_ID_NUMBER) {
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT,
|
||||
"Invalid API name \"" << str << "\", domain ID(" << domain << ")");
|
||||
}
|
||||
if (kind != nullptr) *kind = 0;
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HIP_API: {
|
||||
*op = hipApiIdByName(str);
|
||||
if (*op == HIP_API_ID_NONE) {
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT,
|
||||
"Invalid API name \"" << str << "\", domain ID(" << domain << ")");
|
||||
}
|
||||
if (kind != nullptr) *kind = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "limited domain ID(" << domain << ")");
|
||||
}
|
||||
}
|
||||
|
||||
// Return Op string by given domain and activity/API codes
|
||||
// nullptr returned on the error and the library errno is set
|
||||
const char* roctracer_op_string(uint32_t domain, uint32_t op) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
return hsa_support::GetApiName(op);
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
return hsa_support::GetEvtName(op);
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
return hsa_support::GetOpsName(op);
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
return HipLoader::Instance().GetOpName(op);
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
return HipLoader::Instance().ApiName(op);
|
||||
case ACTIVITY_DOMAIN_EXT_API:
|
||||
return "EXT_API";
|
||||
default:
|
||||
throw roctracer::ApiError(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID");
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <activity_domain_t> struct DomainTraits;
|
||||
|
||||
template <> struct DomainTraits<ACTIVITY_DOMAIN_HIP_API> {
|
||||
using ApiData = hip_api_data_t;
|
||||
using OperationId = hip_api_id_t;
|
||||
static constexpr size_t kOpIdBegin = HIP_API_ID_FIRST;
|
||||
static constexpr size_t kOpIdEnd = HIP_API_ID_LAST + 1;
|
||||
};
|
||||
|
||||
template <> struct DomainTraits<ACTIVITY_DOMAIN_HSA_API> {
|
||||
using ApiData = hsa_api_data_t;
|
||||
using OperationId = hsa_api_id_t;
|
||||
static constexpr size_t kOpIdBegin = 0;
|
||||
static constexpr size_t kOpIdEnd = HSA_API_ID_NUMBER;
|
||||
};
|
||||
|
||||
template <> struct DomainTraits<ACTIVITY_DOMAIN_ROCTX> {
|
||||
using ApiData = roctx_api_data_t;
|
||||
using OperationId = roctx_api_id_t;
|
||||
static constexpr size_t kOpIdBegin = 0;
|
||||
static constexpr size_t kOpIdEnd = ROCTX_API_ID_NUMBER;
|
||||
};
|
||||
|
||||
template <> struct DomainTraits<ACTIVITY_DOMAIN_HIP_OPS> {
|
||||
using OperationId = hip_op_id_t;
|
||||
static constexpr size_t kOpIdBegin = 0;
|
||||
static constexpr size_t kOpIdEnd = HIP_OP_ID_NUMBER;
|
||||
};
|
||||
|
||||
template <> struct DomainTraits<ACTIVITY_DOMAIN_HSA_OPS> {
|
||||
using OperationId = hsa_op_id_t;
|
||||
static constexpr size_t kOpIdBegin = 0;
|
||||
static constexpr size_t kOpIdEnd = HSA_OP_ID_NUMBER;
|
||||
};
|
||||
|
||||
template <> struct DomainTraits<ACTIVITY_DOMAIN_HSA_EVT> {
|
||||
using ApiData = hsa_evt_data_t;
|
||||
using OperationId = hsa_evt_id_t;
|
||||
static constexpr size_t kOpIdBegin = 0;
|
||||
static constexpr size_t kOpIdEnd = HSA_EVT_ID_NUMBER;
|
||||
};
|
||||
|
||||
constexpr uint32_t get_op_begin(activity_domain_t domain) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HSA_OPS>::kOpIdBegin;
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HSA_API>::kOpIdBegin;
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HSA_EVT>::kOpIdBegin;
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HIP_OPS>::kOpIdBegin;
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HIP_API>::kOpIdBegin;
|
||||
case ACTIVITY_DOMAIN_ROCTX:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_ROCTX>::kOpIdBegin;
|
||||
case ACTIVITY_DOMAIN_EXT_API:
|
||||
return 0;
|
||||
default:
|
||||
throw roctracer::ApiError(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID");
|
||||
}
|
||||
}
|
||||
|
||||
constexpr uint32_t get_op_end(activity_domain_t domain) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HSA_OPS>::kOpIdEnd;
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HSA_API>::kOpIdEnd;
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HSA_EVT>::kOpIdEnd;
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HIP_OPS>::kOpIdEnd;
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_HIP_API>::kOpIdEnd;
|
||||
case ACTIVITY_DOMAIN_ROCTX:
|
||||
return DomainTraits<ACTIVITY_DOMAIN_ROCTX>::kOpIdEnd;
|
||||
case ACTIVITY_DOMAIN_EXT_API:
|
||||
return get_op_begin(ACTIVITY_DOMAIN_EXT_API);
|
||||
default:
|
||||
throw roctracer::ApiError(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID");
|
||||
}
|
||||
}
|
||||
|
||||
std::atomic<bool> stopped_status{false};
|
||||
|
||||
struct IsStopped {
|
||||
bool operator()() const { return stopped_status.load(std::memory_order_relaxed); }
|
||||
};
|
||||
|
||||
struct NeverStopped {
|
||||
constexpr bool operator()() { return false; }
|
||||
};
|
||||
|
||||
using UserCallback = std::pair<activity_rtapi_callback_t, void*>;
|
||||
|
||||
template <activity_domain_t domain, typename IsStopped>
|
||||
using CallbackRegistrationTable =
|
||||
util::RegistrationTable<UserCallback, DomainTraits<domain>::kOpIdEnd, IsStopped>;
|
||||
|
||||
template <activity_domain_t domain, typename IsStopped>
|
||||
using ActivityRegistrationTable =
|
||||
util::RegistrationTable<roctracer_pool_t*, DomainTraits<domain>::kOpIdEnd, IsStopped>;
|
||||
|
||||
template <activity_domain_t domain> struct ApiTracer {
|
||||
using ApiData = typename DomainTraits<domain>::ApiData;
|
||||
using OperationId = typename DomainTraits<domain>::OperationId;
|
||||
|
||||
struct TraceData {
|
||||
ApiData api_data; // API specific data (for example, function arguments).
|
||||
uint64_t phase_enter_timestamp; // timestamp when phase_enter was executed.
|
||||
uint64_t phase_data; // data that can be shared between phase_enter and
|
||||
// phase_exit.
|
||||
|
||||
void (*phase_enter)(OperationId operation_id, TraceData* data);
|
||||
void (*phase_exit)(OperationId operation_id, TraceData* data);
|
||||
};
|
||||
|
||||
static void Exit(OperationId operation_id, TraceData* trace_data) {
|
||||
uint64_t record_id = 0;
|
||||
if (rocmtools::GetROCMToolObj()) {
|
||||
record_id = rocmtools::GetROCMToolObj()->GetUniqueRecordId();
|
||||
if (auto pool = activity_table.Get(operation_id)) {
|
||||
if (rocmtools::GetROCMToolObj() &&
|
||||
rocmtools::GetROCMToolObj()->GetSession((*pool)->session_id) &&
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)) {
|
||||
if (rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->IsValid()) {
|
||||
std::lock_guard<std::mutex> lock(rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->GetBufferLock());
|
||||
assert(trace_data != nullptr);
|
||||
rocprofiler_record_tracer_t record{};
|
||||
record.header = rocprofiler_record_header_t{ROCPROFILER_TRACER_RECORD,
|
||||
rocprofiler_record_id_t{record_id}};
|
||||
record.domain = domain;
|
||||
record.operation_id = rocprofiler_tracer_operation_id_t{operation_id};
|
||||
record.correlation_id =
|
||||
rocprofiler_tracer_activity_correlation_id_t{trace_data->api_data.correlation_id};
|
||||
record.timestamps = rocprofiler_record_header_timestamp_t{
|
||||
rocprofiler_timestamp_t{trace_data->phase_enter_timestamp},
|
||||
hsa_support::timestamp_ns()};
|
||||
record.thread_id = rocprofiler_thread_id_t{GetTid()};
|
||||
|
||||
if (auto external_id = ExternalCorrelationId()) {
|
||||
rocprofiler_record_tracer_t ext_record{};
|
||||
ext_record.header = rocprofiler_record_header_t{ROCPROFILER_TRACER_RECORD,
|
||||
rocprofiler_record_id_t{record_id}};
|
||||
ext_record.domain = ACTIVITY_DOMAIN_EXT_API;
|
||||
ext_record.operation_id = rocprofiler_tracer_operation_id_t{ACTIVITY_EXT_OP_EXTERN_ID};
|
||||
ext_record.correlation_id =
|
||||
rocprofiler_tracer_activity_correlation_id_t{record.correlation_id};
|
||||
ext_record.external_id = rocprofiler_tracer_external_id_t{*external_id};
|
||||
// Write the external correlation id record directly followed by the
|
||||
// activity record.
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->AddRecord(std::array<rocprofiler_record_tracer_t, 2>{ext_record, record});
|
||||
} else {
|
||||
// Write record to the buffer.
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->AddRecord(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CorrelationIdPop();
|
||||
}
|
||||
|
||||
static void Exit_UserCallback(OperationId operation_id, TraceData* trace_data) {
|
||||
if (auto user_callback = callback_table.Get(operation_id)) {
|
||||
assert(trace_data != nullptr);
|
||||
trace_data->api_data.phase = ACTIVITY_API_PHASE_EXIT;
|
||||
user_callback->first(domain, operation_id, &trace_data->api_data, user_callback->second);
|
||||
}
|
||||
Exit(operation_id, trace_data);
|
||||
}
|
||||
|
||||
static void Enter_UserCallback(OperationId operation_id, TraceData* trace_data) {
|
||||
if (auto user_callback = callback_table.Get(operation_id)) {
|
||||
assert(trace_data != nullptr);
|
||||
trace_data->api_data.phase = ACTIVITY_API_PHASE_ENTER;
|
||||
trace_data->api_data.phase_data = &trace_data->phase_data;
|
||||
user_callback->first(domain, operation_id, &trace_data->api_data, user_callback->second);
|
||||
trace_data->phase_exit = Exit_UserCallback;
|
||||
} else {
|
||||
trace_data->phase_exit = Exit;
|
||||
}
|
||||
}
|
||||
|
||||
static int Enter(OperationId operation_id, TraceData* trace_data) {
|
||||
bool callback_enabled = callback_table.Get(operation_id).has_value(),
|
||||
activity_enabled = activity_table.Get(operation_id).has_value();
|
||||
if (!callback_enabled && !activity_enabled) return -1;
|
||||
|
||||
if (trace_data != nullptr) {
|
||||
// Generate a new correlation ID.
|
||||
trace_data->api_data.correlation_id = CorrelationIdPush();
|
||||
|
||||
if (activity_enabled) {
|
||||
trace_data->phase_enter_timestamp = hsa_support::timestamp_ns().value;
|
||||
trace_data->phase_enter = nullptr;
|
||||
trace_data->phase_exit = Exit;
|
||||
}
|
||||
if (callback_enabled) {
|
||||
trace_data->phase_enter = Enter_UserCallback;
|
||||
trace_data->phase_exit = [](OperationId, TraceData*) {
|
||||
rocmtools::fatal("should not reach here");
|
||||
};
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CallbackRegistrationTable<domain, IsStopped> callback_table;
|
||||
static ActivityRegistrationTable<domain, IsStopped> activity_table;
|
||||
};
|
||||
|
||||
template <activity_domain_t domain>
|
||||
CallbackRegistrationTable<domain, IsStopped> ApiTracer<domain>::callback_table;
|
||||
|
||||
template <activity_domain_t domain>
|
||||
ActivityRegistrationTable<domain, IsStopped> ApiTracer<domain>::activity_table;
|
||||
|
||||
using HIP_ApiTracer = ApiTracer<ACTIVITY_DOMAIN_HIP_API>;
|
||||
using HSA_ApiTracer = ApiTracer<ACTIVITY_DOMAIN_HSA_API>;
|
||||
|
||||
CallbackRegistrationTable<ACTIVITY_DOMAIN_ROCTX, NeverStopped> roctx_api_callback_table;
|
||||
ActivityRegistrationTable<ACTIVITY_DOMAIN_HIP_OPS, IsStopped> hip_ops_activity_table;
|
||||
ActivityRegistrationTable<ACTIVITY_DOMAIN_HSA_OPS, IsStopped> hsa_ops_activity_table;
|
||||
CallbackRegistrationTable<ACTIVITY_DOMAIN_HSA_EVT, IsStopped> hsa_evt_callback_table;
|
||||
|
||||
int TracerCallback(activity_domain_t domain, uint32_t operation_id, void* data) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
return HSA_ApiTracer::Enter(static_cast<HSA_ApiTracer::OperationId>(operation_id),
|
||||
static_cast<HSA_ApiTracer::TraceData*>(data));
|
||||
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
return HIP_ApiTracer::Enter(static_cast<HIP_ApiTracer::OperationId>(operation_id),
|
||||
static_cast<HIP_ApiTracer::TraceData*>(data));
|
||||
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
if (auto pool = hip_ops_activity_table.Get(operation_id)) {
|
||||
if (auto record = static_cast<activity_record_t*>(data)) {
|
||||
// If the record is for a kernel dispatch, write the kernel name in the pool's data,
|
||||
// and make the record point to it. Older HIP runtimes do not provide a kernel name,
|
||||
// so record.kernel_name might be null.
|
||||
uint64_t record_id = 0;
|
||||
if (!rocmtools::GetROCMToolObj()) return 0;
|
||||
if (rocmtools::GetROCMToolObj() &&
|
||||
rocmtools::GetROCMToolObj()->GetSession((*pool)->session_id) &&
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)) {
|
||||
std::lock_guard<std::mutex> lock(rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->GetBufferLock());
|
||||
record_id = rocmtools::GetROCMToolObj()->GetUniqueRecordId();
|
||||
rocprofiler_record_tracer_t rocprofiler_record{};
|
||||
rocprofiler_record.header = rocprofiler_record_header_t{ROCPROFILER_TRACER_RECORD,
|
||||
rocprofiler_record_id_t{record_id}};
|
||||
rocprofiler_record.domain = domain;
|
||||
rocprofiler_record.external_id = rocprofiler_tracer_external_id_t{};
|
||||
rocprofiler_record.operation_id = rocprofiler_tracer_operation_id_t{record->kind};
|
||||
rocprofiler_record.api_data_handle = rocprofiler_tracer_api_data_handle_t{};
|
||||
rocprofiler_record.correlation_id =
|
||||
rocprofiler_tracer_activity_correlation_id_t{record->correlation_id};
|
||||
rocprofiler_record.timestamps = rocprofiler_record_header_timestamp_t{
|
||||
rocprofiler_timestamp_t{record->begin_ns}, rocprofiler_timestamp_t{record->end_ns}};
|
||||
rocprofiler_record.agent_id = rocprofiler_agent_id_t{(uint64_t)record->device_id};
|
||||
rocprofiler_record.queue_id = rocprofiler_queue_id_t{record->queue_id};
|
||||
rocprofiler_record.thread_id = rocprofiler_thread_id_t{GetTid()};
|
||||
if (operation_id == HIP_OP_ID_DISPATCH && record->kernel_name != nullptr) {
|
||||
rocprofiler_record.api_data_handle.handle = strdup(record->kernel_name);
|
||||
rocprofiler_record.api_data_handle.size = (strlen(record->kernel_name) + 1);
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->AddRecord(rocprofiler_record, rocprofiler_record.api_data_handle.handle,
|
||||
rocprofiler_record.api_data_handle.size,
|
||||
[](auto& rocprofiler_record, const void* data) {
|
||||
rocprofiler_record.api_data_handle.handle =
|
||||
static_cast<const char*>(data);
|
||||
});
|
||||
} else {
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->AddRecord(rocprofiler_record);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTIVITY_DOMAIN_ROCTX:
|
||||
if (auto user_callback = roctx_api_callback_table.Get(operation_id)) {
|
||||
if (auto api_data = static_cast<DomainTraits<ACTIVITY_DOMAIN_ROCTX>::ApiData*>(data))
|
||||
user_callback->first(ACTIVITY_DOMAIN_ROCTX, operation_id, api_data,
|
||||
user_callback->second);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
if (auto pool = hsa_ops_activity_table.Get(operation_id)) {
|
||||
if (auto record = static_cast<activity_record_t*>(data)) {
|
||||
uint64_t record_id = 0;
|
||||
if (!rocmtools::GetROCMToolObj()) return 0;
|
||||
if (rocmtools::GetROCMToolObj() &&
|
||||
rocmtools::GetROCMToolObj()->GetSession((*pool)->session_id) &&
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)) {
|
||||
std::lock_guard<std::mutex> lock(rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->GetBufferLock());
|
||||
record_id = rocmtools::GetROCMToolObj()->GetUniqueRecordId();
|
||||
rocprofiler_record_tracer_t rocprofiler_record{};
|
||||
rocprofiler_record.header = rocprofiler_record_header_t{ROCPROFILER_TRACER_RECORD,
|
||||
rocprofiler_record_id_t{record_id}};
|
||||
rocprofiler_record.domain = domain;
|
||||
rocprofiler_record.external_id = rocprofiler_tracer_external_id_t{0};
|
||||
rocprofiler_record.operation_id = rocprofiler_tracer_operation_id_t{record->op};
|
||||
rocprofiler_record.api_data_handle = rocprofiler_tracer_api_data_handle_t{};
|
||||
rocprofiler_record.correlation_id =
|
||||
rocprofiler_tracer_activity_correlation_id_t{record->correlation_id};
|
||||
rocprofiler_record.timestamps = rocprofiler_record_header_timestamp_t{
|
||||
rocprofiler_timestamp_t{record->begin_ns}, rocprofiler_timestamp_t{record->end_ns}};
|
||||
rocprofiler_record.agent_id = rocprofiler_agent_id_t{(uint64_t)record->device_id};
|
||||
rocprofiler_record.queue_id = rocprofiler_queue_id_t{record->queue_id};
|
||||
rocprofiler_record.thread_id = rocprofiler_thread_id_t{GetTid()};
|
||||
if (record->kernel_name != nullptr && record->op == HSA_OP_ID_DISPATCH) {
|
||||
rocprofiler_record.api_data_handle.handle = strdup(record->kernel_name);
|
||||
rocprofiler_record.api_data_handle.size = strlen(record->kernel_name) + 1;
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->AddRecord(rocprofiler_record, rocprofiler_record.api_data_handle.handle,
|
||||
rocprofiler_record.api_data_handle.size,
|
||||
[](auto& rocprofiler_record, const void* data) {
|
||||
rocprofiler_record.api_data_handle.handle =
|
||||
static_cast<const char*>(data);
|
||||
});
|
||||
} else {
|
||||
rocmtools::GetROCMToolObj()
|
||||
->GetSession((*pool)->session_id)
|
||||
->GetBuffer((*pool)->buffer_id)
|
||||
->AddRecord(rocprofiler_record);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
if (auto user_callback = hsa_evt_callback_table.Get(operation_id)) {
|
||||
if (auto api_data = static_cast<DomainTraits<ACTIVITY_DOMAIN_HSA_EVT>::ApiData*>(data))
|
||||
user_callback->first(ACTIVITY_DOMAIN_HSA_EVT, operation_id, api_data,
|
||||
user_callback->second);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} // namespace
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename... Tables> struct RegistrationTableGroup {
|
||||
private:
|
||||
bool AllEmpty() const {
|
||||
return std::apply([](auto&&... tables) { return (tables.IsEmpty() && ...); }, tables_);
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename Functor1, typename Functor2>
|
||||
RegistrationTableGroup(Functor1&& engage_tracer, Functor2&& disengage_tracer, Tables&... tables)
|
||||
: engage_tracer_(std::forward<Functor1>(engage_tracer)),
|
||||
disengage_tracer_(std::forward<Functor2>(disengage_tracer)),
|
||||
tables_(tables...) {}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void Register(T& table, uint32_t operation_id, Args... args) const {
|
||||
if (AllEmpty()) engage_tracer_();
|
||||
table.Register(operation_id, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T> void Unregister(T& table, uint32_t operation_id) const {
|
||||
table.Unregister(operation_id);
|
||||
if (AllEmpty()) disengage_tracer_();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::function<void()> engage_tracer_, disengage_tracer_;
|
||||
const std::tuple<const Tables&...> tables_;
|
||||
};
|
||||
|
||||
RegistrationTableGroup HSA_registration_group(
|
||||
[]() { hsa_support::RegisterTracerCallback(TracerCallback); },
|
||||
[]() { hsa_support::RegisterTracerCallback(nullptr); }, HSA_ApiTracer::callback_table,
|
||||
HSA_ApiTracer::activity_table, hsa_ops_activity_table, hsa_evt_callback_table);
|
||||
|
||||
RegistrationTableGroup HIP_registration_group(
|
||||
[]() { HipLoader::Instance().RegisterTracerCallback(TracerCallback); },
|
||||
[]() { HipLoader::Instance().RegisterTracerCallback(nullptr); }, HIP_ApiTracer::callback_table,
|
||||
HIP_ApiTracer::activity_table, hip_ops_activity_table);
|
||||
|
||||
RegistrationTableGroup ROCTX_registration_group(
|
||||
[]() { RocTxLoader::Instance().RegisterTracerCallback(TracerCallback); },
|
||||
[]() { RocTxLoader::Instance().RegisterTracerCallback(nullptr); }, roctx_api_callback_table);
|
||||
|
||||
} // namespace
|
||||
|
||||
// Enable runtime API callbacks
|
||||
static void roctracer_enable_op_callback(activity_domain_t domain, uint32_t operation_id,
|
||||
roctracer_rtapi_callback_t callback, void* user_data) {
|
||||
std::lock_guard lock(registration_mutex);
|
||||
|
||||
if (operation_id >= get_op_end(domain) || callback == nullptr)
|
||||
throw ApiError(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT, "invalid argument");
|
||||
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
HSA_registration_group.Register(hsa_evt_callback_table, operation_id, callback, user_data);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
HSA_registration_group.Register(HSA_ApiTracer::callback_table, operation_id, callback,
|
||||
user_data);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
if (HipLoader::Instance().IsEnabled())
|
||||
HIP_registration_group.Register(HIP_ApiTracer::callback_table, operation_id, callback,
|
||||
user_data);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_ROCTX:
|
||||
if (RocTxLoader::Instance().IsEnabled())
|
||||
ROCTX_registration_group.Register(roctx_api_callback_table, operation_id, callback,
|
||||
user_data);
|
||||
break;
|
||||
default:
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID(" << domain << ")");
|
||||
}
|
||||
}
|
||||
|
||||
void roctracer_enable_domain_callback(activity_domain_t domain, roctracer_rtapi_callback_t callback,
|
||||
void* user_data) {
|
||||
const uint32_t op_end = get_op_end(domain);
|
||||
for (uint32_t op = get_op_begin(domain); op < op_end; ++op)
|
||||
roctracer_enable_op_callback(domain, op, callback, user_data);
|
||||
}
|
||||
|
||||
// Disable runtime API callbacks
|
||||
void roctracer_disable_op_callback(activity_domain_t domain, uint32_t operation_id) {
|
||||
std::lock_guard lock(registration_mutex);
|
||||
|
||||
if (operation_id >= get_op_end(domain))
|
||||
throw ApiError(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT, "invalid argument");
|
||||
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
HSA_registration_group.Unregister(hsa_evt_callback_table, operation_id);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
HSA_registration_group.Unregister(HSA_ApiTracer::callback_table, operation_id);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
if (HipLoader::Instance().IsEnabled())
|
||||
HIP_registration_group.Unregister(HIP_ApiTracer::callback_table, operation_id);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_ROCTX:
|
||||
if (RocTxLoader::Instance().IsEnabled())
|
||||
ROCTX_registration_group.Unregister(roctx_api_callback_table, operation_id);
|
||||
break;
|
||||
default:
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID(" << domain << ")");
|
||||
}
|
||||
}
|
||||
|
||||
void roctracer_disable_domain_callback(activity_domain_t domain) {
|
||||
const uint32_t op_end = get_op_end(domain);
|
||||
for (uint32_t op = get_op_begin(domain); op < op_end; ++op)
|
||||
roctracer_disable_op_callback(domain, op);
|
||||
}
|
||||
|
||||
// Enable activity records logging
|
||||
void roctracer_enable_op_activity(activity_domain_t domain, uint32_t op,
|
||||
roctracer_pool_t memory_pool) {
|
||||
std::lock_guard lock(registration_mutex);
|
||||
|
||||
if (memory_pool.session_id.handle > 0) {
|
||||
session_buffer_id.buffer_id = memory_pool.buffer_id;
|
||||
session_buffer_id.session_id = memory_pool.session_id;
|
||||
}
|
||||
|
||||
if (op >= get_op_end(domain))
|
||||
throw ApiError(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT, "invalid argument");
|
||||
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
HSA_registration_group.Register(HSA_ApiTracer::activity_table, op, &session_buffer_id);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
HSA_registration_group.Register(hsa_ops_activity_table, op, &session_buffer_id);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
if (HipLoader::Instance().IsEnabled())
|
||||
HIP_registration_group.Register(HIP_ApiTracer::activity_table, op, &session_buffer_id);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
if (HipLoader::Instance().IsEnabled())
|
||||
HIP_registration_group.Register(hip_ops_activity_table, op, &session_buffer_id);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_ROCTX:
|
||||
break;
|
||||
default:
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID(" << domain << ")");
|
||||
}
|
||||
}
|
||||
|
||||
void roctracer_enable_domain_activity(activity_domain_t domain, roctracer_pool_t pool) {
|
||||
const uint32_t op_end = get_op_end(domain);
|
||||
for (uint32_t op = get_op_begin(domain); op < op_end; ++op) {
|
||||
try {
|
||||
roctracer_enable_op_activity(domain, op, pool);
|
||||
} catch (const ApiError& err) {
|
||||
if (err.status() != ROCTRACER_STATUS_ERROR_NOT_IMPLEMENTED) throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable activity records logging
|
||||
void roctracer_disable_activity(activity_domain_t domain, uint32_t op) {
|
||||
std::lock_guard lock(registration_mutex);
|
||||
|
||||
if (op >= get_op_end(domain))
|
||||
throw ApiError(ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT, "invalid argument");
|
||||
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
HSA_registration_group.Unregister(HSA_ApiTracer::activity_table, op);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
HSA_registration_group.Unregister(hsa_ops_activity_table, op);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_API:
|
||||
if (HipLoader::Instance().IsEnabled())
|
||||
HIP_registration_group.Unregister(HIP_ApiTracer::activity_table, op);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
if (HipLoader::Instance().IsEnabled())
|
||||
HIP_registration_group.Unregister(hip_ops_activity_table, op);
|
||||
break;
|
||||
case ACTIVITY_DOMAIN_ROCTX:
|
||||
break;
|
||||
default:
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID(" << domain << ")");
|
||||
}
|
||||
}
|
||||
|
||||
void roctracer_disable_domain_activity(activity_domain_t domain) {
|
||||
const uint32_t op_end = get_op_end(domain);
|
||||
for (uint32_t op = get_op_begin(domain); op < op_end; ++op) try {
|
||||
roctracer_disable_activity(domain, op);
|
||||
} catch (const ApiError& err) {
|
||||
if (err.status() != ROCTRACER_STATUS_ERROR_NOT_IMPLEMENTED) throw;
|
||||
}
|
||||
}
|
||||
|
||||
// Notifies that the calling thread is entering an external API region.
|
||||
// Push an external correlation id for the calling thread.
|
||||
void roctracer_activity_push_external_correlation_id(activity_correlation_id_t id) {
|
||||
ExternalCorrelationIdPush(id);
|
||||
}
|
||||
|
||||
// Notifies that the calling thread is leaving an external API region.
|
||||
// Pop an external correlation id for the calling thread, and return it in
|
||||
// 'last_id' if not null.
|
||||
void roctracer_activity_pop_external_correlation_id(activity_correlation_id_t* last_id) {
|
||||
auto external_id = ExternalCorrelationIdPop();
|
||||
if (!external_id) {
|
||||
if (last_id != nullptr) *last_id = 0;
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_MISMATCHED_EXTERNAL_CORRELATION_ID,
|
||||
"unbalanced external correlation id pop");
|
||||
}
|
||||
|
||||
if (last_id != nullptr) *last_id = *external_id;
|
||||
}
|
||||
|
||||
// Start API
|
||||
void roctracer_start() {
|
||||
if (stopped_status.exchange(false, std::memory_order_relaxed) && roctracer_start_cb)
|
||||
roctracer_start_cb();
|
||||
}
|
||||
|
||||
// Stop API
|
||||
void roctracer_stop() {
|
||||
if (!stopped_status.exchange(true, std::memory_order_relaxed) && roctracer_stop_cb)
|
||||
roctracer_stop_cb();
|
||||
}
|
||||
|
||||
// Set properties
|
||||
void roctracer_set_properties(activity_domain_t domain, void* properties) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_HSA_OPS:
|
||||
case ACTIVITY_DOMAIN_HSA_EVT:
|
||||
case ACTIVITY_DOMAIN_HSA_API:
|
||||
case ACTIVITY_DOMAIN_HIP_OPS:
|
||||
case ACTIVITY_DOMAIN_HIP_API: {
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_EXT_API: {
|
||||
roctracer_ext_properties_t* ops_properties =
|
||||
reinterpret_cast<roctracer_ext_properties_t*>(properties);
|
||||
roctracer_start_cb = ops_properties->start_cb;
|
||||
roctracer_stop_cb = ops_properties->stop_cb;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
EXC_RAISING(ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID, "invalid domain ID(" << domain << ")");
|
||||
}
|
||||
}
|
||||
|
||||
static std::string getKernelNameMultiKernelMultiDevice(hipLaunchParams* launchParamsList,
|
||||
int numDevices) {
|
||||
std::stringstream name_str;
|
||||
for (int i = 0; i < numDevices; ++i) {
|
||||
if (launchParamsList[i].func != nullptr) {
|
||||
name_str << HipLoader::Instance().KernelNameRefByPtr(launchParamsList[i].func) << ":"
|
||||
<< HipLoader::Instance().GetStreamDeviceId(launchParamsList[i].stream) << ";";
|
||||
}
|
||||
}
|
||||
return name_str.str();
|
||||
}
|
||||
|
||||
template <typename... Ts> struct Overloaded : Ts... { using Ts::operator()...; };
|
||||
template <class... Ts> Overloaded(Ts...) -> Overloaded<Ts...>;
|
||||
|
||||
std::optional<std::string> GetHipKernelName(uint32_t cid, hip_api_data_t* data) {
|
||||
std::variant<const void*, hipFunction_t> function;
|
||||
switch (cid) {
|
||||
case HIP_API_ID_hipExtLaunchMultiKernelMultiDevice: {
|
||||
return getKernelNameMultiKernelMultiDevice(
|
||||
data->args.hipExtLaunchMultiKernelMultiDevice.launchParamsList,
|
||||
data->args.hipExtLaunchMultiKernelMultiDevice.numDevices);
|
||||
}
|
||||
case HIP_API_ID_hipLaunchCooperativeKernelMultiDevice: {
|
||||
return getKernelNameMultiKernelMultiDevice(
|
||||
data->args.hipLaunchCooperativeKernelMultiDevice.launchParamsList,
|
||||
data->args.hipLaunchCooperativeKernelMultiDevice.numDevices);
|
||||
}
|
||||
case HIP_API_ID_hipLaunchKernel: {
|
||||
function = data->args.hipLaunchKernel.function_address;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipExtLaunchKernel: {
|
||||
function = data->args.hipExtLaunchKernel.function_address;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipLaunchCooperativeKernel: {
|
||||
function = data->args.hipLaunchCooperativeKernel.f;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipLaunchByPtr: {
|
||||
function = data->args.hipLaunchByPtr.hostFunction;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipGraphAddKernelNode: {
|
||||
function = data->args.hipGraphAddKernelNode.pNodeParams->func;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipGraphExecKernelNodeSetParams: {
|
||||
function = data->args.hipGraphExecKernelNodeSetParams.pNodeParams->func;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipGraphKernelNodeSetParams: {
|
||||
function = data->args.hipGraphKernelNodeSetParams.pNodeParams->func;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipModuleLaunchKernel: {
|
||||
function = data->args.hipModuleLaunchKernel.f;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipExtModuleLaunchKernel: {
|
||||
function = data->args.hipExtModuleLaunchKernel.f;
|
||||
break;
|
||||
}
|
||||
case HIP_API_ID_hipHccModuleLaunchKernel: {
|
||||
function = data->args.hipHccModuleLaunchKernel.f;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
return std::visit(
|
||||
Overloaded{
|
||||
[](const void* func) { return HipLoader::Instance().KernelNameRefByPtr(func); },
|
||||
[](hipFunction_t func) { return HipLoader::Instance().KernelNameRef(func); },
|
||||
},
|
||||
function);
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
/* Copyright (c) 2018-2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_TOOLS_TRACER_SRC_ROCTRACER_H_
|
||||
#define SRC_TOOLS_TRACER_SRC_ROCTRACER_H_
|
||||
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "hip_ostream_ops.h"
|
||||
#include "hsa_ostream_ops.h"
|
||||
#include "hsa_prof_str.h"
|
||||
#include "inc/rocprofiler.h"
|
||||
#include "src/core/memory/generic_buffer.h"
|
||||
|
||||
typedef struct {
|
||||
rocprofiler_session_id_t session_id;
|
||||
rocprofiler_buffer_id_t buffer_id;
|
||||
} session_buffer_id_t;
|
||||
|
||||
typedef session_buffer_id_t roctracer_pool_t;
|
||||
|
||||
/* Correlation id */
|
||||
typedef uint64_t activity_correlation_id_t;
|
||||
|
||||
typedef uint32_t activity_kind_t;
|
||||
typedef uint32_t activity_op_t;
|
||||
|
||||
typedef uint64_t roctracer_timestamp_t;
|
||||
|
||||
typedef rocprofiler_tracer_activity_domain_t roctracer_domain_t;
|
||||
typedef rocprofiler_tracer_activity_domain_t activity_domain_t;
|
||||
|
||||
|
||||
// Prof_Protocol
|
||||
/* Activity record type */
|
||||
typedef struct activity_record_s {
|
||||
uint32_t domain; /* activity domain id */
|
||||
activity_kind_t kind; /* activity kind */
|
||||
activity_op_t op; /* activity op */
|
||||
union {
|
||||
struct {
|
||||
activity_correlation_id_t correlation_id; /* activity ID */
|
||||
roctracer_timestamp_t begin_ns; /* host begin timestamp */
|
||||
roctracer_timestamp_t end_ns; /* host end timestamp */
|
||||
};
|
||||
struct {
|
||||
uint32_t se; /* sampled SE */
|
||||
uint64_t cycle; /* sample cycle */
|
||||
uint64_t pc; /* sample PC */
|
||||
} pc_sample;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
int device_id; /* device id */
|
||||
uint64_t queue_id; /* queue id */
|
||||
};
|
||||
struct {
|
||||
uint32_t process_id; /* device id */
|
||||
uint32_t thread_id; /* thread id */
|
||||
};
|
||||
struct {
|
||||
activity_correlation_id_t external_id; /* external correlation id */
|
||||
};
|
||||
};
|
||||
union {
|
||||
size_t bytes; /* data size bytes */
|
||||
const char* kernel_name; /* kernel name */
|
||||
const char* mark_message;
|
||||
};
|
||||
} activity_record_t;
|
||||
|
||||
typedef activity_record_t roctracer_record_t;
|
||||
|
||||
/* Activity sync callback type */
|
||||
typedef void (*activity_sync_callback_t)(activity_domain_t cid, activity_record_t* record,
|
||||
const void* data, void* arg);
|
||||
/* Activity async callback type */
|
||||
typedef void (*activity_async_callback_t)(activity_domain_t op, void* record, void* arg);
|
||||
|
||||
|
||||
/* API callback type */
|
||||
typedef void (*activity_rtapi_callback_t)(activity_domain_t domain, uint32_t cid, const void* data,
|
||||
void* arg);
|
||||
typedef activity_rtapi_callback_t roctracer_rtapi_callback_t;
|
||||
|
||||
typedef roctracer_timestamp_t (*roctracer_get_timestamp_t)();
|
||||
typedef rocprofiler_timestamp_t (*rocprofiler_get_timestamp_t)();
|
||||
|
||||
typedef uint32_t activity_kind_t;
|
||||
typedef uint32_t activity_op_t;
|
||||
|
||||
/* API callback phase */
|
||||
typedef enum { ACTIVITY_API_PHASE_ENTER = 0, ACTIVITY_API_PHASE_EXIT = 1 } activity_api_phase_t;
|
||||
|
||||
const char* roctracer_op_string(uint32_t domain, uint32_t op);
|
||||
|
||||
/* Trace record types */
|
||||
|
||||
/**
|
||||
* Memory pool allocator callback.
|
||||
*
|
||||
* If \p *ptr is NULL, then allocate memory of \p size bytes and save address
|
||||
* in \p *ptr.
|
||||
*
|
||||
* If \p *ptr is non-NULL and size is non-0, then reallocate the memory at \p
|
||||
* *ptr with size \p size and save the address in \p *ptr. The memory will have
|
||||
* been allocated by the same callback.
|
||||
*
|
||||
* If \p *ptr is non-NULL and size is 0, then deallocate the memory at \p *ptr.
|
||||
* The memory will have been allocated by the same callback.
|
||||
*
|
||||
* \p size is the size of the memory allocation or reallocation, or 0 if
|
||||
* deallocating.
|
||||
*
|
||||
* \p arg Argument provided
|
||||
*/
|
||||
typedef void (*roctracer_allocator_t)(char** ptr, size_t size, void* arg);
|
||||
|
||||
/**
|
||||
* Memory pool buffer callback.
|
||||
*
|
||||
* The callback that will be invoked when a memory pool buffer becomes full or
|
||||
* is flushed.
|
||||
*
|
||||
* \p begin pointer to first entry entry in the buffer.
|
||||
*
|
||||
* \p end pointer to one past the end entry in the buffer.
|
||||
*
|
||||
* \p arg the argument specified when the callback was defined.
|
||||
*/
|
||||
typedef void (*roctracer_buffer_callback_t)(const char* begin, const char* end, void* arg);
|
||||
|
||||
/**
|
||||
* Memory pool properties.
|
||||
*
|
||||
* Defines the properties when a tracer memory pool is created.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* ROC Tracer mode.
|
||||
*/
|
||||
uint32_t mode;
|
||||
|
||||
/**
|
||||
* Size of buffer in bytes.
|
||||
*/
|
||||
size_t buffer_size;
|
||||
|
||||
/**
|
||||
* The allocator function to use to allocate and deallocate the buffer. If
|
||||
* NULL then \p malloc, \p realloc, and \p free are used.
|
||||
*/
|
||||
roctracer_allocator_t alloc_fun;
|
||||
|
||||
/**
|
||||
* The argument to pass when invoking the \p alloc_fun allocator.
|
||||
*/
|
||||
void* alloc_arg;
|
||||
|
||||
/**
|
||||
* The function to call when a buffer becomes full or is flushed.
|
||||
*/
|
||||
roctracer_buffer_callback_t buffer_callback_fun;
|
||||
|
||||
/**
|
||||
* The argument to pass when invoking the \p buffer_callback_fun callback.
|
||||
*/
|
||||
void* buffer_callback_arg;
|
||||
} roctracer_properties_t;
|
||||
|
||||
/**
|
||||
* ROC Tracer API status codes.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* The function has executed successfully.
|
||||
*/
|
||||
ROCTRACER_STATUS_SUCCESS = 0,
|
||||
/**
|
||||
* A generic error has occurred.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR = -1,
|
||||
/**
|
||||
* The domain ID is invalid.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID = -2,
|
||||
/**
|
||||
* An invalid argument was given to the function.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT = -3,
|
||||
/**
|
||||
* No default pool is defined.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR_DEFAULT_POOL_UNDEFINED = -4,
|
||||
/**
|
||||
* The default pool is already defined.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR_DEFAULT_POOL_ALREADY_DEFINED = -5,
|
||||
/**
|
||||
* Memory allocation error.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR_MEMORY_ALLOCATION = -6,
|
||||
/**
|
||||
* External correlation ID pop mismatch.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR_MISMATCHED_EXTERNAL_CORRELATION_ID = -7,
|
||||
/**
|
||||
* The operation is not currently implemented. This error may be reported by
|
||||
* any function. Check the \ref known_limitations section to determine the
|
||||
* status of the library implementation of the interface.
|
||||
*/
|
||||
ROCTRACER_STATUS_ERROR_NOT_IMPLEMENTED = -8,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_UNINIT = 2,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_BREAK = 3,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_BAD_DOMAIN = ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_BAD_PARAMETER = ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_HIP_API_ERR = 6,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_HIP_OPS_ERR = 7,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_HCC_OPS_ERR = ROCTRACER_STATUS_HIP_OPS_ERR,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_HSA_ERR = 7,
|
||||
/**
|
||||
* Deprecated error code.
|
||||
*/
|
||||
ROCTRACER_STATUS_ROCTX_ERR = 8,
|
||||
} roctracer_status_t;
|
||||
|
||||
/**
|
||||
* Query textual name of an operation of a domain.
|
||||
* @param[in] domain Domain being queried.
|
||||
* @param[in] op Operation within \p domain.
|
||||
* @param[in] kind \todo Define kind.
|
||||
* @return Returns the NUL terminated string for the operation name, or NULL if
|
||||
* the domain or operation are invalid. The string is owned by the ROC Tracer
|
||||
* library.
|
||||
*/
|
||||
const char* roctracer_op_string(uint32_t domain, uint32_t op, uint32_t kind);
|
||||
|
||||
/**
|
||||
* Query the operation code given a domain and the name of an operation.
|
||||
* @param[in] domain The domain being queried.
|
||||
* @param[in] str The NUL terminated name of the operation name being queried.
|
||||
* @param[out] op The operation code.
|
||||
* @param[out] kind If not NULL then the operation kind code.
|
||||
*/
|
||||
void roctracer_op_code(uint32_t domain, const char* str, uint32_t* op, uint32_t* kind);
|
||||
|
||||
/**
|
||||
* Set the properties of a domain.
|
||||
* @param[in] domain The domain.
|
||||
* @param[in] properties The properties. Each domain defines its own type for
|
||||
* the properties. Some domains require the properties to be set before they
|
||||
* can be enabled.
|
||||
*/
|
||||
void roctracer_set_properties(roctracer_domain_t domain, void* properties);
|
||||
|
||||
/**
|
||||
* Enable runtime API callback for a specific operation of a domain.
|
||||
* @param domain The domain.
|
||||
* @param op The operation ID in \p domain.
|
||||
* @param callback The callback to invoke each time the operation is performed
|
||||
* on entry and exit.
|
||||
* @param pool Value to pass as last argument of \p callback.
|
||||
*/
|
||||
void roctracer_enable_op_callback(roctracer_domain_t domain, uint32_t op,
|
||||
roctracer_rtapi_callback_t callback);
|
||||
|
||||
/**
|
||||
* Enable runtime API callback for all operations of a domain.
|
||||
* @param domain The domain
|
||||
* @param callback The callback to invoke each time the operation is performed
|
||||
* on entry and exit.
|
||||
* @param arg Value to pass as last argument of \p callback.
|
||||
*/
|
||||
void roctracer_enable_domain_callback(roctracer_domain_t domain,
|
||||
roctracer_rtapi_callback_t callback,
|
||||
void* user_data = nullptr);
|
||||
|
||||
/**
|
||||
* Disable runtime API callback for a specific operation of a domain.
|
||||
* @param domain The domain
|
||||
* @param op The operation in \p domain.
|
||||
*/
|
||||
void roctracer_disable_op_callback(roctracer_domain_t domain, uint32_t op);
|
||||
|
||||
/**
|
||||
* Disable runtime API callback for all operations of a domain.
|
||||
* @param domain The domain
|
||||
*/
|
||||
void roctracer_disable_domain_callback(roctracer_domain_t domain);
|
||||
|
||||
/**
|
||||
* Enable activity record logging for a specified operation of a domain using
|
||||
* the default memory pool.
|
||||
* @param[in] domain The domain.
|
||||
* @param[in] op The activity operation ID in \p domain.
|
||||
*/
|
||||
void roctracer_enable_op_activity(roctracer_domain_t domain, uint32_t op, roctracer_pool_t pool);
|
||||
|
||||
/**
|
||||
* Enable activity record logging for all operations of a domain using the
|
||||
* default memory pool.
|
||||
* @param[in] domain The domain.
|
||||
*/
|
||||
void roctracer_enable_domain_activity(roctracer_domain_t domain, roctracer_pool_t pool);
|
||||
|
||||
/**
|
||||
* Disable activity record logging for a specified operation of a domain.
|
||||
* @param[in] domain The domain.
|
||||
* @param[in] op The activity operation ID in \p domain.
|
||||
*/
|
||||
void roctracer_disable_op_activity(roctracer_domain_t domain, uint32_t op);
|
||||
|
||||
/**
|
||||
* Disable activity record logging for all operations of a domain.
|
||||
* @param[in] domain The domain.
|
||||
*/
|
||||
void roctracer_disable_domain_activity(roctracer_domain_t domain);
|
||||
|
||||
std::optional<std::string> GetHipKernelName(uint32_t cid, hip_api_data_t* data);
|
||||
|
||||
// HIP Support
|
||||
typedef enum {
|
||||
HIP_OP_ID_DISPATCH = 0,
|
||||
HIP_OP_ID_COPY = 1,
|
||||
HIP_OP_ID_BARRIER = 2,
|
||||
HIP_OP_ID_NUMBER = 3
|
||||
} hip_op_id_t;
|
||||
|
||||
// HSA Support
|
||||
// HSA OP ID enumeration
|
||||
enum hsa_op_id_t {
|
||||
HSA_OP_ID_DISPATCH = 0,
|
||||
HSA_OP_ID_COPY = 1,
|
||||
HSA_OP_ID_BARRIER = 2,
|
||||
HSA_OP_ID_RESERVED1 = 3,
|
||||
HSA_OP_ID_NUMBER
|
||||
};
|
||||
|
||||
// HSA EVT ID enumeration
|
||||
enum hsa_evt_id_t {
|
||||
HSA_EVT_ID_ALLOCATE = 0, // Memory allocate callback
|
||||
HSA_EVT_ID_DEVICE = 1, // Device assign callback
|
||||
HSA_EVT_ID_MEMCOPY = 2, // Memcopy callback
|
||||
HSA_EVT_ID_SUBMIT = 3, // Packet submission callback
|
||||
HSA_EVT_ID_KSYMBOL = 4, // Loading/unloading of kernel symbol
|
||||
HSA_EVT_ID_CODEOBJ = 5, // Loading/unloading of device code object
|
||||
HSA_EVT_ID_NUMBER
|
||||
};
|
||||
|
||||
struct hsa_ops_properties_t {
|
||||
void* reserved1[4];
|
||||
};
|
||||
|
||||
// ROCTx Support
|
||||
typedef uint64_t roctx_range_id_t;
|
||||
|
||||
/**
|
||||
* ROCTX API ID enumeration
|
||||
*/
|
||||
enum roctx_api_id_t {
|
||||
ROCTX_API_ID_roctxMarkA = 0,
|
||||
ROCTX_API_ID_roctxRangePushA = 1,
|
||||
ROCTX_API_ID_roctxRangePop = 2,
|
||||
ROCTX_API_ID_roctxRangeStartA = 3,
|
||||
ROCTX_API_ID_roctxRangeStop = 4,
|
||||
ROCTX_API_ID_NUMBER,
|
||||
};
|
||||
|
||||
/**
|
||||
* ROCTX callbacks data type
|
||||
*/
|
||||
typedef struct roctx_api_data_s {
|
||||
union {
|
||||
struct {
|
||||
const char* message;
|
||||
roctx_range_id_t id;
|
||||
};
|
||||
struct {
|
||||
const char* message;
|
||||
} roctxMarkA;
|
||||
struct {
|
||||
const char* message;
|
||||
} roctxRangePushA;
|
||||
struct {
|
||||
const char* message;
|
||||
} roctxRangePop;
|
||||
struct {
|
||||
const char* message;
|
||||
roctx_range_id_t id;
|
||||
} roctxRangeStartA;
|
||||
struct {
|
||||
const char* message;
|
||||
roctx_range_id_t id;
|
||||
} roctxRangeStop;
|
||||
} args;
|
||||
} roctx_api_data_t;
|
||||
|
||||
// External Support
|
||||
/* Extension opcodes */
|
||||
typedef enum { ACTIVITY_EXT_OP_MARK = 0, ACTIVITY_EXT_OP_EXTERN_ID = 1 } activity_ext_op_t;
|
||||
|
||||
typedef void (*roctracer_start_cb_t)();
|
||||
typedef void (*roctracer_stop_cb_t)();
|
||||
typedef struct {
|
||||
roctracer_start_cb_t start_cb;
|
||||
roctracer_stop_cb_t stop_cb;
|
||||
} roctracer_ext_properties_t;
|
||||
|
||||
// Tracing start
|
||||
void roctracer_start();
|
||||
|
||||
// Tracing stop
|
||||
void roctracer_stop();
|
||||
|
||||
// Notifies that the calling thread is entering an external region.
|
||||
// Push an external correlation id for the calling thread.
|
||||
void roctracer_activity_push_external_correlation_id(activity_correlation_id_t id);
|
||||
|
||||
// Notifies that the calling thread is leaving an external region.
|
||||
// Pop an external correlation id for the calling thread.
|
||||
// 'lastId' returns the last external correlation if not NULL
|
||||
void roctracer_activity_pop_external_correlation_id(activity_correlation_id_t* last_id);
|
||||
|
||||
#endif /* SRC_TOOLS_TRACER_SRC_ROCTRACER_H_ */
|
||||
@@ -0,0 +1,434 @@
|
||||
#include "tracer.h"
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
#include "src/api/rocmtool.h"
|
||||
#include "src/utils/helper.h"
|
||||
#include "src/core/hsa/hsa_support.h"
|
||||
#include "src/core/memory/generic_buffer.h"
|
||||
|
||||
namespace rocmtools {
|
||||
namespace tracer {
|
||||
|
||||
std::mutex stream_ids_map_lock;
|
||||
std::map<uint64_t, std::pair<uint64_t, uint64_t>> stream_ids;
|
||||
std::map<uint64_t, uint64_t> used_stream_ids;
|
||||
std::atomic<uint64_t> stream_count{1};
|
||||
|
||||
uint32_t GetPid() {
|
||||
static uint32_t pid = syscall(__NR_getpid);
|
||||
return pid;
|
||||
}
|
||||
uint32_t GetTid() {
|
||||
static thread_local uint32_t tid = syscall(__NR_gettid);
|
||||
return tid;
|
||||
}
|
||||
|
||||
Tracer::Tracer(rocprofiler_session_id_t session_id, rocprofiler_sync_callback_t callback,
|
||||
rocprofiler_buffer_id_t buffer_id,
|
||||
std::vector<rocprofiler_tracer_activity_domain_t> domains)
|
||||
: domains_(domains), callback_(callback), buffer_id_(buffer_id), session_id_(session_id) {
|
||||
assert(!is_active_.load(std::memory_order_release) && "Error: The tracer was initialized!");
|
||||
std::lock_guard<std::mutex> lock(tracer_lock_);
|
||||
|
||||
callback_data_ = api_callback_data_t{callback, session_id};
|
||||
|
||||
is_active_.exchange(true, std::memory_order_release);
|
||||
}
|
||||
|
||||
void Tracer::StartRoctracer() {
|
||||
if (!roctracer_initiated_.load(std::memory_order_release)) {
|
||||
std::map<rocprofiler_tracer_activity_domain_t, is_filtered_domain_t> domains_filteration_map;
|
||||
// TODO(aelwazir): get filter property and parse it here
|
||||
for (auto& domain : domains_) {
|
||||
domains_filteration_map.emplace(domain, false);
|
||||
}
|
||||
std::vector<std::string> api_filter_data_vector;
|
||||
InitRoctracer(domains_filteration_map, api_filter_data_vector);
|
||||
roctracer_initiated_.exchange(true, std::memory_order_release);
|
||||
} else {
|
||||
roctracer_start();
|
||||
}
|
||||
}
|
||||
|
||||
void Tracer::StopRoctracer() {
|
||||
if (roctracer_initiated_.load(std::memory_order_release)) roctracer_stop();
|
||||
}
|
||||
|
||||
void Tracer::DisableRoctracer() {
|
||||
std::lock_guard<std::mutex> lock(tracer_lock_);
|
||||
for (auto domain : domains_) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_ROCTX: {
|
||||
roctracer_disable_domain_callback(ACTIVITY_DOMAIN_ROCTX);
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HSA_API: {
|
||||
roctracer_disable_domain_callback(ACTIVITY_DOMAIN_HSA_API);
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HSA_OPS: {
|
||||
roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HSA_OPS);
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HIP_API: {
|
||||
roctracer_disable_domain_callback(ACTIVITY_DOMAIN_HIP_API);
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HIP_OPS: {
|
||||
roctracer_disable_domain_activity(ACTIVITY_DOMAIN_HIP_OPS);
|
||||
break;
|
||||
}
|
||||
// TODO(aelwazir): Make sure if any other domain is needed by the
|
||||
// API(User Usage)
|
||||
default: {
|
||||
fatal("Error: Provided Domain is not supported!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tracer::~Tracer() {
|
||||
assert(is_active_.load(std::memory_order_release) && "Error: The tracer was not initialized!");
|
||||
std::lock_guard<std::mutex> lock(tracer_lock_);
|
||||
|
||||
is_active_.exchange(false, std::memory_order_release);
|
||||
// tracer_lock_.unlock();
|
||||
}
|
||||
|
||||
std::mutex& Tracer::GetTracerLock() { return tracer_lock_; }
|
||||
|
||||
// TODO(aelwazir): To be implemented from here
|
||||
bool Tracer::FindROCTxApiData(rocprofiler_tracer_api_data_handle_t api_data_handler) {
|
||||
// std::lock_guard<std::mutex> lock(tracer_lock_);
|
||||
return true;
|
||||
}
|
||||
bool Tracer::FindHSAApiData(rocprofiler_tracer_api_data_handle_t api_data_handler) {
|
||||
// std::lock_guard<std::mutex> lock(tracer_lock_);
|
||||
return true;
|
||||
}
|
||||
bool Tracer::FindHIPApiData(rocprofiler_tracer_api_data_handle_t api_data_handler) {
|
||||
// std::lock_guard<std::mutex> lock(tracer_lock_);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Tracer::GetROCTxApiDataInfoSize(rocprofiler_tracer_roctx_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id) {
|
||||
const roctx_api_data_t* roctx_data =
|
||||
reinterpret_cast<const roctx_api_data_t*>(api_data_id.handle);
|
||||
switch (kind) {
|
||||
case ROCPROFILER_ROCTX_MESSAGE: {
|
||||
if (roctx_data && roctx_data->args.message)
|
||||
return strlen(reinterpret_cast<const roctx_api_data_t*>(api_data_id.handle)->args.message) +
|
||||
1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
case ROCPROFILER_ROCTX_ID: {
|
||||
if (roctx_data && roctx_data->args.id >= 0)
|
||||
return std::to_string(roctx_data->args.id).size() + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
warning("ROCTX API Data Not Supported!");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
size_t Tracer::GetHSAApiDataInfoSize(rocprofiler_tracer_hsa_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_HSA_FUNCTION_NAME: {
|
||||
return strlen(roctracer_op_string(ACTIVITY_DOMAIN_HSA_API, operation_id.id)) + 1;
|
||||
}
|
||||
case ROCPROFILER_HSA_ACTIVITY_NAME: {
|
||||
return strlen(roctracer_op_string(ACTIVITY_DOMAIN_HSA_OPS, operation_id.id)) + 1;
|
||||
}
|
||||
case ROCPROFILER_HSA_API_DATA: {
|
||||
return api_data_id.size;
|
||||
}
|
||||
default:
|
||||
warning("HSA API Data Not Supported!");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
size_t Tracer::GetHIPApiDataInfoSize(rocprofiler_tracer_hip_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_HIP_KERNEL_NAME: {
|
||||
hip_api_data_t* hip_data =
|
||||
const_cast<hip_api_data_t*>(reinterpret_cast<const hip_api_data_t*>(api_data_id.handle));
|
||||
if (api_data_id.handle && hip_data) {
|
||||
auto kernel_name = GetHipKernelName(operation_id.id, hip_data);
|
||||
if (kernel_name) return kernel_name->size() + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case ROCPROFILER_HIP_FUNCTION_NAME: {
|
||||
return strlen(roctracer_op_string(ACTIVITY_DOMAIN_HIP_API, operation_id.id)) + 1;
|
||||
}
|
||||
case ROCPROFILER_HIP_ACTIVITY_NAME: {
|
||||
return strlen(roctracer_op_string(ACTIVITY_DOMAIN_HIP_OPS, operation_id.id)) + 1;
|
||||
}
|
||||
case ROCPROFILER_HIP_STREAM_ID: {
|
||||
std::lock_guard<std::mutex> lock(stream_ids_map_lock);
|
||||
if (!stream_ids.empty() && stream_ids.find(operation_id.id) != stream_ids.end())
|
||||
return std::to_string(stream_ids.at(operation_id.id).second).size() + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
case ROCPROFILER_HIP_API_DATA: {
|
||||
return api_data_id.size;
|
||||
}
|
||||
default:
|
||||
warning("HIP API Data Not Supported!");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* Tracer::GetROCTxApiDataInfo(rocprofiler_tracer_roctx_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_ROCTX_MESSAGE: {
|
||||
return const_cast<char*>(
|
||||
reinterpret_cast<const roctx_api_data_t*>(api_data_id.handle)->args.message);
|
||||
}
|
||||
case ROCPROFILER_ROCTX_ID: {
|
||||
const roctx_api_data_t* roctx_data =
|
||||
reinterpret_cast<const roctx_api_data_t*>(api_data_id.handle);
|
||||
if (roctx_data && roctx_data->args.id >= 0)
|
||||
return strdup(std::to_string(roctx_data->args.id).c_str());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
default:
|
||||
warning("HSA API Data Not Supported!");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
char* Tracer::GetHSAApiDataInfo(rocprofiler_tracer_hsa_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_HSA_FUNCTION_NAME: {
|
||||
return const_cast<char*>(roctracer_op_string(ACTIVITY_DOMAIN_HSA_API, operation_id.id));
|
||||
}
|
||||
case ROCPROFILER_HSA_ACTIVITY_NAME: {
|
||||
return const_cast<char*>(roctracer_op_string(ACTIVITY_DOMAIN_HSA_OPS, operation_id.id));
|
||||
}
|
||||
case ROCPROFILER_HSA_API_DATA: {
|
||||
return const_cast<char*>(reinterpret_cast<const char*>(api_data_id.handle));
|
||||
}
|
||||
default:
|
||||
warning("HSA API Data Not Supported!");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
char* Tracer::GetHIPApiDataInfo(rocprofiler_tracer_hip_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id) {
|
||||
switch (kind) {
|
||||
case ROCPROFILER_HIP_KERNEL_NAME: {
|
||||
std::optional<std::string> kernel_name = GetHipKernelName(
|
||||
operation_id.id,
|
||||
const_cast<hip_api_data_t*>(reinterpret_cast<const hip_api_data_t*>(api_data_id.handle)));
|
||||
|
||||
if (kernel_name && kernel_name->find(" ") == std::string::npos) {
|
||||
return strdup(kernel_name->c_str());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
case ROCPROFILER_HIP_FUNCTION_NAME: {
|
||||
return const_cast<char*>(roctracer_op_string(ACTIVITY_DOMAIN_HIP_API, operation_id.id));
|
||||
}
|
||||
case ROCPROFILER_HIP_ACTIVITY_NAME: {
|
||||
return const_cast<char*>(roctracer_op_string(ACTIVITY_DOMAIN_HIP_OPS, operation_id.id));
|
||||
}
|
||||
case ROCPROFILER_HIP_STREAM_ID: {
|
||||
std::lock_guard<std::mutex> lock(stream_ids_map_lock);
|
||||
if (!stream_ids.empty() && stream_ids.find(operation_id.id) != stream_ids.end())
|
||||
return strdup(
|
||||
const_cast<char*>(std::to_string(stream_ids.at(operation_id.id).second).c_str()));
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
case ROCPROFILER_HIP_API_DATA: {
|
||||
return const_cast<char*>(reinterpret_cast<const char*>(api_data_id.handle));
|
||||
}
|
||||
default:
|
||||
warning("HIP API Data Not Supported!");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO(aelwazir): Till here
|
||||
|
||||
void api_callback(activity_domain_t domain, uint32_t cid, const void* callback_data, void* args) {
|
||||
api_callback_data_t* args_data = reinterpret_cast<api_callback_data_t*>(args);
|
||||
if (args_data && rocmtools::GetROCMToolObj() &&
|
||||
rocmtools::GetROCMToolObj()->GetSession(args_data->session_id) &&
|
||||
rocmtools::GetROCMToolObj()->GetSession(args_data->session_id)->GetTracer()) {
|
||||
switch (domain) {
|
||||
case ACTIVITY_DOMAIN_ROCTX: {
|
||||
const roctx_api_data_t* data = reinterpret_cast<const roctx_api_data_t*>(callback_data);
|
||||
// if (data->args.message) roctx_labels.emplace(data->args.id, data->args.message);
|
||||
args_data->user_sync_callback(
|
||||
rocprofiler_record_tracer_t{
|
||||
rocprofiler_record_header_t{
|
||||
ROCPROFILER_TRACER_RECORD,
|
||||
rocprofiler_record_id_t{rocmtools::GetROCMToolObj()->GetUniqueRecordId()}},
|
||||
rocprofiler_tracer_external_id_t{0}, ACTIVITY_DOMAIN_ROCTX,
|
||||
rocprofiler_tracer_operation_id_t{cid},
|
||||
rocprofiler_tracer_api_data_handle_t{callback_data, sizeof(*data)},
|
||||
rocprofiler_tracer_activity_correlation_id_t{0},
|
||||
rocprofiler_record_header_timestamp_t{roctracer::hsa_support::timestamp_ns(),
|
||||
rocprofiler_timestamp_t{0}},
|
||||
0, 0, GetTid()},
|
||||
args_data->session_id);
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HSA_API: {
|
||||
hsa_api_data_t* data =
|
||||
const_cast<hsa_api_data_t*>(reinterpret_cast<const hsa_api_data_t*>(callback_data));
|
||||
if (data->phase == ACTIVITY_API_PHASE_ENTER) {
|
||||
*(data->phase_data) = roctracer::hsa_support::timestamp_ns().value;
|
||||
} else {
|
||||
args_data->user_sync_callback(
|
||||
rocprofiler_record_tracer_t{
|
||||
rocprofiler_record_header_t{
|
||||
ROCPROFILER_TRACER_RECORD,
|
||||
rocprofiler_record_id_t{rocmtools::GetROCMToolObj()->GetUniqueRecordId()}},
|
||||
rocprofiler_tracer_external_id_t{0}, ACTIVITY_DOMAIN_HSA_API,
|
||||
rocprofiler_tracer_operation_id_t{cid},
|
||||
rocprofiler_tracer_api_data_handle_t{callback_data, sizeof(*data)},
|
||||
rocprofiler_tracer_activity_correlation_id_t{data->correlation_id},
|
||||
rocprofiler_record_header_timestamp_t{rocprofiler_timestamp_t{*(data->phase_data)},
|
||||
roctracer::hsa_support::timestamp_ns()},
|
||||
0, 0, GetTid()},
|
||||
args_data->session_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HIP_API: {
|
||||
hip_api_data_t* data =
|
||||
const_cast<hip_api_data_t*>(reinterpret_cast<const hip_api_data_t*>(callback_data));
|
||||
if (data->phase == ACTIVITY_API_PHASE_ENTER) {
|
||||
*(data->phase_data) = roctracer::hsa_support::timestamp_ns().value;
|
||||
} else {
|
||||
hipApiArgsInit((hip_api_id_t)cid, data);
|
||||
std::string hip_api_data_string = hipApiString((hip_api_id_t)cid, data);
|
||||
std::string start_str = "stream=";
|
||||
int start = hip_api_data_string.find(start_str);
|
||||
uint64_t stream_id = 0;
|
||||
if (start >= 0) {
|
||||
int end = hip_api_data_string.find(",", start);
|
||||
std::string stream_id_str = hip_api_data_string.substr(start + start_str.length(), end);
|
||||
std::stringstream ss;
|
||||
ss << std::hex << stream_id_str;
|
||||
ss >> stream_id;
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(stream_ids_map_lock);
|
||||
if (used_stream_ids.find(stream_id) == used_stream_ids.end()) {
|
||||
uint64_t stream_generated_id = stream_count.fetch_add(1, std::memory_order_release);
|
||||
used_stream_ids.emplace(stream_id, stream_generated_id);
|
||||
stream_ids.emplace(data->correlation_id,
|
||||
std::make_pair(stream_id, stream_generated_id));
|
||||
} else {
|
||||
stream_ids.emplace(data->correlation_id,
|
||||
std::make_pair(stream_id, used_stream_ids.at(stream_id)));
|
||||
}
|
||||
}
|
||||
args_data->user_sync_callback(
|
||||
rocprofiler_record_tracer_t{
|
||||
rocprofiler_record_header_t{
|
||||
ROCPROFILER_TRACER_RECORD,
|
||||
rocprofiler_record_id_t{rocmtools::GetROCMToolObj()->GetUniqueRecordId()}},
|
||||
rocprofiler_tracer_external_id_t{0}, ACTIVITY_DOMAIN_HIP_API,
|
||||
rocprofiler_tracer_operation_id_t{cid},
|
||||
rocprofiler_tracer_api_data_handle_t{callback_data, sizeof(*data)},
|
||||
rocprofiler_tracer_activity_correlation_id_t{data->correlation_id},
|
||||
rocprofiler_record_header_timestamp_t{rocprofiler_timestamp_t{*(data->phase_data)},
|
||||
roctracer::hsa_support::timestamp_ns()},
|
||||
0, 0, GetTid()},
|
||||
args_data->session_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
warning("Domain(%u) is not supported for Synchronous callbacks!", domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tracer::InitRoctracer(
|
||||
const std::map<rocprofiler_tracer_activity_domain_t, is_filtered_domain_t>& domains,
|
||||
const std::vector<std::string>& api_filter_data_vector) {
|
||||
for (auto domain : domains) {
|
||||
switch (domain.first) {
|
||||
case ACTIVITY_DOMAIN_ROCTX: {
|
||||
assert(!domain.second && "Error: ROCTX API can't be filtered!");
|
||||
roctracer_enable_domain_callback(ACTIVITY_DOMAIN_ROCTX, api_callback, &callback_data_);
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HSA_API: {
|
||||
if (!domain.second) {
|
||||
roctracer_enable_domain_callback(ACTIVITY_DOMAIN_HSA_API, api_callback, &callback_data_);
|
||||
} else {
|
||||
assert(!api_filter_data_vector.empty() &&
|
||||
"Error: HSA API calls filter data is empty and domain "
|
||||
"filter option was enabled!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HIP_API: {
|
||||
if (!domain.second) {
|
||||
roctracer_enable_domain_callback(ACTIVITY_DOMAIN_HIP_API, api_callback, &callback_data_);
|
||||
} else {
|
||||
assert(!api_filter_data_vector.empty() &&
|
||||
"Error: HIP API calls filter data is empty and domain "
|
||||
"filter option was enabled!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HSA_OPS: {
|
||||
// assert(!domain.second && "Error: HSA OPS can't be filtered!");
|
||||
// Tracer_enable_domain_activity(ACTIVITY_DOMAIN_HSA_OPS, pool);
|
||||
// TODO(aelwazir): to be replaced with the above lines after the
|
||||
// whole integeration is done, make sure that tracer is responsible
|
||||
// of kernel dispatches alongside mem copies, profiler will be only
|
||||
// responsible for counter collection
|
||||
roctracer_enable_op_activity(ACTIVITY_DOMAIN_HSA_OPS, HSA_OP_ID_COPY,
|
||||
session_buffer_id_t{session_id_, buffer_id_});
|
||||
break;
|
||||
}
|
||||
case ACTIVITY_DOMAIN_HIP_OPS: {
|
||||
assert(!domain.second && "Error: HIP OPS can't be filtered!");
|
||||
roctracer_enable_domain_activity(ACTIVITY_DOMAIN_HIP_OPS,
|
||||
session_buffer_id_t{session_id_, buffer_id_});
|
||||
break;
|
||||
}
|
||||
// TODO(aelwazir): Make sure if any other domain is needed by the
|
||||
// API(User Usage)
|
||||
default: {
|
||||
fatal("Error: Provided Domain is not supported!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tracer
|
||||
} // namespace rocmtools
|
||||
@@ -0,0 +1,104 @@
|
||||
/* Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef SRC_TOOLS_TRACER_TRACER_H_
|
||||
#define SRC_TOOLS_TRACER_TRACER_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "inc/rocprofiler.h"
|
||||
#include "src/roctracer.h"
|
||||
|
||||
typedef bool is_filtered_domain_t;
|
||||
|
||||
typedef struct {
|
||||
rocprofiler_sync_callback_t user_sync_callback;
|
||||
rocprofiler_session_id_t session_id;
|
||||
} api_callback_data_t;
|
||||
|
||||
namespace rocmtools {
|
||||
namespace tracer {
|
||||
|
||||
class Tracer {
|
||||
public:
|
||||
// Getting Buffer and/or sync callback
|
||||
Tracer(rocprofiler_session_id_t session_id, rocprofiler_sync_callback_t callback,
|
||||
rocprofiler_buffer_id_t buffer_id, std::vector<rocprofiler_tracer_activity_domain_t> domains);
|
||||
~Tracer();
|
||||
|
||||
rocprofiler_tracer_api_data_handle_t AddROCTxApiData(std::string api_data);
|
||||
rocprofiler_tracer_api_data_handle_t AddHSAApiData(hsa_api_data_t api_data);
|
||||
rocprofiler_tracer_api_data_handle_t AddHIPApiData(hip_api_data_t api_data);
|
||||
|
||||
bool FindROCTxApiData(rocprofiler_tracer_api_data_handle_t api_data_handler);
|
||||
bool FindHSAApiData(rocprofiler_tracer_api_data_handle_t api_data_handler);
|
||||
bool FindHIPApiData(rocprofiler_tracer_api_data_handle_t api_data_handler);
|
||||
|
||||
size_t GetROCTxApiDataInfoSize(rocprofiler_tracer_roctx_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id);
|
||||
size_t GetHSAApiDataInfoSize(rocprofiler_tracer_hsa_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id);
|
||||
size_t GetHIPApiDataInfoSize(rocprofiler_tracer_hip_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id);
|
||||
|
||||
char* GetROCTxApiDataInfo(rocprofiler_tracer_roctx_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id);
|
||||
char* GetHSAApiDataInfo(rocprofiler_tracer_hsa_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id);
|
||||
char* GetHIPApiDataInfo(rocprofiler_tracer_hip_api_data_info_t kind,
|
||||
rocprofiler_tracer_api_data_handle_t api_data_id,
|
||||
rocprofiler_tracer_operation_id_t operation_id);
|
||||
|
||||
void InitRoctracer(
|
||||
const std::map<rocprofiler_tracer_activity_domain_t, is_filtered_domain_t>& domains,
|
||||
const std::vector<std::string>& api_filter_data_vector);
|
||||
|
||||
std::mutex& GetTracerLock();
|
||||
void DisableRoctracer();
|
||||
void StartRoctracer();
|
||||
void StopRoctracer();
|
||||
|
||||
private:
|
||||
std::atomic<bool> is_active_{false};
|
||||
std::atomic<bool> roctracer_initiated_{false};
|
||||
std::atomic<int (*)(rocprofiler_tracer_activity_domain_t domain, uint32_t operation_id, void* data)>
|
||||
roctx_report_activity_;
|
||||
|
||||
std::vector<rocprofiler_tracer_activity_domain_t> domains_;
|
||||
rocprofiler_sync_callback_t callback_;
|
||||
rocprofiler_buffer_id_t buffer_id_;
|
||||
rocprofiler_session_id_t session_id_;
|
||||
api_callback_data_t callback_data_;
|
||||
std::mutex tracer_lock_;
|
||||
};
|
||||
|
||||
} // namespace tracer
|
||||
} // namespace rocmtools
|
||||
|
||||
#endif // SRC_TOOLS_TRACER_TRACER_H_
|
||||
Reference in New Issue
Block a user