AGENTS.md
This commit is contained in:
parent
087c8b32c3
commit
b701059c8c
7 changed files with 331 additions and 62 deletions
|
|
@ -443,50 +443,21 @@ namespace Crafter {
|
|||
}
|
||||
}
|
||||
|
||||
// Through Shuffle, as VectorF32::Cross is: it checks whether every lane
|
||||
// move stays inside its 128-bit lane and takes a full permute when one
|
||||
// does not. This used to call _mm*_shuffle_epi8 directly, which
|
||||
// shuffles bytes per 128-bit lane only, so in a 256- or 512-bit
|
||||
// register a 3-vector whose halves straddle a lane boundary (the third
|
||||
// of every eight for Packing 8, say) came out wrong.
|
||||
constexpr static VectorF16<Len, Packing> Cross(VectorF16<Len, Packing> a, VectorF16<Len, Packing> b) requires(Len == 3) {
|
||||
if constexpr(std::is_same_v<typename VectorBase<Len, Packing, _Float16>::VectorType, __m128h>) {
|
||||
constexpr std::array<std::uint8_t, VectorBase<Len, Packing, _Float16>::AlignmentElement*2> shuffleMask1 = VectorBase<Len, Packing, _Float16>::template GetShuffleMaskEpi8<{{1,2,0}}>();
|
||||
__m128i shuffleVec1 = _mm_loadu_epi8(shuffleMask1.data());
|
||||
__m128h row1 = _mm_castsi128_ph(_mm_shuffle_epi8(_mm_castph_si128(a.v), shuffleVec1));
|
||||
__m128h row4 = _mm_castsi128_ph(_mm_shuffle_epi8(_mm_castph_si128(b.v), shuffleVec1));
|
||||
VectorF16<Len, Packing> row1 = a.template Shuffle<{{1,2,0}}>();
|
||||
VectorF16<Len, Packing> row4 = b.template Shuffle<{{1,2,0}}>();
|
||||
|
||||
constexpr std::array<std::uint8_t, VectorBase<Len, Packing, _Float16>::AlignmentElement*2> shuffleMask3 = VectorBase<Len, Packing, _Float16>::template GetShuffleMaskEpi8<{{2,0,1}}>();
|
||||
__m128i shuffleVec3 = _mm_loadu_epi8(shuffleMask3.data());
|
||||
__m128h row3 = _mm_castsi128_ph(_mm_shuffle_epi8(_mm_castph_si128(a.v), shuffleVec3));
|
||||
__m128h row2 = _mm_castsi128_ph(_mm_shuffle_epi8(_mm_castph_si128(b.v), shuffleVec3));
|
||||
VectorF16<Len, Packing> row3 = a.template Shuffle<{{2,0,1}}>();
|
||||
VectorF16<Len, Packing> row2 = b.template Shuffle<{{2,0,1}}>();
|
||||
|
||||
__m128h result = _mm_mul_ph(row3, row4);
|
||||
return _mm_fmsub_ph(row1,row2,result);
|
||||
} else if constexpr (std::is_same_v<typename VectorBase<Len, Packing, _Float16>::VectorType, __m256h>) {
|
||||
constexpr std::array<std::uint8_t, VectorBase<Len, Packing, _Float16>::AlignmentElement*2> shuffleMask1 = VectorBase<Len, Packing, _Float16>::template GetShuffleMaskEpi8<{{1,2,0}}>();
|
||||
__m512i shuffleVec1 = _mm512_castsi256_si512(_mm256_loadu_epi8(shuffleMask1.data()));
|
||||
__m256h row1 = _mm256_castsi256_ph(_mm512_castsi512_si256(_mm512_shuffle_epi8(_mm512_castsi256_si512(_mm256_castph_si256(a.v)), shuffleVec1)));
|
||||
__m256h row4 = _mm256_castsi256_ph(_mm512_castsi512_si256(_mm512_shuffle_epi8(_mm512_castsi256_si512(_mm256_castph_si256(b.v)), shuffleVec1)));
|
||||
|
||||
constexpr std::array<std::uint8_t, VectorBase<Len, Packing, _Float16>::AlignmentElement*2> shuffleMask3 = VectorBase<Len, Packing, _Float16>::template GetShuffleMaskEpi8<{{2,0,1}}>();
|
||||
|
||||
__m512i shuffleVec3 = _mm512_castsi256_si512(_mm256_loadu_epi8(shuffleMask3.data()));
|
||||
__m256h row3 = _mm256_castsi256_ph(_mm512_castsi512_si256(_mm512_shuffle_epi8(_mm512_castsi256_si512(_mm256_castph_si256(a.v)), shuffleVec3)));
|
||||
__m256h row2 = _mm256_castsi256_ph(_mm512_castsi512_si256(_mm512_shuffle_epi8(_mm512_castsi256_si512(_mm256_castph_si256(b.v)), shuffleVec3)));
|
||||
|
||||
__m256h result = _mm256_mul_ph(row3, row4);
|
||||
return _mm256_fmsub_ph(row1,row2,result);
|
||||
} else {
|
||||
constexpr std::array<std::uint8_t, VectorBase<Len, Packing, _Float16>::AlignmentElement*2> shuffleMask1 = VectorBase<Len, Packing, _Float16>::template GetShuffleMaskEpi8<{{1,2,0}}>();
|
||||
|
||||
__m512i shuffleVec1 = _mm512_loadu_epi8(shuffleMask1.data());
|
||||
__m512h row1 = _mm512_castsi512_ph(_mm512_shuffle_epi8(_mm512_castph_si512(a.v), shuffleVec1));
|
||||
__m512h row4 = _mm512_castsi512_ph(_mm512_shuffle_epi8(_mm512_castph_si512(b.v), shuffleVec1));
|
||||
|
||||
constexpr std::array<std::uint8_t, VectorBase<Len, Packing, _Float16>::AlignmentElement*2> shuffleMask3 = VectorBase<Len, Packing, _Float16>::template GetShuffleMaskEpi8<{{2,0,1}}>();
|
||||
|
||||
__m512i shuffleVec3 = _mm512_loadu_epi8(shuffleMask3.data());
|
||||
__m512h row3 = _mm512_castsi512_ph(_mm512_shuffle_epi8(_mm512_castph_si512(a.v), shuffleVec3));
|
||||
__m512h row2 = _mm512_castsi512_ph(_mm512_shuffle_epi8(_mm512_castph_si512(b.v), shuffleVec3));
|
||||
|
||||
__m512h result = _mm512_mul_ph(row3, row4);
|
||||
return _mm512_fmsub_ph(row1,row2,result);
|
||||
}
|
||||
VectorF16<Len, Packing> result = row3 * row4;
|
||||
return VectorF16<Len, Packing>::MulitplySub(row1, row2, result);
|
||||
}
|
||||
|
||||
constexpr static _Float16 Dot(VectorF16<Len, Packing> a, VectorF16<Len, Packing> b) requires(Packing == 1) {
|
||||
|
|
@ -1007,12 +978,10 @@ namespace Crafter {
|
|||
return v + t * q.template Shuffle<{{3,3,3,3}}>() + Cross(qv, t);
|
||||
}
|
||||
|
||||
constexpr static VectorF16<4, 2> RotatePivot(VectorF16<3, Packing> v, VectorF16<4, Packing> q, VectorF16<3, Packing> pivot) requires(Len == 3) {
|
||||
VectorF16<Len, Packing> translated = v - pivot;
|
||||
VectorF16<3, Packing> qv(q.v);
|
||||
VectorF16<Len, Packing> t = Cross(qv, translated) * _Float16(2);
|
||||
VectorF16<Len, Packing> rotated = translated + t * q.template Shuffle<{{3,3,3,3}}>() + Cross(qv, t);
|
||||
return rotated + pivot;
|
||||
// Through Rotate, like the other backends; see VectorF32's note.
|
||||
constexpr static VectorF16<3, Packing> RotatePivot(VectorF16<3, Packing> v, VectorF16<4, Packing> q, VectorF16<3, Packing> pivot) requires(Len == 3) {
|
||||
VectorF16<3, Packing> translated = v - pivot;
|
||||
return Rotate(translated, q) + pivot;
|
||||
}
|
||||
|
||||
constexpr static VectorF16<4, Packing> QuanternionFromEuler(VectorF16<3, Packing> EulerHalf) requires(Len == 4) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue