SWDEV-508477 Eval Flops Percent (#85)
SWDEV-508477 - Profiler add FP*_PERCENT
Change-Id: Idb6250fe6b7ba3df6fe7d30861e0fbbda7e9bdce
Signed-off-by: adapryor <Adam.pryor@amd.com>
Signed-off-by: Galantsev, Dmitrii <dmitrii.galantsev@amd.com>
[ROCm/rdc commit: 6f358ddc9e]
Этот коммит содержится в:
@@ -144,6 +144,10 @@ FLD_DESC_ENT(RDC_FI_PROF_VALU_PIPE_ISSUE_UTIL, "Percent of Active Pipe VALU",
|
||||
FLD_DESC_ENT(RDC_FI_PROF_SM_ACTIVE, "Ratio of Cycles with active warp on SM","VALUBusy", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_OCC_PER_ACTIVE_CU, "Mean occ per active compute unit", "OCC_CU", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_OCC_ELAPSED, "Mean occ per active cu over elapsed", "OCC_CU_ELAPSED", false)
|
||||
// metrics below are divided by time passed
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_16_PERCENT, "Number of fp16 OPS percent of max", "FLOPS_16_PERCENT", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_32_PERCENT, "Number of fp32 OPS percent of max", "FLOPS_32_PERCENT", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_64_PERCENT, "Number of fp64 OPS percent of max", "FLOPS_64_PERCENT", false)
|
||||
|
||||
// Events
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_0_NOP_TX, "NOPs sent to neighbor 0", "XGMI_NOP_0", false)
|
||||
|
||||
@@ -292,6 +292,10 @@ typedef enum {
|
||||
RDC_FI_PROF_SM_ACTIVE,
|
||||
RDC_FI_PROF_OCC_PER_ACTIVE_CU,
|
||||
RDC_FI_PROF_OCC_ELAPSED,
|
||||
// metrics below are divided by time passed
|
||||
RDC_FI_PROF_EVAL_FLOPS_16_PERCENT,
|
||||
RDC_FI_PROF_EVAL_FLOPS_32_PERCENT,
|
||||
RDC_FI_PROF_EVAL_FLOPS_64_PERCENT,
|
||||
|
||||
/**
|
||||
* @brief Raw XGMI counter events
|
||||
|
||||
@@ -156,6 +156,9 @@ class rdc_field_t(c_int):
|
||||
RDC_FI_PROF_SM_ACTIVE = 812
|
||||
RDC_FI_PROF_OCC_PER_ACTIVE_CU = 813
|
||||
RDC_FI_PROF_OCC_ELAPSED = 814
|
||||
RDC_FI_PROF_EVAL_FLOPS_16_PERCENT = 815
|
||||
RDC_FI_PROF_EVAL_FLOPS_32_PERCENT = 816
|
||||
RDC_FI_PROF_EVAL_FLOPS_64_PERCENT = 817
|
||||
RDC_EVNT_XGMI_0_NOP_TX = 1000
|
||||
RDC_EVNT_XGMI_0_REQ_TX = 1001
|
||||
RDC_EVNT_XGMI_0_RESP_TX = 1002
|
||||
|
||||
@@ -118,6 +118,9 @@ RdcRocpBase::RdcRocpBase() {
|
||||
{RDC_FI_PROF_EVAL_FLOPS_16, "TOTAL_16_OPS"},
|
||||
{RDC_FI_PROF_EVAL_FLOPS_32, "TOTAL_32_OPS"},
|
||||
{RDC_FI_PROF_EVAL_FLOPS_64, "TOTAL_64_OPS"},
|
||||
{RDC_FI_PROF_EVAL_FLOPS_16_PERCENT, "RDC_OPS_16_PER_SIMDCYCLE"},
|
||||
{RDC_FI_PROF_EVAL_FLOPS_32_PERCENT, "RDC_OPS_32_PER_SIMDCYCLE"},
|
||||
{RDC_FI_PROF_EVAL_FLOPS_64_PERCENT, "RDC_OPS_64_PER_SIMDCYCLE"},
|
||||
// metrics below are not divided by time passed
|
||||
{RDC_FI_PROF_VALU_PIPE_ISSUE_UTIL, "ValuPipeIssueUtil"},
|
||||
{RDC_FI_PROF_SM_ACTIVE, "VALUBusy"},
|
||||
@@ -188,18 +191,6 @@ rdc_status_t RdcRocpBase::rocp_lookup(rdc_gpu_field_t gpu_field, double* value)
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
if (field == RDC_FI_PROF_OCC_ELAPSED) {
|
||||
double occupancy_val = run_profiler(gpu_index, RDC_FI_PROF_OCC_PER_ACTIVE_CU);
|
||||
double active_cycles_val = run_profiler(gpu_index, RDC_FI_PROF_ACTIVE_CYCLES);
|
||||
|
||||
if (active_cycles_val != 0.0) {
|
||||
*value = occupancy_val / active_cycles_val;
|
||||
return RDC_ST_OK;
|
||||
} else {
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
const auto start_time = std::chrono::high_resolution_clock::now();
|
||||
*value = run_profiler(gpu_index, field);
|
||||
const auto stop_time = std::chrono::high_resolution_clock::now();
|
||||
@@ -209,11 +200,48 @@ rdc_status_t RdcRocpBase::rocp_lookup(rdc_gpu_field_t gpu_field, double* value)
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(stop_time - start_time).count();
|
||||
*value = *value / elapsed;
|
||||
}
|
||||
// GPU_UTIL metric is available on more GPUs than ENGINE_ACTIVE.
|
||||
// ENGINE_ACTIVE = GPU_UTIL/100, so do the math ourselves
|
||||
if (field == RDC_FI_PROF_GPU_UTIL_PERCENT) {
|
||||
*value = *value / 100.0F;
|
||||
|
||||
auto simd_to_cu = [this, gpu_index](double prof_value, double matrix_fp) {
|
||||
// profiler result of RDC_OPS_*_PER_SIMDCYCLE is per SIMD, RDC needs it per CU
|
||||
//
|
||||
return prof_value / (matrix_fp / static_cast<double>(agents[gpu_index].simd_per_cu));
|
||||
};
|
||||
|
||||
switch (field) {
|
||||
case RDC_FI_PROF_GPU_UTIL_PERCENT:
|
||||
// GPU_UTIL metric is available on more GPUs than ENGINE_ACTIVE.
|
||||
// ENGINE_ACTIVE = GPU_UTIL/100, so do the math ourselves
|
||||
*value = *value / 100.0F;
|
||||
break;
|
||||
case RDC_FI_PROF_OCC_ELAPSED: {
|
||||
const double occupancy_val = run_profiler(gpu_index, RDC_FI_PROF_OCC_PER_ACTIVE_CU);
|
||||
const double active_cycles_val = run_profiler(gpu_index, RDC_FI_PROF_ACTIVE_CYCLES);
|
||||
if (active_cycles_val != 0.0) {
|
||||
*value = occupancy_val / active_cycles_val;
|
||||
return RDC_ST_OK;
|
||||
} else {
|
||||
return RDC_ST_BAD_PARAMETER;
|
||||
}
|
||||
} break;
|
||||
case RDC_FI_PROF_EVAL_FLOPS_16_PERCENT: {
|
||||
// 1024, 2048, and 256 are taken from "INTRODUCING AMD CDNA 3 ARCHITECTURE" white paper
|
||||
const std::string target_version = agents[gpu_index].name;
|
||||
// TODO: Design a lookup table for other GPUs
|
||||
const bool isMI200 = (target_version.find("gfx90a") != std::string::npos);
|
||||
if (isMI200) {
|
||||
*value = simd_to_cu(*value, 1024.0F); // FLOPS/clock/CU
|
||||
} else { // Assume mi300
|
||||
*value = simd_to_cu(*value, 2048.0F); // FLOPS/clock/CU
|
||||
}
|
||||
} break;
|
||||
case RDC_FI_PROF_EVAL_FLOPS_32_PERCENT:
|
||||
case RDC_FI_PROF_EVAL_FLOPS_64_PERCENT:
|
||||
*value = simd_to_cu(*value, 256.0F); // FLOPS/clock/CU
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user