fix(vector): batched Dot in the scalar VectorF32 fallback #2
1 changed files with 22 additions and 0 deletions
fix(vector): batched Dot in the scalar VectorF32 fallback
MatrixRowMajor calls VectorF32<Len, 1>::Dot(a0, b0, a1, b1, ...) for its matrix-vector products and for LookAt. The x86, wasm and RISC-V backends each define it; the scalar fallback, which every other target gets, did not. Anything that imports Crafter.Math on such a target failed to compile with "no member named 'Dot' in VectorF32", aarch64 included: cross-building Crafter.Graphics for a phone stopped there. The fallback gains the same batched Dot, written like the RISC-V one: one lane per (a, b) pair, summing only the first Len lanes of each input. No test exercises it: the suite builds the x86 and RISC-V tiers only. Checked by cross-building Crafter.Graphics for aarch64-alpine-linux-musl and running its UI on the device. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
commit
ed188f207b
|
|
@ -2136,6 +2136,28 @@ namespace Crafter {
|
|||
return sq;
|
||||
}
|
||||
|
||||
// Batched dot product over BatchSize (a, b) pairs: Dot(a0, b0, a1, b1,
|
||||
// ...) returns one lane per pair. MatrixRowMajor relies on it, so
|
||||
// without it this fallback (every target that has no intrinsic
|
||||
// backend above) does not compile. Only the first Len lanes of each
|
||||
// input are summed, as in the other backends.
|
||||
template<typename... Rest>
|
||||
requires((std::is_same_v<Rest, VectorF32<Len, Packing>> && ...) &&
|
||||
(1 + sizeof...(Rest) == 2 * VectorBase<Len, Packing, float>::BatchSize))
|
||||
constexpr static auto Dot(VectorF32<Len, Packing> first, Rest... rest) {
|
||||
constexpr std::uint8_t N = VectorBase<Len, Packing, float>::BatchSize;
|
||||
VectorF32<1, static_cast<std::uint8_t>(Packing * N)> r;
|
||||
std::array<VectorF32<Len, Packing>, 2 * N> args{ first, rest... };
|
||||
for (std::uint8_t i = 0; i < N; ++i)
|
||||
for (std::uint8_t p = 0; p < Packing; ++p) {
|
||||
float acc = 0.0f;
|
||||
for (std::uint8_t k = 0; k < Len; ++k)
|
||||
acc += args[2 * i].v[p * Len + k] * args[2 * i + 1].v[p * Len + k];
|
||||
r.v[i * Packing + p] = acc;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename... Rest>
|
||||
requires((std::is_same_v<Rest, VectorF32<Len, Packing>> && ...) &&
|
||||
(1 + sizeof...(Rest) == VectorBase<Len, Packing, float>::BatchSize))
|
||||
|
|
|
|||
Loading…
Reference in a new issue