// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2021 Everton Constantino (everton.constantino@hotmail.com) // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PACKING_OPS_NEON_H #define EIGEN_PACKING_OPS_NEON_H namespace Eigen { namespace internal { template struct PackMap<0, CPU, Index, Scalar, DataMapper, isLhs> { const Scalar *pBase; const Scalar *pCur; Index stride; Index offset; Index d2Size; Index shift; Index jump; PackMap(const Scalar *base, Index d2Size, Index stride, Index offset) : pBase(base), pCur(base), d2Size(d2Size), stride(stride), offset(offset) { shift = (d2Size / 4) * 4; jump = shift; } EIGEN_STRONG_INLINE void resetCur() { pCur = pBase; } EIGEN_STRONG_INLINE void moveTo(Index p1) { Index offset; if(isLhs) { if(p1 >= shift) { offset = static_cast(shift*d2Size + ((p1%4))*d2Size); jump = 1; } else { offset = p1; jump = shift; } } else { offset = static_cast(4*d2Size*(p1/4)); pCur = pBase + offset; } pCur = pBase + offset; } EIGEN_STRONG_INLINE void advance(int progress) { Index offset = static_cast(isLhs ? jump : progress); pCur += offset; } }; /* template constexpr int PACK_SHAPES_COUNT<0, CPU, Scalar, isLhs> = 3; template constexpr int PACK_SHAPES_COUNT<0, CPU, Scalar, true> = 4; template constexpr int PACK_SHAPES<0, CPU, Scalar, isLhs>[PACK_SHAPES_COUNT<0, CPU, Scalar, isLhs>][PACK_SHAPES_DIMENSION] = {{1,1,PACK_SHAPES_END},{4,1,0},{4,4,0}}; template constexpr int PACK_SHAPES<0, CPU, Scalar, true>[PACK_SHAPES_COUNT<0, CPU, Scalar, true>][PACK_SHAPES_DIMENSION] = {{1,1,PACK_SHAPES_END},{4,1,0},{4,4,0},{8,1,2}}; template struct PackingOperator<0, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, 4, 4> { EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data) { using Packet = typename packet_traits::type; constexpr int vectorSize = packet_traits::size; Scalar *c = block; if(!isLhs) { int tD = d1Idx; d1Idx = d2Idx; d2Idx = tD; } if(isLhs && StorageOrder == ColMajor || !isLhs && StorageOrder == RowMajor) { Packet p0 = data.template loadPacket(d1Idx, d2Idx + 0); Packet p1 = data.template loadPacket(d1Idx, d2Idx + 1); Packet p2 = data.template loadPacket(d1Idx, d2Idx + 2); Packet p3 = data.template loadPacket(d1Idx, d2Idx + 3); pstore(c + 0*vectorSize, p0); pstore(c + 1*vectorSize, p1); pstore(c + 2*vectorSize, p2); pstore(c + 3*vectorSize, p3); c+=4*vectorSize; } else { PacketBlock pblock; pblock.packet[0] = data.template loadPacket(d1Idx, d2Idx + 0); pblock.packet[1] = data.template loadPacket(d1Idx, d2Idx + 1); pblock.packet[2] = data.template loadPacket(d1Idx, d2Idx + 2); pblock.packet[3] = data.template loadPacket(d1Idx, d2Idx + 3); ptranspose(pblock); pstore(c + 0*vectorSize, pblock.packet[0]); pstore(c + 1*vectorSize, pblock.packet[1]); pstore(c + 2*vectorSize, pblock.packet[2]); pstore(c + 3*vectorSize, pblock.packet[3]); c+=4*vectorSize; } return c; } }; template struct PackingOperator<0, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, 8, 1> { EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data) { using Packet = typename packet_traits::type; Scalar *c = block; if(isLhs && StorageOrder == ColMajor) { Packet p = data.template loadPacket(d1Idx + 0, d2Idx); pstore(c, p); c+=4; p = data.template loadPacket(d1Idx + 4, d2Idx); pstore(c, p); c+=4; } else if(!isLhs && StorageOrder == RowMajor) { Packet p = data.template loadPacket(d2Idx, d1Idx + 0); pstore(c, p); c+=4; p = data.template loadPacket(d2Idx, d1Idx + 4); pstore(c, p); c+=4; } else { if(isLhs) { *c = data(d1Idx + 0, d2Idx + 0); c++; *c = data(d1Idx + 1, d2Idx + 0); c++; *c = data(d1Idx + 2, d2Idx + 0); c++; *c = data(d1Idx + 3, d2Idx + 0); c++; *c = data(d1Idx + 0, d2Idx + 4); c++; *c = data(d1Idx + 1, d2Idx + 4); c++; *c = data(d1Idx + 2, d2Idx + 4); c++; *c = data(d1Idx + 3, d2Idx + 4); c++; } else { *c = data(d2Idx, d1Idx + 0); c++; *c = data(d2Idx, d1Idx + 1); c++; *c = data(d2Idx, d1Idx + 2); c++; *c = data(d2Idx, d1Idx + 3); c++; *c = data(d2Idx + 4, d1Idx + 0); c++; *c = data(d2Idx + 4, d1Idx + 1); c++; *c = data(d2Idx + 4, d1Idx + 2); c++; *c = data(d2Idx + 4, d1Idx + 3); c++; } } return c; } }; template struct PackingOperator<0, CPU, Index, Scalar, isLhs, DataMapper, Conjugate, PanelMode, StorageOrder, 4, 1> { EIGEN_STRONG_INLINE Scalar* operator()(Index d1Idx, Index d2Idx, Scalar *block, const DataMapper& data) { using Packet = typename packet_traits::type; Scalar *c = block; if(isLhs && StorageOrder == ColMajor) { Packet p = data.template loadPacket(d1Idx, d2Idx); pstore(c, p); c+=4; } else if(!isLhs && StorageOrder == RowMajor) { Packet p = data.template loadPacket(d2Idx, d1Idx); pstore(c, p); c+=4; } else { if(isLhs) { *c = data(d1Idx + 0, d2Idx); c++; *c = data(d1Idx + 1, d2Idx); c++; *c = data(d1Idx + 2, d2Idx); c++; *c = data(d1Idx + 3, d2Idx); c++; } else { *c = data(d2Idx, d1Idx + 0); c++; *c = data(d2Idx, d1Idx + 1); c++; *c = data(d2Idx, d1Idx + 2); c++; *c = data(d2Idx, d1Idx + 3); c++; } } return c; } }; */ } // end namespace internal } // end namespace Eigen #endif // EIGEN_PACKING_OPS_NEON_H