[SWDEV-493274/SWDEV-514998] Add AMD SMI partition tests + Add Guest amd-smi static --partition (#127)

* [SWDEV-493274/SWDEV-514998] Add AMD SMI partition tests + Add Guest amd-smi static --partition

Changes:
    - Added amd-smi static --partition for guest systems
    - Added C++ tests for memory and compute (accelerator) partitions
    - Added Python tests for amdsmi_get_gpu_vram_info(),
       amdsmi_get_gpu_accelerator_partition_profile_config()
    - Updated Python tests for
      amdsmi_get_gpu_accelerator_partition_profile()
      Now includes more profile and resource detail
    - Added amdsmi_get_gpu_xcd_counter();
      Tests provided for both C++/Python APIs
    - Added AmdSmiVramType & AmdSmiVramVendor: they were missing
      python testing required adding.

Change-Id: Ib6549d8ccc5fb68726f38745b87c78f890186022
Signed-off-by: Charis Poag <Charis.Poag@amd.com>

[ROCm/amdsmi commit: 48cb5529d2]
This commit is contained in:
Poag, Charis
2025-03-11 16:38:46 -05:00
committed by GitHub
parent cb56b5e193
commit 267fa91e8a
30 changed files with 3505 additions and 399 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,51 @@
/*
* Copyright (c) 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 TESTS_AMD_SMI_TEST_FUNCTIONAL_COMPUTEPARTITION_READ_WRITE_H_
#define TESTS_AMD_SMI_TEST_FUNCTIONAL_COMPUTEPARTITION_READ_WRITE_H_
#include "../test_base.h"
class TestComputePartitionReadWrite : public TestBase {
public:
TestComputePartitionReadWrite();
// @Brief: Destructor for test case of TestComputePartitionReadWrite
virtual ~TestComputePartitionReadWrite();
// @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_AMD_SMI_TEST_FUNCTIONAL_COMPUTEPARTITION_READ_WRITE_H_
@@ -35,6 +35,7 @@
#include "gpu_metrics_read.h"
#include "../test_common.h"
#include "rocm_smi/rocm_smi_utils.h"
#include "amd_smi/impl/amd_smi_utils.h"
TestGpuMetricsRead::TestGpuMetricsRead() : TestBase() {
@@ -101,6 +102,15 @@ void TestGpuMetricsRead::Run(void) {
}
}
} else {
auto temp_xcd_counter_value = uint16_t(0);
auto ret_xcd = amdsmi_get_gpu_xcd_counter(processor_handles_[i], &temp_xcd_counter_value);
IF_VERB(STANDARD) {
std::cout << "\t\t** amdsmi_get_gpu_xcd_counter(): "
<< smi_amdgpu_get_status_string(ret_xcd, false)
<< "\n\t\t** XCD Counter Value: "
<< temp_xcd_counter_value
<< "\n";
}
CHK_ERR_ASRT(err);
IF_VERB(STANDARD) {
std::cout << "METRIC TABLE HEADER:\n";
@@ -380,13 +390,5 @@ void TestGpuMetricsRead::Run(void) {
amdsmi_status_code_to_string(err, &status_string);
std::cout << "\t\t** amdsmi_get_gpu_metrics_info(nullptr check): " << status_string << "\n";
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
// TODO(AMD_SMI_team): add xcd_counter_get for amd smi
// auto temp_xcd_counter_value = uint16_t(0);
// err = rsmi_dev_metrics_xcd_counter_get(i, &temp_xcd_counter_value);
// if (err != RSMI_STATUS_NOT_SUPPORTED) {
// CHK_ERR_ASRT(err);
// }
}
}
@@ -22,11 +22,11 @@
#include <stdint.h>
#include <stddef.h>
#include <gtest/gtest.h>
#include <iostream>
#include <string>
#include <gtest/gtest.h>
#include <map>
#include "amd_smi/amdsmi.h"
#include "id_info_read.h"
#include "../test_common.h"
@@ -63,6 +63,15 @@ void TestIdInfoRead::Close() {
static const uint32_t kBufferLen = 80;
static const std::map< amdsmi_virtualization_mode_t, std::string>
virtualization_mode_map = {
{AMDSMI_VIRTUALIZATION_MODE_UNKNOWN, "UNKNOWN"},
{AMDSMI_VIRTUALIZATION_MODE_BAREMETAL, "BAREMETAL"},
{ AMDSMI_VIRTUALIZATION_MODE_HOST, "HOST"},
{ AMDSMI_VIRTUALIZATION_MODE_GUEST, "GUEST"},
{AMDSMI_VIRTUALIZATION_MODE_PASSTHROUGH, "PASSTHROUGH"}
};
void TestIdInfoRead::Run(void) {
amdsmi_status_t err;
uint16_t id;
@@ -227,5 +236,20 @@ void TestIdInfoRead::Run(void) {
// Verify api support checking functionality is working
err = amdsmi_get_gpu_bdf_id(processor_handles_[i], nullptr);
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
// Verify api support checking functionality is working
err = amdsmi_get_gpu_virtualization_mode(processor_handles_[i], nullptr);
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
amdsmi_virtualization_mode_t vmode;
err = amdsmi_get_gpu_virtualization_mode(processor_handles_[i], &vmode);
ASSERT_EQ(err, AMDSMI_STATUS_SUCCESS);
IF_VERB(STANDARD) {
auto it = virtualization_mode_map.find(vmode);
if (it != virtualization_mode_map.end()) {
std::cout << "\t**Virtualization Mode: " << it->second << std::endl;
} else {
std::cout << "\t**Virtualization Mode: MAP TYPE UNKNOWN?" << std::endl;
}
}
}
}
@@ -0,0 +1,744 @@
/*
* Copyright (c) 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 <stdint.h>
#include <stddef.h>
#include <cstdint>
#include <iostream>
#include <string>
#include <map>
#include <limits>
#include "gtest/gtest.h"
#include "../test_base.h"
#include "../test_common.h"
#include "amd_smi/amdsmi.h"
#include "amd_smi/impl/amd_smi_utils.h"
#include "memorypartition_read_write.h"
const uint32_t MAX_UNSUPPORTED_PARTITIONS = 0;
const uint32_t MAX_SPX_PARTITIONS = 1; // Single GPU node
const uint32_t MAX_DPX_PARTITIONS = 2;
const uint32_t MAX_TPX_PARTITIONS = 3;
const uint32_t MAX_QPX_PARTITIONS = 4;
TestMemoryPartitionReadWrite::TestMemoryPartitionReadWrite() : TestBase() {
set_title("AMDSMI Memory Partition Read Test");
set_description("The memory partition tests verifies that the memory "
"partition settings can be read and updated properly.");
}
TestMemoryPartitionReadWrite::~TestMemoryPartitionReadWrite(void) {
}
void TestMemoryPartitionReadWrite::SetUp(void) {
TestBase::SetUp();
return;
}
void TestMemoryPartitionReadWrite::DisplayTestInfo(void) {
TestBase::DisplayTestInfo();
}
void TestMemoryPartitionReadWrite::DisplayResults(void) const {
TestBase::DisplayResults();
return;
}
void TestMemoryPartitionReadWrite::Close() {
// This will close handles opened within rsmitst utility calls and call
// amdsmi_shut_down(), so it should be done after other hsa cleanup
TestBase::Close();
}
static const std::string
memoryPartitionString(amdsmi_memory_partition_type_t memoryPartitionType) {
switch (memoryPartitionType) {
case AMDSMI_MEMORY_PARTITION_NPS1:
return "NPS1";
case AMDSMI_MEMORY_PARTITION_NPS2:
return "NPS2";
case AMDSMI_MEMORY_PARTITION_NPS4:
return "NPS4";
case AMDSMI_MEMORY_PARTITION_NPS8:
return "NPS8";
default:
return "UNKNOWN";
}
}
static const std::map<std::string, amdsmi_memory_partition_type_t>
mapStringToRSMIMemoryPartitionTypes {
{"NPS1", AMDSMI_MEMORY_PARTITION_NPS1},
{"NPS2", AMDSMI_MEMORY_PARTITION_NPS2},
{"NPS4", AMDSMI_MEMORY_PARTITION_NPS4},
{"NPS8", AMDSMI_MEMORY_PARTITION_NPS8}
};
void TestMemoryPartitionReadWrite::Run(void) {
amdsmi_status_t ret, err, ret_set;
constexpr uint32_t k255Len = 255;
constexpr uint32_t k0Len = 0;
char orig_memory_partition[k255Len];
char current_memory_partition[k255Len];
orig_memory_partition[0] = '\0';
current_memory_partition[0] = '\0';
amdsmi_memory_partition_config_t current_memory_config;
const uint32_t kMAX_UINT32 = std::numeric_limits<uint32_t>::max();
std::map<uint32_t, AcceleratorProfileConfig> orig_dev_config; // index, ProfileConfig
TestBase::Run();
if (setup_failed_) {
std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl;
return;
}
bool isVerbose = (this->verbosity() &&
this->verbosity() >= (this->TestBase::VERBOSE_STANDARD)) ? true: false;
// Save original memory partition settings (see orig_dev_config ^)
IF_VERB(STANDARD) {
std::cout << "\t**=========================================================\n";
std::cout << "\t**Save Original Compute Partition Settings ================\n";
std::cout << "\t**=========================================================\n";
}
auto initial_num_devices = num_monitor_devs();
for (uint32_t dv_ind = 0; dv_ind < initial_num_devices; ++dv_ind) {
if (dv_ind != 0) {
std::cout << "\n";
}
PrintDeviceHeader(processor_handles_[dv_ind]);
amdsmi_accelerator_partition_profile_t profile = {};
uint32_t partition_id[8] = {0, 0, 0, 0, 0, 0, 0, 0};
ret = amdsmi_get_gpu_accelerator_partition_profile(processor_handles_[dv_ind],
&profile, &partition_id[0]);
std::string nps_caps_str = "";
if ((profile.memory_caps.nps_flags.nps1_cap == 0
&& profile.memory_caps.nps_flags.nps2_cap == 0
&& profile.memory_caps.nps_flags.nps4_cap == 0
&& profile.memory_caps.nps_flags.nps8_cap == 0)) {
nps_caps_str = "N/A";
} else {
nps_caps_str.clear();
if (profile.memory_caps.nps_flags.nps1_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS1" : nps_caps_str += ", NPS1";
}
if (profile.memory_caps.nps_flags.nps2_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS2" : nps_caps_str += ", NPS2";
}
if (profile.memory_caps.nps_flags.nps4_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS4" : nps_caps_str += ", NPS4";
}
if (profile.memory_caps.nps_flags.nps8_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS8" : nps_caps_str += ", NPS8";
}
}
std::string profile_type_str = "N/A";
if (profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_SPX) {
profile_type_str = "SPX";
} else if (profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_DPX) {
profile_type_str = "DPX";
} else if (profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_TPX) {
profile_type_str = "TPX";
} else if (profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_QPX) {
profile_type_str = "QPX";
} else if (profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_CPX) {
profile_type_str = "CPX";
}
std::string partition_id_str = "";
for (int i = 0; i < 8; i++) {
partition_id_str += std::to_string(partition_id[i]);
if (i < 7) {
partition_id_str += ", ";
}
switch (profile.profile_type) {
case AMDSMI_ACCELERATOR_PARTITION_SPX:
EXPECT_LT(partition_id[i], MAX_SPX_PARTITIONS);
break;
case AMDSMI_ACCELERATOR_PARTITION_DPX:
EXPECT_LT(partition_id[i], MAX_DPX_PARTITIONS);
break;
case AMDSMI_ACCELERATOR_PARTITION_TPX:
EXPECT_LT(partition_id[i], MAX_TPX_PARTITIONS);
break;
case AMDSMI_ACCELERATOR_PARTITION_QPX:
EXPECT_LT(partition_id[i], MAX_QPX_PARTITIONS);
break;
case AMDSMI_ACCELERATOR_PARTITION_CPX: {
uint16_t num_xcd;
uint32_t max_xcps = 0;
ret = amdsmi_get_gpu_xcd_counter(processor_handles_[dv_ind], &num_xcd);
if (ret == AMDSMI_STATUS_SUCCESS) {
max_xcps = static_cast<uint32_t>(num_xcd);
}
EXPECT_LT(partition_id[i], max_xcps);
break;
}
case AMDSMI_ACCELERATOR_PARTITION_INVALID:
EXPECT_EQ(partition_id[i], MAX_UNSUPPORTED_PARTITIONS);
break;
default:
EXPECT_EQ(partition_id[i], MAX_UNSUPPORTED_PARTITIONS);
break;
}
}
IF_VERB(STANDARD) {
std::cout << "\t**amdsmi_get_gpu_accelerator_partition_profile(processor_handles_["
<< dv_ind << "], &profile, &partition_id[0]):\n"
<< "\t\t" << smi_amdgpu_get_status_string(ret, false)
<< "\n\t**Current profile.profile_type: "
<< profile_type_str
<< "\n\t**profile.num_partitions: "
<< (profile.num_partitions == kMAX_UINT32
? "N/A" : std::to_string(profile.num_partitions))
<< "\n\t**profile.memory_caps: "
<< nps_caps_str
<< "\n\t**profile.profile_index: "
<< (profile.profile_index == kMAX_UINT32
? "N/A" : std::to_string(profile.profile_index))
<< "\n\t**profile.num_resources: "
<< profile.num_resources
<< "\n\t**partition_id: "
<< partition_id_str
<< std::endl;
}
EXPECT_TRUE(ret == AMDSMI_STATUS_SUCCESS
|| ret == AMDSMI_STATUS_NOT_SUPPORTED);
amdsmi_accelerator_partition_profile_config_t profile_config = {};
ret = amdsmi_get_gpu_accelerator_partition_profile_config(processor_handles_[dv_ind],
&profile_config);
IF_VERB(STANDARD) {
std::cout << "\t**amdsmi_get_gpu_accelerator_partition_profile_config(processor_handles_["
<< dv_ind << "], &profile_config):\n"
<< "\t\t" << smi_amdgpu_get_status_string(ret, false)
<< "\n\t**profile_config.num_profiles: "
<< profile_config.num_profiles
<< "\n\t**profile_config.num_resource_profiles: "
<< profile_config.num_resource_profiles
<< std::endl;
}
AcceleratorProfileConfig original_profile_config =
getAvailableProfileConfigs(dv_ind, profile, profile_config, isVerbose);
orig_dev_config[dv_ind] = original_profile_config;
// waitForUserInput(); // watch for any errors
IF_VERB(STANDARD) {
std::cout << "\t**=========================================================\n";
std::cout << "\t**Checking valid profile Sets =============================\n";
std::cout << "\t**=========================================================\n";
}
int resource_index = 0;
for (uint32_t i = 0; i < profile_config.num_profiles; i++) {
auto current_profile = profile_config.profiles[i];
std::string profile_type_str = "N/A";
if (current_profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_SPX) {
profile_type_str = "SPX";
} else if (current_profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_DPX) {
profile_type_str = "DPX";
} else if (current_profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_TPX) {
profile_type_str = "TPX";
} else if (current_profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_QPX) {
profile_type_str = "QPX";
} else if (current_profile.profile_type == AMDSMI_ACCELERATOR_PARTITION_CPX) {
profile_type_str = "CPX";
}
std::string nps_caps_str = "";
if ((current_profile.memory_caps.nps_flags.nps1_cap == 0
&& current_profile.memory_caps.nps_flags.nps2_cap == 0
&& current_profile.memory_caps.nps_flags.nps4_cap == 0
&& current_profile.memory_caps.nps_flags.nps8_cap == 0)) {
nps_caps_str = "N/A";
} else {
nps_caps_str.clear();
if (current_profile.memory_caps.nps_flags.nps1_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS1" : nps_caps_str += ", NPS1";
}
if (current_profile.memory_caps.nps_flags.nps2_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS2" : nps_caps_str += ", NPS2";
}
if (current_profile.memory_caps.nps_flags.nps4_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS4" : nps_caps_str += ", NPS4";
}
if (current_profile.memory_caps.nps_flags.nps8_cap) {
(nps_caps_str.empty()) ? nps_caps_str += "NPS8" : nps_caps_str += ", NPS8";
}
}
IF_VERB(STANDARD) {
std::cout << "\t**profile_config.profiles[" << i << "]:\n"
<< "\t\tprofile_type: " << profile_type_str
<< "\n\t\tnum_partitions: " << current_profile.num_partitions
<< "\n\t\tmemory_caps: " << nps_caps_str
<< "\n\t\tcurrent_profile.num_resources: " << current_profile.num_resources
<< std::endl;
}
for (auto j = 0; j < current_profile.num_resources; j++) {
auto rp = profile_config.resource_profiles[resource_index];
IF_VERB(STANDARD) {
std::cout << "\n\t\t\tprofile_index: " << current_profile.profile_index
<< "\n\t\t\tresource_index: " << resource_index
<< "\n\t\t\tprofile_config.resource_profiles[" << resource_index
<< "].resource_type: "
<< getResourceType(rp.resource_type)
<< "\n\t\t\tprofile_config.resource_profiles[" << resource_index
<< "].partition_resource: "
<< rp.partition_resource
<< "\n\t\t\tprofile_config.resource_profiles[" << resource_index
<< "].num_partitions_share_resource: "
<< rp.num_partitions_share_resource
<< std::endl;
}
resource_index++;
}
}
EXPECT_TRUE(ret == AMDSMI_STATUS_SUCCESS
|| ret == AMDSMI_STATUS_NOT_SUPPORTED);
if (ret == AMDSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" << "amdsmi_get_gpu_accelerator_partition_profile_config: "
<< "Not supported on this machine" << std::endl;
}
continue;
}
}
// Run memory partition tests
uint32_t current_num_devices = 0;
smi_amdgpu_get_device_count(&current_num_devices);
IF_VERB(STANDARD) {
std::cout << "\t**Total Num Devices: " << current_num_devices << std::endl;
}
// Leaving for debug purposes - uncomment to test a specific number of devices
// uint32_t num_devices_to_test = promptNumDevicesToTest(current_num_devices);
uint32_t num_devices_to_test = current_num_devices;
for (uint32_t dv_ind = 0; dv_ind < num_devices_to_test; ++dv_ind) {
bool wasSetSuccess = false;
if (dv_ind != 0) {
IF_VERB(STANDARD) {
std::cout << std::endl;
}
}
PrintDeviceHeader(processor_handles_[dv_ind]);
// Standard checks to see if API is supported, before running full tests
ret = amdsmi_get_gpu_memory_partition(
processor_handles_[dv_ind], orig_memory_partition, k255Len);
if (ret == AMDSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" << ": "
<< "Not supported on this machine" << std::endl;
}
continue;
} else {
CHK_ERR_ASRT(ret)
}
IF_VERB(STANDARD) {
std::cout << std::endl << "\t**Current Memory Partition: "
<< orig_memory_partition << std::endl;
}
if ((orig_memory_partition == nullptr) ||
(orig_memory_partition[0] == '\0')) {
std::cout << "***System memory partition value is not defined or received"
" unexpected data. Skip memory partition test." << std::endl;
continue;
}
ASSERT_TRUE(ret == AMDSMI_STATUS_SUCCESS);
// Verify api support checking functionality is working
constexpr uint32_t k2Len = 2;
char smallBuffer[k2Len];
err = amdsmi_get_gpu_memory_partition(processor_handles_[dv_ind], smallBuffer, k2Len);
uint32_t size = static_cast<uint32_t>(sizeof(smallBuffer)/sizeof(*smallBuffer));
ASSERT_EQ(err, AMDSMI_STATUS_INSUFFICIENT_SIZE);
ASSERT_EQ(k2Len, size);
if (err == AMDSMI_STATUS_INSUFFICIENT_SIZE) {
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "Confirmed AMDSMI_STATUS_INSUFFICIENT_SIZE was returned "
<< "and size is 2, as requested." << std::endl;
}
}
// Verify api support checking functionality is working
err = amdsmi_get_gpu_memory_partition(processor_handles_[dv_ind], nullptr, k255Len);
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
if (err == AMDSMI_STATUS_INVAL) {
IF_VERB(STANDARD) {
std::cout << "\t**amdsmi_get_gpu_memory_partition(processor_handles_[" << dv_ind << "], "
<< "nullptr, 255): "
<< "Confirmed AMDSMI_STATUS_INVAL was returned."
<< std::endl;
}
}
err = amdsmi_get_gpu_memory_partition_config(processor_handles_[dv_ind], nullptr);
ASSERT_EQ(err, AMDSMI_STATUS_INVAL);
if (err == AMDSMI_STATUS_INVAL) {
IF_VERB(STANDARD) {
std::cout << "\t**amdsmi_get_gpu_memory_partition(processor_handles_[" << dv_ind
<< "], nullptr): Confirmed AMDSMI_STATUS_INVAL was returned."
<< std::endl;
}
}
// Verify api support checking functionality is working
err = amdsmi_get_gpu_memory_partition(processor_handles_[dv_ind], orig_memory_partition, k0Len);
ASSERT_TRUE(err == AMDSMI_STATUS_INVAL);
if (err == AMDSMI_STATUS_INVAL) {
IF_VERB(STANDARD) {
std::cout << "\t**amdsmi_get_gpu_memory_partition(processor_handles_[" << dv_ind << "], "
<< "orig_memory_partition, 0): "
<< "Confirmed AMDSMI_STATUS_INVAL was returned."
<< std::endl;
}
}
amdsmi_memory_partition_config_t* null_memory_partition_config = nullptr;
err = amdsmi_get_gpu_memory_partition_config(processor_handles_[dv_ind],
null_memory_partition_config);
ASSERT_TRUE((err == AMDSMI_STATUS_INVAL) ||
(err == AMDSMI_STATUS_NOT_SUPPORTED));
if (err == AMDSMI_STATUS_INVAL) {
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "amdsmi_get_gpu_memory_partition_config(processor_handles_[" << dv_ind << "], "
<< "nullptr): "
<< "Confirmed AMDSMI_STATUS_INVAL was returned."
<< std::endl;
}
}
/****************************************/
/* amdsmi_set_gpu_memory_partition(...) */
/****************************************/
// Verify api support checking functionality is working
amdsmi_memory_partition_type_t null_memory_partition = {};
err = amdsmi_set_gpu_memory_partition_mode(processor_handles_[dv_ind], null_memory_partition);
std::cout << "\t**amdsmi_set_gpu_memory_partition(amdsmi_set_gpu_memory_partition_mode"
<< "(processor_handles_[" << dv_ind << "], nullptr): "
<< smi_amdgpu_get_status_string(err, false) << "\n";
// Note: new_memory_partition is not set
ASSERT_TRUE(err == AMDSMI_STATUS_INVAL);
if (err == AMDSMI_STATUS_INVAL) {
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "Confirmed AMDSMI_STATUS_INVAL was returned."
<< std::endl;
}
} else if (err == AMDSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" << ": "
<< "amdsmi_set_gpu_memory_partition_mode not supported on this "
<< "device\n\t (if amdsmi_get_gpu_memory_partition works, "
<< "then likely need to set in bios)"
<< std::endl;
}
continue;
} else {
DISPLAY_AMDSMI_ERR(err)
}
ASSERT_FALSE(err == AMDSMI_STATUS_NO_PERM);
// Verify api support checking functionality is working
amdsmi_memory_partition_type_t new_memory_partition = AMDSMI_MEMORY_PARTITION_UNKNOWN;
err = amdsmi_set_gpu_memory_partition_mode(processor_handles_[dv_ind], new_memory_partition);
ASSERT_TRUE((err == AMDSMI_STATUS_INVAL) ||
(err == AMDSMI_STATUS_NOT_SUPPORTED) ||
(err == AMDSMI_STATUS_NO_PERM));
if (err == AMDSMI_STATUS_INVAL) {
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "Confirmed AMDSMI_STATUS_INVAL was returned."
<< std::endl;
} else if (err == AMDSMI_STATUS_NO_PERM) {
DISPLAY_AMDSMI_ERR(err)
// tests should not continue if err is a permission issue
ASSERT_FALSE(err == AMDSMI_STATUS_NO_PERM);
} else {
DISPLAY_AMDSMI_ERR(err)
}
}
// Re-run original get, so we can reset to later
ret = amdsmi_get_gpu_memory_partition(processor_handles_[dv_ind],
orig_memory_partition, k255Len);
ASSERT_EQ(AMDSMI_STATUS_SUCCESS, ret);
for (int partition = static_cast<int>(AMDSMI_MEMORY_PARTITION_NPS1);
partition <= static_cast<int>(AMDSMI_MEMORY_PARTITION_NPS8);
partition++) {
ret_set = AMDSMI_STATUS_NOT_SUPPORTED;
wasSetSuccess = false;
new_memory_partition = static_cast<amdsmi_memory_partition_type_t>(partition);
if (new_memory_partition != AMDSMI_MEMORY_PARTITION_NPS1
&& new_memory_partition != AMDSMI_MEMORY_PARTITION_NPS2
&& new_memory_partition != AMDSMI_MEMORY_PARTITION_NPS4
&& new_memory_partition != AMDSMI_MEMORY_PARTITION_NPS8) {
continue; // skip unknown partition, this is already tested above ^
}
IF_VERB(STANDARD) {
std::cout << std::endl;
std::cout << "\t**"
<< "======== TEST AMDSMI_MEMORY_PARTITION_"
<< memoryPartitionString(new_memory_partition)
<< " ===============" << std::endl;
}
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "Attempting to set memory partition to: "
<< memoryPartitionString(new_memory_partition) << std::endl;
}
auto ret_caps = amdsmi_get_gpu_memory_partition_config(processor_handles_[dv_ind],
&current_memory_config);
std::string memory_caps_str = "N/A";
if (ret_caps == AMDSMI_STATUS_SUCCESS) {
memory_caps_str.clear();
if (current_memory_config.partition_caps.nps_flags.nps1_cap) {
memory_caps_str += (memory_caps_str.empty() ? "NPS1" : ", NPS1");
}
if (current_memory_config.partition_caps.nps_flags.nps2_cap) {
memory_caps_str += (memory_caps_str.empty() ? "NPS2" : ", NPS2");
}
if (current_memory_config.partition_caps.nps_flags.nps4_cap) {
memory_caps_str += (memory_caps_str.empty() ? "NPS4" : ", NPS4");
}
if (current_memory_config.partition_caps.nps_flags.nps8_cap) {
memory_caps_str += (memory_caps_str.empty() ? "NPS8" : ", NPS8");
}
}
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "amdsmi_get_gpu_memory_partition_config(processor_handles_[" << dv_ind
<< "], current_memory_config): "
<< smi_amdgpu_get_status_string(ret_caps, false) << std::endl;
std::cout << "\t**" << "Available Memory Partition Capabilities: "
<< memory_caps_str << "\n"
<< "\t**" << "current_memory_partition_mode: "
<< memoryPartitionString(current_memory_config.mp_mode) << "\n"
<< "\t**" << "num_numa_ranges: "
<< current_memory_config.num_numa_ranges
<< std::endl;
}
ASSERT_TRUE((ret_caps == AMDSMI_STATUS_NOT_SUPPORTED) ||
(ret_caps == AMDSMI_STATUS_SUCCESS));
ret_set = amdsmi_set_gpu_memory_partition_mode(processor_handles_[dv_ind],
new_memory_partition);
IF_VERB(STANDARD) {
std::cout << "\t**" << "amdsmi_set_gpu_memory_partition_mode(processor_handles_["
<< dv_ind << "], " << memoryPartitionString(new_memory_partition) << "): "
<< smi_amdgpu_get_status_string(ret_set, false) << "\n";
}
if (ret_set == AMDSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" << ": "
<< "Not supported on this machine" << std::endl;
}
break;
} else {
ASSERT_TRUE((ret_set == AMDSMI_STATUS_SUCCESS)
|| (ret_set == AMDSMI_STATUS_BUSY)
|| (ret_set == AMDSMI_STATUS_AMDGPU_RESTART_ERR)
|| (ret_set == AMDSMI_STATUS_INVAL)
|| (ret_set == AMDSMI_STATUS_NOT_SUPPORTED));
}
if (ret_set == AMDSMI_STATUS_SUCCESS) { // do not continue trying to reset
wasSetSuccess = true;
}
ret = amdsmi_get_gpu_memory_partition_config(processor_handles_[dv_ind],
&current_memory_config);
if (ret == AMDSMI_STATUS_NOT_SUPPORTED) {
IF_VERB(STANDARD) {
std::cout << "\t**" << "amdsmi_get_gpu_memory_partition_config(): "
<< "Not supported on this machine" << std::endl;
}
continue;
}
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "Current memory partition: "
<< memoryPartitionString(current_memory_config.mp_mode)
<< std::endl;
}
if (wasSetSuccess) {
ASSERT_EQ(AMDSMI_STATUS_SUCCESS, ret_set);
ASSERT_STREQ(memoryPartitionString(new_memory_partition).c_str(),
memoryPartitionString(current_memory_config.mp_mode).c_str());
CHK_ERR_ASRT(ret_set)
} else {
ASSERT_NE(AMDSMI_STATUS_SUCCESS, ret_set);
ASSERT_STRNE(memoryPartitionString(new_memory_partition).c_str(),
memoryPartitionString(current_memory_config.mp_mode).c_str());
}
} // END MEMORY PARTITION FOR LOOP
/* TEST RETURN TO ORIGINAL MEMORY PARTITION SETTING */
IF_VERB(STANDARD) {
std::cout << std::endl;
std::cout << "\t**"
<< "=========== TEST RETURN TO ORIGINAL MEMORY PARTITION "
<< "SETTING (" << orig_memory_partition
<< ") ========" << std::endl;
}
ret = amdsmi_get_gpu_memory_partition_config(processor_handles_[dv_ind],
&current_memory_config);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "amdsmi_get_gpu_memory_partition_config(processor_handles_[" << dv_ind
<< "], current_memory_config): "
<< smi_amdgpu_get_status_string(ret, false) << std::endl;
std::cout << "\t**"
<< "Current memory partition: "
<< memoryPartitionString(current_memory_config.mp_mode)
<< std::endl;
}
new_memory_partition
= mapStringToRSMIMemoryPartitionTypes.at(orig_memory_partition);
IF_VERB(STANDARD) {
std::cout << "\t**" << "Returning memory partition to: "
<< memoryPartitionString(new_memory_partition) << std::endl;
}
ret = amdsmi_set_gpu_memory_partition(processor_handles_[dv_ind], new_memory_partition);
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "amdsmi_set_gpu_memory_partition(processor_handles_[" << dv_ind
<< "], " << orig_memory_partition << "): "
<< smi_amdgpu_get_status_string(ret, false) << std::endl;
}
CHK_ERR_ASRT(ret)
ret = amdsmi_get_gpu_memory_partition(processor_handles_[dv_ind],
current_memory_partition, k255Len);
CHK_ERR_ASRT(ret)
IF_VERB(STANDARD) {
std::cout << "\t**" << "Attempted to set memory partition: "
<< memoryPartitionString(new_memory_partition) << std::endl
<< "\t**" << "Current memory partition: "
<< current_memory_partition
<< std::endl;
}
ASSERT_EQ(AMDSMI_STATUS_SUCCESS, ret);
ASSERT_STREQ(orig_memory_partition, current_memory_partition);
IF_VERB(STANDARD) {
std::cout << "\t**"
<< "Confirmed prior memory partition (" << orig_memory_partition
<< ") is equal to current memory partition ("
<< current_memory_partition << ")" << std::endl;
}
} // END DEVICE FOR LOOP
// Restore original compute partition settings (see orig_dev_config ^)
IF_VERB(STANDARD) {
std::cout << "\t**=========================================================\n";
std::cout << "\t**Restore Original Compute Partition Settings =============\n";
std::cout << "\t**=========================================================\n";
}
initial_num_devices = num_monitor_devs();
for (uint32_t dv_ind = 0; dv_ind < initial_num_devices; ++dv_ind) {
if (dv_ind != 0) {
std::cout << "\n";
}
PrintDeviceHeader(processor_handles_[dv_ind]);
AcceleratorProfileConfig original_profile_config = orig_dev_config[dv_ind];
// Return to original profile
IF_VERB(STANDARD) {
std::cout << "\t**Device Index: " << dv_ind << std::endl
<< "\t**======== Return to original AMDSMI_ACCELERATOR_PARTITION_"
<< original_profile_config.original_profile_type_str
<< " (profile_index: "
<< (original_profile_config.original_profile_index == kMAX_UINT32
? "N/A" : std::to_string(original_profile_config.original_profile_index))
<< ")"
<< " ===============" << std::endl;
}
auto ret_set = amdsmi_set_gpu_accelerator_partition_profile(
processor_handles_[dv_ind],
original_profile_config.original_profile_index);
EXPECT_TRUE((ret_set == AMDSMI_STATUS_SETTING_UNAVAILABLE)
|| (ret_set== AMDSMI_STATUS_NO_PERM)
|| (ret_set == AMDSMI_STATUS_SUCCESS)
|| ret_set == AMDSMI_STATUS_BUSY
|| ret_set == AMDSMI_STATUS_NOT_SUPPORTED);
amdsmi_accelerator_partition_profile_t profile = {};
uint32_t partition_id[8] = {0, 0, 0, 0, 0, 0, 0, 0};
auto ret_get = amdsmi_get_gpu_accelerator_partition_profile(processor_handles_[dv_ind],
&profile, &partition_id[0]);
if (ret_get == AMDSMI_STATUS_SUCCESS && ret_set == AMDSMI_STATUS_SUCCESS) {
std::string profile_type_str = partition_types_map.at(profile.profile_type);
IF_VERB(STANDARD) {
std::cout << "\t**amdsmi_set_gpu_accelerator_partition_profile(processor_handles_["
<< dv_ind << "],"
<< "\n\t\t" << original_profile_config.original_profile_index
<< " (AMDSMI_ACCELERATOR_PARTITION_"
<< original_profile_config.original_profile_type_str
<< "): "
<< "\n\t\t" << smi_amdgpu_get_status_string(ret_set, false)
<< "\n\t**amdsmi_get_gpu_accelerator_partition_profile(processor_handles_["
<< dv_ind << "], &profile, &partition_id[0]):\n"
<< "\t\t" << smi_amdgpu_get_status_string(ret_get, false)
<< "\n\t**Current profile.profile_type: "
<< profile_type_str
<< "\n\t**profile.num_partitions: "
<< (profile.num_partitions == kMAX_UINT32
? "N/A" : std::to_string(profile.num_partitions))
<< "\n\t**profile.profile_index: "
<< (profile.profile_index == kMAX_UINT32
? "N/A" : std::to_string(profile.profile_index))
<< std::endl;
}
EXPECT_STREQ(partition_types_map.at(profile.profile_type).c_str(),
original_profile_config.original_profile_type_str.c_str());
EXPECT_EQ(profile.profile_type, original_profile_config.original_profile_type);
EXPECT_EQ(profile.profile_index, original_profile_config.original_profile_index);
} else {
IF_VERB(STANDARD) {
std::cout << "\t**Could not change or read profiles. "
<< "Skipping return to original profile on this device."
<< "\n\t**amdsmi_set_gpu_accelerator_partition_profile(): "
<< smi_amdgpu_get_status_string(ret_set, false)
<< "\n\t**amdsmi_get_gpu_accelerator_partition_profile(): "
<< smi_amdgpu_get_status_string(ret_get, false)
<< std::endl;
}
}
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 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 TESTS_AMD_SMI_TEST_FUNCTIONAL_MEMORYPARTITION_READ_WRITE_H_
#define TESTS_AMD_SMI_TEST_FUNCTIONAL_MEMORYPARTITION_READ_WRITE_H_
#include "../test_base.h"
class TestMemoryPartitionReadWrite : public TestBase {
public:
TestMemoryPartitionReadWrite();
// @Brief: Destructor for test case of TestMemoryPartitionReadWrite
virtual ~TestMemoryPartitionReadWrite();
// @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_AMD_SMI_TEST_FUNCTIONAL_MEMORYPARTITION_READ_WRITE_H_
+13 -2
View File
@@ -64,6 +64,8 @@
#include "functional/version_read.h"
#include "functional/mutual_exclusion.h"
#include "functional/init_shutdown_refcount.h"
#include "functional/memorypartition_read_write.h"
#include "functional/computepartition_read_write.h"
static AMDSMITstGlobals *sRSMIGlvalues = nullptr;
@@ -250,8 +252,17 @@ TEST(amdsmitstReadOnly, TestMutualExclusion) {
RunCustomTestEpilog(&tst);
}
*/
// TODO: add TestComputePartitionReadWrite
// TODO: add TestMemoryPartitionReadWrite
TEST(amdsmitstReadWrite, TestComputePartitionReadWrite) {
TestComputePartitionReadWrite tst;
RunGenericTest(&tst);
}
TEST(amdsmitstReadWrite, TestMemoryPartitionReadWrite) {
TestMemoryPartitionReadWrite tst;
RunGenericTest(&tst);
}
TEST(amdsmitstReadWrite, TestEvtNotifReadWrite) {
TestEvtNotifReadWrite tst;
RunGenericTest(&tst);
+159 -1
View File
@@ -20,12 +20,14 @@
* THE SOFTWARE.
*/
#include <gtest/gtest.h>
#include <cassert>
#include <limits>
#include "amd_smi/amdsmi.h"
#include "amd_smi/impl/amd_smi_utils.h"
#include "test_base.h"
#include "test_common.h"
#include <gtest/gtest.h>
static const int kOutputLineLength = 80;
static const char kLabelDelimiter[] = "####";
@@ -136,8 +138,21 @@ void TestBase::SetUp(uint64_t init_flags) {
void TestBase::PrintDeviceHeader(amdsmi_processor_handle dv_ind) {
amdsmi_status_t err;
uint16_t val_ui16;
uint32_t val_ui32;
amdsmi_asic_info_t info;
err = smi_amdgpu_get_device_count(&val_ui32);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Total Devices: " << val_ui32 << std::endl;
}
err = smi_amdgpu_get_device_index(dv_ind, &val_ui32);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**AMD SMI Device index: " << val_ui32 << std::endl;
}
IF_VERB(STANDARD) {
std::cout << "\t**Device handle: " << dv_ind << std::endl;
}
@@ -168,6 +183,15 @@ void TestBase::PrintDeviceHeader(amdsmi_processor_handle dv_ind) {
}
}
amdsmi_asic_info_t asic_info;
err = amdsmi_get_gpu_asic_info(dv_ind, &asic_info);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
std::cout << "\t**Market name: " << asic_info.market_name << std::endl;
std::cout << "\t**ASIC serial: 0x" << std::hex << asic_info.asic_serial << std::endl;
std::cout << "\t**Target GFX Version: gfx" << asic_info.target_graphics_version << std::endl;
}
err = amdsmi_get_gpu_subsystem_id(dv_ind, &val_ui16);
CHK_ERR_ASRT(err)
IF_VERB(STANDARD) {
@@ -234,3 +258,137 @@ void TestBase::set_description(std::string d) {
}
}
TestBase::AcceleratorProfileConfig TestBase::getAvailableProfileConfigs(
uint32_t device_index,
amdsmi_accelerator_partition_profile_t current_profile,
amdsmi_accelerator_partition_profile_config_t config,
bool isVerbose) {
AcceleratorProfileConfig profile_config = {};
profile_config.number_of_profiles = config.num_profiles;
profile_config.original_profile_type = current_profile.profile_type;
profile_config.original_profile_index = current_profile.profile_index;
profile_config.original_profile_type_str =
partition_types_map.at(current_profile.profile_type);
profile_config.available_profiles = std::vector<amdsmi_accelerator_partition_type_t>(
config.num_profiles);
profile_config.available_profile_str = std::vector<std::string>(config.num_profiles);
profile_config.available_profile_indices = std::vector<uint32_t>(config.num_profiles);
for (uint32_t i = 0; i < config.num_profiles; i++) {
std::string profile_type_str = "N/A";
profile_config.available_profiles[i] = config.profiles[i].profile_type;
profile_config.available_profile_str[i].clear();
profile_config.available_profile_str[i] =
partition_types_map.at(config.profiles[i].profile_type);
profile_config.available_profile_indices[i] = config.profiles[i].profile_index;
}
if (isVerbose) {
const uint32_t kMAX_UINT32 = std::numeric_limits<uint32_t>::max();
std::cout << "\t**[Device #" << device_index << "] Profile Configs: ";
std::cout << "\n\t\t**Original Profile Index: "
<< (profile_config.original_profile_index == kMAX_UINT32 ?
"N/A" : std::to_string(profile_config.original_profile_index))
<< "\n\t\t**Original Profile Type: "
<< profile_config.original_profile_type_str
<< "\n\t\t**Original profile: " << profile_config.original_profile_type
<< " (" << accelerator_types_map.at(profile_config.original_profile_type) << ")"
<< "\n\t\t**Number of Profiles: " << profile_config.number_of_profiles
<< "\n\t\t**Available_profiles: ";
}
std::string available_profiles_str = "N/A\n";
for (uint32_t j = 0; j < profile_config.number_of_profiles; j++) {
if (available_profiles_str == "N/A\n") {
available_profiles_str.clear();
}
if (j + 1 >= profile_config.number_of_profiles) {
available_profiles_str += ("\n\t\t\tProfile[profile_index: "
+ std::to_string(profile_config.available_profile_indices[j])
+ "]: " + profile_config.available_profile_str[j] + "\n");
} else {
available_profiles_str += ("\n\t\t\tProfile[profile_index: "
+ std::to_string(profile_config.available_profile_indices[j])
+ "]: " + profile_config.available_profile_str[j] + ", ");
}
}
if (isVerbose) {
std::cout << available_profiles_str;
}
return profile_config;
}
void TestBase::waitForUserInput() {
for (;;) {
std::cout << "\n\t**Press any key to continue**" << std::endl;
int input = std::cin.get();
if (input == EOF) {
std::cout << "EOF detected. Exiting." << std::endl;
return;
}
char input_char = static_cast<char>(input);
std::cout << "User entered: " << input_char << std::endl;
if (input_char == '\n') {
return;
}
}
}
uint32_t TestBase::promptNumDevicesToTest(uint32_t current_num_devices) {
uint32_t return_value = 0;
std::cout << "**How many devices would you like to test? (0 to skip): ";
std::string devices_to_test = "";
do {
int input = std::cin.get();
if (input == EOF) {
std::cout << "EOF detected. Exiting." << std::endl;
return 0;
}
char input_char = static_cast<char>(input);
if (input_char == '\n') {
break;
}
if (input_char >= '0' && input_char <= '9') {
devices_to_test += input_char;
} else {
std::cout << "Invalid input. Please enter a number between 0 and "
<< current_num_devices << std::endl;
}
} while (true);
return_value = std::stoi(devices_to_test);
if (return_value > current_num_devices) {
std::cout << "Invalid input. Please enter a number between 0 and "
<< current_num_devices << std::endl;
return 0;
}
return return_value;
}
std::string TestBase::getResourceType(amdsmi_accelerator_partition_resource_type_t resource_type) {
std::string resource_type_str = "";
switch (resource_type) {
case AMDSMI_ACCELERATOR_XCC:
resource_type_str = "XCC";
break;
case AMDSMI_ACCELERATOR_ENCODER:
resource_type_str = "ENCODER";
break;
case AMDSMI_ACCELERATOR_DECODER:
resource_type_str = "DECODER";
break;
case AMDSMI_ACCELERATOR_DMA:
resource_type_str = "DMA";
break;
case AMDSMI_ACCELERATOR_JPEG:
resource_type_str = "JPEG";
break;
case AMDSMI_ACCELERATOR_MAX:
resource_type_str = "MAX";
break;
default:
resource_type_str = "N/A";
break;
}
return resource_type_str;
}
@@ -26,6 +26,7 @@
#include <cstdint>
#include <string>
#include <vector>
#include <map>
#include "amd_smi/amdsmi.h"
// The max devices can be monitored
@@ -98,6 +99,46 @@ class TestBase {
return num_iterations_;
}
const std::map<amdsmi_accelerator_partition_type_t, std::string> partition_types_map = {
{ AMDSMI_ACCELERATOR_PARTITION_INVALID, "N/A" },
{ AMDSMI_ACCELERATOR_PARTITION_SPX, "SPX" },
{ AMDSMI_ACCELERATOR_PARTITION_DPX, "DPX" },
{ AMDSMI_ACCELERATOR_PARTITION_TPX, "TPX" },
{ AMDSMI_ACCELERATOR_PARTITION_QPX, "QPX" },
{ AMDSMI_ACCELERATOR_PARTITION_CPX, "CPX" },
{ AMDSMI_ACCELERATOR_PARTITION_MAX, "MAX" },
};
const std::map<amdsmi_accelerator_partition_type_t, std::string> accelerator_types_map = {
{ AMDSMI_ACCELERATOR_PARTITION_INVALID, "AMDSMI_ACCELERATOR_PARTITION_INVALID" },
{ AMDSMI_ACCELERATOR_PARTITION_SPX, "AMDSMI_ACCELERATOR_PARTITION_SPX" },
{ AMDSMI_ACCELERATOR_PARTITION_DPX, "AMDSMI_ACCELERATOR_PARTITION_DPX" },
{ AMDSMI_ACCELERATOR_PARTITION_TPX, "AMDSMI_ACCELERATOR_PARTITION_TPX" },
{ AMDSMI_ACCELERATOR_PARTITION_QPX, "AMDSMI_ACCELERATOR_PARTITION_QPX" },
{ AMDSMI_ACCELERATOR_PARTITION_CPX, "AMDSMI_ACCELERATOR_PARTITION_CPX" },
{ AMDSMI_ACCELERATOR_PARTITION_MAX, "AMDSMI_ACCELERATOR_PARTITION_MAX" },
};
struct AcceleratorProfileConfig {
amdsmi_accelerator_partition_type_t original_profile_type;
std::string original_profile_type_str;
uint32_t original_profile_index;
uint32_t number_of_profiles;
std::vector<amdsmi_accelerator_partition_type_t> available_profiles;
std::vector<std::string> available_profile_str;
std::vector<uint32_t> available_profile_indices;
};
AcceleratorProfileConfig getAvailableProfileConfigs(uint32_t device_index,
amdsmi_accelerator_partition_profile_t current_profile,
amdsmi_accelerator_partition_profile_config_t config,
bool isVerbose);
void waitForUserInput();
uint32_t promptNumDevicesToTest(uint32_t current_num_devices);
std::string getResourceType(amdsmi_accelerator_partition_resource_type_t resource_type);
protected:
void MakeHeaderStr(const char *inStr, std::string *outStr) const;
void PrintDeviceHeader(amdsmi_processor_handle dv_ind);
@@ -121,6 +121,83 @@ class TestAmdSmiPythonInterface(unittest.TestCase):
print()
self.tearDown()
# amdsmi_get_vram_info should be supported on all ASICs
@handle_exceptions
def test_get_vram_info(self):
self.setUp()
processors = amdsmi.amdsmi_get_processor_handles()
self.assertGreaterEqual(len(processors), 1)
self.assertLessEqual(len(processors), 32)
for i in range(0, len(processors)):
bdf = amdsmi.amdsmi_get_gpu_device_bdf(processors[i])
print("\n\n###Test Processor {}, bdf: {}".format(i, bdf))
print("\n###Test amdsmi_get_gpu_vram_info \n")
vram_types = {
amdsmi.AmdSmiVramType.UNKNOWN: "UNKNOWN",
amdsmi.AmdSmiVramType.HBM: "HBM",
amdsmi.AmdSmiVramType.HBM2: "HBM2",
amdsmi.AmdSmiVramType.HBM2E: "HBM2E",
amdsmi.AmdSmiVramType.HBM3: "HBM3",
amdsmi.AmdSmiVramType.DDR2: "DDR2",
amdsmi.AmdSmiVramType.DDR3: "DDR3",
amdsmi.AmdSmiVramType.DDR4: "DDR4",
amdsmi.AmdSmiVramType.GDDR1: "GDDR1",
amdsmi.AmdSmiVramType.GDDR2: "GDDR2",
amdsmi.AmdSmiVramType.GDDR3: "GDDR3",
amdsmi.AmdSmiVramType.GDDR4: "GDDR4",
amdsmi.AmdSmiVramType.GDDR5: "GDDR5",
amdsmi.AmdSmiVramType.GDDR6: "GDDR6",
amdsmi.AmdSmiVramType.GDDR7: "GDDR7",
amdsmi.AmdSmiVramType.MAX: "MAX"
}
vram_vendors = {
amdsmi.AmdSmiVramVendor.SAMSUNG: "SAMSUNG",
amdsmi.AmdSmiVramVendor.INFINEON: "INFINEON",
amdsmi.AmdSmiVramVendor.ELPIDA: "ELPIDA",
amdsmi.AmdSmiVramVendor.ETRON: "ETRON",
amdsmi.AmdSmiVramVendor.NANYA: "NANYA",
amdsmi.AmdSmiVramVendor.HYNIX: "HYNIX",
amdsmi.AmdSmiVramVendor.MOSEL: "MOSEL",
amdsmi.AmdSmiVramVendor.WINBOND: "WINBOND",
amdsmi.AmdSmiVramVendor.ESMT: "ESMT",
amdsmi.AmdSmiVramVendor.MICRON: "MICRON",
amdsmi.AmdSmiVramVendor.UNKNOWN: "UNKNOWN"
}
vram_info = amdsmi.amdsmi_get_gpu_vram_info(processors[i])
print(" vram_info['vram_type'] is: {}".format(
vram_types[vram_info['vram_type']]))
print(" vram_info['vram_vendor'] is: {}".format(
vram_vendors[vram_info['vram_vendor']]))
print(" vram_info['vram_size'] is: {} MB".format(
vram_info['vram_size']))
print(" vram_info['vram_bit_width'] is: {}".format(
vram_info['vram_bit_width']))
print(" vram_info['vram_max_bandwidth'] is: {} GB/s".format(
vram_info['vram_max_bandwidth']))
print()
self.tearDown()
# amdsmi_get_gpu_xcd_counter should be supported on all ASICs
@handle_exceptions
def test_get_xcd_counter(self):
self.setUp()
processors = amdsmi.amdsmi_get_processor_handles()
self.assertGreaterEqual(len(processors), 1)
self.assertLessEqual(len(processors), 32)
for i in range(0, len(processors)):
bdf = amdsmi.amdsmi_get_gpu_device_bdf(processors[i])
print("\n\n###Test Processor {}, bdf: {}".format(i, bdf))
print("\n###Test amdsmi_get_gpu_xcd_counter \n")
xcd_count = amdsmi.amdsmi_get_gpu_xcd_counter(processors[i])
print(" xcd_counter['counter'] is: {}".format(
xcd_count))
print()
self.tearDown()
# amdsmi_get_gpu_bad_page_info is not supported in Navi2x, Navi3x
@handle_exceptions
def test_bad_page_info(self):
@@ -863,6 +940,44 @@ class TestAmdSmiPythonInterface(unittest.TestCase):
accelerator_partition = amdsmi.amdsmi_get_gpu_accelerator_partition_profile(processors[i])
print(" Current partition id: {}".format(
accelerator_partition['partition_id']))
print(" Profile_type: {}".format(
accelerator_partition['partition_profile']['profile_type']))
print(" profile_index: {}".format(
accelerator_partition['partition_profile']['profile_index']))
print(" memory_caps: {}".format(
accelerator_partition['partition_profile']['memory_caps']))
print(" num_resources: {}".format(
accelerator_partition['partition_profile']['num_resources']))
print()
self.tearDown()
# Requires sudo (to see full resource/config detail).
# Should only be supported on MI300+ ASICs
@handle_exceptions
def test_accelerator_partition_profile_config(self):
self.setUp()
processors = amdsmi.amdsmi_get_processor_handles()
self.assertGreaterEqual(len(processors), 1)
self.assertLessEqual(len(processors), 32)
for i in range(0, len(processors)):
bdf = amdsmi.amdsmi_get_gpu_device_bdf(processors[i])
print("\n\n###Test Processor {}, bdf: {}".format(i, bdf))
print("\n###Test amdsmi_get_gpu_accelerator_partition_profile_config \n")
profile_config = amdsmi.amdsmi_get_gpu_accelerator_partition_profile_config(processors[i])
print(" num_profiles: {}".format(profile_config['num_profiles']))
print(" num_resource_profiles: {}".format(profile_config['num_resource_profiles']))
print(" default_profile_index: {}".format(profile_config['default_profile_index']))
for p in profile_config['profiles']:
print("\t\t profile_type: {}".format(p['profile_type']))
print("\t\t num_partitions: {}".format(p['num_partitions']))
print("\t\t profile_index: {}".format(p['profile_index']))
print("\t\t num_resources: {}".format(p['num_resources']))
for r in range(0, p['num_resources']):
print("\t\t\t profile_index: {}".format(p['resources'][r]['profile_index']))
print("\t\t\t resource_type: {}".format(p['resources'][r]['resource_type']))
print("\t\t\t partition_resource: {}".format(p['resources'][r]['partition_resource']))
print("\t\t\t num_partitions_share_resource: {}".format(
p['resources'][r]['num_partitions_share_resource']))
print()
self.tearDown()