Skip to content

Fix qb4 packw bias tail in neon#10787

Merged
copybara-service[bot] merged 4 commits into
google:masterfrom
JakeStevens:fix/qb4-packw-bias-tail
Jul 23, 2026
Merged

Fix qb4 packw bias tail in neon#10787
copybara-service[bot] merged 4 commits into
google:masterfrom
JakeStevens:fix/qb4-packw-bias-tail

Conversation

@JakeStevens

Copy link
Copy Markdown
Contributor

The kernel template allows for indexing past the end the bias, which can result in a SIGSEGV at packing.

Here we handle the tail with a a memcpy + memset with proper bounds.

Added a test for these cases as well.

Also confirmed with actual usecases on device it resolves a SIGSEGV.

Comment thread src/qb4-packw/gen/qb4-packw-x16c4-gemm-goi-aarch64-neondot.c Outdated
@JakeStevens
JakeStevens force-pushed the fix/qb4-packw-bias-tail branch from e8c02c7 to 476c60d Compare July 20, 2026 16:28

@fbarchard fbarchard left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

wrong amount of bias values are copied.
the memcpy/memset version looks right.

const int32x4_t b3 = vld1q_s32(&b[12]);
vst1q_s32((int32_t*)out + 12, b3);
b += 16;
if (n >= 16) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this isnt right. you copy 16 but not the rest. it needs to be in a loop and copy n bias values.
ditto for scalar.

you can/should write the full NR (16 floats) but its important on the remainder to only read n to avoid out of bounds.
optional, but a good idea to clear the rest to zero.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

disreguard... you are doing the neon right. its a direct copy of 4 vectors when n >= 16
and memcpy/memset for remainder.

@fbarchard fbarchard left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

looks good. I tried it on android and it runs smoothly

const int32x4_t b3 = vld1q_s32(&b[12]);
vst1q_s32((int32_t*)out + 12, b3);
b += 16;
if (n >= 16) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

disreguard... you are doing the neon right. its a direct copy of 4 vectors when n >= 16
and memcpy/memset for remainder.

((uint32_t*) out)[12] = b[12];
((uint32_t*) out)[13] = b[13];
((uint32_t*) out)[14] = b[14];
((uint32_t*) out)[15] = b[15];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this is fine and both this and memcpy(out, b, 16 * sizeof(uint32_t));
will vectorize to 4 vectors, but the unrolling exposes a pedantic compiler performance issue for very large NR ... e.g. NR=256 will be heavily unrolled and the compiler will spend a long time (more than 10 minutes) trying to compile this file. It eventually does the right thing, which is a few vectors.

@fbarchard fbarchard self-assigned this Jul 23, 2026
@copybara-service
copybara-service Bot merged commit d3aba2a into google:master Jul 23, 2026
8 checks passed
@JakeStevens
JakeStevens deleted the fix/qb4-packw-bias-tail branch July 23, 2026 20:57
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