Skip to content

llama-graph: fix UB warning from cross-attn mask loop indices - #18528

Open
nabbi wants to merge 1 commit into
ggml-org:masterfrom
nabbi:aggressive-loop-optimizations
Open

llama-graph: fix UB warning from cross-attn mask loop indices#18528
nabbi wants to merge 1 commit into
ggml-org:masterfrom
nabbi:aggressive-loop-optimizations

Conversation

@nabbi

@nabbi nabbi commented Jan 1, 2026

Copy link
Copy Markdown

I observed this behavior when building ollama on Gentoo.
Confirmed llm_graph_input_attn_cross::set_input functions are aligned between these two projects so submitting the PR here.

GCC emits the following warning when building with optimizations:

llama-graph.cpp:473:9: warning: iteration 2147483645 invokes undefined
behavior [-Waggressive-loop-optimizations]

The warning is caused by using int loop induction variables against int64_t bounds (n_tokens, n_enc), which allows signed overflow in the induction variable and enables undefined behavior.

This change widens the loop counters to int64_t to match the bounds and removes an unreachable loop of the form:

for (i = n_tokens; i < n_tokens; ++i)

which could never execute.

Thank you

@nabbi
nabbi requested a review from CISC as a code owner January 1, 2026 21:09
@CISC

CISC commented Jan 1, 2026

Copy link
Copy Markdown
Member

It's not quite that simple, n_tokens is actually limited to uint32_t, and you made some other odd changes here, any particular reason? Nvm, didn't read OP closely enough.

@CISC CISC left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So, why not fix the others, like f.ex. llm_graph_input_mem_hybrid::set_input with the same issue?

Comment thread src/llama-graph.cpp Outdated
for (int h = 0; h < 1; ++h) {
for (int i = 0; i < n_tokens; ++i) {
for (int j = 0; j < n_enc; ++j) {
for (int64_t h = 0; h < 1; ++h) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
for (int64_t h = 0; h < 1; ++h) {
for (int h = 0; h < 1; ++h) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I find this a very strange "loop" BTW. :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

right :) it runs once

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

right :) it runs once

The value is also used for multiplication, so I'm guessing the loop is kept for historical reasons.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It emphasizes that we construct the mask for a single attention head - there was a comment about this, but it got removed at some point. It's ok to keep the loop as it is.

@CISC
CISC requested a review from ggerganov January 1, 2026 21:41
@nabbi

nabbi commented Jan 1, 2026

Copy link
Copy Markdown
Author

Within that function, n_tokens is redefined as an int64_t constant.
I certainly could be mistaken on how this should behave, would you prefer this split out or have the other functions in the file reviewed too ?

I think that dead loop came from previous refactoring efforts where there was separate data and data_sma loops. Yet I got lost in the reasoning with all those edits :)

@CISC

CISC commented Jan 1, 2026

Copy link
Copy Markdown
Member

Within that function, n_tokens is redefined as an int64_t constant. I certainly could be mistaken on how this should behave, would you prefer this split out or have the other functions in the file reviewed too ?

Sure, I was just curious why you only fixed one of a multitude of functions that would produce this warning?

I think that dead loop came from previous refactoring efforts where there was separate data and data_sma loops. Yet I got lost in the reasoning with all those edits :)

Probably.

@nabbi

nabbi commented Jan 1, 2026

Copy link
Copy Markdown
Author

Interestingly, that compilation warning only tripped on that dead loop line. And not the first loop.

So I was hyper focused on just this one function...
Yet I agree those int >> int64_t changes also need to be corrected elsewhere, to prevent runtime issues. Unless as you stated it really is uint32_t??

Good conversation :)

@CISC

CISC commented Jan 1, 2026

Copy link
Copy Markdown
Member

So I was hyper focused on just this one function... Yet I agree those int >> int64_t changes also need to be corrected elsewhere, to prevent runtime issues. Unless as you stated it really is uint32_t??

Well, uint32_t will be larger than int too in the same scenarios where int64_t is.

@nabbi
nabbi force-pushed the aggressive-loop-optimizations branch from b68e1d7 to cdd47ab Compare January 2, 2026 01:01
@nabbi

nabbi commented Jan 2, 2026

Copy link
Copy Markdown
Author

more holistic approach. targeted n_tokens and adjacent code for correctness. I hadn't analyzed the entire repo for other integer type mismatches

Comment thread src/llama-graph.cpp
Comment on lines -472 to -477

for (int i = n_tokens; i < n_tokens; ++i) {
for (int j = 0; j < n_enc; ++j) {
data[h*(n_enc*n_tokens) + i*n_enc + j] = -INFINITY;
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is the only meaningful change.

The rest of the changes in the PR seem redundant? Or am I missing something?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Well, at least the n_tokens loops are "possible" overflows.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I'm more than happy to shirk the PR down to just the compilation warning only of type mismatches need a more focused effort.

We are throwing -Wformat= against LLAMA_LOG_DEBUG for the loop counters for at least in print_mask; that that needs correcting yet. Those are bound by a limit of 20 where as most other loops are bound to whatever the upper limit of n_tokens is set as.

Normalize loop index types across batch, graph, and KV code paths to
match the width of their bounds (e.g. n_tokens, n_rs,
n_seq_id, n_expert_used).

This also removes an unreachable loop with identical start/end
conditions
GCC emited the following warning when building with optimizations:

  llama-graph.cpp:473:9: warning: iteration 2147483645 invokes undefined
  behavior [-Waggressive-loop-optimizations]

Signed-off-by: Nic Boet <nic@boet.cc>
@nabbi
nabbi force-pushed the aggressive-loop-optimizations branch from cdd47ab to 4f310f4 Compare January 5, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants