[SWDEV-498711] RDC Partition Implementation (#119)

* [SWDEV-498711] RDC Partition Implementation

Change-Id: Ibfc3709793770537e4c9d36458f34c6b4f461724
Signed-off-by: adapryor <Adam.pryor@amd.com>

[ROCm/rdc commit: 47692d3ed5]
Cette révision appartient à :
Pryor, Adam
2025-03-27 14:10:11 -05:00
révisé par GitHub
Parent 791fa376e9
révision fe868f6763
29 fichiers modifiés avec 1503 ajouts et 358 suppressions
+173 -16
Voir le fichier
@@ -24,6 +24,10 @@ THE SOFTWARE.
#include <getopt.h>
#include <unistd.h>
#include <cstring>
#include <iomanip>
#include <set>
#include "rdc/rdc.h"
#include "rdc/rdc_private.h"
#include "rdc_lib/RdcException.h"
@@ -33,22 +37,23 @@ namespace amd {
namespace rdc {
RdciDiscoverySubSystem::RdciDiscoverySubSystem()
: show_help_(false),
is_list_(false),
show_version_(false) {}
: show_help_(false), is_list_(false), is_partition_(false), show_version_(false) {}
void RdciDiscoverySubSystem::parse_cmd_opts(int argc, char** argv) {
const int HOST_OPTIONS = 1000;
const int JSON_OPTIONS = 1001;
const struct option long_options[] = {
{"host", required_argument, nullptr, HOST_OPTIONS}, {"help", optional_argument, nullptr, 'h'},
{"unauth", optional_argument, nullptr, 'u'}, {"list", optional_argument, nullptr, 'l'},
{"json", optional_argument, nullptr, JSON_OPTIONS}, {"version", optional_argument, nullptr, 'v'}, {nullptr, 0, nullptr, 0}};
const struct option long_options[] = {{"host", required_argument, nullptr, HOST_OPTIONS},
{"help", optional_argument, nullptr, 'h'},
{"unauth", optional_argument, nullptr, 'u'},
{"list", optional_argument, nullptr, 'l'},
{"json", optional_argument, nullptr, JSON_OPTIONS},
{"version", optional_argument, nullptr, 'v'},
{nullptr, 0, nullptr, 0}};
int option_index = 0;
int opt = 0;
while ((opt = getopt_long(argc, argv, "hluv", long_options, &option_index)) != -1) {
while ((opt = getopt_long(argc, argv, "hliuv", long_options, &option_index)) != -1) {
switch (opt) {
case HOST_OPTIONS:
ip_port_ = optarg;
@@ -65,6 +70,9 @@ void RdciDiscoverySubSystem::parse_cmd_opts(int argc, char** argv) {
case 'l':
is_list_ = true;
break;
case 'i':
is_partition_ = true;
break;
case 'v':
show_version_ = true;
break;
@@ -74,9 +82,10 @@ void RdciDiscoverySubSystem::parse_cmd_opts(int argc, char** argv) {
}
}
if ((!is_list_ && !show_version_) || (is_list_ && show_version_)) {
int opCount = (is_list_ ? 1 : 0) + (is_partition_ ? 1 : 0) + (show_version_ ? 1 : 0);
if (opCount != 1) {
show_help();
throw RdcException(RDC_ST_BAD_PARAMETER, "Need to specify operations");
throw RdcException(RDC_ST_BAD_PARAMETER, "Need to specify exactly one operation");
}
}
@@ -93,6 +102,8 @@ void RdciDiscoverySubSystem::show_help() const {
<< "Output using json.\n";
std::cout << " -l --list list GPU discovered"
<< " on the system\n";
std::cout << " -i --gpu-instance list GPU discovered"
<< " on the system with partitions\n";
std::cout << " -v --version Display version information of the"
<< " the server and libraries used by the server\n";
}
@@ -108,7 +119,7 @@ void RdciDiscoverySubSystem::show_attributes() {
if (is_json_output()) {
std::cout << "\"gpus\" : [], \"status\": \"ok\"";
} else {
std::cout << "No GPUs find on the system\n";
std::cout << "No GPUs found on the system\n";
}
return;
}
@@ -145,6 +156,145 @@ void RdciDiscoverySubSystem::show_attributes() {
}
}
void RdciDiscoverySubSystem::show_attributes_with_partitions() {
uint32_t gpu_index_list[RDC_MAX_NUM_DEVICES];
uint32_t count = 0;
rdc_status_t result = rdc_device_get_all(rdc_handle_, gpu_index_list, &count);
if (result != RDC_ST_OK) {
throw RdcException(result, "Fail to get all devices");
}
if (count == 0) {
if (is_json_output())
std::cout << "\"gpus\" : [], \"status\": \"ok\"";
else
std::cout << "No GPUs found on the system\n";
return;
}
// Print header.
if (!is_json_output()) {
std::cout << count << " GPUs found." << std::endl;
std::cout << "---------------------------------------------------------------------"
<< std::endl;
std::cout << std::setw(12) << std::left << "GPU Index" << std::setw(20) << "Instance Index"
<< std::setw(25) << "Device Information" << std::setw(8) << "XCC" << std::setw(8)
<< "DECODER" << std::endl;
} else {
std::cout << "\"gpus\" : [";
}
// Loop over each GPU.
for (uint32_t i = 0; i < count; i++) {
rdc_device_attributes_t attribute;
result = rdc_device_get_attributes(rdc_handle_, gpu_index_list[i], &attribute);
if (result != RDC_ST_OK) return;
// Build physical device entity info.
rdc_entity_info_t phys_info;
phys_info.device_index = i;
phys_info.instance_index = 0;
phys_info.entity_role = RDC_DEVICE_ROLE_PHYSICAL;
phys_info.device_type = RDC_DEVICE_TYPE_GPU;
uint32_t phys_entity_index = rdc_get_entity_index_from_info(phys_info);
rdc_resource_profile_t phys_xcc = {};
rdc_resource_profile_t phys_decoder_profile = {};
result =
rdc_instance_profile_get(rdc_handle_, phys_entity_index, RDC_ACCELERATOR_XCC, &phys_xcc);
result = rdc_instance_profile_get(rdc_handle_, phys_entity_index, RDC_ACCELERATOR_DECODER,
&phys_decoder_profile);
std::string phys_xcc_str = std::to_string(phys_xcc.partition_resource);
std::string phys_decoder_str = std::to_string(phys_decoder_profile.partition_resource);
if (!is_json_output()) {
std::cout << std::setw(12) << std::left << i << std::setw(20) << "" << std::setw(25)
<< attribute.device_name << std::setw(8) << phys_xcc_str << std::setw(8)
<< phys_decoder_str << std::endl;
} else {
std::cout << "{\"gpu_index\": \"" << i << "\", "
<< "\"device_name\": \"" << attribute.device_name << "\", "
<< "\"physical\": {"
<< "\"xcc\": \"" << phys_xcc_str << "\", "
<< "\"decoder\": \"" << phys_decoder_str << "\" "
<< "}";
}
uint16_t num_partition = 0;
rdc_status_t result = rdc_get_num_partition(rdc_handle_, i, &num_partition);
if (result != RDC_ST_OK) {
return;
}
// A partitionable device not in partitionable mode will have metrics.num_partition=1
// Where as, a non-partitionable device will have metrics.num_partition = UINT16_MAX
if (num_partition != UINT16_MAX && num_partition > 1) {
if (is_json_output()) {
std::cout << ", \"partitions\": [";
}
for (uint32_t pid = 0; pid < num_partition; pid++) {
std::string instance_str = "g" + std::to_string(i) + "." + std::to_string(pid);
rdc_entity_info_t part_info;
part_info.device_index = i;
part_info.instance_index = pid;
part_info.entity_role = RDC_DEVICE_ROLE_PARTITION_INSTANCE;
part_info.device_type = RDC_DEVICE_TYPE_GPU;
uint32_t part_entity_index = rdc_get_entity_index_from_info(part_info);
rdc_resource_profile_t part_xcc = {};
rdc_resource_profile_t part_decoder = {};
result = rdc_instance_profile_get(rdc_handle_, part_entity_index, RDC_ACCELERATOR_XCC,
&part_xcc);
result = rdc_instance_profile_get(rdc_handle_, part_entity_index, RDC_ACCELERATOR_DECODER,
&part_decoder);
std::string part_decoder_str = std::to_string(part_decoder.partition_resource);
std::string part_xcc_str = std::to_string(part_xcc.partition_resource);
std::string starColumn = " ";
if (part_decoder.num_partitions_share_resource > 1) {
starColumn = "*";
}
if (!is_json_output()) {
std::cout << std::setw(12) << "" << std::setw(20) << instance_str << std::setw(25) << ""
<< std::setw(7) << part_xcc_str << std::setw(1) << starColumn << std::setw(8)
<< part_decoder_str << std::endl;
} else {
std::string decoder_shared =
(part_decoder.num_partitions_share_resource > 1) ? "true" : "false";
std::cout << "{\"instance_index\": \"" << instance_str << "\", "
<< "\"xcc\": \"" << part_xcc_str << "\", "
<< "\"decoder\": \"" << part_decoder_str << "\", "
<< "\"decoder_shared\": " << decoder_shared << "}";
if (pid != num_partition - 1) {
std::cout << ",";
} else {
std::cout << "]";
}
}
}
}
if (is_json_output()) {
if (i != count - 1)
std::cout << "},";
else
std::cout << "}";
}
}
if (!is_json_output()) {
std::cout << "---------------------------------------------------------------------"
<< std::endl;
std::cout << "* if the resource is shared" << std::endl;
} else {
std::cout << ']';
}
}
void RdciDiscoverySubSystem::show_version() {
rdc_component_version_t smiv;
rdc_status_t result = rdc_device_get_component_version(rdc_handle_, RDC_AMDMSI_COMPONENT, &smiv);
@@ -155,18 +305,21 @@ void RdciDiscoverySubSystem::show_version() {
mixed_component_version_t rdcdv;
uint32_t ret = get_mixed_component_version(rdc_handle_, RDCD_COMPONENT, &rdcdv);
if (ret) {
std::cout << "get rdcd version fail"<< std::endl;
std::cout << "get rdcd version fail" << std::endl;
return;
}
if (is_json_output()) {
if (is_json_output()) {
std::cout << "\"version\" : ";
std::cout << '{';
std::cout << "\"rdcd\": " << "\"" << rdcdv.version << "\", ";
std::cout << "\"amdsmi_lib\": " << "\"" << smiv.version << "\"";
std::cout << "\"rdcd\": "
<< "\"" << rdcdv.version << "\", ";
std::cout << "\"amdsmi_lib\": "
<< "\"" << smiv.version << "\"";
std::cout << '}';
} else {
std::cout << "RDCD : " << rdcdv.version << " | " << "AMDSMI Library : " << smiv.version << std::endl;
std::cout << "RDCD : " << rdcdv.version << " | "
<< "AMDSMI Library : " << smiv.version << std::endl;
}
return;
@@ -181,6 +334,10 @@ void RdciDiscoverySubSystem::process() {
return show_attributes();
}
if (is_partition_) {
return show_attributes_with_partitions();
}
if (show_version_) {
return show_version();
}