diff --git a/docs/README.md b/docs/README.md index 38b56a9aed..7574668df6 100755 --- a/docs/README.md +++ b/docs/README.md @@ -46,6 +46,10 @@ In order to verify the build and capability of ROCm SMI on your system and to se ##### ```$ cmake -DROCM_DIR= /tests/rocm_smi_test``` To run the test, execute the program `rsmitst` that is built from the steps above. Make sure ROCm SMI library is in your library search path when executing the test program. +# Usage Basics +## Device Indices +Many of the functions in the library take a "device index". The device index is a number greater than or equal to 0, and less than the number of devices detected, as determined by `rsmi_num_monitor_devices()`. The index is used to distinguish the detected devices from one another. It is important to note that a device may end up with a different index after a reboot, so an index should not be relied upon to be constant over reboots. + # Hello ROCm SMI The only required ROCm-SMI call for any program that wants to use ROCm-SMI is the `rsmi_init()` call. This call initializes some internal data structures that will be used by subsequent ROCm-SMI calls. diff --git a/docs/ROCm_SMI_Manual.pdf b/docs/ROCm_SMI_Manual.pdf index 954af57023..cd8544cd1b 100644 Binary files a/docs/ROCm_SMI_Manual.pdf and b/docs/ROCm_SMI_Manual.pdf differ diff --git a/example/rocm_smi_example.cc b/example/rocm_smi_example.cc index 5e881b5f70..d78e6fcd87 100755 --- a/example/rocm_smi_example.cc +++ b/example/rocm_smi_example.cc @@ -401,13 +401,14 @@ int main() { uint64_t val_ui64, val2_ui64; int64_t val_i64; uint32_t val_ui32; + uint16_t val_ui16; rsmi_dev_perf_level_t pfl; rsmi_frequencies_t f; uint32_t num_monitor_devs = 0; rsmi_num_monitor_devices(&num_monitor_devs); for (uint32_t i = 0; i< num_monitor_devs; ++i) { - ret = rsmi_dev_id_get(i, &val_ui64); + ret = rsmi_dev_id_get(i, &val_ui16); CHK_RSMI_RET(ret) std::cout << "\t**Device ID: 0x" << std::hex << val_ui64 << std::endl; diff --git a/include/rocm_smi/rocm_smi.h b/include/rocm_smi/rocm_smi.h index 789e50ae2a..c6f0be7177 100755 --- a/include/rocm_smi/rocm_smi.h +++ b/include/rocm_smi/rocm_smi.h @@ -500,14 +500,33 @@ rsmi_status_t rsmi_num_monitor_devices(uint32_t *num_devices); * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. * */ -rsmi_status_t rsmi_dev_id_get(uint32_t dv_ind, uint64_t *id); +rsmi_status_t rsmi_dev_id_get(uint32_t dv_ind, uint16_t *id); /** - * @brief Get the name of a gpu device. + * @brief Get the device vendor id associated with the device with provided + * device index. + * + * @details Given a device index @p dv_ind and a pointer to a uint32_t @p id, + * this function will write the device vendor id value to the uint64_t pointed + * to by @p id. + * + * @param[in] dv_ind a device index + * + * @param[inout] id a pointer to uint64_t to which the device vendor id will + * be written + * + * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. + * + */ +rsmi_status_t rsmi_dev_vendor_id_get(uint32_t dv_ind, uint16_t *id); + +/** + * @brief Get the name string of a gpu device. * * @details Given a device index @p dv_ind, a pointer to a caller provided * char buffer @p name, and a length of this buffer @p len, this function - * will write the name of the device (up to @p len characters) buffer @p name. + * will write the name of the device (up to @p len characters) to the buffer + * @p name. * * @param[in] dv_ind a device index * @@ -518,12 +537,95 @@ rsmi_status_t rsmi_dev_id_get(uint32_t dv_ind, uint64_t *id); * * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. * @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not - * large enough to hold the entire name. In this case, only @len bytes will + * large enough to hold the entire name. In this case, only @p len bytes will * be written. * */ rsmi_status_t rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len); +/** + * @brief Get the name string for a give vendor ID + * + * @details Given vendor ID @p id, a pointer to a caller provided char buffer + * @p name, and a length of this buffer @p len, this function will write the + * name of the vendor (up to @p len characters) buffer @p name. The @p id may + * be a device vendor or subsystem vendor ID. + * + * @param[in] id a vendor ID + * + * @param[inout] name a pointer to a caller provided char buffer to which the + * name will be written + * + * @param[in] len the length of the caller provided buffer @p name. + * + * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. + * @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not + * large enough to hold the entire name. In this case, only @p len bytes will + * be written. + * + */ +rsmi_status_t rsmi_dev_vendor_name_get(uint32_t id, char *name, size_t len); + +/** + * @brief Get the subsystem device id associated with the device with + * provided device index. + * + * @details Given a device index @p dv_ind and a pointer to a uint32_t @p id, + * this function will write the subsystem device id value to the uint64_t + * pointed to by @p id. + * + * @param[in] dv_ind a device index + * + * @param[inout] id a pointer to uint64_t to which the subsystem device id + * will be written + * + * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. + * + */ +rsmi_status_t rsmi_dev_subsystem_id_get(uint32_t dv_ind, uint16_t *id); + +/** + * @brief Get the name string for the device subsytem + * + * @details Given a device index @p dv_ind, a pointer to a caller provided + * char buffer @p name, and a length of this buffer @p len, this function + * will write the name of the device subsystem (up to @p len characters) + * to the buffer @p name. + * + * @param[in] dv_ind a device index + * + * @param[inout] name a pointer to a caller provided char buffer to which the + * name will be written + * + * @param[in] len the length of the caller provided buffer @p name. + * + * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. + * @retval ::RSMI_STATUS_INSUFFICIENT_SIZE is returned if @p len bytes is not + * large enough to hold the entire name. In this case, only @p len bytes will + * be written. + * + */ +rsmi_status_t +rsmi_dev_subsystem_name_get(uint32_t dv_ind, char *name, size_t len); + +/** + * @brief Get the device subsystem vendor id associated with the device with + * provided device index. + * + * @details Given a device index @p dv_ind and a pointer to a uint32_t @p id, + * this function will write the device subsystem vendor id value to the + * uint64_t pointed to by @p id. + * + * @param[in] dv_ind a device index + * + * @param[inout] id a pointer to uint64_t to which the device subsystem vendor + * id will be written + * + * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. + * + */ +rsmi_status_t rsmi_dev_subsystem_vendor_id_get(uint32_t dv_ind, uint16_t *id); + /** @} */ // end of IDQuer /*****************************************************************************/ @@ -915,7 +1017,7 @@ rsmi_status_t rsmi_dev_temp_metric_get(uint32_t dv_ind, uint32_t sensor_ind, /** @} */ // end of PhysQuer /*****************************************************************************/ -/** @defgroup PhysCont Physcial State Control +/** @defgroup PhysCont Physical State Control * These functions provide control over the physical state of a device. * @{ */ diff --git a/include/rocm_smi/rocm_smi_device.h b/include/rocm_smi/rocm_smi_device.h index 902c14897d..07292a6840 100755 --- a/include/rocm_smi/rocm_smi_device.h +++ b/include/rocm_smi/rocm_smi_device.h @@ -60,6 +60,9 @@ enum DevInfoTypes { kDevPerfLevel, kDevOverDriveLevel, kDevDevID, + kDevVendorID, + kDevSubSysDevID, + kDevSubSysVendorID, kDevGPUMClk, kDevGPUSClk, kDevPCIEClk, diff --git a/src/rocm_smi.cc b/src/rocm_smi.cc index 25e4c6b5f0..15bcc0c06f 100755 --- a/src/rocm_smi.cc +++ b/src/rocm_smi.cc @@ -387,17 +387,6 @@ static rsmi_status_t get_power_mon_value(amd::smi::PowerMonTypes type, return errno_to_rsmi_status(ret); } -static rsmi_status_t get_dev_mon_value_str(amd::smi::MonitorTypes type, - uint32_t dv_ind, int32_t sensor_ind, std::string *val_str) { - GET_DEV_FROM_INDX - - assert(dev->monitor() != nullptr); - - int ret = dev->monitor()->readMonitor(type, sensor_ind, val_str); - return errno_to_rsmi_status(ret); -} - - static rsmi_status_t get_dev_value_vec(amd::smi::DevInfoTypes type, uint32_t dv_ind, std::vector *val_vec) { GET_DEV_FROM_INDX @@ -509,11 +498,11 @@ rsmi_dev_pci_id_get(uint32_t dv_ind, uint64_t *bdfid) { CATCH } -rsmi_status_t -rsmi_dev_id_get(uint32_t dv_ind, uint64_t *id) { +static rsmi_status_t +get_id(uint32_t dv_ind, amd::smi::DevInfoTypes typ, uint16_t *id) { TRY std::string val_str; - rsmi_status_t ret = get_dev_value_str(amd::smi::kDevDevID, dv_ind, &val_str); + rsmi_status_t ret = get_dev_value_str(typ, dv_ind, &val_str); if (ret != RSMI_STATUS_SUCCESS) { return ret; @@ -527,6 +516,26 @@ rsmi_dev_id_get(uint32_t dv_ind, uint64_t *id) { CATCH } +rsmi_status_t +rsmi_dev_id_get(uint32_t dv_ind, uint16_t *id) { + return get_id(dv_ind, amd::smi::kDevDevID, id); +} + +rsmi_status_t +rsmi_dev_subsystem_id_get(uint32_t dv_ind, uint16_t *id) { + return get_id(dv_ind, amd::smi::kDevSubSysDevID, id); +} + +rsmi_status_t +rsmi_dev_vendor_id_get(uint32_t dv_ind, uint16_t *id) { + return get_id(dv_ind, amd::smi::kDevVendorID, id); +} + +rsmi_status_t +rsmi_dev_subsystem_vendor_id_get(uint32_t dv_ind, uint16_t *id) { + return get_id(dv_ind, amd::smi::kDevSubSysVendorID, id); +} + rsmi_status_t rsmi_dev_perf_level_get(uint32_t dv_ind, rsmi_dev_perf_level_t *perf) { TRY @@ -957,15 +966,74 @@ static std::vector pci_name_files = { "/var/lib/pciutils/pci.ids" }; + +enum eNameStrType { + NAME_STR_VENDOR = 0, + NAME_STR_DEVICE, + NAME_STR_SUBSYS +}; + +static std::string +get_id_name_str_from_line(uint64_t id, std::string ln, + std::istringstream *ln_str) { + std::string token1; + std::string ret_str; + + assert(ln_str != nullptr); + + *ln_str >> token1; + if (std::stoul(token1, nullptr, 16) == id) { + int64_t pos = ln_str->tellg(); + + pos = ln.find_first_not_of("\t ", pos); + ret_str = ln.substr(pos); + } + return ret_str; +} + // Parse pci.ids files. Comment lines have # in first column. Otherwise, // Syntax: // vendor vendor_name // device device_name <-- single tab // subvendor subdevice subsystem_name <-- two tabs -static std::string get_dev_name_from_id(uint64_t id) { +static rsmi_status_t get_dev_name_from_id(uint32_t dv_ind, char *name, + size_t len, eNameStrType typ) { std::string ln; std::string token1; - std::string description; + rsmi_status_t ret; + uint16_t device_id; + uint16_t vendor_id; + uint16_t subsys_vend_id; + uint16_t subsys_id; + bool found_device_vendor = false; + std::string val_str; + + assert(name != nullptr); + assert(len > 0); + + name[0] = '\0'; + + ret = rsmi_dev_vendor_id_get(dv_ind, &vendor_id); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + + if (typ != NAME_STR_VENDOR) { + ret = rsmi_dev_id_get(dv_ind, &device_id); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + if (typ != NAME_STR_DEVICE) { + ret = rsmi_dev_subsystem_vendor_id_get(dv_ind, &subsys_vend_id); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + ret = rsmi_dev_subsystem_id_get(dv_ind, &subsys_id); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + } + } for (auto fl : pci_name_files) { std::ifstream id_file_strm(fl); @@ -973,71 +1041,120 @@ static std::string get_dev_name_from_id(uint64_t id) { while (std::getline(id_file_strm, ln)) { std::istringstream ln_str(ln); // parse line - if (ln_str.peek() == '#') { + if (ln[0] == '#' || ln.size() == 0) { continue; } if (ln[0] == '\t') { - if (ln[1] == '\t') { - if (ln[2] == '\t') { - // This is a subvendor line - } - } else { // ln[1] != '\t' - // This is a device line - ln_str >> token1; - if (std::stoul(token1, nullptr, 16) == id) { - int64_t pos = ln_str.tellg(); + if (found_device_vendor) { + if (ln[1] == '\t') { + // This is a subsystem line + if (typ == NAME_STR_SUBSYS) { + val_str = get_id_name_str_from_line(subsys_vend_id, ln, &ln_str); - pos = ln.find_first_not_of("\t ", pos); - description = ln.substr(pos); - return description; + if (val_str.size() > 0) { + // We've chopped the subsys_vend ID, now we need to get the + // subsys description + val_str = get_id_name_str_from_line(subsys_id, ln, &ln_str); + + if (val_str.size() > 0) { + break; + } else { + val_str.clear(); + } + } + } + } else if (typ == NAME_STR_DEVICE) { // ln[1] != '\t' + // This is a device line + val_str = get_id_name_str_from_line(device_id, ln, &ln_str); + + if (val_str.size() > 0) { + break; + } + } + } + } else { // ln[0] != '\t'; Vendor line + if (found_device_vendor) { + // We already found the vendor but didn't find the device or + // subsystem we were looking for, so bail out. + val_str.clear(); + return RSMI_STATUS_NOT_FOUND; + } + + val_str = get_id_name_str_from_line(vendor_id, ln, &ln_str); + + if (val_str.size() > 0) { + if (typ == NAME_STR_VENDOR) { + break; + } else { + val_str.clear(); + found_device_vendor = true; } } - } else { // ln[0] != '\t' - // This is a vendor line } } - } - return description; -} -rsmi_status_t -rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len) { - TRY - if (name == nullptr || len == 0) { - return RSMI_STATUS_INVALID_ARGS; - } - - std::string val_str; - rsmi_status_t ret; - uint64_t id; - - ret = rsmi_dev_id_get(dv_ind, &id); - - if (ret != RSMI_STATUS_SUCCESS) { - return ret; - } - - val_str = get_dev_name_from_id(id); - - if (val_str.size() == 0) { - ret = get_dev_mon_value_str(amd::smi::kMonName, dv_ind, -1, &val_str); - if (ret != RSMI_STATUS_SUCCESS) { - return ret; + if (val_str.size() > 0) { + break; } } - size_t ln = val_str.copy(name, len); + size_t ct = val_str.copy(name, len); - name[std::min(len - 1, ln)] = '\0'; + name[std::min(len - 1, ct)] = '\0'; if (len < val_str.size()) { return RSMI_STATUS_INSUFFICIENT_SIZE; } + return RSMI_STATUS_SUCCESS; +} +rsmi_status_t +rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len) { + rsmi_status_t ret; + + TRY + if (name == nullptr || len == 0) { + return RSMI_STATUS_INVALID_ARGS; + } + + ret = get_dev_name_from_id(dv_ind, name, len, NAME_STR_DEVICE); + if (ret != RSMI_STATUS_SUCCESS) { + return ret; + } + return RSMI_STATUS_SUCCESS; CATCH } +rsmi_status_t +rsmi_dev_subsystem_name_get(uint32_t dv_ind, char *name, size_t len) { + rsmi_status_t ret; + + TRY + if (name == nullptr || len == 0) { + return RSMI_STATUS_INVALID_ARGS; + } + + ret = get_dev_name_from_id(dv_ind, name, len, NAME_STR_SUBSYS); + return ret; + CATCH +} + +rsmi_status_t +rsmi_dev_vendor_name_get(uint32_t dv_ind, char *name, size_t len) { + rsmi_status_t ret; + + TRY + if (name == nullptr || len == 0) { + return RSMI_STATUS_INVALID_ARGS; + } + + ret = get_dev_name_from_id(dv_ind, name, len, NAME_STR_VENDOR); + return ret; + CATCH +} + + rsmi_status_t rsmi_dev_pci_bandwidth_get(uint32_t dv_ind, rsmi_pcie_bandwidth_t *b) { TRY diff --git a/src/rocm_smi_device.cc b/src/rocm_smi_device.cc index 4c21dc04ab..4d6db9ff3b 100755 --- a/src/rocm_smi_device.cc +++ b/src/rocm_smi_device.cc @@ -62,6 +62,9 @@ namespace smi { // Sysfs file names static const char *kDevPerfLevelFName = "power_dpm_force_performance_level"; static const char *kDevDevIDFName = "device"; +static const char *kDevVendorIDFName = "vendor"; +static const char *kDevSubSysDevIDFName = "subsystem_device"; +static const char *kDevSubSysVendorIDFName = "subsystem_vendor"; static const char *kDevOverDriveLevelFName = "pp_sclk_od"; static const char *kDevGPUSClkFName = "pp_dpm_sclk"; static const char *kDevGPUMClkFName = "pp_dpm_mclk"; @@ -96,6 +99,9 @@ static const std::map kDevAttribNameMap = { {kDevPerfLevel, kDevPerfLevelFName}, {kDevOverDriveLevel, kDevOverDriveLevelFName}, {kDevDevID, kDevDevIDFName}, + {kDevVendorID, kDevVendorIDFName}, + {kDevSubSysDevID, kDevSubSysDevIDFName}, + {kDevSubSysVendorID, kDevSubSysVendorIDFName}, {kDevGPUMClk, kDevGPUMClkFName}, {kDevGPUSClk, kDevGPUSClkFName}, {kDevPCIEClk, kDevGPUPCIEClkFname}, @@ -236,10 +242,6 @@ int Device::writeDevInfo(DevInfoTypes type, uint64_t val) { kDevPerfLvlMap.at((rsmi_dev_perf_level)val)); break; - case kDevGPUMClk: // integer (index within num-freq range) - case kDevGPUSClk: // integer (index within num-freq range) - case kDevPCIEClk: // integer (index within num-freq range) - case kDevDevID: // string (read-only) default: break; } @@ -255,9 +257,6 @@ int Device::writeDevInfo(DevInfoTypes type, std::string val) { case kDevPowerODVoltage: return writeDevInfoStr(type, val); - case kDevOverDriveLevel: - case kDevPerfLevel: - case kDevDevID: default: break; } @@ -315,6 +314,9 @@ int Device::readDevInfo(DevInfoTypes type, uint64_t *val) { int ret; switch (type) { case kDevDevID: + case kDevSubSysDevID: + case kDevSubSysVendorID: + case kDevVendorID: ret = readDevInfoStr(type, &tempStr); RET_IF_NONZERO(ret); *val = std::stoi(tempStr, 0, 16); @@ -369,6 +371,9 @@ int Device::readDevInfo(DevInfoTypes type, std::string *val) { case kDevUsage: case kDevOverDriveLevel: case kDevDevID: + case kDevSubSysDevID: + case kDevSubSysVendorID: + case kDevVendorID: case kDevVBiosVer: case kDevPCIEThruPut: return readDevInfoStr(type, val); diff --git a/src/rocm_smi_main.cc b/src/rocm_smi_main.cc index 4c7d5f96d5..b90c698133 100755 --- a/src/rocm_smi_main.cc +++ b/src/rocm_smi_main.cc @@ -136,7 +136,8 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) { tmp = in_name.copy(name, 12); assert(tmp == 12); - // BDFID = (( & 0x1f) << 8) | ((device& 0x1f) <<3 ) | (function & 0x7). + // BDFID = (( & 0xffff) << 13) | (( & 0x1f) << 8) | + // ((device& 0x1f) <<3 ) | (function & 0x7) *bdfid = 0; name_start = name; p = name_start; @@ -146,10 +147,10 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) { if (*p != ':' || p - name_start != 4) { return false; } - // We are ignoring the domain part for now as KFD is not encoding it yet + *bdfid |= tmp << 13; // Match this: xxxx:XX:xx.x - p++; + p++; // Skip past ':' tmp = std::strtoul(p, &p, 16); if (*p != ':' || p - name_start != 7) { return false; @@ -157,7 +158,7 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) { *bdfid |= tmp << 8; // Match this: xxxx:xx:XX.x - p++; + p++; // Skip past ':' tmp = std::strtoul(p, &p, 16); if (*p != '.' || p - name_start != 10) { return false; @@ -165,7 +166,7 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) { *bdfid |= tmp << 3; // Match this: xxxx:xx:xx.X - p++; + p++; // Skip past '.' tmp = std::strtoul(p, &p, 16); if (*p != '\0' || p - name_start != 12) { return false; diff --git a/tests/rocm_smi_test/functional/id_info_read.cc b/tests/rocm_smi_test/functional/id_info_read.cc new file mode 100755 index 0000000000..38bb9103ac --- /dev/null +++ b/tests/rocm_smi_test/functional/id_info_read.cc @@ -0,0 +1,190 @@ +/* + * ============================================================================= + * The University of Illinois/NCSA + * Open Source License (NCSA) + * + * Copyright (c) 2019, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Developed by: + * + * AMD Research and AMD ROC Software Development + * + * Advanced Micro Devices, Inc. + * + * www.amd.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal with 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: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimers. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimers in + * the documentation and/or other materials provided with the distribution. + * - Neither the names of , + * nor the names of its contributors may be used to endorse or promote + * products derived from this Software without specific prior written + * permission. + * + * 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 CONTRIBUTORS 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 WITH THE SOFTWARE. + * + */ + +#include +#include + +#include +#include + +#include "gtest/gtest.h" +#include "rocm_smi/rocm_smi.h" +#include "rocm_smi_test/functional/id_info_read.h" +#include "rocm_smi_test/test_common.h" + +TestIdInfoRead::TestIdInfoRead() : TestBase() { + set_title("RSMI ID Info Read Test"); + set_description("This test verifies that ID information such as the " + "device, subsystem and vendor IDs can be read properly."); +} + +TestIdInfoRead::~TestIdInfoRead(void) { +} + +void TestIdInfoRead::SetUp(void) { + TestBase::SetUp(); + + return; +} + +void TestIdInfoRead::DisplayTestInfo(void) { + TestBase::DisplayTestInfo(); +} + +void TestIdInfoRead::DisplayResults(void) const { + TestBase::DisplayResults(); + return; +} + +void TestIdInfoRead::Close() { + // This will close handles opened within rsmitst utility calls and call + // rsmi_shut_down(), so it should be done after other hsa cleanup + TestBase::Close(); +} + +static const uint32_t kBufferLen = 80; + +void TestIdInfoRead::Run(void) { + rsmi_status_t err; + uint16_t id; + uint64_t val_ui64; + + char buffer[kBufferLen]; + + TestBase::Run(); + + for (uint32_t i = 0; i < num_monitor_devs(); ++i) { + IF_VERB(STANDARD) { + std::cout << "\t**Device index: " << id << std::endl; + } + + // Get the device ID, name, vendor ID and vendor name for the device + err = rsmi_dev_id_get(i, &id); + if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Device ID: 0x" << std::hex << id << std::endl; + } + } + err = rsmi_dev_name_get(i, buffer, kBufferLen); + if (err == RSMI_STATUS_NOT_FOUND) { + std::cout << "\t**Device Marketing name not found on this system." << + std::endl; + } else if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Device Marketing name: " << buffer << std::endl; + } + } + err = rsmi_dev_vendor_id_get(i, &id); + if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Vendor ID: 0x" << std::hex << id << std::endl; + } + } + err = rsmi_dev_vendor_name_get(i, buffer, kBufferLen); + if (err == RSMI_STATUS_NOT_FOUND) { + std::cout << "\t**Device Vendor name string not found on this system." << + std::endl; + } else if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Device Vendor name: " << buffer << std::endl; + } + } + + // Get the device ID, name, vendor ID and vendor name for the sub-device + err = rsmi_dev_subsystem_id_get(i, &id); + if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Subsystem ID: 0x" << std::hex << id << std::endl; + } + } + err = rsmi_dev_subsystem_name_get(i, buffer, kBufferLen); + if (err == RSMI_STATUS_NOT_FOUND) { + std::cout << "\t**Subsystem name string not found on this system." << + std::endl; + } else if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Subsystem name: " << buffer << std::endl; + } + } + err = rsmi_dev_subsystem_vendor_id_get(i, &id); + if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Sub-system Vendor ID: 0x" << std::hex << + id << std::endl; + } + } + err = rsmi_dev_vendor_name_get(i, buffer, kBufferLen); + if (err == RSMI_STATUS_NOT_FOUND) { + std::cout << + "\t**Subsystem Vendor name string not found on this system." << + std::endl; + } else if (err != RSMI_STATUS_SUCCESS) { + CHK_ERR_ASRT(err) + } else { + IF_VERB(STANDARD) { + std::cout << "\t**Subsystem Vendor name: " << buffer << std::endl; + } + } + + err = rsmi_dev_pci_id_get(i, &val_ui64); + CHK_ERR_ASRT(err) + IF_VERB(STANDARD) { + std::cout << "\t**PCI ID (BDFID): 0x" << std::hex << val_ui64; + std::cout << " (" << std::dec << val_ui64 << ")" << std::endl; + } + } +} diff --git a/tests/rocm_smi_test/functional/id_info_read.h b/tests/rocm_smi_test/functional/id_info_read.h new file mode 100755 index 0000000000..b3abe32840 --- /dev/null +++ b/tests/rocm_smi_test/functional/id_info_read.h @@ -0,0 +1,73 @@ +/* + * ============================================================================= + * ROC Runtime Conformance Release License + * ============================================================================= + * The University of Illinois/NCSA + * Open Source License (NCSA) + * + * Copyright (c) 2019, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Developed by: + * + * AMD Research and AMD ROC Software Development + * + * Advanced Micro Devices, Inc. + * + * www.amd.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal with 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: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimers. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimers in + * the documentation and/or other materials provided with the distribution. + * - Neither the names of , + * nor the names of its contributors may be used to endorse or promote + * products derived from this Software without specific prior written + * permission. + * + * 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 CONTRIBUTORS 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 WITH THE SOFTWARE. + * + */ +#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_ID_INFO_READ_H_ +#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_ID_INFO_READ_H_ + +#include "rocm_smi_test/test_base.h" + +class TestIdInfoRead : public TestBase { + public: + TestIdInfoRead(); + + // @Brief: Destructor for test case of TestIdInfoRead + virtual ~TestIdInfoRead(); + + // @Brief: Setup the environment for measurement + virtual void SetUp(); + + // @Brief: Core measurement execution + virtual void Run(); + + // @Brief: Clean up and retrive the resource + virtual void Close(); + + // @Brief: Display results + virtual void DisplayResults() const; + + // @Brief: Display information about what this test does + virtual void DisplayTestInfo(void); +}; + +#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_ID_INFO_READ_H_ diff --git a/tests/rocm_smi_test/main.cc b/tests/rocm_smi_test/main.cc index 315345dfa0..febfd67f2c 100755 --- a/tests/rocm_smi_test/main.cc +++ b/tests/rocm_smi_test/main.cc @@ -70,6 +70,7 @@ #include "functional/version_read.h" #include "functional/err_cnt_read.h" #include "functional/mem_util_read.h" +#include "functional/id_info_read.h" static RSMITstGlobals *sRSMIGlvalues = nullptr; @@ -191,6 +192,10 @@ TEST(rsmitstReadOnly, TestMemUtilRead) { TestMemUtilRead tst; RunGenericTest(&tst); } +TEST(rsmitstReadOnly, TestIdInfoRead) { + TestIdInfoRead tst; + RunGenericTest(&tst); +} int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/tests/rocm_smi_test/test_base.cc b/tests/rocm_smi_test/test_base.cc index 0351a9e4ec..f5a3ae3b25 100755 --- a/tests/rocm_smi_test/test_base.cc +++ b/tests/rocm_smi_test/test_base.cc @@ -100,24 +100,40 @@ void TestBase::SetUp(void) { void TestBase::PrintDeviceHeader(uint32_t dv_ind) { rsmi_status_t err; - uint64_t val_ui64; + uint16_t val_ui16; IF_VERB(STANDARD) { std::cout << "\t**Device index: " << dv_ind << std::endl; } - err = rsmi_dev_id_get(dv_ind, &val_ui64); + err = rsmi_dev_id_get(dv_ind, &val_ui16); CHK_ERR_ASRT(err) IF_VERB(STANDARD) { - std::cout << "\t**Device ID: 0x" << std::hex << val_ui64 << std::endl; + std::cout << "\t**Device ID: 0x" << std::hex << val_ui16 << std::endl; } - std::cout << std::setbase(10); - char name[128]; err = rsmi_dev_name_get(dv_ind, name, 128); CHK_ERR_ASRT(err) IF_VERB(STANDARD) { std::cout << "\t**Device name: " << name << std::endl; } + err = rsmi_dev_vendor_id_get(dv_ind, &val_ui16); + CHK_ERR_ASRT(err) + IF_VERB(STANDARD) { + std::cout << "\t**Device Vendor ID: 0x" << std::hex << val_ui16 << + std::endl; + } + err = rsmi_dev_subsystem_id_get(dv_ind, &val_ui16); + CHK_ERR_ASRT(err) + IF_VERB(STANDARD) { + std::cout << "\t**Subsystem ID: 0x" << std::hex << val_ui16 << std::endl; + } + err = rsmi_dev_subsystem_vendor_id_get(dv_ind, &val_ui16); + CHK_ERR_ASRT(err) + IF_VERB(STANDARD) { + std::cout << "\t**Subsystem Vendor ID: 0x" << std::hex << val_ui16 << + std::endl; + } + std::cout << std::setbase(10); } void TestBase::Run(void) { std::string label;