add dmabuf capability check

This commit is contained in:
Ruben Ortlam
2026-08-25 11:51:21 +02:00
parent 7d3f70332e
commit 76c4417827
+44 -12
View File
@@ -15720,14 +15720,41 @@ static void ggml_vk_bench_pair(
stg.free_resources();
}
// Check whether exporting dma-buf from one device and importing on
// another is supported for the given buffer usage flags.
auto check_dmabuf_caps = [](vk_device & exp_dev, vk::BufferUsageFlags exp_usage,
vk_device & imp_dev, vk::BufferUsageFlags imp_usage,
const char * label) -> bool {
vk::PhysicalDeviceExternalBufferInfo info{};
info.handleType = vk::ExternalMemoryHandleTypeFlagBits::eDmaBufEXT;
info.usage = exp_usage;
auto exp_caps = exp_dev->physical_device.getExternalBufferProperties(info);
if (!(exp_caps.externalMemoryProperties.externalMemoryFeatures & vk::ExternalMemoryFeatureFlagBits::eExportable)) {
std::cerr << " " << std::left << std::setw(24) << label << ": SKIPPED (export not supported)" << std::endl;
return false;
}
info.usage = imp_usage;
auto imp_caps = imp_dev->physical_device.getExternalBufferProperties(info);
if (!(imp_caps.externalMemoryProperties.externalMemoryFeatures & vk::ExternalMemoryFeatureFlagBits::eImportable)) {
std::cerr << " " << std::left << std::setw(24) << label << ": SKIPPED (import not supported)" << std::endl;
return false;
}
return true;
};
const auto transfer_src_dst = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst;
// =================================================================
// 6. DMA-BUF P2P: import source device memory directly on dest
// device via dma-buf fd — true zero-copy if PCIe P2P works.
// Setup (export/import) is outside the timing loop.
// =================================================================
if (dev0->external_memory_dma_buf && dev1->external_memory_dma_buf &&
!((dev0->vendor_id == VK_VENDOR_ID_NVIDIA) != (dev1->vendor_id == VK_VENDOR_ID_NVIDIA))) {
bool setup_ok = true;
if (dev0->external_memory_dma_buf && dev1->external_memory_dma_buf) {
bool setup_ok = check_dmabuf_caps(dev0, transfer_src_dst,
dev1, vk::BufferUsageFlagBits::eTransferSrc,
"dmabuf_p2p");
// Create exportable source buffer on dev0
vk::Buffer exp_buffer{};
@@ -15740,7 +15767,7 @@ static void ggml_vk_bench_pair(
exp_bci.usage = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst;
exp_bci.setPNext(&exp_ext_bci);
try {
if (setup_ok) try {
exp_buffer = dev0->device.createBuffer(exp_bci);
vk::MemoryRequirements exp_mem_req = dev0->device.getBufferMemoryRequirements(exp_buffer);
@@ -15894,7 +15921,9 @@ static void ggml_vk_bench_pair(
// import on both devices, two-hop GPU copy through shared GTT.
// =================================================================
if (dev0->external_memory_dma_buf && dev1->external_memory_dma_buf) {
bool setup_ok = true;
bool setup_ok = check_dmabuf_caps(dev0, transfer_src_dst,
dev1, transfer_src_dst,
"dmabuf_gtt");
vk::Buffer gtt_buffer{};
vk::DeviceMemory gtt_mem{};
@@ -15909,7 +15938,7 @@ static void ggml_vk_bench_pair(
bci.usage = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst;
bci.setPNext(&ext_bci);
try {
if (setup_ok) try {
gtt_buffer = dev0->device.createBuffer(bci);
vk::MemoryRequirements mem_req = dev0->device.getBufferMemoryRequirements(gtt_buffer);
@@ -16084,7 +16113,9 @@ static void ggml_vk_bench_pair(
// are importable but dev0's are not.
// =================================================================
if (dev0->external_memory_dma_buf && dev1->external_memory_dma_buf) {
bool setup_ok = true;
bool setup_ok = check_dmabuf_caps(dev1, transfer_src_dst,
dev0, transfer_src_dst,
"dmabuf_gtt_rev");
vk::Buffer gtt_buffer{};
vk::DeviceMemory gtt_mem{};
@@ -16099,7 +16130,7 @@ static void ggml_vk_bench_pair(
bci.usage = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst;
bci.setPNext(&ext_bci);
try {
if (setup_ok) try {
gtt_buffer = dev1->device.createBuffer(bci);
vk::MemoryRequirements mem_req = dev1->device.getBufferMemoryRequirements(gtt_buffer);
@@ -16271,9 +16302,10 @@ static void ggml_vk_bench_pair(
// 6d. DMA-BUF P2P (reversed): dest device exports VRAM, source
// device imports and writes into it via P2P.
// =================================================================
if (dev0->external_memory_dma_buf && dev1->external_memory_dma_buf &&
!((dev0->vendor_id == VK_VENDOR_ID_NVIDIA) != (dev1->vendor_id == VK_VENDOR_ID_NVIDIA))) {
bool setup_ok = true;
if (dev0->external_memory_dma_buf && dev1->external_memory_dma_buf) {
bool setup_ok = check_dmabuf_caps(dev1, transfer_src_dst,
dev0, vk::BufferUsageFlagBits::eTransferDst,
"dmabuf_p2p_rev");
// Create exportable VRAM buffer on dev1 (destination)
vk::Buffer exp_buffer{};
@@ -16286,7 +16318,7 @@ static void ggml_vk_bench_pair(
exp_bci.usage = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst;
exp_bci.setPNext(&exp_ext_bci);
try {
if (setup_ok) try {
exp_buffer = dev1->device.createBuffer(exp_bci);
vk::MemoryRequirements exp_mem_req = dev1->device.getBufferMemoryRequirements(exp_buffer);