161template <
size_t D0,
size_t D1,
typename T>
166template <
size_t D0,
size_t D1,
typename T,
typename ConstOrNonConstT>
171template <
size_t D0,
size_t D1,
typename T>
175template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
182template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
187template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
193template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
198template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
203template <
size_t D0,
size_t D1,
typename T>
209template <
size_t D0,
size_t D1,
typename T>
214template <
size_t D0,
size_t D1,
typename T>
219template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
226template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
232template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
237template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
240#define MOCHI_DETAILS_UNROLL_OP_SCALAR_ARRAY(result, OP, a, b) \
241 if constexpr (D0 <= 4) { \
242 (result)[0] = a OP b[0]; \
243 if constexpr (D0 > 1) { \
244 (result)[1] = a OP b[1]; \
246 if constexpr (D0 > 2) { \
247 (result)[2] = a OP b[2]; \
249 if constexpr (D0 > 3) { \
250 (result)[3] = a OP b[3]; \
253 for (size_t i = 0; i < D0; ++i) { \
254 (result)[i] = a OP b[i]; \
259#define MOCHI_DETAILS_NDARRAY_SIMD_MEMBERWISE_OP(OP_EQ, OP) \
260 template <typename T, int N, size_t D0, size_t... DIMS> \
261 MOCHI_FORCE_INLINE constexpr NdArray<Simd<T, N>, D0, DIMS...> operator OP( \
262 NdArray<Simd<T, N>, D0, DIMS...> const& lhs, T rhs) { \
263 return lhs OP Simd<T, N>(rhs); \
265 template <typename T, int N, size_t D0, size_t... DIMS> \
266 MOCHI_FORCE_INLINE constexpr NdArray<Simd<T, N>, D0, DIMS...> operator OP( \
267 T lhs, NdArray<Simd<T, N>, D0, DIMS...> const& rhs) { \
268 NdArray<Simd<T, N>, D0, DIMS...> result{}; \
269 MOCHI_DETAILS_UNROLL_OP_SCALAR_ARRAY( \
270 result, OP, (Simd<T, N>{lhs}), rhs); \
279#undef MOCHI_DETAILS_NDARRAY_SIMD_MEMBERWISE_OP
280#undef MOCHI_DETAILS_UNROLL_OP_SCALAR_ARRAY
286template <
typename T,
size_t D0>
290 auto isEqual =
VEqual(lhs[0], rhs[0]);
291 if constexpr (D0 > 1) {
292 isEqual &=
VEqual(lhs[1], rhs[1]);
294 if constexpr (D0 > 2) {
295 isEqual &=
VEqual(lhs[2], rhs[2]);
297 if constexpr (D0 > 3) {
298 isEqual &=
VEqual(lhs[3], rhs[3]);
300 if constexpr (D0 > 4) {
301 for (
size_t i = 4; i < D0; ++i) {
302 isEqual &=
VEqual(lhs[i], rhs[i]);
308template <
typename T,
size_t D0,
size_t... DIMS>
312 return !(lhs == rhs);
377 Store(result[0].data(), m[0]);
378 Store(result[1].data(), m[1]);
386 Store(result[0].data(), m[0]);
387 Store(result[1].data(), m[1]);
388 Store(result[2].data(), m[2]);
389 Store(result[3].data(), m[3]);
414 return {v[0], v[1], z, w};
419 return {v[0], v[1], v[2], w};
424 return {v[0], v[1], v[2], v[3]};
429 return {m[0][0], m[0][1], m[1][0], m[1][1]};
457 for (
int i = 0; i < 3; ++i) {
458 for (
int j = 0; j < 3; ++j) {
473 for (
int i = 0; i < 3; ++i) {
474 for (
int j = 0; j < 3; ++j) {
484 for (
int i = 0; i < 3; ++i) {
493 for (
int i = 0; i < 3; ++i) {
503template <
size_t D0,
size_t D1,
typename T>
505 static_assert(D1 >= 1 && D1 <= 4,
"Unsupported size");
507 if constexpr ((D0 == 4) && (D1 == 3)) {
514 for (
size_t i = 0; i < D0 - 1; ++i) {
521template <
size_t D0,
size_t D1,
typename T,
typename ConstOrNonConstT>
527template <
size_t D0,
size_t D1,
typename T>
532template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
534 static_assert(D3 >= 1 && D3 <= 4,
"Unsupported size");
536 for (
size_t i = 0; i < D0; ++i) {
537 for (
size_t j = 0; j < D1; ++j) {
538 for (
size_t k = 0; k < D2; ++k) {
539 out[i][j][k] =
Load<int(D3), V>(x + i * D1 * D2 * D3 + j * D2 * D3 + k * D3);
545template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
552template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
554 static_assert(D1 >= 1 && D1 <= 4,
"Unsupported size");
555 static_assert(D0 <= D2 && D1 <= D3,
"Unsupported dimensions");
560 for (
size_t i = 0; i < D0 - 1; ++i) {
561 out[i] =
Load<V>(x + (coords[0] + i) * D3 + coords[1]);
566template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T,
typename ConstOrNonConstT>
573template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
579template <
size_t D0,
size_t D1,
typename T>
581 static_assert(D1 >= 1 && D1 <= 4,
"Unsupported size");
582 if constexpr ((D0 == 4) && (D1 == 3)) {
584 Store(out + 0 * D1, x[0]);
585 Store(out + 1 * D1, x[1]);
586 Store(out + 2 * D1, x[2]);
589 for (
size_t i = 0; i < D0 - 1; ++i) {
590 Store(out + i * D1, x[i]);
596template <
size_t D0,
size_t D1,
typename T>
602template <
size_t D0,
size_t D1,
typename T>
607template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
609 static_assert(D3 >= 1 && D3 <= 4,
"Unsupported size");
610 for (
size_t i = 0; i < D0; ++i) {
611 for (
size_t j = 0; j < D1; ++j) {
612 for (
size_t k = 0; k < D2; ++k) {
613 Store<int(D3)>(out + i * D1 * D2 * D3 + j * D2 * D3 + k * D3, x[i][j][k]);
619template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
626template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
628 static_assert(D1 >= 1 && D1 <= 4,
"Unsupported size");
629 static_assert(D0 <= D2 && D1 <= D3,
"Unsupported dimensions");
633 for (
size_t i = 0; i < D0; ++i) {
638template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
644template <
size_t D0,
size_t D1,
size_t D2,
size_t D3,
typename T>
654namespace ndarray_details {
655template <
class V,
size_t D0,
size_t... DIMS,
size_t... I>
657 NdArray<typename V::Scalar, D0, DIMS...>
const& a,
658 std::index_sequence<I...>) {
659 if constexpr (
sizeof...(DIMS) == 0) {
662 return NdArray<V, D0, DIMS...>{BroadcastEach<V>(a[I])...};
665template <
class V,
int N,
size_t... I>
667 Simd<typename V::Scalar, N>
const& a, std::index_sequence<I...>) {
668 if constexpr (V::kSize == N) {
684 return ndarray_details::BroadcastEach<V>(a, std::make_index_sequence<D0>());
692template <
class V,
int N, MOCHI_CONCEPT(IsSimd<V>)>
694 return ndarray_details::BroadcastEach<V>(a, std::make_index_sequence<(
size_t)N>());
702template <
class V,
int N, MOCHI_CONCEPT(IsSimd<V>&& N >= 3)>
704 if constexpr (V::kSize == N) {
717template <
class V,
size_t D0,
int D1, MOCHI_CONCEPT(IsSimd<V>&& D0 >= 3 && D1 >= 3)>
730template <
int kTupleCount = -1,
class V,
MOCHI_CONCEPT(IsSimd<V>)>
732 auto constexpr kTupleCount_ = (kTupleCount == -1) ? V::kSize : kTupleCount;
739template <
int kTupleCount = -1,
class V,
MOCHI_CONCEPT(IsSimd<V>)>
741 auto constexpr kTupleCount_ = (kTupleCount == -1) ? V::kSize : kTupleCount;
743 ptr, src[0], src[1], src[2]);
constexpr SizeT size() const
constexpr T * data() const
#define MOCHI_ASSERT_VERBOSE(condition_without_side_effects,...)
void LoadMatrix(NdArray< Simd< T, 4 >, D0 > &out, NdArray< T, D0, D1 > const &x)
Simd< T, 2 > Shuffle(Simd< T, 2 > a)
constexpr bool operator==(NdArray< T, D0, DIMS... > const &lhs, NdArray< T, D0, DIMS... > const &rhs)
NdArray< Simd< T, 4 >, 3, 3, 3 > ToSimdTensor(NdArray< T, 3, 3, 3, 3 > const &t)
NdArray< Simd< real, 4 >, 2 > VMatrix2x4r
Simd< T, 4 > ToSimdFromSymComponents2x2(T a00, T a01, T a11)
NdArray< Simd< real, 4 >, 3, 3 > VTensor3x3x3r
Simd< T, 4 > ToSimd(NdArray< T, 2 > const &v, T z=T(0), T w=T(0))
Simd< float, 4 > VSymMatrix2x2f
void LoadSubmatrix(NdArray< Simd< T, 4 >, D0 > &out, Int2 coords, NdArray< T, D2, D3 > const &x)
NdArray< Simd< float, 4 >, 3 > VMatrix3x4f
NdArray< Simd< real, 4 >, 3 > VMatrix3x3r
NdArray< T, 3, 3 > ToNdArray3x3(NdArray< Simd< T, 4 >, 3 > m)
NdArray< Simd< float, 4 >, 4 > VMatrix4x4f
Real3 ToReal3(Simd< T, 4 > v)
NdArray< Simd< float, 4 >, 3 > VMatrix3x3f
NdArray< V, 3 > Broadcast3(Simd< typename V::Scalar, N > const &a)
Simd< T, 4 > ToSimdSymMatrix(NdArray< T, 2, 2 > const &m)
NdArray< Simd< real, 4 >, 4, 3 > VTensor4x3x3r
Real4 ToReal4(Simd< T, 4 > v)
Simd< real, 4 > VSymMatrix2x2r
Special case for the SIMD representation of a 2x2 symmetric matrix.
NdArray< Simd< float, 4 >, 2 > VSymMatrix3x3f
V Broadcast(typename V::Scalar a)
NdArray< Simd< real, 4 >, 4 > VMatrix4x4r
NdArray< Simd< float, 4 >, 3, 3 > VTensor3x3x3f
Simd< T, N > Blend(Simd< T, N > a, Simd< T, N > b)
void StoreSubmatrix(NdArray< T, D2, D3 > &out, Int2 coords, NdArray< Simd< T, 4 >, D0 > const &x)
NdArray< Simd< float, 4 >, 2 > VMatrix2x4f
NdArray< T, 3, 3 > ToNdArraySym3x3(NdArray< Simd< T, 4 >, 2 > m)
NdArray< Simd< T, 4 >, 3 > SimdSymToFull(NdArray< Simd< T, 4 >, 2 > const &m)
NdArray< T, 4, 4 > ToNdArray(NdArray< Simd< T, 4 >, 4 > m)
NdArray< Simd< real, 4 >, 3 > VMatrix3x4r
NdArray< T, 2, 2 > ToNdArray2x2(Simd< T, 4 > m)
NdArray< Simd< double, 4 >, 3 > VMatrix3x3d
NdArray< Simd< T, 4 >, 2 > SimdFullToSym(NdArray< Simd< T, 4 >, 3 > const &m)
NdArray< Simd< real, 4 >, 3, 3, 3 > VTensor3x3x3x3r
SIMD representation of tensors.
NdArray< Simd< float, 4 >, 3 > VMatrix3x2f
NdArray< T, 3, 3, 3, 3 > ToNdArrayTensor(NdArray< Simd< T, 4 >, 3, 3, 3 > const &t)
NdArray< Simd< float, 4 >, 3, 3, 3 > VTensor3x3x3x3f
Simd< real, 4 > VMatrix2x2r
Special case for the SIMD representation of a 2x2 matrix.
void LoadTransposed(T const *ptr, Simd< T, N > &out0, Simd< T, N > &out1, Simd< T, N > &out2)
Simd< float, 4 > VMatrix2x2f
NdArray< Simd< float, 4 >, 4 > VMatrix4x3f
NdArray< Simd< real, 4 >, 2 > VSymMatrix3x3r
Special case for the SIMD representation of a 3x3 symmetric matrix.
void StoreTransposed(T *ptr, Simd< T, N > a, Simd< T, N > b, Simd< T, N > c)
void Store(T *ptr, Simd< T, N > a)
NdArray< Simd< real, 4 >, 2 > VMatrix2x3r
NdArray< Simd< real, 4 >, 4 > VMatrix4x3r
void StoreMatrix(NdArray< T, D0, D1 > &out, NdArray< Simd< T, 4 >, D0 > const &x)
constexpr bool operator!=(NdArray< T, D0, DIMS... > const &lhs, NdArray< T, D0, DIMS... > const &rhs)
Real2 ToReal2(Simd< T, 4 > v)
V Load(typename V::Scalar const *ptr)
NdArray< V, 3, 3 > Broadcast3x3(NdArray< Simd< typename V::Scalar, D1 >, D0 > const &a)
NdArray< Simd< real, 4 >, 3 > VMatrix3x2r
SIMD representation of a NxM matrices.
NdArray< V, D0, DIMS... > BroadcastEach(NdArray< typename V::Scalar, D0, DIMS... > const &a)
NdArray< Simd< float, 4 >, 2 > VMatrix2x3f
NdArray< T, 2, 2 > ToNdArraySym2x2(Simd< T, 4 > m)
Simd< T, 4 > ToSimdMatrix(NdArray< T, 2, 2 > const &m)
#define MOCHI_DETAILS_NDARRAY_SIMD_MEMBERWISE_OP(OP_EQ, OP)