Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/gfx1100_w7900.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"device": {
"gpu_id": 7019,
"gfx_target_version": 110000,
"ip_versions": [
{"hardware_id": 11, "major": 11, "minor": 0, "revision": 0},
{"hardware_id": 42, "major": 6, "minor": 0, "revision": 0},
{"hardware_id": 108, "major": 4, "minor": 3, "revision": 0}
],
"vendor_id": 4098,
"device_id": 29768,
"family_id": 145,
Expand Down
7 changes: 6 additions & 1 deletion emulation/rocjitsu/configs/gfx1151.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"device": {
"gpu_id": 5510,
"gfx_target_version": 110501,
"ip_versions": [
{"hardware_id": 11, "major": 11, "minor": 5, "revision": 1},
{"hardware_id": 42, "major": 6, "minor": 1, "revision": 1},
{"hardware_id": 108, "major": 7, "minor": 11, "revision": 1}
],
"vendor_id": 4098,
"device_id": 5510,
"family_id": 145,
Expand Down Expand Up @@ -74,7 +79,7 @@
"type": "compute_unit",
"config": [
{ "key": "num_wf_slots", "value": "32" },
{ "key": "sgprs_per_wf", "value": "104" },
{ "key": "sgprs_per_wf", "value": "106" },
{ "key": "vgprs_per_wf", "value": "256" },
{ "key": "lds_size_kb", "value": "64" }
]
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/gfx1201_r9700.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"device": {
"gpu_id": 8716,
"gfx_target_version": 120001,
"ip_versions": [
{"hardware_id": 11, "major": 12, "minor": 0, "revision": 1},
{"hardware_id": 42, "major": 7, "minor": 0, "revision": 1},
{"hardware_id": 108, "major": 6, "minor": 3, "revision": 1}
],
"vendor_id": 4098,
"device_id": 30033,
"family_id": 152,
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/gfx942_cdna3.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"device": {
"gpu_id": 50148,
"gfx_target_version": 90402,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 4, "revision": 3},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 2},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 29856,
"family_id": 146,
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/gfx942_cdna3_kmd.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"device": {
"gpu_id": 50148,
"gfx_target_version": 90402,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 4, "revision": 3},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 2},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 29857,
"family_id": 146,
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/gfx950_mi355x.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
"device": {
"gpu_id": 38144,
"gfx_target_version": 90500,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 5, "revision": 0},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 5},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 30112,
"family_id": 160,
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/gfx950_mi355x_kmd.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
"device": {
"gpu_id": 38144,
"gfx_target_version": 90500,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 5, "revision": 0},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 5},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 30112,
"family_id": 160,
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/gfx950_mi355x_kmd_2gpu.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"device": {
"gpu_id": 38144,
"gfx_target_version": 90500,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 5, "revision": 0},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 5},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 30112,
"family_id": 160,
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/guest_gfx950_on_gfx1201.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
"guest_device": {
"gpu_id": 38144,
"gfx_target_version": 90500,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 5, "revision": 0},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 5},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 30112,
"family_id": 160,
Expand Down
5 changes: 5 additions & 0 deletions emulation/rocjitsu/configs/guest_gfx950_on_gfx942.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
"guest_device": {
"gpu_id": 38144,
"gfx_target_version": 90500,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 5, "revision": 0},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 5},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 30112,
"family_id": 160,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
"guest_device": {
"gpu_id": 38144,
"gfx_target_version": 90500,
"ip_versions": [
{"hardware_id": 11, "major": 9, "minor": 5, "revision": 0},
{"hardware_id": 42, "major": 4, "minor": 4, "revision": 5},
{"hardware_id": 108, "major": 7, "minor": 9, "revision": 0}
],
"vendor_id": 4098,
"device_id": 30112,
"family_id": 160,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "flatbuffers/idl.h"
#include "simulation_config_generated.h"

#include <algorithm>
#include <charconv>
#include <cstdint>
#include <fstream>
Expand Down Expand Up @@ -93,9 +94,8 @@ inline PciDeviceConfig pci_device_from_fb(const fb::PciDeviceInfo *pci) {

/// @brief Convert a FlatBuffers KFD identity table into the runtime config form.
///
/// @details This copies only scalar/string topology values. The resulting
/// config owns its marketing-name string so it is safe after the FlatBuffers
/// parser storage goes out of scope.
/// @details The resulting config owns its strings and IP versions so it is safe
/// after the FlatBuffers parser storage goes out of scope.
/// @param json_path JSON path of @p device, used in validation diagnostics.
inline KfdDeviceConfig kfd_device_from_fb(const fb::KfdDeviceInfo *device,
std::string_view json_path) {
Expand Down Expand Up @@ -170,6 +170,20 @@ inline KfdDeviceConfig kfd_device_from_fb(const fb::KfdDeviceInfo *device,
config.capability = device->capability();
config.capability2 = device->capability2();
config.debug_prop = device->debug_prop();
if (const auto *versions = device->ip_versions()) {
for (const auto *version : *versions) {
if (version->hardware_id() == 0 || version->major() == 0)
throw std::runtime_error(std::string(json_path) +
".ip_versions requires nonzero hardware_id and major");
if (std::ranges::any_of(config.ip_versions, [&](const DeviceIpVersion &existing) {
return existing.hardware_id == version->hardware_id();
}))
throw std::runtime_error(std::string(json_path) +
".ip_versions contains a duplicate hardware_id");
config.ip_versions.push_back(
{version->hardware_id(), version->major(), version->minor(), version->revision()});
}
}
return config;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,18 @@
#include <cstdint>
#include <optional>
#include <string>
#include <vector>

namespace rocjitsu::config {

/// @brief Hardware block version for device IP discovery.
struct DeviceIpVersion {
uint16_t hardware_id = 0;
uint8_t major = 0;
uint8_t minor = 0;
uint8_t revision = 0;
};

/// @brief Per-field topology values explicitly supplied by configuration.
struct KfdDiscoveryOverrides {
std::optional<uint32_t> max_waves_per_simd;
Expand Down Expand Up @@ -76,6 +85,7 @@ struct KfdDeviceConfig {
bool present = false; ///< True if device section existed in config.
uint32_t num_sdma_queues_per_engine = 0; ///< Regular SDMA queues per engine.
KfdDiscoveryOverrides discovery_overrides; ///< Explicit PCI discovery topology overrides.
std::vector<DeviceIpVersion> ip_versions; ///< Die-zero, instance-zero discovery versions.
};

} // namespace rocjitsu::config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2174,7 +2174,9 @@ void *SimulatedKfd::dispatch_mmap(KfdProcess &proc, void *addr, size_t length, i
alloc.gpu_va, reinterpret_cast<uintptr_t>(host_ptr), length, alloc.flags,
bool(flags & MAP_FIXED), alloc.user_va, alloc.memfd);
});
map_to_gpu(proc, alloc.gpu_va, host_ptr, length, pte_mtype_for_flags(alloc.flags));
// mmap and KFD BOs cover whole pages, including the last partial page.
const size_t mapped_bytes = std::min(alloc.size, (uint64_t(length) + 0xFFF) & ~uint64_t(0xFFF));
map_to_gpu(proc, alloc.gpu_va, host_ptr, mapped_bytes, pte_mtype_for_flags(alloc.flags));

return host_ptr;
}
Expand Down Expand Up @@ -2415,19 +2417,24 @@ int SimulatedKfd::unmap_memory_ioctl(void *arg) {

int SimulatedKfd::alloc_memory_ioctl(KfdProcess &proc, void *arg) {
auto *args = static_cast<kfd_ioctl_alloc_memory_of_gpu_args *>(arg);
if (args->size == 0 || args->size > UINT64_MAX - 0xFFF)
return -EINVAL;
// The kernel creates a PAGE_ALIGN(size) BO. LLVM can legally widen a scalar
// load within its mapped tail page even when the logical tensor is smaller.
const uint64_t allocation_size = (args->size + 0xFFF) & ~uint64_t(0xFFF);

std::lock_guard<std::mutex> lock(proc.alloc_mutex_);

bool user_provided_va = (args->va_addr != 0);
uint64_t va = args->va_addr;
if (va == 0) {
va = proc.next_gpu_va_;
proc.next_gpu_va_ += (args->size + 0xFFF) & ~0xFFFULL;
proc.next_gpu_va_ += allocation_size;
}

KfdProcess::GpuAllocation alloc{};
alloc.gpu_va = va;
alloc.size = args->size;
alloc.size = allocation_size;
alloc.flags = args->flags;
alloc.handle = proc.next_handle_++;
alloc.host_ptr = nullptr;
Expand All @@ -2439,7 +2446,7 @@ int SimulatedKfd::alloc_memory_ioctl(KfdProcess &proc, void *arg) {
bool is_doorbell = (args->flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) != 0;
if (is_userptr && !daemon_mode_) {
alloc.host_ptr = reinterpret_cast<void *>(va);
map_to_gpu(proc, va, reinterpret_cast<void *>(va), args->size, alloc_mtype);
map_to_gpu(proc, va, reinterpret_cast<void *>(va), alloc.size, alloc_mtype);
} else if (daemon_mode_ || !user_provided_va) {
auto raw_fd = memfd_create("rocjitsu_alloc", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (raw_fd >= 0) {
Expand Down Expand Up @@ -2823,10 +2830,9 @@ int SimulatedKfd::create_queue_ioctl(KfdProcess &proc, void *arg) {
: is_pm4_compute ? amdgpu::QueuePacketFormat::Pm4
: amdgpu::QueuePacketFormat::Aql;
queue_request.abi = is_aql_compute ? amdgpu::QueueAbi::KfdAql : amdgpu::QueueAbi::Generic;
// Queue creation initializes both SDMA pointers to zero below. Preserve that
// device-side cursor explicitly so execution does not depend on reading the
// writeback destination before the first packet can retire.
if (is_sdma)
// Fresh SDMA and native PM4 MQDs start at zero; the writeback destination
// need not contain the initial hardware cursor before the first retirement.
if (is_sdma || is_pm4_compute)
queue_request.initial_consumer_cursor = 0;
// The topology advertises every XCD's compute units as one agent, so a
// compute dispatch must be able to reach all of them. Without this a
Expand All @@ -2842,7 +2848,7 @@ int SimulatedKfd::create_queue_ioctl(KfdProcess &proc, void *arg) {
if (is_aql_compute)
queue_request.queue_descriptor_address =
args->write_pointer_address - offsetof(amd_queue_t, write_dispatch_id);
if (!is_sdma && args->ctx_save_restore_address != 0) {
if (is_aql_compute && args->ctx_save_restore_address != 0) {
constexpr uint32_t kErrorReasonOffset = 6 * sizeof(uint32_t);
const std::optional<amdgpu::GpuVmAccess> access =
gpu->soc->gpu_vm().snapshot(gs.address_space);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,14 @@ void Sysfs::write_drm_tree(const std::vector<GpuInfo> &gpus) {
write_file(device_dir + "/revision", revision_hex.str());
write_file(device_dir + "/subsystem_vendor", vendor_hex.str());
write_file(device_dir + "/subsystem_device", device_hex.str());
for (const auto &block : gpu.ip_versions) {
std::string instance_dir =
device_dir + "/ip_discovery/die/0/" + std::to_string(block.hardware_id) + "/0";
make_dir(instance_dir);
write_file(instance_dir + "/major", std::to_string(block.major) + "\n");
write_file(instance_dir + "/minor", std::to_string(block.minor) + "\n");
write_file(instance_dir + "/revision", std::to_string(block.revision) + "\n");
}
}
}

Expand Down Expand Up @@ -546,6 +554,7 @@ Sysfs::GpuInfo gpu_info_from_config(const config::KfdDeviceConfig &dev, uint32_t
gpu.debug_prop = dev.debug_prop;
gpu.drm_render_minor = dev.drm_render_minor;
gpu.marketing_name = dev.marketing_name;
gpu.ip_versions = dev.ip_versions;
gpu.revision_id = dev.revision_id;
gpu.pci_revision_id = dev.pci_revision_id;
gpu.simd_count = dev.simd_count;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Sysfs {
uint32_t revision_id = 0;
uint32_t pci_revision_id = 0;
std::string marketing_name;
std::vector<config::DeviceIpVersion> ip_versions;

// Compute unit organization
uint32_t simd_count = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ RJ_DIAGNOSTIC_IGNORE_PEDANTIC
#include "hsa/amd_ext_aql_packet.h"
RJ_DIAGNOSTIC_POP

#include <array>
#include <bit>
#include <cstring>
#include <limits>
Expand Down Expand Up @@ -228,10 +229,19 @@ AqlPacketProcessor::process_vendor(const Request &request,
}

if (extension.amd_format == kAmdAqlFormatPm4Ib) {
return admit(request, {.kind = AqlPreparedPacketKind::NonKernel,
// ROCr's amd_aql_pm4_ib: four-word INDIRECT_BUFFER, ten remaining words,
// eight reserved words, then the completion signal. Copy before ring retirement.
std::array<uint32_t, 16> words{};
std::memcpy(words.data(), &packet, sizeof(packet));
if (words[1] != 0xc0023f00 || (words[2] & 3) || words[3] > 0xffff ||
(words[4] & ~0x000fffffu) != (1u << 23) || !(words[4] & 0xfffff) || words[5] != 10)
return terminal(PacketProcessStatus::Malformed, AqlPacketDiagnostic::MalformedPm4Ib);
return admit(request, {.kind = AqlPreparedPacketKind::Pm4Ib,
.pm4_ib_address = uint64_t{words[2]} | (uint64_t{words[3]} << 32),
.pm4_ib_dwords = words[4] & 0xfffff,
.completion_signal = extension.completion_signal.handle,
.barrier_bit = ((packet.header >> HSA_PACKET_HEADER_BARRIER) & 1) != 0,
.blocks_following = false});
.blocks_following = true});
}

return terminal(PacketProcessStatus::Unsupported, AqlPacketDiagnostic::UnsupportedVendorFormat);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ enum class AqlPacketDiagnostic : uint8_t {
InvalidSignalAddress,
MissingSignalReader,
MissingAdmissionCallback,
MalformedPm4Ib,
};

enum class AqlPreparedPacketKind : uint8_t {
KernelDispatch,
NonKernel,
Pm4Ib,
};

/// @brief Outcome of attempting to commit a decoded AQL action to its CP queue.
Expand All @@ -74,6 +76,8 @@ struct AqlPreparedPacket {
AqlPreparedPacketKind kind = AqlPreparedPacketKind::NonKernel;
hsa_kernel_dispatch_packet_t kernel_dispatch{};
ClusterDispatchShape cluster_shape{};
uint64_t pm4_ib_address = 0;
uint32_t pm4_ib_dwords = 0;
uint64_t completion_signal = 0;
bool barrier_bit = false;
bool blocks_following = false;
Expand Down
Loading
Loading