mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-11 04:56:56 +02:00
add dmabuf capability check
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user