From 0d352c515ed5dc9845f1f0d4ea5e67faa315d6f1 Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Wed, 16 Apr 2025 21:00:19 +0000 Subject: [PATCH] Profiler - Align SMI and Profiler indices Change-Id: If2bb850ffd1c1b8b16a8f5963a0f6971f82d4863 Signed-off-by: Galantsev, Dmitrii [ROCm/rdc commit: eff955fdf729b6119753909f1847e58f36ba3aab] --- projects/rdc/common/rdc_field.data | 9 ++ projects/rdc/include/rdc/rdc.h | 2 + .../rdc_modules/rdc_rocp/RdcRocpBase.h | 9 +- .../rdc_libs/rdc/src/RdcMetricFetcherImpl.cc | 6 +- projects/rdc/rdc_libs/rdc/src/RdcSmiLib.cc | 4 +- .../rdc_modules/rdc_rocp/CMakeLists.txt | 13 +- .../rdc_modules/rdc_rocp/RdcRocpBase.cc | 142 ++++++++++++++---- .../rdc_modules/rdc_rocp/RdcTelemetryLib.cc | 24 ++- 8 files changed, 164 insertions(+), 45 deletions(-) diff --git a/projects/rdc/common/rdc_field.data b/projects/rdc/common/rdc_field.data index 90eb1ff89c..ecf4ce824c 100644 --- a/projects/rdc/common/rdc_field.data +++ b/projects/rdc/common/rdc_field.data @@ -39,6 +39,13 @@ FLD_DESC_ENT(RDC_FI_INVALID, "Unknown/Invalid field", FLD_DESC_ENT(RDC_FI_GPU_COUNT, "GPU count in the system", "GPU_COUNT", true) FLD_DESC_ENT(RDC_FI_DEV_NAME, "Name of the device", "DEV_NAME", true) FLD_DESC_ENT(RDC_FI_OAM_ID, "OAM ID of the device", "OAM_ID", true) + +FLD_DESC_ENT(RDC_FI_DEV_ID, "ID of the device", "DEV_ID", true) +FLD_DESC_ENT(RDC_FI_REV_ID, "Revision ID of the device", "REV_ID", true) +FLD_DESC_ENT(RDC_FI_TARGET_GRAPHICS_VERSION, "GFX version of the device", "GFX", true) +FLD_DESC_ENT(RDC_FI_NUM_OF_COMPUTE_UNITS, "Number of Compute Units", "COMPUTE_UNITS", true) +FLD_DESC_ENT(RDC_FI_UUID, "Unique ID of the device AKA asic_serial", "UUID", true) + FLD_DESC_ENT(RDC_FI_GPU_CLOCK, "Current GPU clock frequencies", "GPU_CLOCK", true) FLD_DESC_ENT(RDC_FI_MEM_CLOCK, "Current Memory clock frequencies", "MEM_CLOCK", true) FLD_DESC_ENT(RDC_FI_MEMORY_TEMP, "Memory temperature in millidegrees Celsius", "MEMORY_TEMP", true) @@ -185,7 +192,9 @@ FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_STAT_STALL, "", "CPF_CPF_STAT_S FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_TCIU_BUSY, "", "CPF_CPF_TCIU_BUSY", false) FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_TCIU_IDLE, "", "CPF_CPF_TCIU_IDLE", false) FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_TCIU_STALL, "", "CPF_CPF_TCIU_STALL", false) +// Misc FLD_DESC_ENT(RDC_FI_PROF_SIMD_UTILIZATION, "Fraction of time the SIMDs are being utilized", "SIMD_UTILIZATION", false) +FLD_DESC_ENT(RDC_FI_PROF_UUID, "UUID from rocprofiler", "PROF_UUID", false) // Events FLD_DESC_ENT(RDC_EVNT_XGMI_0_NOP_TX, "NOPs sent to neighbor 0", "XGMI_NOP_0", false) diff --git a/projects/rdc/include/rdc/rdc.h b/projects/rdc/include/rdc/rdc.h index 8481c8d47a..fda8b25a3d 100644 --- a/projects/rdc/include/rdc/rdc.h +++ b/projects/rdc/include/rdc/rdc.h @@ -172,6 +172,7 @@ typedef enum { RDC_FI_REV_ID, //!< RDC_FI_TARGET_GRAPHICS_VERSION, //!< Target graphics version RDC_FI_NUM_OF_COMPUTE_UNITS, //!< Number of compute units + RDC_FI_UUID, //!< Device UUID /** * @brief Frequency related fields @@ -342,6 +343,7 @@ typedef enum { RDC_FI_PROF_CPF_CPF_TCIU_IDLE, RDC_FI_PROF_CPF_CPF_TCIU_STALL, RDC_FI_PROF_SIMD_UTILIZATION, + RDC_FI_PROF_UUID, /** * @brief Raw XGMI counter events diff --git a/projects/rdc/include/rdc_modules/rdc_rocp/RdcRocpBase.h b/projects/rdc/include/rdc_modules/rdc_rocp/RdcRocpBase.h index 29cdf32440..ccf71ab9df 100644 --- a/projects/rdc/include/rdc_modules/rdc_rocp/RdcRocpBase.h +++ b/projects/rdc/include/rdc_modules/rdc_rocp/RdcRocpBase.h @@ -56,7 +56,8 @@ class RdcRocpBase { * @retval ::ROCMTOOLS_STATUS_SUCCESS The function has been executed * successfully. */ - rdc_status_t rocp_lookup(rdc_gpu_field_t gpu_field, double* value); + rdc_status_t rocp_lookup(rdc_gpu_field_t gpu_field, rdc_field_value_data* value, + rdc_field_type_t* type); const char* get_field_id_from_name(rdc_field_t); const std::vector get_field_ids(); @@ -69,11 +70,17 @@ class RdcRocpBase { static const uint32_t collection_duration_us_k = 10000; double read_feature(rocprofiler_record_counter_t* record, uint32_t gpu_index); + + /** + * @brief By default all profiler values are read as doubles + */ double run_profiler(uint32_t gpu_index, rdc_field_t field); + void map_smi_to_profiler_by_uuid(); std::vector agents = {}; std::vector> samplers = {}; std::map field_to_metric = {}; + std::map smi_to_profiler_map = {}; // these fields must be divided by time passed std::unordered_set eval_fields = { diff --git a/projects/rdc/rdc_libs/rdc/src/RdcMetricFetcherImpl.cc b/projects/rdc/rdc_libs/rdc/src/RdcMetricFetcherImpl.cc index 2be028f979..11c262b6f9 100644 --- a/projects/rdc/rdc_libs/rdc/src/RdcMetricFetcherImpl.cc +++ b/projects/rdc/rdc_libs/rdc/src/RdcMetricFetcherImpl.cc @@ -851,7 +851,8 @@ rdc_status_t RdcMetricFetcherImpl::fetch_smi_field(uint32_t gpu_index, rdc_field case RDC_FI_DEV_ID: case RDC_FI_REV_ID: case RDC_FI_TARGET_GRAPHICS_VERSION: - case RDC_FI_NUM_OF_COMPUTE_UNITS: { + case RDC_FI_NUM_OF_COMPUTE_UNITS: + case RDC_FI_UUID: { amdsmi_asic_info_t asic_info; value->status = amdsmi_get_gpu_asic_info(processor_handle, &asic_info); value->type = INTEGER; @@ -881,6 +882,9 @@ rdc_status_t RdcMetricFetcherImpl::fetch_smi_field(uint32_t gpu_index, rdc_field } else { value->value.l_int = asic_info.num_of_compute_units; } + } else if (field_id == RDC_FI_UUID) { + value->type = STRING; + memcpy(value->value.str, asic_info.asic_serial, sizeof(asic_info.asic_serial)); } else { // this should never happen as all fields are handled above RDC_LOG(RDC_ERROR, "Unexpected field id: " << field_id); diff --git a/projects/rdc/rdc_libs/rdc/src/RdcSmiLib.cc b/projects/rdc/rdc_libs/rdc/src/RdcSmiLib.cc index a42de4d289..37db7207b6 100644 --- a/projects/rdc/rdc_libs/rdc/src/RdcSmiLib.cc +++ b/projects/rdc/rdc_libs/rdc/src/RdcSmiLib.cc @@ -184,7 +184,9 @@ rdc_status_t RdcSmiLib::rdc_telemetry_fields_query(uint32_t field_ids[MAX_NUM_FI RDC_HEALTH_PENDING_PAGE_NUM, RDC_HEALTH_RETIRED_PAGE_LIMIT, RDC_HEALTH_EEPROM_CONFIG_VALID, RDC_HEALTH_POWER_THROTTLE_TIME, RDC_HEALTH_THERMAL_THROTTLE_TIME, RDC_FI_GPU_MEMORY_MAX_BANDWIDTH, RDC_FI_GPU_MEMORY_CUR_BANDWIDTH, - RDC_FI_GPU_BUSY_PERCENT, RDC_FI_GPU_PAGE_RETRIED + RDC_FI_GPU_BUSY_PERCENT, RDC_FI_GPU_PAGE_RETRIED, + RDC_FI_DEV_ID, RDC_FI_REV_ID, RDC_FI_TARGET_GRAPHICS_VERSION, + RDC_FI_NUM_OF_COMPUTE_UNITS, RDC_FI_UUID, }; // clang-format on std::copy(fields.begin(), fields.end(), field_ids); diff --git a/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/CMakeLists.txt b/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/CMakeLists.txt index 0d8cb9be5c..848b274402 100644 --- a/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/CMakeLists.txt +++ b/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/CMakeLists.txt @@ -9,8 +9,12 @@ set(RDC_ROCP_LIB_COMPONENT "lib${RDC_ROCP_LIB}") set(RDC_ROCP_LIB_SRC_LIST "${BOOTSTRAP_LIB_SRC_DIR}/RdcLogger.cc" "${SRC_DIR}/RdcTelemetryLib.cc" "${SRC_DIR}/RdcRocpCounterSampler.cc" "${SRC_DIR}/RdcRocpBase.cc") set(RDC_ROCP_LIB_INC_LIST - "${PROJECT_SOURCE_DIR}/include/rdc/rdc.h" "${RDC_LIB_INC_DIR}/RdcDiagnosticLibInterface.h" - "${RDC_LIB_INC_DIR}/rdc_common.h" "${RDC_LIB_INC_DIR}/RdcLogger.h" "${INC_DIR}/RdcRocpBase.h" + "${PROJECT_SOURCE_DIR}/include/rdc/rdc.h" + "${RDC_LIB_INC_DIR}/RdcDiagnosticLibInterface.h" + "${RDC_LIB_INC_DIR}/rdc_common.h" + "${RDC_LIB_INC_DIR}/RdcLogger.h" + "${SRC_DIR}/../../rdc/src/SmiUtils.cc" + "${INC_DIR}/RdcRocpBase.h" "${INC_DIR}/RdcRocpCounterSampler.h") if(BUILD_PROFILER) @@ -31,8 +35,9 @@ if(BUILD_PROFILER) ${RDC_LIB_MODULES} ${RDC_ROCP_LIB} PARENT_SCOPE) add_library(${RDC_ROCP_LIB} SHARED ${RDC_ROCP_LIB_SRC_LIST} ${RDC_ROCP_LIB_INC_LIST}) - target_link_libraries(${RDC_ROCP_LIB} PRIVATE hsa-runtime64::hsa-runtime64 - rocprofiler-sdk::rocprofiler-sdk pthread dl) + target_link_libraries( + ${RDC_ROCP_LIB} PRIVATE hsa-runtime64::hsa-runtime64 rocprofiler-sdk::rocprofiler-sdk + pthread dl amd_smi) target_include_directories( ${RDC_ROCP_LIB} PRIVATE "${PROJECT_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}/include" "${COMMON_DIR}" diff --git a/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcRocpBase.cc b/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcRocpBase.cc index 1de03debf8..a904c88176 100644 --- a/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcRocpBase.cc +++ b/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcRocpBase.cc @@ -35,13 +35,17 @@ THE SOFTWARE. #include #include #include +#include #include #include // #include "hsa.h" +#include "amd_smi/amdsmi.h" #include "rdc/rdc.h" #include "rdc_lib/RdcLogger.h" #include "rdc_lib/RdcTelemetryLibInterface.h" +#include "rdc_lib/impl/SmiUtils.h" +#include "rdc_lib/rdc_common.h" #include "rdc_modules/rdc_rocp/RdcRocpCounterSampler.h" namespace amd { @@ -97,6 +101,70 @@ const std::vector RdcRocpBase::get_field_ids() { return field_ids; } +rocprofiler_uuid_t asic_serial_to_uuid(const char* asic_serial) { + rocprofiler_uuid_t uuid = {0}; + // have to cast to stoull as a workaround for amdsmi ignoring leading zeroes + uuid.value = std::stoull(asic_serial, nullptr, 16); + return uuid; +} + +std::string uuid_to_string(const uint64_t uuid) { + std::ostringstream oss; + oss << "0x" << std::hex << std::setw(16) << std::setfill('0') << uuid; + return oss.str(); +} + +std::string uuid_to_string(const rocprofiler_uuid_t& uuid) { return uuid_to_string(uuid.value); } + +void RdcRocpBase::map_smi_to_profiler_by_uuid() { + std::map index_to_prof_map; + std::map index_to_smi_map; + + // find intersection of supported and requested fields + for (uint32_t gpu_index = 0; gpu_index < agents.size(); gpu_index++) { + index_to_prof_map.insert({gpu_index, agents[gpu_index].uuid}); + + amdsmi_processor_handle processor_handle = nullptr; + auto amdsmi_status = get_processor_handle_from_id(gpu_index, &processor_handle); + if (amdsmi_status != AMDSMI_STATUS_SUCCESS) { + continue; + } + amdsmi_asic_info_t asic_info; + amdsmi_status = amdsmi_get_gpu_asic_info(processor_handle, &asic_info); + if (amdsmi_status != AMDSMI_STATUS_SUCCESS) { + continue; + } + rocprofiler_uuid_t temp_id = asic_serial_to_uuid(asic_info.asic_serial); + index_to_smi_map.insert({gpu_index, temp_id}); + + // clang-format off + RDC_LOG(RDC_DEBUG, "\n" + "ID[" << gpu_index << "]:\n" + " PROF: " << uuid_to_string(index_to_prof_map[gpu_index]) << "\n" + " SMI: " << uuid_to_string(index_to_smi_map[gpu_index])); + // clang-format on + } + + // Create a mapping from SMI to ROCProfiler by comparing uuid + for (const auto& [smi_index, smi_uuid] : index_to_smi_map) { + for (const auto& [prof_index, prof_uuid] : index_to_prof_map) { + if (std::memcmp(&smi_uuid, &prof_uuid, sizeof(rocprofiler_uuid_t)) == 0) { + // match found + smi_to_profiler_map[smi_index] = prof_index; + break; + } + } + } + + for (const auto& [smi_index, prof_index] : smi_to_profiler_map) { + const auto& prof_uuid = index_to_prof_map[prof_index]; + const auto& smi_uuid = index_to_smi_map[smi_index]; + RDC_LOG(RDC_DEBUG, "SMI index " << smi_index << " maps to ROCProfiler index " << prof_index + << " with UUID: " << uuid_to_string(prof_uuid) << " = " + << uuid_to_string(smi_uuid)); + } +} + RdcRocpBase::RdcRocpBase() { // all fields static const std::map temp_field_map_k = { @@ -120,8 +188,8 @@ RdcRocpBase::RdcRocpBase() { {RDC_FI_PROF_VALU_PIPE_ISSUE_UTIL, "ValuPipeIssueUtil"}, {RDC_FI_PROF_SM_ACTIVE, "VALUBusy"}, {RDC_FI_PROF_OCC_PER_ACTIVE_CU, "MeanOccupancyPerActiveCU"}, - {RDC_FI_PROF_OCC_ELAPSED, - "GRBM_GUI_ACTIVE"}, // this metric is derived from OCC_PER_ACTIVE_CU and ACTIVE_CYCLES + {RDC_FI_PROF_OCC_ELAPSED, "GRBM_GUI_ACTIVE"}, // this metric is derived from + // OCC_PER_ACTIVE_CU and ACTIVE_CYCLES {RDC_FI_PROF_CPC_CPC_STAT_BUSY, "CPC_CPC_STAT_BUSY"}, {RDC_FI_PROF_CPC_CPC_STAT_IDLE, "CPC_CPC_STAT_IDLE"}, {RDC_FI_PROF_CPC_CPC_STAT_STALL, "CPC_CPC_STAT_STALL"}, @@ -158,7 +226,7 @@ RdcRocpBase::RdcRocpBase() { {RDC_FI_PROF_CPF_CPF_TCIU_IDLE, "CPF_CPF_TCIU_IDLE"}, {RDC_FI_PROF_CPF_CPF_TCIU_STALL, "CPF_CPF_TCIU_STALL"}, {RDC_FI_PROF_SIMD_UTILIZATION, "SIMD_UTILIZATION"}, - + {RDC_FI_PROF_UUID, "SQ_WAVES"}, // dummy value, }; hsa_status_t status = hsa_init(); @@ -183,16 +251,14 @@ RdcRocpBase::RdcRocpBase() { RDC_LOG(RDC_DEBUG, "Agent count: " << agents.size()); samplers = CounterSampler::get_samplers(); - // populate fields - for (const auto& [k, v] : temp_field_map_k) { - all_fields.emplace_back(v); - } + map_smi_to_profiler_by_uuid(); // find intersection of supported and requested fields for (uint32_t gpu_index = 0; gpu_index < agents.size(); gpu_index++) { auto& cs = *samplers[gpu_index]; - RDC_LOG(RDC_DEBUG, - "gpu_index[" << gpu_index << "] = node_id[" << agents[gpu_index].node_id << "]"); + RDC_LOG(RDC_DEBUG, "gpu_index[" << gpu_index << "] = node_id[" << agents[gpu_index].node_id + << "] agent_id[" << agents[gpu_index].id.handle << "]"); + for (auto& [str, id] : CounterSampler::get_supported_counters(cs.get_agent())) { checked_fields.emplace_back(str); } @@ -205,6 +271,11 @@ RdcRocpBase::RdcRocpBase() { } } + // populate fields + for (const auto& [k, v] : temp_field_map_k) { + all_fields.emplace_back(v); + } + RDC_LOG(RDC_DEBUG, "Rocprofiler supports " << field_to_metric.size() << " fields"); } @@ -216,26 +287,31 @@ RdcRocpBase::~RdcRocpBase() { assert(status == HSA_STATUS_ERROR_NOT_INITIALIZED); } -rdc_status_t RdcRocpBase::rocp_lookup(rdc_gpu_field_t gpu_field, double* value) { - const auto& gpu_index = gpu_field.gpu_index; +rdc_status_t RdcRocpBase::rocp_lookup(rdc_gpu_field_t gpu_field, rdc_field_value_data* data, + rdc_field_type_t* type) { + // default type + *type = DOUBLE; + + const auto& gpu_index = smi_to_profiler_map[gpu_field.gpu_index]; const auto& field = gpu_field.field_id; - if (value == nullptr) { + if (data == nullptr) { return RDC_ST_BAD_PARAMETER; } const bool is_eval_field = (eval_fields.find(field) != eval_fields.end()); const auto start_time = std::chrono::high_resolution_clock::now(); - const double read_value = run_profiler(gpu_index, field); + // direct read from rocprofiler + const double read_dbl = run_profiler(gpu_index, field); const auto stop_time = std::chrono::high_resolution_clock::now(); const double elapsed = std::chrono::duration(stop_time - start_time).count(); - double divided_value = NAN; - double final_value = NAN; + // divide by elapsed time if needed + double divided_dbl = NAN; if (is_eval_field) { if (elapsed != 0.0) { - divided_value = read_value / (elapsed / 1000.0); + divided_dbl = read_dbl / (elapsed / 1000.0); } else { RDC_LOG(RDC_ERROR, "Error: Elapsed time is zero. Cannot divide by zero."); return RDC_ST_BAD_PARAMETER; @@ -247,16 +323,16 @@ rdc_status_t RdcRocpBase::rocp_lookup(rdc_gpu_field_t gpu_field, double* value) // RDC_FI_PROF_GPU_UTIL_PERCENT is mapped to GPU_UTIL // GPU_UTIL metric is available on more GPUs than ENGINE_ACTIVE. // ENGINE_ACTIVE = GPU_UTIL/100, so do the math ourselves - final_value = read_value / 100.0F; + data->dbl = read_dbl / 100.0F; break; case RDC_FI_PROF_OCC_ELAPSED: { // RDC_FI_PROF_OCC_ELAPSED is mapped to GRBM_GUI_ACTIVE, the read happens earlier in this // function - const double active_cycles_val = read_value; + const double active_cycles_val = read_dbl; if (active_cycles_val != 0.0) { // read second value from rocprofiler const double occupancy_val = run_profiler(gpu_index, RDC_FI_PROF_OCC_PER_ACTIVE_CU); - final_value = occupancy_val / active_cycles_val; + data->dbl = occupancy_val / active_cycles_val; } else { return RDC_ST_BAD_PARAMETER; } @@ -272,11 +348,9 @@ rdc_status_t RdcRocpBase::rocp_lookup(rdc_gpu_field_t gpu_field, double* value) const bool isMI200 = (target_version.find("gfx90a") != std::string::npos); // FLOPS/clock/CU if (isMI200) { - final_value = - divided_value / (1024.0F / static_cast(agents[gpu_index].simd_per_cu)); + data->dbl = divided_dbl / (1024.0F / static_cast(agents[gpu_index].simd_per_cu)); } else { // Assume mi300 - final_value = - divided_value / (2048.0F / static_cast(agents[gpu_index].simd_per_cu)); + data->dbl = divided_dbl / (2048.0F / static_cast(agents[gpu_index].simd_per_cu)); } } break; case RDC_FI_PROF_EVAL_FLOPS_32_PERCENT: @@ -286,24 +360,26 @@ rdc_status_t RdcRocpBase::rocp_lookup(rdc_gpu_field_t gpu_field, double* value) return RDC_ST_BAD_PARAMETER; } // FLOPS/clock/CU - final_value = divided_value / (256.0F / static_cast(agents[gpu_index].simd_per_cu)); + data->dbl = divided_dbl / (256.0F / static_cast(agents[gpu_index].simd_per_cu)); break; + case RDC_FI_PROF_UUID: { + // do not care what RDC_FI_PROF_UUID is mapped to. read value from agents + *type = STRING; + std::string uuid_str = uuid_to_string(agents[gpu_index].uuid); + strncpy_with_null(data->str, uuid_str.c_str(), uuid_str.length()); + break; + } default: + // only support default fallback for doubles + assert(*type == DOUBLE); if (is_eval_field) { - final_value = divided_value; + data->dbl = divided_dbl; } else { - final_value = read_value; + data->dbl = read_dbl; } break; } - if (final_value == NAN) { - RDC_LOG(RDC_ERROR, "Error: Final value is NaN."); - return RDC_ST_BAD_PARAMETER; - } - - *value = final_value; - return RDC_ST_OK; } diff --git a/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcTelemetryLib.cc b/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcTelemetryLib.cc index 61a76763e8..664637d894 100644 --- a/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcTelemetryLib.cc +++ b/projects/rdc/rdc_libs/rdc_modules/rdc_rocp/RdcTelemetryLib.cc @@ -98,7 +98,7 @@ rdc_status_t rdc_telemetry_fields_value_get(rdc_gpu_field_t* fields, const uint3 // Bulk fetch fields std::vector bulk_results; - struct timeval tv{}; + struct timeval tv {}; gettimeofday(&tv, nullptr); const uint64_t curTime = static_cast(tv.tv_sec) * 1000 + tv.tv_usec / 1000; @@ -107,7 +107,8 @@ rdc_status_t rdc_telemetry_fields_value_get(rdc_gpu_field_t* fields, const uint3 rdc_gpu_field_value_t values[BULK_FIELDS_MAX]; uint32_t bulk_count = 0; rdc_status_t status = RDC_ST_UNKNOWN_ERROR; - double data = NAN; + rdc_field_value_data data; + rdc_field_type_t type = DOUBLE; for (uint32_t i = 0; i < fields_count; i++) { if (bulk_count >= BULK_FIELDS_MAX) { @@ -119,14 +120,27 @@ rdc_status_t rdc_telemetry_fields_value_get(rdc_gpu_field_t* fields, const uint3 bulk_count = 0; } - status = rocp_p->rocp_lookup(fields[i], &data); + status = rocp_p->rocp_lookup(fields[i], &data, &type); // get value values[bulk_count].gpu_index = fields[i].gpu_index; - values[bulk_count].field_value.type = DOUBLE; values[bulk_count].field_value.status = status; values[bulk_count].field_value.ts = curTime; - values[bulk_count].field_value.value.dbl = data; + values[bulk_count].field_value.type = type; values[bulk_count].field_value.field_id = fields[i].field_id; + switch (type) { + case DOUBLE: + values[bulk_count].field_value.value.dbl = data.dbl; + break; + case INTEGER: + values[bulk_count].field_value.value.l_int = data.l_int; + break; + case STRING: + case BLOB: + strncpy_with_null(values[bulk_count].field_value.value.str, data.str, RDC_MAX_STR_LENGTH); + break; + default: + break; + } bulk_count++; } if (bulk_count != 0) {