F16 and F32
This commit is contained in:
parent
1544e92391
commit
07910a81c3
6 changed files with 898 additions and 7 deletions
|
|
@ -20,10 +20,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
export module Crafter.Math:Basic;
|
export module Crafter.Math:Basic;
|
||||||
import std;
|
import std;
|
||||||
|
import :VectorF16;
|
||||||
|
import :VectorF32;
|
||||||
|
|
||||||
namespace Crafter {
|
namespace Crafter {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr T ToRadian(T degrees) {
|
constexpr T ToRadian(T degrees) {
|
||||||
return degrees * (std::numbers::pi / 180);
|
return degrees * (std::numbers::pi / 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __AVX512FP16__
|
||||||
|
export template <std::uint32_t Len, std::uint32_t Packing, std::uint32_t Repeats>
|
||||||
|
using VectorF16L = VectorF16<Len, Packing, Repeats>;
|
||||||
|
#else
|
||||||
|
export template <std::uint32_t Len, std::uint32_t Packing, std::uint32_t Repeats>
|
||||||
|
using VectorF16L = VectorF32<Len, Packing, Repeats>;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +78,7 @@ namespace Crafter {
|
||||||
v = _mm512_loadu_ph(vB);
|
v = _mm512_loadu_ph(vB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constexpr void Store(const _Float16* vB) const {
|
constexpr void Store(_Float16* vB) const {
|
||||||
if constexpr(std::is_same_v<VectorType, __m128h>) {
|
if constexpr(std::is_same_v<VectorType, __m128h>) {
|
||||||
_mm_storeu_ph(vB, v);
|
_mm_storeu_ph(vB, v);
|
||||||
} else if constexpr(std::is_same_v<VectorType, __m256h>) {
|
} else if constexpr(std::is_same_v<VectorType, __m256h>) {
|
||||||
|
|
@ -91,7 +91,7 @@ namespace Crafter {
|
||||||
template <std::uint32_t VLen, std::uint32_t VAlign>
|
template <std::uint32_t VLen, std::uint32_t VAlign>
|
||||||
constexpr Vector<_Float16, VLen, VAlign> Store() const {
|
constexpr Vector<_Float16, VLen, VAlign> Store() const {
|
||||||
Vector<_Float16, VLen, VAlign> returnVec;
|
Vector<_Float16, VLen, VAlign> returnVec;
|
||||||
Store(&returnVec);
|
Store(returnVec.v);
|
||||||
return returnVec;
|
return returnVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1501,14 +1501,14 @@ namespace Crafter {
|
||||||
constexpr static VectorF16<Len, Packing, Repeats> Rotate(VectorF16<3, 2, Repeats> v, VectorF16<4, 2, Repeats> q) requires(Len == 3 && Packing == 2) {
|
constexpr static VectorF16<Len, Packing, Repeats> Rotate(VectorF16<3, 2, Repeats> v, VectorF16<4, 2, Repeats> q) requires(Len == 3 && Packing == 2) {
|
||||||
VectorF16<3, 2, Repeats> qv(q.v);
|
VectorF16<3, 2, Repeats> qv(q.v);
|
||||||
VectorF16<Len, Packing, Repeats> t = Cross(qv, v) * _Float16(2);
|
VectorF16<Len, Packing, Repeats> t = Cross(qv, v) * _Float16(2);
|
||||||
return v + t * q.template Shuffle<3,3,3,3,3,3,3,3>(); + Cross(qv, t);
|
return v + t * q.template Shuffle<3,3,3,3,7,7,7,7>(); + Cross(qv, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr static VectorF16<4, 2, Repeats> RotatePivot(VectorF16<3, 2, Repeats> v, VectorF16<4, 2, Repeats> q, VectorF16<3, 2, Repeats> pivot) requires(Len == 3 && Packing == 2) {
|
constexpr static VectorF16<4, 2, Repeats> RotatePivot(VectorF16<3, 2, Repeats> v, VectorF16<4, 2, Repeats> q, VectorF16<3, 2, Repeats> pivot) requires(Len == 3 && Packing == 2) {
|
||||||
VectorF16<Len, Packing, Repeats> translated = v - pivot;
|
VectorF16<Len, Packing, Repeats> translated = v - pivot;
|
||||||
VectorF16<3, 2, Repeats> qv(q.v);
|
VectorF16<3, 2, Repeats> qv(q.v);
|
||||||
VectorF16<Len, Packing, Repeats> t = Cross(qv, translated) * _Float16(2);
|
VectorF16<Len, Packing, Repeats> t = Cross(qv, translated) * _Float16(2);
|
||||||
VectorF16<Len, Packing, Repeats> rotated = translated + t * q.template Shuffle<3,3,3,3,3,3,3,3>() + Cross(qv, t);
|
VectorF16<Len, Packing, Repeats> rotated = translated + t * q.template Shuffle<3,3,3,3,7,7,7,7>() + Cross(qv, t);
|
||||||
return rotated + pivot;
|
return rotated + pivot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
874
interfaces/Crafter.Math-VectorF32.cppm
Executable file
874
interfaces/Crafter.Math-VectorF32.cppm
Executable file
|
|
@ -0,0 +1,874 @@
|
||||||
|
/*
|
||||||
|
Crafter®.Math
|
||||||
|
Copyright (C) 2026 Catcrafts®
|
||||||
|
catcrafts.net
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License version 3.0 as published by the Free Software Foundation;
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
module;
|
||||||
|
#ifdef __x86_64
|
||||||
|
#include <immintrin.h>
|
||||||
|
#endif
|
||||||
|
export module Crafter.Math:VectorF32;
|
||||||
|
import std;
|
||||||
|
import :Vector;
|
||||||
|
|
||||||
|
namespace Crafter {
|
||||||
|
export template <std::uint32_t Len, std::uint32_t Packing, std::uint32_t Repeats>
|
||||||
|
struct VectorF32 {
|
||||||
|
#ifdef __AVX512F__
|
||||||
|
static constexpr std::uint32_t MaxSize = 16;
|
||||||
|
#else
|
||||||
|
static constexpr std::uint32_t MaxSize = 8;
|
||||||
|
#endif
|
||||||
|
static constexpr std::uint32_t MaxElement = 4;
|
||||||
|
static consteval std::uint32_t GetAlignment() {
|
||||||
|
#ifdef __AVX512F__
|
||||||
|
if constexpr (Len * Packing <= 4) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
if constexpr (Len * Packing <= 8) {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
if constexpr (Len * Packing <= 16) {
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
static_assert(Len * Packing <= 16, "Len * Packing is larger than supported max size of 16");
|
||||||
|
static_assert(Len * Packing <= 4, "Len * Packing is larger than supported packed size of 4");
|
||||||
|
static_assert(Len * Packing * Repeats <= 16, "Len * Packing * Repeats is larger than supported max of 16");
|
||||||
|
#else
|
||||||
|
if constexpr (Len * Packing <= 4) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
if constexpr (Len * Packing <= 8) {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
static_assert(Len * Packing <= 8, "Len * Packing is larger than supported max size of 8");
|
||||||
|
static_assert(Len * Packing <= 4, "Len * Packing is larger than supported packed size of 4");
|
||||||
|
static_assert(Len * Packing * Repeats <= 8, "Len * Packing * Repeats is larger than supported max of 8");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static consteval std::uint32_t GetTotalSize() {
|
||||||
|
return GetAlignment() * Repeats;
|
||||||
|
}
|
||||||
|
|
||||||
|
using VectorType = std::conditional_t<
|
||||||
|
(GetTotalSize() == 16), __m512,
|
||||||
|
std::conditional_t<(GetTotalSize() == 8), __m256, __m128>
|
||||||
|
>;
|
||||||
|
|
||||||
|
VectorType v;
|
||||||
|
|
||||||
|
constexpr VectorF32() = default;
|
||||||
|
constexpr VectorF32(VectorType v) : v(v) {}
|
||||||
|
constexpr VectorF32(const float* vB) {
|
||||||
|
Load(vB);
|
||||||
|
};
|
||||||
|
constexpr VectorF32(const _Float16* vB) {
|
||||||
|
Load(vB);
|
||||||
|
};
|
||||||
|
constexpr VectorF32(float val) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
v = _mm_set1_ps(val);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
v = _mm256_set1_ps(val);
|
||||||
|
} else {
|
||||||
|
v = _mm512_set1_ps(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
constexpr void Load(const float* vB) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
v = _mm_loadu_ps(vB);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
v = _mm256_loadu_ps(vB);
|
||||||
|
} else {
|
||||||
|
v = _mm512_loadu_ps(vB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constexpr void Store(float* vB) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
_mm_storeu_ps(vB, v);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
_mm256_storeu_ps(vB, v);
|
||||||
|
} else {
|
||||||
|
_mm512_storeu_ps(vB, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constexpr void Load(const _Float16* vB) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
v = _mm_cvtph_ps(_mm_loadu_si128(reinterpret_cast<__m128i const*>(vB)));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
v = _mm256_cvtph_ps(_mm_loadu_si128(reinterpret_cast<__m128i const*>(vB)));
|
||||||
|
} else {
|
||||||
|
v = _mm512_cvtph_ps(_mm256_loadu_si256(reinterpret_cast<__m256i const*>(vB)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constexpr void Store(_Float16* vB) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
_mm_storeu_si128(_mm_cvtps_ph(v, _MM_FROUND_TO_NEAREST_INT), v);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
_mm_storeu_si128(_mm256_cvtps_ph(v, _MM_FROUND_TO_NEAREST_INT), v);
|
||||||
|
} else {
|
||||||
|
_mm256_storeu_si256(_mm512_cvtps_ph(v, _MM_FROUND_TO_NEAREST_INT), v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::uint32_t VLen, std::uint32_t VAlign>
|
||||||
|
constexpr Vector<float, VLen, VAlign> Store() const {
|
||||||
|
Vector<float, VLen, VAlign> returnVec;
|
||||||
|
Store(returnVec.v);
|
||||||
|
return returnVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::uint32_t BLen, std::uint32_t BPacking, std::uint32_t BRepeats>
|
||||||
|
constexpr operator VectorF32<BLen, BPacking, BRepeats>() const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m256> && std::is_same_v<typename VectorF32<BLen, BPacking, BRepeats>::VectorType, __m128>) {
|
||||||
|
return VectorF32<BLen, BPacking, BRepeats>(_mm256_castps256_ps128(v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m512> && std::is_same_v<typename VectorF32<BLen, BPacking, BRepeats>::VectorType, __m128>) {
|
||||||
|
return VectorF32<BLen, BPacking, BRepeats>(_mm512_castps512_ps128(v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m512> && std::is_same_v<typename VectorF32<BLen, BPacking, BRepeats>::VectorType, __m256>) {
|
||||||
|
return VectorF32<BLen, BPacking, BRepeats>(_mm512_castps512_ps256(v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m128> && std::is_same_v<typename VectorF32<BLen, BPacking, BRepeats>::VectorType, __m256>) {
|
||||||
|
return VectorF32<BLen, BPacking, BRepeats>(_mm256_castps128_ps256(v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m128> && std::is_same_v<typename VectorF32<BLen, BPacking, BRepeats>::VectorType, __m512>) {
|
||||||
|
return VectorF32<BLen, BPacking, BRepeats>(_mm512_castps128_ps512(v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256> && std::is_same_v<typename VectorF32<BLen, BPacking, BRepeats>::VectorType, __m512>) {
|
||||||
|
return VectorF32<BLen, BPacking, BRepeats>(_mm512_castps256_ps512(v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<BLen, BPacking, BRepeats>(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator+(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_add_ps(v, b.v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_add_ps(v, b.v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_add_ps(v, b.v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator-(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_sub_ps(v, b.v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_sub_ps(v, b.v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_sub_ps(v, b.v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator*(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_mul_ps(v, b.v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_mul_ps(v, b.v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_mul_ps(v, b.v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator/(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_div_ps(v, b.v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_div_ps(v, b.v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_div_ps(v, b.v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constexpr void operator+=(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
v = _mm_add_ps(v, b.v);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
v = _mm256_add_ps(v, b.v);
|
||||||
|
} else {
|
||||||
|
v = _mm512_add_ps(v, b.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void operator-=(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
v = _mm_sub_ps(v, b.v);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
v = _mm256_sub_ps(v, b.v);
|
||||||
|
} else {
|
||||||
|
v = _mm512_sub_ps(v, b.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void operator*=(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
v = _mm_mul_ps(v, b.v);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
v = _mm256_mul_ps(v, b.v);
|
||||||
|
} else {
|
||||||
|
v = _mm512_mul_ps(v, b.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void operator/=(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
v = _mm_div_ps(v, b.v);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
v = _mm256_div_ps(v, b.v);
|
||||||
|
} else {
|
||||||
|
v = _mm512_div_ps(v, b.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator+(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
return this + vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator-(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
return this - vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator*(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
return this * vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator/(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
return this / vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void operator+=(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
this += vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void operator-=(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
this -= vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void operator*=(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
this *= vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void operator/=(float b) const {
|
||||||
|
VectorF32<Len, Packing, Repeats> vB(b);
|
||||||
|
this /= vB;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> operator-(){
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
constexpr std::uint64_t mask[] {0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000};
|
||||||
|
__m128i sign_mask = _mm_loadu_si128(reinterpret_cast<const __m128i*>(mask));
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_castsi128_ps(_mm_xor_si128(sign_mask, _mm_castps_si128(v))));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
constexpr std::uint64_t mask[] {0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000};
|
||||||
|
__m256i sign_mask = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(mask));
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_castsi256_ps(_mm256_xor_si256(sign_mask, _mm256_castps_si256(v))));
|
||||||
|
} else {
|
||||||
|
constexpr std::uint64_t mask[] {0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000};
|
||||||
|
__m512i sign_mask = _mm512_loadu_si512(reinterpret_cast<const __m256i*>(mask));
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_castsi512_ps(_mm512_xor_si512(sign_mask, _mm512_castps_si512(v))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator==(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return _mm_cmp_ps_mask(v, b.v, _CMP_EQ_OQ) == 255;
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return _mm256_cmp_ps_mask(v, b.v, _CMP_EQ_OQ) == 65535;
|
||||||
|
} else {
|
||||||
|
return _mm512_cmp_ps_mask(v, b.v, _CMP_EQ_OQ) == 4294967295;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator!=(VectorF32<Len, Packing, Repeats> b) const {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return _mm_cmp_ps_mask(v, b.v, _CMP_EQ_OQ) != 255;
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return _mm256_cmp_ps_mask(v, b.v, _CMP_EQ_OQ) != 65535;
|
||||||
|
} else {
|
||||||
|
return _mm512_cmp_ps_mask(v, b.v, _CMP_EQ_OQ) != 4294967295;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void Normalize() {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
float dot = LengthSq();
|
||||||
|
__m128 vec = _mm_set1_ps(dot);
|
||||||
|
__m128 sqrt = _mm_rsqrt_ps(vec);
|
||||||
|
v = _mm_div_ps(v, sqrt);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
float dot = LengthSq();
|
||||||
|
__m256 vec = _mm256_set1_ps(dot);
|
||||||
|
__m256 sqrt = _mm256_rsqrt_ps(vec);
|
||||||
|
v = _mm256_div_ps(v, sqrt);
|
||||||
|
} else {
|
||||||
|
float dot = LengthSq();
|
||||||
|
__m512 vec = _mm512_set1_ps(dot);
|
||||||
|
__m512 sqrt = _mm512_rsqrt14_ps(vec);
|
||||||
|
v = _mm512_div_ps(v, sqrt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr float Length() const {
|
||||||
|
float Result = LengthSq();
|
||||||
|
return std::sqrtf(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr float LengthSq() const {
|
||||||
|
return Dot(*this, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> Cos() requires(Len == 3) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_cos_ps(v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_cos_ps(v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_cos_ps(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> Sin() requires(Len == 3) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_sin_ps(v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_sin_ps(v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_sin_ps(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::uint8_t A, std::uint8_t B, std::uint8_t C, std::uint8_t D>
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> Shuffle() {
|
||||||
|
constexpr std::uint32_t val =
|
||||||
|
(A & 0x3) |
|
||||||
|
((B & 0x3) << 2) |
|
||||||
|
((C & 0x3) << 4) |
|
||||||
|
((D & 0x3) << 6);
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(v), val)));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(v), val)));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_castsi512_ps(_mm512_shuffle_epi32(_mm_512castps_si512(v), val)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
std::uint8_t A0, std::uint8_t B0, std::uint8_t C0, std::uint8_t D0,
|
||||||
|
std::uint8_t A1, std::uint8_t B1, std::uint8_t C1, std::uint8_t D1
|
||||||
|
>
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> Shuffle() requires(Repeats == 2) {
|
||||||
|
constexpr std::uint8_t shuffleMask[] {
|
||||||
|
A0,A0,A0,A0,B0,B0,B0,B0,C0,C0,C0,C0,D0,D0,D0,D0,
|
||||||
|
A1,A1,A1,A1,B1,B1,B1,B1,C1,C1,C1,C1,D1,D1,D1,D1,
|
||||||
|
};
|
||||||
|
__m256 shuffleVec = _mm256_loadu_epi8(shuffleMask);
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_castsi256_ps(_mm256_shuffle_epi8(_mm256_castps_si256(v), shuffleVec)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <
|
||||||
|
std::uint8_t A0, std::uint8_t B0, std::uint8_t C0, std::uint8_t D0, std::uint8_t E0, std::uint8_t F0, std::uint8_t G0, std::uint8_t H0,
|
||||||
|
std::uint8_t A1, std::uint8_t B1, std::uint8_t C1, std::uint8_t D1, std::uint8_t E1, std::uint8_t F1, std::uint8_t G1, std::uint8_t H1,
|
||||||
|
std::uint8_t A2, std::uint8_t B2, std::uint8_t C2, std::uint8_t D2, std::uint8_t E2, std::uint8_t F2, std::uint8_t G2, std::uint8_t H2,
|
||||||
|
std::uint8_t A3, std::uint8_t B3, std::uint8_t C3, std::uint8_t D3, std::uint8_t E3, std::uint8_t F3, std::uint8_t G3, std::uint8_t H3
|
||||||
|
>
|
||||||
|
constexpr VectorF32<Len, Packing, Repeats> Shuffle() requires(Repeats == 4) {
|
||||||
|
constexpr std::uint8_t shuffleMask[] {
|
||||||
|
A0,A0,A0,A0,B0,B0,B0,B0,C0,C0,C0,C0,D0,D0,D0,D0,
|
||||||
|
A1,A1,A1,A1,B1,B1,B1,B1,C1,C1,C1,C1,D1,D1,D1,D1,
|
||||||
|
A2,A2,A2,A2,B2,B2,B2,B2,C2,C2,C2,C2,D2,D2,D2,D2,
|
||||||
|
A3,A3,A3,A3,B3,B3,B3,B3,C3,C3,C3,C3,D3,D3,D3,D3,
|
||||||
|
};
|
||||||
|
__m512 shuffleVec = _mm512_loadu_epi8(shuffleMask);
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_castsi512_ps(_mm512_shuffle_epi8(_mm512_castps_si512(v), shuffleVec)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr VectorF32<Len, Packing, Repeats> MulitplyAdd(VectorF32<Len, Packing, Repeats> a, VectorF32<Len, Packing, Repeats> b, VectorF32<Len, Packing, Repeats> add) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_fmadd_ps(a, b, add));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_fmadd_ps(a, b, add));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_fmadd_ps(a, b, add));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr VectorF32<Len, Packing, Repeats> MulitplySub(VectorF32<Len, Packing, Repeats> a, VectorF32<Len, Packing, Repeats> b, VectorF32<Len, Packing, Repeats> sub) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_fmsub_ps(a, b, sub));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_fmsub_ps(a, b, sub));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_fmsub_ps(a, b, sub));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> Cross(VectorF32<Len, Packing, Repeats> a, VectorF32<Len, Packing, Repeats> b) requires(Len == 3) {
|
||||||
|
if constexpr(Len == 3) {
|
||||||
|
if constexpr(Repeats == 1) {
|
||||||
|
__m128 row4 = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b.v), 0b01'10'00'11));
|
||||||
|
__m128 row3 = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(a.v), 0b01'10'00'11));
|
||||||
|
__m128 result = _mm_mul_ps(row3, row4);
|
||||||
|
|
||||||
|
__m128 row1 = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(a.v), 0b10'00'01'11));
|
||||||
|
__m128 row2 = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b.v), 0b10'00'01'11));
|
||||||
|
|
||||||
|
return _mm_fmsub_ps(row1,row2,result);
|
||||||
|
}
|
||||||
|
if constexpr(Repeats == 2) {
|
||||||
|
__m256 row4 = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(b.v), 0b01'10'00'11));
|
||||||
|
__m256 row3 = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(a.v), 0b01'10'00'11));
|
||||||
|
__m256 result = _mm256_mul_ps(row3, row4);
|
||||||
|
|
||||||
|
__m256 row1 = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(a.v), 0b10'00'01'11));
|
||||||
|
__m256 row2 = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(b.v), 0b10'00'01'11));
|
||||||
|
|
||||||
|
return _mm256_fmsub_ps(row1,row2,result);
|
||||||
|
}
|
||||||
|
if constexpr(Repeats == 4) {
|
||||||
|
__m512 row4 = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(b.v), 0b01'10'00'11));
|
||||||
|
__m512 row3 = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(a.v), 0b01'10'00'11));
|
||||||
|
__m512 result = _mm512_mul_ps(row3, row4);
|
||||||
|
|
||||||
|
__m512 row1 = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(a.v), 0b10'00'01'11));
|
||||||
|
__m512 row2 = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(b.v), 0b10'00'01'11));
|
||||||
|
|
||||||
|
return _mm512_fmsub_ps(row1,row2,result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static float Dot(VectorF32<Len, 1, 1> a, VectorF32<Len, 1, 1> b) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
union UN {
|
||||||
|
float f;
|
||||||
|
int i;
|
||||||
|
};
|
||||||
|
UN val;
|
||||||
|
val.i = _mm_extract_ps(_mm_dp_ps(a.v, b.v, 0b01110111), 0);
|
||||||
|
return val.f;
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
union UN {
|
||||||
|
float f;
|
||||||
|
int i;
|
||||||
|
};
|
||||||
|
UN val;
|
||||||
|
val.i = _mm_extract_epi32(_mm256_castsi256_si128(_mm256_castps_si256(_mm256_dp_ps(a.v, b.v, 0b01110111))), 0);
|
||||||
|
return val.f;
|
||||||
|
} else {
|
||||||
|
__m512 mul = _mm512_mul_ps(a.v, b.v);
|
||||||
|
return _mm512_reduce_add_ps(mul);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constexpr static std::tuple<VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>> Normalize(
|
||||||
|
VectorF32<Len, Packing, Repeats> A,
|
||||||
|
VectorF32<Len, Packing, Repeats> B,
|
||||||
|
VectorF32<Len, Packing, Repeats> C,
|
||||||
|
VectorF32<Len, Packing, Repeats> D
|
||||||
|
) requires(Packing == 1) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenght = Length(A, B, C, D);
|
||||||
|
constexpr float oneArr[] {1, 1, 1, 1};
|
||||||
|
__m128 one = _mm_loadu_ps(oneArr);
|
||||||
|
__m128 fLenght = _mm_div_ps(one, lenght.v);
|
||||||
|
|
||||||
|
__m128 fLenghtA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(fLenght), 0b00'00'00'00));
|
||||||
|
__m128 fLenghtB = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(fLenght), 0b01'01'01'01));
|
||||||
|
__m128 fLenghtC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(fLenght), 0b10'10'10'10));
|
||||||
|
__m128 fLenghtD = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(fLenght), 0b11'11'11'11));
|
||||||
|
return {
|
||||||
|
_mm_mul_ps(A.v, fLenghtA),
|
||||||
|
_mm_mul_ps(B.v, fLenghtB),
|
||||||
|
_mm_mul_ps(C.v, fLenghtC),
|
||||||
|
_mm_mul_ps(D.v, fLenghtD),
|
||||||
|
};
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenght = Length(A, B, C, D);
|
||||||
|
constexpr float oneArr[] {1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
|
__m256 one = _mm256_loadu_ps(oneArr);
|
||||||
|
__m256 fLenght = _mm256_div_ps(one, lenght.v);
|
||||||
|
|
||||||
|
__m256 fLenghtA = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(fLenght), 0b00'00'00'00));
|
||||||
|
__m256 fLenghtB = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(fLenght), 0b01'01'01'01));
|
||||||
|
__m256 fLenghtC = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(fLenght), 0b10'10'10'10));
|
||||||
|
__m256 fLenghtD = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(fLenght), 0b11'11'11'11));
|
||||||
|
return {
|
||||||
|
_mm256_mul_ps(A.v, fLenghtA),
|
||||||
|
_mm256_mul_ps(B.v, fLenghtB),
|
||||||
|
_mm256_mul_ps(C.v, fLenghtC),
|
||||||
|
_mm256_mul_ps(D.v, fLenghtD),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenght = Length(A, B, C, D);
|
||||||
|
constexpr float oneArr[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
|
__m512 one = _mm512_loadu_ps(oneArr);
|
||||||
|
__m512 fLenght = _mm512_div_ps(one, lenght.v);
|
||||||
|
|
||||||
|
__m512 fLenghtA = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(fLenght), 0b00'00'00'00));
|
||||||
|
__m512 fLenghtB = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(fLenght), 0b01'01'01'01));
|
||||||
|
__m512 fLenghtC = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(fLenght), 0b10'10'10'10));
|
||||||
|
__m512 fLenghtD = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(fLenght), 0b11'11'11'11));
|
||||||
|
return {
|
||||||
|
_mm512_mul_ps(A.v, fLenghtA),
|
||||||
|
_mm512_mul_ps(B.v, fLenghtB),
|
||||||
|
_mm512_mul_ps(C.v, fLenghtC),
|
||||||
|
_mm512_mul_ps(D.v, fLenghtD),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static std::tuple<VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>, VectorF32<Len, Packing, Repeats>> Normalize(
|
||||||
|
VectorF32<Len, Packing, Repeats> A,
|
||||||
|
VectorF32<Len, Packing, Repeats> C
|
||||||
|
) requires(Packing == 2) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenght = Length(A, C);
|
||||||
|
constexpr float oneArr[] {1, 1, 1, 1};
|
||||||
|
__m128 one = _mm_loadu_ps(oneArr);
|
||||||
|
__m128 fLenght = _mm_div_ps(one, lenght.v);
|
||||||
|
|
||||||
|
__m128 fLenghtA = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(fLenght), 0b00'00'01'01));
|
||||||
|
__m128 fLenghtC = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(fLenght), 0b10'10'11'11));
|
||||||
|
|
||||||
|
return {
|
||||||
|
_mm_mul_ps(A.v, fLenghtA),
|
||||||
|
_mm_mul_ps(C.v, fLenghtC),
|
||||||
|
};
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenght = Length(A, C);
|
||||||
|
constexpr float oneArr[] {1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
|
__m256 one = _mm256_loadu_ps(oneArr);
|
||||||
|
__m256 fLenght = _mm256_div_ps(one, lenght.v);
|
||||||
|
|
||||||
|
__m256 fLenghtA = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(fLenght), 0b00'00'01'01));
|
||||||
|
__m256 fLenghtC = _mm256_castsi256_ps(_mm256_shuffle_epi32(_mm256_castps_si256(fLenght), 0b10'10'11'11));
|
||||||
|
return {
|
||||||
|
_mm256_mul_ps(A.v, fLenghtA),
|
||||||
|
_mm256_mul_ps(C.v, fLenghtC),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenght = Length(A, C);
|
||||||
|
constexpr float oneArr[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||||
|
__m512 one = _mm512_loadu_ps(oneArr);
|
||||||
|
__m512 fLenght = _mm512_div_ps(one, lenght.v);
|
||||||
|
|
||||||
|
__m512 fLenghtA = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(fLenght), 0b00'00'01'01));
|
||||||
|
__m512 fLenghtC = _mm512_castsi512_ps(_mm512_shuffle_epi32(_mm512_castps_si512(fLenght), 0b10'10'11'11));
|
||||||
|
return {
|
||||||
|
_mm512_mul_ps(A.v, fLenghtA),
|
||||||
|
_mm512_mul_ps(C.v, fLenghtC),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> Length(
|
||||||
|
VectorF32<Len, Packing, Repeats> A,
|
||||||
|
VectorF32<Len, Packing, Repeats> B,
|
||||||
|
VectorF32<Len, Packing, Repeats> C,
|
||||||
|
VectorF32<Len, Packing, Repeats> D
|
||||||
|
) requires(Packing == 1) {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenghtSq = LengthSq(A, B, C, D);
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_sqrt_ps(lenghtSq.v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_sqrt_ps(lenghtSq.v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_sqrt_ps(lenghtSq.v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> Length(
|
||||||
|
VectorF32<Len, Packing, Repeats> A,
|
||||||
|
VectorF32<Len, Packing, Repeats> C
|
||||||
|
) requires(Packing == 2) {
|
||||||
|
VectorF32<Len, Packing, Repeats> lenghtSq = LengthSq(A, C);
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm_sqrt_ps(lenghtSq.v));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm256_sqrt_ps(lenghtSq.v));
|
||||||
|
} else {
|
||||||
|
return VectorF32<Len, Packing, Repeats>(_mm512_sqrt_ps(lenghtSq.v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> LengthSq(
|
||||||
|
VectorF32<Len, Packing, Repeats> A,
|
||||||
|
VectorF32<Len, Packing, Repeats> B,
|
||||||
|
VectorF32<Len, Packing, Repeats> C,
|
||||||
|
VectorF32<Len, Packing, Repeats> D
|
||||||
|
) requires(Packing == 1) {
|
||||||
|
return Dot(A, A, B, B, C, C, D, D);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> LengthSq(
|
||||||
|
VectorF32<Len, Packing, Repeats> A,
|
||||||
|
VectorF32<Len, Packing, Repeats> C
|
||||||
|
) requires(Packing == 2) {
|
||||||
|
return Dot(A, A, C, C);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> Dot(
|
||||||
|
VectorF32<Len, Packing, Repeats> A0, VectorF32<Len, Packing, Repeats> A1,
|
||||||
|
VectorF32<Len, Packing, Repeats> B0, VectorF32<Len, Packing, Repeats> B1,
|
||||||
|
VectorF32<Len, Packing, Repeats> C0, VectorF32<Len, Packing, Repeats> C1,
|
||||||
|
VectorF32<Len, Packing, Repeats> D0, VectorF32<Len, Packing, Repeats> D1
|
||||||
|
) requires(Packing == 1) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
__m128 mulA = _mm_mul_ps(A0.v, A1.v);
|
||||||
|
__m128 mulB = _mm_mul_ps(B0.v, B1.v);
|
||||||
|
__m128i row12Temp1 = _mm_unpacklo_epi32(_mm_castps_si128(mulA), _mm_castps_si128(mulB)); // A1 B1 A2 B2
|
||||||
|
__m128i row56Temp1 = _mm_unpackhi_epi32(_mm_castps_si128(mulA), _mm_castps_si128(mulB)); // A3 B3 A4 B4
|
||||||
|
__m128i row1TempTemp1 = row12Temp1;
|
||||||
|
__m128i row5TempTemp1 = row56Temp1;
|
||||||
|
|
||||||
|
__m128 mulC = _mm_mul_ps(C0.v, C1.v);
|
||||||
|
__m128 mulD = _mm_mul_ps(D0.v, D1.v);
|
||||||
|
__m128i row34Temp1 = _mm_unpacklo_epi32(_mm_castps_si128(mulC), _mm_castps_si128(mulD)); // C1 D1 C2 D2
|
||||||
|
__m128i row78Temp1 = _mm_unpackhi_epi32(_mm_castps_si128(mulA), _mm_castps_si128(mulB)); // C3 D3 C4 D4
|
||||||
|
|
||||||
|
row12Temp1 = _mm_unpacklo_epi32(row12Temp1, row34Temp1); // A1 C1 B1 D1
|
||||||
|
row34Temp1 = _mm_unpackhi_epi32(row1TempTemp1, row34Temp1); // A2 C2 B2 D2
|
||||||
|
row56Temp1 = _mm_unpacklo_epi32(row56Temp1, row78Temp1); // A3 C3 B3 D3
|
||||||
|
row78Temp1 = _mm_unpackhi_epi32(row5TempTemp1, row78Temp1); // A4 C4 B4 D4
|
||||||
|
|
||||||
|
|
||||||
|
__m128 row1 = _mm_add_ps(row12Temp1, row34Temp1);
|
||||||
|
row1 = _mm_add_ps(row1, row56Temp1);
|
||||||
|
row1 = _mm_add_ps(row1, row78Temp1);
|
||||||
|
|
||||||
|
return row1;
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
__m256 mulA = _mm256_mul_ps(A0.v, A1.v);
|
||||||
|
__m256 mulB = _mm256_mul_ps(B0.v, B1.v);
|
||||||
|
__m256i row12Temp1 = _mm256_unpacklo_epi32(_mm256_castps_si256(mulA), _mm256_castps_si256(mulB)); // A1 B1 A2 B2
|
||||||
|
__m256i row56Temp1 = _mm256_unpackhi_epi32(_mm256_castps_si256(mulA), _mm256_castps_si256(mulB)); // A3 B3 A4 B4
|
||||||
|
__m256i row1TempTemp1 = row12Temp1;
|
||||||
|
__m256i row5TempTemp1 = row56Temp1;
|
||||||
|
|
||||||
|
__m256 mulC = _mm256_mul_ps(C0.v, C1.v);
|
||||||
|
__m256 mulD = _mm256_mul_ps(D0.v, D1.v);
|
||||||
|
__m256i row34Temp1 = _mm256_unpacklo_epi32(_mm256_castps_si256(mulC), _mm256_castps_si256(mulD)); // C1 D1 C2 D2
|
||||||
|
__m256i row78Temp1 = _mm256_unpackhi_epi32(_mm256_castps_si256(mulA), _mm256_castps_si256(mulB)); // C3 D3 C4 D4
|
||||||
|
|
||||||
|
row12Temp1 = _mm256_unpacklo_epi32(row12Temp1, row34Temp1); // A1 C1 B1 D1
|
||||||
|
row34Temp1 = _mm256_unpackhi_epi32(row1TempTemp1, row34Temp1); // A2 C2 B2 D2
|
||||||
|
row56Temp1 = _mm256_unpacklo_epi32(row56Temp1, row78Temp1); // A3 C3 B3 D3
|
||||||
|
row78Temp1 = _mm256_unpackhi_epi32(row5TempTemp1, row78Temp1); // A4 C4 B4 D4
|
||||||
|
|
||||||
|
|
||||||
|
__m256 row1 = _mm256_add_ps(row12Temp1, row34Temp1);
|
||||||
|
row1 = _mm256_add_ps(row1, row56Temp1);
|
||||||
|
row1 = _mm256_add_ps(row1, row78Temp1);
|
||||||
|
|
||||||
|
return row1;
|
||||||
|
} else {
|
||||||
|
__m512 mulA = _mm512_mul_ps(A0.v, A1.v);
|
||||||
|
__m512 mulB = _mm512_mul_ps(B0.v, B1.v);
|
||||||
|
__m512i row12Temp1 = _mm512_unpacklo_epi32(_mm512_castps_si512(mulA), _mm512_castps_si512(mulB)); // A1 B1 A2 B2
|
||||||
|
__m512i row56Temp1 = _mm512_unpackhi_epi32(_mm512_castps_si512(mulA), _mm512_castps_si512(mulB)); // A3 B3 A4 B4
|
||||||
|
__m512i row1TempTemp1 = row12Temp1;
|
||||||
|
__m512i row5TempTemp1 = row56Temp1;
|
||||||
|
|
||||||
|
__m512 mulC = _mm512_mul_ps(C0.v, C1.v);
|
||||||
|
__m512 mulD = _mm512_mul_ps(D0.v, D1.v);
|
||||||
|
__m512i row34Temp1 = _mm512_unpacklo_epi32(_mm512_castps_si512(mulC), _mm512_castps_si512(mulD)); // C1 D1 C2 D2
|
||||||
|
__m512i row78Temp1 = _mm512_unpackhi_epi32(_mm512_castps_si512(mulA), _mm512_castps_si512(mulB)); // C3 D3 C4 D4
|
||||||
|
|
||||||
|
row12Temp1 = _mm512_unpacklo_epi32(row12Temp1, row34Temp1); // A1 C1 B1 D1
|
||||||
|
row34Temp1 = _mm512_unpackhi_epi32(row1TempTemp1, row34Temp1); // A2 C2 B2 D2
|
||||||
|
row56Temp1 = _mm512_unpacklo_epi32(row56Temp1, row78Temp1); // A3 C3 B3 D3
|
||||||
|
row78Temp1 = _mm512_unpackhi_epi32(row5TempTemp1, row78Temp1); // A4 C4 B4 D4
|
||||||
|
|
||||||
|
|
||||||
|
__m512 row1 = _mm512_add_ps(row12Temp1, row34Temp1);
|
||||||
|
row1 = _mm512_add_ps(row1, row56Temp1);
|
||||||
|
row1 = _mm512_add_ps(row1, row78Temp1);
|
||||||
|
|
||||||
|
return row1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> Dot(
|
||||||
|
VectorF32<Len, Packing, Repeats> A0, VectorF32<Len, Packing, Repeats> A1,
|
||||||
|
VectorF32<Len, Packing, Repeats> C0, VectorF32<Len, Packing, Repeats> C1
|
||||||
|
) requires(Packing == 2) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
__m128 mulA = _mm_mul_ps(A0.v, A1.v);
|
||||||
|
__m128 mulB = _mm_mul_ps(C0.v, C1.v);
|
||||||
|
__m128i row12Temp1 = _mm_unpacklo_epi32(_mm_castps_si128(mulA), _mm_castps_si128(mulB)); // A1 C1 A2 C2
|
||||||
|
__m128i row56Temp1 = _mm_unpackhi_epi32(_mm_castps_si128(mulA), _mm_castps_si128(mulB)); // B1 D1 B2 D2
|
||||||
|
__m128i row1TempTemp1 = row12Temp1;
|
||||||
|
__m128i row5TempTemp1 = row56Temp1;
|
||||||
|
|
||||||
|
row12Temp1 = _mm_unpacklo_epi32(row12Temp1, row56Temp1); // A1 B1 C1 D1
|
||||||
|
row56Temp1 = _mm_unpackhi_epi32(row1TempTemp1, row56Temp1); // A2 B2 C2 D2
|
||||||
|
|
||||||
|
return _mm_add_ps(row12Temp1, row56Temp1);
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
__m256 mulA = _mm256_mul_ps(A0.v, A1.v);
|
||||||
|
__m256 mulB = _mm256_mul_ps(C0.v, C1.v);
|
||||||
|
__m256i row12Temp1 = _mm256_unpacklo_epi32(_mm256_castps_si256(mulA), _mm256_castps_si256(mulB)); // A1 C1 A2 C2
|
||||||
|
__m256i row56Temp1 = _mm256_unpackhi_epi32(_mm256_castps_si256(mulA), _mm256_castps_si256(mulB)); // B1 D1 B2 D2
|
||||||
|
__m256i row1TempTemp1 = row12Temp1;
|
||||||
|
__m256i row5TempTemp1 = row56Temp1;
|
||||||
|
|
||||||
|
row12Temp1 = _mm256_unpacklo_epi32(row12Temp1, row56Temp1); // A1 B1 C1 D1
|
||||||
|
row56Temp1 = _mm256_unpackhi_epi32(row1TempTemp1, row56Temp1); // A2 B2 C2 D2
|
||||||
|
|
||||||
|
return _mm256_add_ps(row12Temp1, row56Temp1);
|
||||||
|
} else {
|
||||||
|
__m512 mulA = _mm512_mul_ps(A0.v, A1.v);
|
||||||
|
__m512 mulB = _mm512_mul_ps(C0.v, C1.v);
|
||||||
|
__m512i row12Temp1 = _mm512_unpacklo_epi32(_mm512_castps_si512(mulA), _mm512_castps_si512(mulB)); // A1 C1 A2 C2
|
||||||
|
__m512i row56Temp1 = _mm512_unpackhi_epi32(_mm512_castps_si512(mulA), _mm512_castps_si512(mulB)); // B1 D1 B2 D2
|
||||||
|
__m512i row1TempTemp1 = row12Temp1;
|
||||||
|
__m512i row5TempTemp1 = row56Temp1;
|
||||||
|
|
||||||
|
row12Temp1 = _mm512_unpacklo_epi32(row12Temp1, row56Temp1); // A1 B1 C1 D1
|
||||||
|
row56Temp1 = _mm512_unpackhi_epi32(row1TempTemp1, row56Temp1); // A2 B2 C2 D2
|
||||||
|
|
||||||
|
return _mm512_add_ps(row12Temp1, row56Temp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::uint8_t A, std::uint8_t B, std::uint8_t C, std::uint8_t D>
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> Blend(VectorF32<Len, Packing, Repeats> a, VectorF32<Len, Packing, Repeats> b) {
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
constexpr std::uint8_t val =
|
||||||
|
(A & 1) |
|
||||||
|
((B & 1) << 1) |
|
||||||
|
((C & 1) << 2) |
|
||||||
|
((D & 1) << 3);
|
||||||
|
return _mm_castsi128_ps(_mm_blend_epi32(_mm_castps_si128(a.v), _mm_castps_si128(b), val));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
constexpr std::uint8_t val =
|
||||||
|
(A & 1) |
|
||||||
|
((B & 1) << 1) |
|
||||||
|
((C & 1) << 2) |
|
||||||
|
((D & 1) << 3);
|
||||||
|
return _mm256_castsi256_ps(_mm256_blend_epi32(_mm256_castps_si256(a.v), _mm256_castps_si256(b), val));
|
||||||
|
} else {
|
||||||
|
constexpr std::uint16_t val =
|
||||||
|
(A & 1) |
|
||||||
|
((B & 1) << 1) |
|
||||||
|
((C & 1) << 2) |
|
||||||
|
((D & 1) << 3) |
|
||||||
|
((A & 1) << 4) |
|
||||||
|
((B & 1) << 5) |
|
||||||
|
((C & 1) << 6) |
|
||||||
|
((D & 1) << 7) |
|
||||||
|
((A & 1) << 8) |
|
||||||
|
((B & 1) << 9) |
|
||||||
|
((C & 1) << 10) |
|
||||||
|
((D & 1) << 11) |
|
||||||
|
((A & 1) << 12) |
|
||||||
|
((B & 1) << 13) |
|
||||||
|
((C & 1) << 14) |
|
||||||
|
((D & 1) << 15);
|
||||||
|
return _mm512_castsi512_ps(_mm512_mask_blend_epi32(val, _mm512_castps_si512(a.v), _mm512_castps_si512(b)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<Len, Packing, Repeats> Rotate(VectorF32<3, 2, Repeats> v, VectorF32<4, 2, Repeats> q) requires(Len == 3 && Packing == 1) {
|
||||||
|
VectorF32<3, 2, Repeats> qv(q.v);
|
||||||
|
VectorF32<Len, Packing, Repeats> t = Cross(qv, v) * float(2);
|
||||||
|
return v + t * q.template Shuffle<3,3,3,3>(); + Cross(qv, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<4, 2, Repeats> RotatePivot(VectorF32<3, 2, Repeats> v, VectorF32<4, 2, Repeats> q, VectorF32<3, 2, Repeats> pivot) requires(Len == 3 && Packing == 1) {
|
||||||
|
VectorF32<Len, Packing, Repeats> translated = v - pivot;
|
||||||
|
VectorF32<3, 2, Repeats> qv(q.v);
|
||||||
|
VectorF32<Len, Packing, Repeats> t = Cross(qv, translated) * float(2);
|
||||||
|
VectorF32<Len, Packing, Repeats> rotated = translated + t * q.template Shuffle<3,3,3,3>() + Cross(qv, t);
|
||||||
|
return rotated + pivot;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static VectorF32<4, 2, Repeats> QuanternionFromEuler(VectorF32<3, 2, Repeats> EulerHalf) requires(Len == 3 && Packing == 1) {
|
||||||
|
VectorF32<3, 2, Repeats> sin = EulerHalf.Sin();
|
||||||
|
VectorF32<3, 2, Repeats> cos = EulerHalf.Cos();
|
||||||
|
|
||||||
|
VectorF32<3, 2, Repeats> row1 = cos.template Shuffle<0,0,0,0>();
|
||||||
|
row1 = VectorF32<3, 2, Repeats>::Blend<0,1,1,1>(sin, row1);
|
||||||
|
|
||||||
|
VectorF32<3, 2, Repeats> row2 = cos.template Shuffle<1,1,1,1>();
|
||||||
|
row2 = VectorF32<3, 2, Repeats>::Blend<1,0,1,1>(sin, row2);
|
||||||
|
|
||||||
|
row1 = row2;
|
||||||
|
|
||||||
|
VectorF32<3, 2, Repeats> row3 = cos.template Shuffle<2,2,2,2>();
|
||||||
|
row3 = VectorF32<3, 2, Repeats>::Blend<1,1,0,1>(sin, row3);
|
||||||
|
|
||||||
|
VectorF32<3, 2, Repeats> row4 = sin.template Shuffle<0,0,0,0>();
|
||||||
|
row4 = VectorF32<3, 2, Repeats>::Blend<1,0,0,0>(sin, row4);
|
||||||
|
|
||||||
|
|
||||||
|
if constexpr(std::is_same_v<VectorType, __m128>) {
|
||||||
|
constexpr std::uint64_t mask[] {0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000};
|
||||||
|
__m128i sign_mask = _mm_load_si128(reinterpret_cast<const __m128i*>(mask));
|
||||||
|
row4.v = (_mm_castsi128_ps(_mm_xor_si128(sign_mask, _mm_castps_si128(row4.v))));
|
||||||
|
} else if constexpr(std::is_same_v<VectorType, __m256>) {
|
||||||
|
constexpr std::uint64_t mask[] {0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000};
|
||||||
|
__m256i sign_mask = _mm256_load_si256(reinterpret_cast<const __m256i*>(mask));
|
||||||
|
row4.v = (_mm256_castsi256_ps(_mm256_xor_si256(sign_mask, _mm256_castps_si256(row4.v))));
|
||||||
|
} else {
|
||||||
|
constexpr std::uint64_t mask[] {0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000, 0b1000000000000000000000000000000010000000000000000000000000000000};
|
||||||
|
__m512i sign_mask = _mm512_load_si512(reinterpret_cast<const __m256i*>(mask));
|
||||||
|
row4.v = (_mm512_castsi512_ps(_mm512_xor_si512(sign_mask, _mm512_castps_si512(row4.v))));
|
||||||
|
}
|
||||||
|
|
||||||
|
row1 = MulitplyAdd(row1, row3, row4);
|
||||||
|
|
||||||
|
VectorF32<3, 2, Repeats> row5 = sin.template Shuffle<1,1,1,1>();
|
||||||
|
row5 = VectorF32<3, 2, Repeats>::Blend<0,1,0,0>(sin, row5);
|
||||||
|
|
||||||
|
row1 *= row5;
|
||||||
|
|
||||||
|
VectorF32<3, 2, Repeats> row6 = sin.template Shuffle<2,2,2,2>();
|
||||||
|
row6 = VectorF32<3, 2, Repeats>::Blend<0,0,1,0>(sin, row6);
|
||||||
|
|
||||||
|
return row1 * row6;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export template <std::uint32_t Len, std::uint32_t Packing, std::uint32_t Repeats>
|
||||||
|
struct std::formatter<Crafter::VectorF32<Len, Packing, Repeats>> : std::formatter<std::string> {
|
||||||
|
auto format(const Crafter::VectorF32<Len, Packing, Repeats>& obj, format_context& ctx) const {
|
||||||
|
Crafter::Vector<float, Len * Packing * Repeats, 0> vec = obj.template Store<Len * Packing * Repeats, 0>();
|
||||||
|
std::string out;
|
||||||
|
for(std::uint32_t i = 0; i < Repeats; i++) {
|
||||||
|
out += "{";
|
||||||
|
for(std::uint32_t i2 = 0; i2 < Packing; i2++) {
|
||||||
|
out += "{";
|
||||||
|
for(std::uint32_t i3 = 0; i3 < Len; i3++) {
|
||||||
|
out += std::format("{}", static_cast<float>(vec.v[i * Packing * Len + i2 * Len + i3]));
|
||||||
|
if (i3 + 1 < Len) out += ",";
|
||||||
|
}
|
||||||
|
out += "}";
|
||||||
|
}
|
||||||
|
out += "}";
|
||||||
|
}
|
||||||
|
return std::formatter<std::string>::format(out, ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -23,4 +23,5 @@ export import :Basic;
|
||||||
export import :Vector;
|
export import :Vector;
|
||||||
export import :MatrixRowMajor;
|
export import :MatrixRowMajor;
|
||||||
export import :Intersection;
|
export import :Intersection;
|
||||||
export import :VectorF16;
|
export import :VectorF16;
|
||||||
|
export import :VectorF32;
|
||||||
|
|
@ -5,6 +5,10 @@ import std;
|
||||||
using namespace Crafter;
|
using namespace Crafter;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
_Float16 test[] {0,1,2,3,0,1,2,3};
|
||||||
|
VectorF16L<4,1,2> vec(test);
|
||||||
|
VectorF16L<4,1,2> vec2(test);
|
||||||
|
std::println("{}", vec+vec2);
|
||||||
// std::random_device rd;
|
// std::random_device rd;
|
||||||
// std::mt19937 gen(rd());
|
// std::mt19937 gen(rd());
|
||||||
// std::uniform_real_distribution<float> dist(0, 100);
|
// std::uniform_real_distribution<float> dist(0, 100);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
"interfaces/Crafter.Math-MatrixRowMajor",
|
"interfaces/Crafter.Math-MatrixRowMajor",
|
||||||
"interfaces/Crafter.Math",
|
"interfaces/Crafter.Math",
|
||||||
"interfaces/Crafter.Math-Intersection",
|
"interfaces/Crafter.Math-Intersection",
|
||||||
"interfaces/Crafter.Math-VectorF16"
|
"interfaces/Crafter.Math-VectorF16",
|
||||||
|
"interfaces/Crafter.Math-VectorF32"
|
||||||
],
|
],
|
||||||
"implementations": []
|
"implementations": []
|
||||||
},
|
},
|
||||||
|
|
@ -28,7 +29,8 @@
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"implementations": ["interfaces/main"],
|
"implementations": ["interfaces/main"],
|
||||||
"extends": ["base"],
|
"extends": ["base"],
|
||||||
"debug": false
|
"debug": true,
|
||||||
|
"march": "raptorlake"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue