Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
a6b82a7
llama : moe cache prompt path: copy all experts without the ids sync …
danielhanchen Oct 12, 2026
ae10ae3
ggml-backend : prefetch host weights on a copy queue in ggml_backend_…
danielhanchen Oct 12, 2026
40b5c8d
Merge branch 'moe-cache-prompt' into strata-combo
danielhanchen Oct 12, 2026
f2ee4b9
llama : fill prefetched MoE experts from the MoE cache on the copy queue
danielhanchen Oct 12, 2026
df4b95e
llama : moe cache: copy only runs of at least 4 MiB from the cache fo…
danielhanchen Oct 12, 2026
eb761c8
moe cache: look up the experts of small batches on the device
danielhanchen Oct 12, 2026
9773c1f
moe cache: keep device copies of the per-expert scales and biases
danielhanchen Oct 12, 2026
e345a2e
moe cache: device lookup per cache group, generic host mapping
danielhanchen Oct 12, 2026
7fe4763
Merge branch 'moe-cache-prompt' (4 MiB cache-run rule) into strata-combo
danielhanchen Oct 12, 2026
63ac2b9
llama : moe cache: count large ubatches and copy calls per ubatch (ca…
danielhanchen Oct 12, 2026
26bdf01
llama : moe cache: fill large-batch experts with one batched copy per…
danielhanchen Oct 12, 2026
ada4e66
Merge branch 'moe-cache-decode' into strata-combo2
danielhanchen Oct 12, 2026
521ca75
ggml-backend : sched prefetch: review fixes
danielhanchen Oct 12, 2026
79d53ac
moe cache: device lookup review fixes
danielhanchen Oct 12, 2026
8a257ed
Revert "ggml-backend : sched prefetch: review fixes"
danielhanchen Oct 12, 2026
416cd2d
ggml-backend : sched prefetch: never prefetch user inputs reached thr…
danielhanchen Oct 12, 2026
97af3d1
ggml-backend : sched prefetch: do not give staging slots to splits wi…
danielhanchen Oct 12, 2026
fc5c24c
ggml-backend : sched prefetch: retry the graph allocation without sta…
danielhanchen Oct 12, 2026
7557cc5
ggml-backend : sched prefetch: drain the copy queues when a computati…
danielhanchen Oct 12, 2026
2ffc775
ggml-backend : sched prefetch: honor copy and prefetch callbacks set …
danielhanchen Oct 12, 2026
c32f484
ggml-backend : sched prefetch: keep SYCL on the regular path, reset t…
danielhanchen Oct 12, 2026
31beb5c
ggml-backend : sched prefetch: size the staging arena for two consecu…
danielhanchen Oct 12, 2026
ff374cc
ggml-backend : upload host split inputs asynchronously, synchronize o…
danielhanchen Oct 12, 2026
a6e53c7
ggml-cuda : copy regions: device copies with a kernel, uploads in the…
danielhanchen Oct 12, 2026
e3982e4
ggml-backend, llama : sched prefetch: regular path copies only the ro…
danielhanchen Oct 12, 2026
90a34bc
ggml-cuda : copy regions: no device-copy kernel on a copy-only instance
danielhanchen Oct 12, 2026
3142161
llama : MoE cache: seed at the end of a prompt however the caller spl…
danielhanchen Oct 12, 2026
316a0fa
llama : MoE cache: seed only from experts staged for the seeding ubatch
danielhanchen Oct 13, 2026
1762594
ggml-cuda : copy regions: device-copy kernel on a copy-only instance …
danielhanchen Oct 13, 2026
95660d3
ggml-cuda : AGPL-3.0 license headers on the new copy-regions and moe-…
danielhanchen Oct 13, 2026
5f77918
Fix merge conflicts
danielhanchen Oct 13, 2026
e9e110a
ggml, llama : shorter comments for the host weight prefetch and the M…
danielhanchen Oct 13, 2026
fb2ebac
common : MoE cache: cap the free memory that disables mmap by the cgr…
danielhanchen Oct 13, 2026
f51db4d
ggml-cuda : copy regions: device-copy kernel on a copy-only instance …
danielhanchen Oct 13, 2026
efe0d04
ggml-rpc : reject GGML_OP_MOE_CACHE_LOOKUP, its op params hold proces…
danielhanchen Oct 13, 2026
7a07db5
common : MoE cache: keep mmap when no used device can do the device l…
danielhanchen Oct 13, 2026
8af17ae
common : MoE cache: keep mmap with -ngl 0
danielhanchen Oct 13, 2026
1b902e9
common : MoE cache: keep mmap unless a repeating layer is offloaded
danielhanchen Oct 13, 2026
76c345e
ggml-cuda : map host memory per target device
danielhanchen Oct 13, 2026
67edd5a
common : MoE cache: keep mmap when no expert can be placed in host me…
danielhanchen Oct 13, 2026
6e7668f
llama : MoE cache: keep the seed state per group
danielhanchen Oct 13, 2026
dd2570d
common : MoE cache: keep each comment sentence on one line
danielhanchen Oct 13, 2026
0dbd5f3
common : MoE cache: count only host overrides that match expert tenso…
danielhanchen Oct 13, 2026
ef8f414
common : MoE cache: decide the load mode after --fit has placed the e…
danielhanchen Oct 13, 2026
3954908
docs : add MOE_CACHE_LOOKUP to the ops support matrix
danielhanchen Oct 13, 2026
d5199e7
common : MoE cache: require a complete host expert set per layer, do …
danielhanchen Oct 13, 2026
6f86c50
common : MoE cache: only count host experts on layers that are offloa…
danielhanchen Oct 13, 2026
b3185a8
llama : MoE cache: release the host mappings of a group whose device …
danielhanchen Oct 13, 2026
60bbee5
common : MoE cache: drop mmap only when every device that gets layers…
danielhanchen Oct 13, 2026
0a1a7bf
llama : MoE cache: restore the experts evicted by a dropped seed
danielhanchen Oct 13, 2026
d210f90
common : MoE cache: treat a block count above 512 as unknown and boun…
danielhanchen Oct 14, 2026
72bee9a
common : MoE cache: check the expert tensor layout the GGUF actually has
danielhanchen Oct 14, 2026
04f8cae
ggml : free a larger staging arena when the graph allocator holds SYN…
danielhanchen Oct 14, 2026
b0bc690
common : MoE cache: read the expert layout from the other splits when…
danielhanchen Oct 14, 2026
ff2a0f8
llama : MoE cache: prepare the device slot maps before optimizer eval…
danielhanchen Oct 14, 2026
e1c1401
ggml : the meta backend does not support the MoE cache lookup
danielhanchen Oct 14, 2026
976424e
common : MoE cache: only check the expert tensors each layer of the G…
danielhanchen Oct 14, 2026
4d46477
llama : MoE cache: a dropped seed keeps the slots another layer took …
danielhanchen Oct 14, 2026
22a25c5
llama : MoE cache: trainable scales and biases are read from the mode…
danielhanchen Oct 14, 2026
14442c1
common : fit: give the MoE cache the memory left after the layers
danielhanchen Oct 14, 2026
12a5f87
sched, fit : gate the async input upload like the prefetch, whole MiB…
danielhanchen Oct 14, 2026
74ac7c6
ggml : sched: SYNC host weight copies reuse the staging arena
danielhanchen Oct 14, 2026
1c1ba19
llama : MoE cache: seed groups with fewer slots than layers, exact st…
danielhanchen Oct 14, 2026
117ec9b
llama : MoE cache: seed check skips evicted seeds, auto load mode cou…
danielhanchen Oct 14, 2026
5ea57fe
ggml-alloc : a failed reserve invalidates the tensor assignments
danielhanchen Oct 14, 2026
686c345
tests : test-alloc: allocate a graph after a reserve that failed to a…
danielhanchen Oct 14, 2026
4e834c2
llama : a memory measurement (--fit) does not count the host weight p…
danielhanchen Oct 15, 2026
a58a5df
ggml-backend : host split inputs of a meta backend are not uploaded a…
danielhanchen Oct 15, 2026
119295b
common : fit: shrink the MoE cache until every device meets its target
danielhanchen Oct 14, 2026
4ffd9b8
common : MoE cache load mode: an explicit --device none uses no devic…
danielhanchen Oct 15, 2026
f4ce181
llama : a memory measurement without the MoE cache prices weight copi…
danielhanchen Oct 15, 2026
87fa81f
llama : context: include <algorithm> for std::none_of (Windows HIP / …
danielhanchen Oct 15, 2026
e5e12c6
ggml : sched: check the prefetch headroom on every graph allocation, …
danielhanchen Oct 15, 2026
109d0d8
tests : test-alloc: set GGML_SCHED_PREFETCH with _putenv_s on Windows
danielhanchen Oct 15, 2026
a97a224
llama : MoE cache: copy memory-mapped experts that the device lookup …
danielhanchen Oct 15, 2026
87f5c3d
common : MoE cache: log the automatic load mode decision
danielhanchen Oct 15, 2026
6e14ff8
llama : MoE cache: check every cgroup limit before copying mapped exp…
danielhanchen Oct 15, 2026
807e747
llama : MoE cache: mlock'd page cache is not reclaimable when sizing …
danielhanchen Oct 15, 2026
ec08e0d
tests : test-alloc: get the CPU backend from the registry so GGML_BAC…
danielhanchen Oct 15, 2026
5206f10
llama : count the MoE cache's copies of memory-mapped experts in the …
danielhanchen Oct 15, 2026
95bebe6
ggml-virtgpu : reject MOE_CACHE_LOOKUP across the remoting boundary, …
danielhanchen Oct 15, 2026
28ac14d
common : MoE cache load mode: use the system memory estimate of the m…
danielhanchen Oct 16, 2026
c07406c
common : fit: MoE cache keeps the margins and the lowest priority
danielhanchen Oct 16, 2026
a5471af
sched : prefetch invalidation clears the async split count
danielhanchen Oct 16, 2026
aee25df
ggml-cuda : batched copies accept host memory pinned outside of ggml_…
danielhanchen Oct 16, 2026
d6be8c6
test-alloc : prefetch headroom: reserve a graph of another size befor…
danielhanchen Oct 16, 2026
faff888
common : fit: MoE cache handoff probe only for a single device
danielhanchen Oct 16, 2026
fd7489e
tests : link the MoE cache tests against llama only
danielhanchen Oct 16, 2026
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
312 changes: 310 additions & 2 deletions common/common.cpp

Large diffs are not rendered by default.

238 changes: 232 additions & 6 deletions common/fit.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Legend:
| LIGHTNING_INDEXER | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| LOG | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
| MEAN | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | 🟡 | ✅ | ❌ | ❌ | ❌ |
| MOE_CACHE_LOOKUP | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| MUL | ❌ | ✅ | ✅ | ✅ | 🟡 | 🟡 | 🟡 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| MUL_MAT | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 | 🟡 |
| MUL_MAT_HADAMARD | ❌ | ❌ | ✅ | ❌ | ✅ | 🟡 | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
Expand Down
1 change: 1 addition & 0 deletions docs/ops/CPU.csv
Original file line number Diff line number Diff line change
Expand Up @@ -11445,6 +11445,7 @@
"CPU","MUL_MAT_ID","type_a=iq4_xs,type_b=f32,n_mats=4,n_used=2,b=0,m=512,n=32,k=256,amax=1.000000,m_v=0","support","1","yes","CPU"
"CPU","MUL_MAT_ID","type_a=bf16,type_b=f32,n_mats=4,n_used=2,b=0,m=512,n=1,k=256,amax=1.000000,m_v=0","support","1","yes","CPU"
"CPU","MUL_MAT_ID","type_a=bf16,type_b=f32,n_mats=4,n_used=2,b=0,m=512,n=32,k=256,amax=1.000000,m_v=0","support","1","yes","CPU"
"CPU","MOE_CACHE_LOOKUP","n_expert=8,n_used=2,n_tokens=4,n_slots=8,n_banks=3","support","0","no","CPU"
"CPU","OUT_PROD","type_a=f32,type_b=f32,m=256,n=1,k=1,bs=[1,1],nr=[1,1],trans_b=0","support","1","yes","CPU"
"CPU","OUT_PROD","type_a=f32,type_b=f32,m=256,n=1,k=1,bs=[1,1],nr=[1,2],trans_b=0","support","1","yes","CPU"
"CPU","OUT_PROD","type_a=f32,type_b=f32,m=256,n=1,k=1,bs=[1,1],nr=[2,1],trans_b=0","support","1","yes","CPU"
Expand Down
1 change: 1 addition & 0 deletions docs/ops/CUDA.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7613,6 +7613,7 @@
"CUDA0","MUL_MAT_ID","type_a=iq4_xs,type_b=f32,n_mats=4,n_used=2,b=0,m=512,n=32,k=256","support","1","yes","CUDA"
"CUDA0","MUL_MAT_ID","type_a=bf16,type_b=f32,n_mats=4,n_used=2,b=0,m=512,n=1,k=256","support","1","yes","CUDA"
"CUDA0","MUL_MAT_ID","type_a=bf16,type_b=f32,n_mats=4,n_used=2,b=0,m=512,n=32,k=256","support","1","yes","CUDA"
"CUDA0","MOE_CACHE_LOOKUP","n_expert=8,n_used=2,n_tokens=4,n_slots=8,n_banks=3","support","1","yes","CUDA"
"CUDA0","OUT_PROD","type_a=f32,type_b=f32,m=256,n=1,k=1,bs=[1,1],nr=[1,1],trans_b=0","support","1","yes","CUDA"
"CUDA0","OUT_PROD","type_a=f32,type_b=f32,m=256,n=1,k=1,bs=[1,1],nr=[1,2],trans_b=0","support","1","yes","CUDA"
"CUDA0","OUT_PROD","type_a=f32,type_b=f32,m=256,n=1,k=1,bs=[1,1],nr=[2,1],trans_b=0","support","1","yes","CUDA"
Expand Down
32 changes: 32 additions & 0 deletions ggml/include/ggml-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ extern "C" {
// automatic fallback to sync copy if async is not supported
GGML_API void ggml_backend_tensor_copy_async(ggml_backend_t backend_src, ggml_backend_t backend_dst, const struct ggml_tensor * src, struct ggml_tensor * dst);

// a copy of `size` bytes from `src` at byte offset `src_offset` to `dst` at byte offset `dst_offset`
struct ggml_backend_copy_region {
const struct ggml_tensor * src;
size_t src_offset;
struct ggml_tensor * dst;
size_t dst_offset;
size_t size;
};

// queue the copies on `backend` as one batch in stream order, the copies of a batch may run in any order and must not overlap
// dst: device memory of the backend; src: device memory of the same device, or host memory it can read async (e.g. pinned)
// returns false (nothing copied) if the backend cannot batch them; with n_regions == 0, returns whether batched copies are supported
GGML_API bool ggml_backend_tensor_copy_regions_async(ggml_backend_t backend, const struct ggml_backend_copy_region * regions, size_t n_regions);

GGML_API ggml_backend_dev_t ggml_backend_get_device(ggml_backend_t backend);

//
Expand Down Expand Up @@ -334,6 +348,18 @@ extern "C" {
// `graph_size_changed` is true if the graph size changed since the last allocation
typedef void (*ggml_backend_sched_realloc_callback)(ggml_backend_sched_t sched, struct ggml_cgraph * graph, bool backend_ids_changed, bool graph_size_changed, void * user_data);

// How an input weight in a host buffer is copied to the backend of the split that uses it
enum ggml_backend_sched_prefetch_mode {
GGML_BACKEND_SCHED_PREFETCH_NONE = 0, // copied when the split starts, the copy is allocated by the graph allocator (no prefetch)
GGML_BACKEND_SCHED_PREFETCH_SYNC = 1, // copied when the split starts (the copy needs results of earlier splits), no weight of the split is prefetched, the copy uses a staging slot if the backend has an arena
GGML_BACKEND_SCHED_PREFETCH_ASYNC = 2, // copied into a staging slot on a separate copy queue, ahead of the split
};

// Callback selecting the prefetch mode of the host weight `src` (`dst` is its copy, `graph` the split graph), return NONE for host tensors that change during the graph computation
// ASYNC copies go through the copy callback with the copy queue backend (whole if it returns false) and may run before earlier splits, so they must not depend on graph results
// with a copy callback but no prefetch callback nothing is prefetched; env: GGML_SCHED_PREFETCH (0 = off), GGML_SCHED_PREFETCH_DEPTH
typedef enum ggml_backend_sched_prefetch_mode (*ggml_backend_sched_prefetch_callback)(const struct ggml_tensor * src, const struct ggml_tensor * dst, struct ggml_cgraph * graph, void * user_data);

// Initialize a backend scheduler, backends with low index are given priority over backends with high index
GGML_API ggml_backend_sched_t ggml_backend_sched_new(ggml_backend_t * backends, ggml_backend_buffer_type_t * bufts, int n_backends, size_t graph_size, bool parallel, bool op_offload);
GGML_API void ggml_backend_sched_free(ggml_backend_sched_t sched);
Expand All @@ -351,6 +377,9 @@ extern "C" {

GGML_API ggml_backend_buffer_type_t ggml_backend_sched_get_buffer_type(ggml_backend_sched_t sched, ggml_backend_t backend);
GGML_API size_t ggml_backend_sched_get_buffer_size(ggml_backend_sched_t sched, ggml_backend_t backend);
// a reserve that leaves less than `headroom` bytes free on a device with a staging arena drops the host weight prefetch (0 = never),
// default GGML_SCHED_PREFETCH_HEADROOM_MIB (512): for users whose memory measurement does not count the staging
GGML_API void ggml_backend_sched_set_prefetch_headroom(ggml_backend_sched_t sched, size_t headroom);

GGML_API void ggml_backend_sched_set_tensor_backend(ggml_backend_sched_t sched, struct ggml_tensor * node, ggml_backend_t backend);
GGML_API ggml_backend_t ggml_backend_sched_get_tensor_backend(ggml_backend_sched_t sched, struct ggml_tensor * node);
Expand Down Expand Up @@ -378,6 +407,9 @@ extern "C" {
// Set a callback to be called when the compute buffers of a graph are being reallocated
GGML_API void ggml_backend_sched_set_realloc_callback(ggml_backend_sched_t sched, ggml_backend_sched_realloc_callback callback, void * user_data);

// Set a callback that selects how the input weights in host buffers are prefetched
GGML_API void ggml_backend_sched_set_prefetch_callback(ggml_backend_sched_t sched, ggml_backend_sched_prefetch_callback callback, void * user_data);

//
// Meta backend
//
Expand Down
4 changes: 2 additions & 2 deletions ggml/include/ggml-rpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ extern "C" {

#define RPC_PROTO_MAJOR_VERSION 8
#define RPC_PROTO_MINOR_VERSION 0
#define RPC_PROTO_PATCH_VERSION 0
#define RPC_PROTO_PATCH_VERSION 1

#ifdef __cplusplus
static_assert(GGML_OP_COUNT == 101, "GGML_OP_COUNT has changed - update RPC_PROTO_PATCH_VERSION");
static_assert(GGML_OP_COUNT == 102, "GGML_OP_COUNT has changed - update RPC_PROTO_PATCH_VERSION");
#endif

#define GGML_RPC_MAX_SERVERS 16
Expand Down
20 changes: 20 additions & 0 deletions ggml/include/ggml.h
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,8 @@ extern "C" {

GGML_OP_GLU,

GGML_OP_MOE_CACHE_LOOKUP,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add backend-op coverage for the cache lookup

This adds a stateful GGML operator and a substantial CUDA kernel, but the commit adds no test-backend-ops case or CPU reference implementation against which its slot assignment, eviction, and copied expert data can be checked. As a result, backend consistency testing cannot exercise this operator, leaving correctness regressions in the new cache path undetected; add the required backend-op test coverage and reference behavior.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The op has no CPU implementation (the CPU backend reports it as unsupported, it is a device-side cache over host-mapped expert memory), so test-backend-ops has no reference to compare against, and a CPU port of the CLOCK assignment plus the stateful harness would be a sizeable addition on its own. Correctness is covered end to end instead: the decode gate shows KLD 0, 100% same top-1 and identical generated text (same md5) against the master cache path on both Qwen3.6 and Gemma 4, and LLAMA_MOE_CACHE_SEED_CHECK verifies the cached expert bytes against the host weights. A CPU reference and a test-backend-ops case are listed as a follow-up.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Document the new GGML operator

Adding GGML_OP_MOE_CACHE_LOOKUP without updating the generated operator-support documentation leaves docs/ops.md and every docs/ops/*.csv unaware of the operator, so the repository's advertised backend matrix omits this CUDA-only capability. Add the operator to the support-generation coverage and regenerate the operation documentation.

AGENTS.md reference: AGENTS.md:L91-L91

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3954908. test-backend-ops has no MOE_CACHE_LOOKUP case, so I added the support rows to docs/ops/CUDA.csv (supported) and docs/ops/CPU.csv (not supported) by hand in the format test-backend-ops emits, and regenerated docs/ops.md with scripts/create_ops_docs.py.


GGML_OP_COUNT,
};

Expand Down Expand Up @@ -1503,6 +1505,24 @@ extern "C" {
struct ggml_tensor * b,
struct ggml_tensor * ids);

// device-side lookup in a cache of MoE experts (see llama-moe-cache.cpp)
// ids: I32 [n_expert_used, n_tokens], the experts selected in layer il
// map: I32 [n_expert, n_layer], the slot of each expert of each layer, -1 if not cached (updated in place)
// state: I32 [8 + 3*n_slots], eviction state of the slots of the cache (updated in place)
// banks: the cached experts, [ne0, ne1, n_slots + 1] each (updated in place)
// host: device-accessible pointers to the experts of layer il in host memory, with the layout of the banks
// the missing experts get a slot (the least recently used one, approximated with a CLOCK) and are copied from host memory
// result: I32 [n_expert_used, n_tokens] slots of the selected experts, then the copied experts; ggml_view_2d(ctx, res, n_expert_used, n_tokens, res->nb[1], 0) gives the ids for ggml_mul_mat_id with a bank
GGML_API struct ggml_tensor * ggml_moe_cache_lookup(
struct ggml_context * ctx,
struct ggml_tensor * ids,
struct ggml_tensor * map,
struct ggml_tensor * state,
struct ggml_tensor ** banks,
const void ** host,
int n_banks,
int il);

// A: m columns, n rows,
// B: p columns, n rows,
// result is m columns, p rows
Expand Down
3 changes: 3 additions & 0 deletions ggml/src/ggml-alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,9 @@ static bool ggml_gallocr_reserve_n_impl(
galloc->buffers[i] = ggml_vbuffer_alloc(galloc->bufts[i], galloc->buf_tallocs[i], GGML_BACKEND_BUFFER_USAGE_COMPUTE);
if (galloc->buffers[i] == NULL) {
GGML_LOG_ERROR("%s: failed to allocate %s buffer of size %zu\n", __func__, ggml_backend_buft_name(galloc->bufts[i]), new_size);
// the assignments point into the freed buffer: the next ggml_gallocr_alloc_graph must reserve again instead of using them
galloc->n_nodes = 0;
galloc->n_leafs = 0;
return false;
}
}
Expand Down
4 changes: 4 additions & 0 deletions ggml/src/ggml-backend-meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ static ggml_backend_buffer_type_t ggml_backend_meta_device_get_host_buffer_type(

static bool ggml_backend_meta_device_supports_op(ggml_backend_dev_t dev, const ggml_tensor * op) {
GGML_ASSERT(ggml_backend_dev_is_meta(dev));
// the MoE cache lookup reads and writes per-device slot state through raw pointers, it has no split state
if (op->op == GGML_OP_MOE_CACHE_LOOKUP) {
return false;
}
const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context *) dev->context;
return std::all_of(meta_dev_ctx->simple_devs.begin(), meta_dev_ctx->simple_devs.end(),
[op](ggml_backend_dev_t simple_dev) { return ggml_backend_dev_supports_op(simple_dev, op); });
Expand Down
Loading