Skip to content

Commit 24352d3

Browse files
committed
model-loader: NVMe->VRAM direct via SAM fine-grained staging on ROCm
With --direct-io on ROCm+SAM, allocate staging buffers using hipExtMallocWithFlags(hipDeviceMallocFinegrained) instead of hipHostMalloc. Fine-grained VRAM is CPU-accessible via BAR1, so io_uring writes land directly in VRAM over PCIe without touching system RAM. Falls back to pinned host memory if hipExtMallocWithFlags fails.
1 parent 36713ec commit 24352d3

1 file changed

Lines changed: 41 additions & 1 deletion

File tree

src/llama-model-loader.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#include "llama-model-loader.h"
22
#include "llama-io-uring.h"
33

4+
#if defined(GGML_USE_CUDA) && defined(__HIP_PLATFORM_AMD__)
5+
#include <hip/hip_runtime.h>
6+
#endif
7+
48
#include "ggml-alloc.h"
59
#include "ggml.h"
610
#include "gguf.h"
@@ -1434,6 +1438,9 @@ bool llama_model_loader::load_all_data(
14341438
std::vector<ggml_backend_buffer_t> host_buffers;
14351439
std::vector<ggml_backend_event_t> events;
14361440
std::vector<void *> host_ptrs;
1441+
#if defined(GGML_USE_CUDA) && defined(__HIP_PLATFORM_AMD__)
1442+
std::vector<void *> sam_ptrs; // fine-grained VRAM staging for SAM direct path
1443+
#endif
14371444
size_t buffer_idx = 0; // buffer to use for async loads
14381445

14391446
#ifdef LLAMA_HAVE_IO_URING
@@ -1482,8 +1489,36 @@ bool llama_model_loader::load_all_data(
14821489
return nullptr;
14831490
}
14841491

1485-
// If the backend is supported, create pinned memory buffers and events for synchronisation.
1492+
// If the backend is supported, create staging buffers and events for synchronisation.
1493+
// With --direct-io on ROCm+SAM: allocate fine-grained VRAM so io_uring writes go
1494+
// NVMe -> BAR1 -> VRAM directly, bypassing CPU RAM entirely.
1495+
const bool use_sam_staging = use_direct_io &&
1496+
(strncmp(ggml_backend_dev_name(dev), "ROCm", 4) == 0);
14861497
for (size_t idx = 0; idx < n_buffers; ++idx) {
1498+
#if defined(GGML_USE_CUDA) && defined(__HIP_PLATFORM_AMD__)
1499+
if (use_sam_staging) {
1500+
void * sam_ptr = nullptr;
1501+
hipError_t herr = hipExtMallocWithFlags(&sam_ptr, buffer_size, hipDeviceMallocFinegrained);
1502+
if (herr != hipSuccess || !sam_ptr) {
1503+
LLAMA_LOG_WARN("%s: hipExtMallocWithFlags failed (%s), falling back to pinned host\n",
1504+
func, hipGetErrorString(herr));
1505+
// fall through to normal host alloc below
1506+
} else {
1507+
sam_ptrs.emplace_back(sam_ptr);
1508+
host_ptrs.emplace_back(sam_ptr);
1509+
auto * event = ggml_backend_event_new(dev);
1510+
if (!event) {
1511+
LLAMA_LOG_DEBUG("%s: failed to create event for SAM staging\n", func);
1512+
hipFree(sam_ptr);
1513+
sam_ptrs.pop_back();
1514+
host_ptrs.pop_back();
1515+
return nullptr;
1516+
}
1517+
events.emplace_back(event);
1518+
continue;
1519+
}
1520+
}
1521+
#endif
14871522
auto * buf = ggml_backend_buft_alloc_buffer(host_buft, buffer_size);
14881523

14891524
if (!buf) {
@@ -1682,6 +1717,11 @@ bool llama_model_loader::load_all_data(
16821717
ggml_backend_event_synchronize(event);
16831718
ggml_backend_event_free(event);
16841719
}
1720+
#if defined(GGML_USE_CUDA) && defined(__HIP_PLATFORM_AMD__)
1721+
for (auto * ptr : sam_ptrs) {
1722+
hipFree(ptr);
1723+
}
1724+
#endif
16851725
for (auto * buf : host_buffers) {
16861726
ggml_backend_buffer_free(buf);
16871727
}

0 commit comments

Comments
 (0)