// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor. No-op / byte-identical when
+ // ne01 % 128 == 0 (M/2 already a multiple of 64 -> no padding).
+ if (gid * 2 + 0 < M) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < M) dst[gid * 2 + 1] = totalSum.s1;
}
}
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- dst[gid] = totalSum;
+ // Guard the output row. The x-grid is padded to CEIL_DIV(M,wavesize)*wavesize,
+ // so when ne01 is not a multiple of the wave size the tail work-items run past
+ // row ne01 and would overrun dst into the adjacent tensor. No-op / byte-identical
+ // when ne01 is wave-aligned (no padding).
+ if (gid < M) dst[gid] = totalSum;
}
}
// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor. No-op / byte-identical when
+ // ne01 % 128 == 0 (M/2 already a multiple of 64 -> no padding).
+ if (gid * 2 + 0 < M) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < M) dst[gid * 2 + 1] = totalSum.s1;
}
}
// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows against the padded x-grid tail overrunning dst.
+ // The current shape specializations are all ne01 % 128 == 0 (no padding), so
+ // this is a no-op / byte-identical today; keep it in lockstep with the base kernel.
+ if (gid * 2 + 0 < ne01) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < ne01) dst[gid * 2 + 1] = totalSum.s1;
}
}
// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor. No-op / byte-identical when
+ // ne01 % 128 == 0 (M/2 already a multiple of 64 -> no padding).
+ if (gid * 2 + 0 < M) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < M) dst[gid * 2 + 1] = totalSum.s1;
}
}
// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor. No-op / byte-identical when
+ // ne01 % 128 == 0 (M/2 already a multiple of 64 -> no padding).
+ if (gid * 2 + 0 < M) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < M) dst[gid * 2 + 1] = totalSum.s1;
}
}
// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor. No-op / byte-identical when
+ // ne01 % 128 == 0 (M/2 already a multiple of 64 -> no padding).
+ if (gid * 2 + 0 < M) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < M) dst[gid * 2 + 1] = totalSum.s1;
}
}
// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor. No-op / byte-identical when
+ // ne01 % 128 == 0 (M/2 already a multiple of 64 -> no padding).
+ if (gid * 2 + 0 < M) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < M) dst[gid * 2 + 1] = totalSum.s1;
}
}
// 2 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor. No-op / byte-identical when
+ // ne01 % 128 == 0 (M/2 already a multiple of 64 -> no padding).
+ if (gid * 2 + 0 < M) dst[gid * 2 + 0] = totalSum.s0;
+ if (gid * 2 + 1 < M) dst[gid * 2 + 1] = totalSum.s1;
}
}
if (grp == 0) {
dst = (global float*)((global char*)dst + offsetd);
- vstore2(total_sum, 0, &(dst[gid * 2]));
+ // Guard the two output rows. The x-grid is padded to CEIL_DIV(ne01/2,64)*64,
+ // so when ne01 is not a multiple of 128 the tail row-pairs run past row ne01
+ // and would overrun dst into the adjacent tensor (garbage downstream).
+ // No-op / byte-identical when ne01 % 128 == 0 (no padding).
+ if (gid * 2 + 0 < ne01) dst[gid * 2 + 0] = total_sum.s0;
+ if (gid * 2 + 1 < ne01) dst[gid * 2 + 1] = total_sum.s1;
}
}
// 1 outputs per fiber in wave 0
if (groupId == 0) {
dst = (global float*)((global char*)dst + offsetd);
- dst[gid] = totalSum;
+ // Guard the output row. The x-grid is padded to CEIL_DIV(M,wavesize)*wavesize,
+ // so when ne01 is not a multiple of the wave size the tail work-items run past
+ // row ne01 and would overrun dst into the adjacent tensor. No-op / byte-identical
+ // when ne01 is wave-aligned (no padding).
+ if (gid < M) dst[gid] = totalSum;
}
}