|
1 | 1 | #include "llama-model-loader.h" |
2 | 2 | #include "llama-io-uring.h" |
3 | 3 |
|
| 4 | +#if defined(GGML_USE_CUDA) && defined(__HIP_PLATFORM_AMD__) |
| 5 | +#include <hip/hip_runtime.h> |
| 6 | +#endif |
| 7 | + |
4 | 8 | #include "ggml-alloc.h" |
5 | 9 | #include "ggml.h" |
6 | 10 | #include "gguf.h" |
@@ -1434,6 +1438,9 @@ bool llama_model_loader::load_all_data( |
1434 | 1438 | std::vector<ggml_backend_buffer_t> host_buffers; |
1435 | 1439 | std::vector<ggml_backend_event_t> events; |
1436 | 1440 | 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 |
1437 | 1444 | size_t buffer_idx = 0; // buffer to use for async loads |
1438 | 1445 |
|
1439 | 1446 | #ifdef LLAMA_HAVE_IO_URING |
@@ -1482,8 +1489,36 @@ bool llama_model_loader::load_all_data( |
1482 | 1489 | return nullptr; |
1483 | 1490 | } |
1484 | 1491 |
|
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); |
1486 | 1497 | 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 |
1487 | 1522 | auto * buf = ggml_backend_buft_alloc_buffer(host_buft, buffer_size); |
1488 | 1523 |
|
1489 | 1524 | if (!buf) { |
@@ -1682,6 +1717,11 @@ bool llama_model_loader::load_all_data( |
1682 | 1717 | ggml_backend_event_synchronize(event); |
1683 | 1718 | ggml_backend_event_free(event); |
1684 | 1719 | } |
| 1720 | +#if defined(GGML_USE_CUDA) && defined(__HIP_PLATFORM_AMD__) |
| 1721 | + for (auto * ptr : sam_ptrs) { |
| 1722 | + hipFree(ptr); |
| 1723 | + } |
| 1724 | +#endif |
1685 | 1725 | for (auto * buf : host_buffers) { |
1686 | 1726 | ggml_backend_buffer_free(buf); |
1687 | 1727 | } |
|
0 commit comments