@smake/eigen 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/eigen/Eigen/AccelerateSupport +52 -0
- package/eigen/Eigen/Cholesky +18 -20
- package/eigen/Eigen/CholmodSupport +28 -28
- package/eigen/Eigen/Core +187 -120
- package/eigen/Eigen/Eigenvalues +16 -13
- package/eigen/Eigen/Geometry +18 -18
- package/eigen/Eigen/Householder +9 -7
- package/eigen/Eigen/IterativeLinearSolvers +8 -4
- package/eigen/Eigen/Jacobi +14 -13
- package/eigen/Eigen/KLUSupport +23 -21
- package/eigen/Eigen/LU +15 -16
- package/eigen/Eigen/MetisSupport +12 -12
- package/eigen/Eigen/OrderingMethods +54 -51
- package/eigen/Eigen/PaStiXSupport +23 -21
- package/eigen/Eigen/PardisoSupport +17 -14
- package/eigen/Eigen/QR +18 -20
- package/eigen/Eigen/QtAlignedMalloc +5 -12
- package/eigen/Eigen/SPQRSupport +21 -14
- package/eigen/Eigen/SVD +23 -17
- package/eigen/Eigen/Sparse +1 -2
- package/eigen/Eigen/SparseCholesky +18 -15
- package/eigen/Eigen/SparseCore +18 -17
- package/eigen/Eigen/SparseLU +9 -9
- package/eigen/Eigen/SparseQR +16 -14
- package/eigen/Eigen/StdDeque +5 -2
- package/eigen/Eigen/StdList +5 -2
- package/eigen/Eigen/StdVector +5 -2
- package/eigen/Eigen/SuperLUSupport +30 -24
- package/eigen/Eigen/ThreadPool +80 -0
- package/eigen/Eigen/UmfPackSupport +19 -17
- package/eigen/Eigen/Version +14 -0
- package/eigen/Eigen/src/AccelerateSupport/AccelerateSupport.h +423 -0
- package/eigen/Eigen/src/AccelerateSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Cholesky/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Cholesky/LDLT.h +366 -405
- package/eigen/Eigen/src/Cholesky/LLT.h +323 -367
- package/eigen/Eigen/src/Cholesky/LLT_LAPACKE.h +81 -56
- package/eigen/Eigen/src/CholmodSupport/CholmodSupport.h +585 -529
- package/eigen/Eigen/src/CholmodSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Core/ArithmeticSequence.h +143 -317
- package/eigen/Eigen/src/Core/Array.h +329 -370
- package/eigen/Eigen/src/Core/ArrayBase.h +190 -203
- package/eigen/Eigen/src/Core/ArrayWrapper.h +126 -170
- package/eigen/Eigen/src/Core/Assign.h +30 -40
- package/eigen/Eigen/src/Core/AssignEvaluator.h +651 -604
- package/eigen/Eigen/src/Core/Assign_MKL.h +125 -120
- package/eigen/Eigen/src/Core/BandMatrix.h +267 -282
- package/eigen/Eigen/src/Core/Block.h +371 -390
- package/eigen/Eigen/src/Core/CommaInitializer.h +85 -100
- package/eigen/Eigen/src/Core/ConditionEstimator.h +51 -53
- package/eigen/Eigen/src/Core/CoreEvaluators.h +1214 -937
- package/eigen/Eigen/src/Core/CoreIterators.h +72 -63
- package/eigen/Eigen/src/Core/CwiseBinaryOp.h +112 -129
- package/eigen/Eigen/src/Core/CwiseNullaryOp.h +676 -702
- package/eigen/Eigen/src/Core/CwiseTernaryOp.h +77 -103
- package/eigen/Eigen/src/Core/CwiseUnaryOp.h +55 -67
- package/eigen/Eigen/src/Core/CwiseUnaryView.h +127 -92
- package/eigen/Eigen/src/Core/DenseBase.h +630 -658
- package/eigen/Eigen/src/Core/DenseCoeffsBase.h +511 -628
- package/eigen/Eigen/src/Core/DenseStorage.h +511 -590
- package/eigen/Eigen/src/Core/DeviceWrapper.h +153 -0
- package/eigen/Eigen/src/Core/Diagonal.h +168 -207
- package/eigen/Eigen/src/Core/DiagonalMatrix.h +346 -317
- package/eigen/Eigen/src/Core/DiagonalProduct.h +12 -10
- package/eigen/Eigen/src/Core/Dot.h +167 -217
- package/eigen/Eigen/src/Core/EigenBase.h +74 -85
- package/eigen/Eigen/src/Core/Fill.h +138 -0
- package/eigen/Eigen/src/Core/FindCoeff.h +464 -0
- package/eigen/Eigen/src/Core/ForceAlignedAccess.h +90 -113
- package/eigen/Eigen/src/Core/Fuzzy.h +82 -105
- package/eigen/Eigen/src/Core/GeneralProduct.h +315 -261
- package/eigen/Eigen/src/Core/GenericPacketMath.h +1182 -520
- package/eigen/Eigen/src/Core/GlobalFunctions.h +193 -157
- package/eigen/Eigen/src/Core/IO.h +131 -156
- package/eigen/Eigen/src/Core/IndexedView.h +209 -125
- package/eigen/Eigen/src/Core/InnerProduct.h +260 -0
- package/eigen/Eigen/src/Core/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Core/Inverse.h +50 -59
- package/eigen/Eigen/src/Core/Map.h +123 -141
- package/eigen/Eigen/src/Core/MapBase.h +255 -282
- package/eigen/Eigen/src/Core/MathFunctions.h +1247 -1201
- package/eigen/Eigen/src/Core/MathFunctionsImpl.h +162 -99
- package/eigen/Eigen/src/Core/Matrix.h +463 -494
- package/eigen/Eigen/src/Core/MatrixBase.h +468 -470
- package/eigen/Eigen/src/Core/NestByValue.h +58 -52
- package/eigen/Eigen/src/Core/NoAlias.h +79 -86
- package/eigen/Eigen/src/Core/NumTraits.h +206 -206
- package/eigen/Eigen/src/Core/PartialReduxEvaluator.h +163 -142
- package/eigen/Eigen/src/Core/PermutationMatrix.h +461 -511
- package/eigen/Eigen/src/Core/PlainObjectBase.h +858 -972
- package/eigen/Eigen/src/Core/Product.h +246 -130
- package/eigen/Eigen/src/Core/ProductEvaluators.h +779 -671
- package/eigen/Eigen/src/Core/Random.h +153 -164
- package/eigen/Eigen/src/Core/RandomImpl.h +262 -0
- package/eigen/Eigen/src/Core/RealView.h +250 -0
- package/eigen/Eigen/src/Core/Redux.h +334 -314
- package/eigen/Eigen/src/Core/Ref.h +259 -257
- package/eigen/Eigen/src/Core/Replicate.h +92 -104
- package/eigen/Eigen/src/Core/Reshaped.h +215 -271
- package/eigen/Eigen/src/Core/ReturnByValue.h +47 -55
- package/eigen/Eigen/src/Core/Reverse.h +133 -148
- package/eigen/Eigen/src/Core/Select.h +68 -140
- package/eigen/Eigen/src/Core/SelfAdjointView.h +254 -290
- package/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h +23 -20
- package/eigen/Eigen/src/Core/SkewSymmetricMatrix3.h +382 -0
- package/eigen/Eigen/src/Core/Solve.h +88 -102
- package/eigen/Eigen/src/Core/SolveTriangular.h +126 -124
- package/eigen/Eigen/src/Core/SolverBase.h +132 -133
- package/eigen/Eigen/src/Core/StableNorm.h +113 -147
- package/eigen/Eigen/src/Core/StlIterators.h +404 -248
- package/eigen/Eigen/src/Core/Stride.h +90 -92
- package/eigen/Eigen/src/Core/Swap.h +70 -39
- package/eigen/Eigen/src/Core/Transpose.h +258 -295
- package/eigen/Eigen/src/Core/Transpositions.h +270 -333
- package/eigen/Eigen/src/Core/TriangularMatrix.h +642 -743
- package/eigen/Eigen/src/Core/VectorBlock.h +59 -72
- package/eigen/Eigen/src/Core/VectorwiseOp.h +653 -704
- package/eigen/Eigen/src/Core/Visitor.h +464 -308
- package/eigen/Eigen/src/Core/arch/AVX/Complex.h +380 -187
- package/eigen/Eigen/src/Core/arch/AVX/MathFunctions.h +65 -163
- package/eigen/Eigen/src/Core/arch/AVX/PacketMath.h +2145 -638
- package/eigen/Eigen/src/Core/arch/AVX/Reductions.h +353 -0
- package/eigen/Eigen/src/Core/arch/AVX/TypeCasting.h +253 -60
- package/eigen/Eigen/src/Core/arch/AVX512/Complex.h +278 -228
- package/eigen/Eigen/src/Core/arch/AVX512/GemmKernel.h +1245 -0
- package/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h +48 -269
- package/eigen/Eigen/src/Core/arch/AVX512/MathFunctionsFP16.h +75 -0
- package/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h +1597 -754
- package/eigen/Eigen/src/Core/arch/AVX512/PacketMathFP16.h +1413 -0
- package/eigen/Eigen/src/Core/arch/AVX512/Reductions.h +297 -0
- package/eigen/Eigen/src/Core/arch/AVX512/TrsmKernel.h +1167 -0
- package/eigen/Eigen/src/Core/arch/AVX512/TrsmUnrolls.inc +1219 -0
- package/eigen/Eigen/src/Core/arch/AVX512/TypeCasting.h +229 -41
- package/eigen/Eigen/src/Core/arch/AVX512/TypeCastingFP16.h +130 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/Complex.h +420 -184
- package/eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h +40 -49
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2962 -2213
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +196 -212
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +713 -441
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMAbfloat16.h +742 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/MatrixVectorProduct.inc +2818 -0
- package/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h +2380 -1362
- package/eigen/Eigen/src/Core/arch/AltiVec/TypeCasting.h +153 -0
- package/eigen/Eigen/src/Core/arch/Default/BFloat16.h +390 -224
- package/eigen/Eigen/src/Core/arch/Default/ConjHelper.h +78 -67
- package/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1784 -799
- package/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +167 -50
- package/eigen/Eigen/src/Core/arch/Default/Half.h +528 -379
- package/eigen/Eigen/src/Core/arch/Default/Settings.h +10 -12
- package/eigen/Eigen/src/Core/arch/GPU/Complex.h +244 -0
- package/eigen/Eigen/src/Core/arch/GPU/MathFunctions.h +41 -40
- package/eigen/Eigen/src/Core/arch/GPU/PacketMath.h +550 -523
- package/eigen/Eigen/src/Core/arch/GPU/Tuple.h +268 -0
- package/eigen/Eigen/src/Core/arch/GPU/TypeCasting.h +27 -30
- package/eigen/Eigen/src/Core/arch/HIP/hcc/math_constants.h +8 -8
- package/eigen/Eigen/src/Core/arch/HVX/PacketMath.h +1088 -0
- package/eigen/Eigen/src/Core/arch/LSX/Complex.h +520 -0
- package/eigen/Eigen/src/Core/arch/LSX/GeneralBlockPanelKernel.h +23 -0
- package/eigen/Eigen/src/Core/arch/LSX/MathFunctions.h +43 -0
- package/eigen/Eigen/src/Core/arch/LSX/PacketMath.h +2866 -0
- package/eigen/Eigen/src/Core/arch/LSX/TypeCasting.h +526 -0
- package/eigen/Eigen/src/Core/arch/MSA/Complex.h +54 -82
- package/eigen/Eigen/src/Core/arch/MSA/MathFunctions.h +84 -92
- package/eigen/Eigen/src/Core/arch/MSA/PacketMath.h +51 -47
- package/eigen/Eigen/src/Core/arch/NEON/Complex.h +454 -306
- package/eigen/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +175 -115
- package/eigen/Eigen/src/Core/arch/NEON/MathFunctions.h +23 -30
- package/eigen/Eigen/src/Core/arch/NEON/PacketMath.h +4366 -2857
- package/eigen/Eigen/src/Core/arch/NEON/TypeCasting.h +616 -393
- package/eigen/Eigen/src/Core/arch/NEON/UnaryFunctors.h +57 -0
- package/eigen/Eigen/src/Core/arch/SSE/Complex.h +350 -198
- package/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h +38 -149
- package/eigen/Eigen/src/Core/arch/SSE/PacketMath.h +1791 -912
- package/eigen/Eigen/src/Core/arch/SSE/Reductions.h +324 -0
- package/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h +128 -40
- package/eigen/Eigen/src/Core/arch/SVE/MathFunctions.h +10 -6
- package/eigen/Eigen/src/Core/arch/SVE/PacketMath.h +156 -234
- package/eigen/Eigen/src/Core/arch/SVE/TypeCasting.h +6 -3
- package/eigen/Eigen/src/Core/arch/SYCL/InteropHeaders.h +27 -32
- package/eigen/Eigen/src/Core/arch/SYCL/MathFunctions.h +119 -117
- package/eigen/Eigen/src/Core/arch/SYCL/PacketMath.h +325 -419
- package/eigen/Eigen/src/Core/arch/SYCL/TypeCasting.h +15 -17
- package/eigen/Eigen/src/Core/arch/ZVector/Complex.h +325 -181
- package/eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h +94 -83
- package/eigen/Eigen/src/Core/arch/ZVector/PacketMath.h +811 -458
- package/eigen/Eigen/src/Core/functors/AssignmentFunctors.h +121 -124
- package/eigen/Eigen/src/Core/functors/BinaryFunctors.h +576 -370
- package/eigen/Eigen/src/Core/functors/NullaryFunctors.h +194 -109
- package/eigen/Eigen/src/Core/functors/StlFunctors.h +95 -112
- package/eigen/Eigen/src/Core/functors/TernaryFunctors.h +34 -7
- package/eigen/Eigen/src/Core/functors/UnaryFunctors.h +1038 -749
- package/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h +1883 -1375
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h +312 -370
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +189 -176
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +84 -81
- package/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +154 -73
- package/eigen/Eigen/src/Core/products/GeneralMatrixVector.h +292 -337
- package/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +80 -77
- package/eigen/Eigen/src/Core/products/Parallelizer.h +207 -105
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +327 -388
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +206 -224
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h +138 -147
- package/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +58 -61
- package/eigen/Eigen/src/Core/products/SelfadjointProduct.h +71 -71
- package/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h +48 -47
- package/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h +294 -369
- package/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +246 -238
- package/eigen/Eigen/src/Core/products/TriangularMatrixVector.h +244 -247
- package/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +212 -192
- package/eigen/Eigen/src/Core/products/TriangularSolverMatrix.h +328 -277
- package/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +108 -109
- package/eigen/Eigen/src/Core/products/TriangularSolverVector.h +68 -94
- package/eigen/Eigen/src/Core/util/Assert.h +158 -0
- package/eigen/Eigen/src/Core/util/BlasUtil.h +342 -303
- package/eigen/Eigen/src/Core/util/ConfigureVectorization.h +348 -317
- package/eigen/Eigen/src/Core/util/Constants.h +297 -262
- package/eigen/Eigen/src/Core/util/DisableStupidWarnings.h +130 -90
- package/eigen/Eigen/src/Core/util/EmulateArray.h +270 -0
- package/eigen/Eigen/src/Core/util/ForwardDeclarations.h +449 -247
- package/eigen/Eigen/src/Core/util/GpuHipCudaDefines.inc +101 -0
- package/eigen/Eigen/src/Core/util/GpuHipCudaUndefines.inc +45 -0
- package/eigen/Eigen/src/Core/util/IndexedViewHelper.h +417 -116
- package/eigen/Eigen/src/Core/util/IntegralConstant.h +211 -204
- package/eigen/Eigen/src/Core/util/MKL_support.h +39 -37
- package/eigen/Eigen/src/Core/util/Macros.h +655 -773
- package/eigen/Eigen/src/Core/util/MaxSizeVector.h +139 -0
- package/eigen/Eigen/src/Core/util/Memory.h +970 -748
- package/eigen/Eigen/src/Core/util/Meta.h +581 -633
- package/eigen/Eigen/src/Core/util/MoreMeta.h +638 -0
- package/eigen/Eigen/src/Core/util/ReenableStupidWarnings.h +32 -19
- package/eigen/Eigen/src/Core/util/ReshapedHelper.h +17 -17
- package/eigen/Eigen/src/Core/util/Serializer.h +209 -0
- package/eigen/Eigen/src/Core/util/StaticAssert.h +50 -166
- package/eigen/Eigen/src/Core/util/SymbolicIndex.h +377 -225
- package/eigen/Eigen/src/Core/util/XprHelper.h +784 -547
- package/eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h +246 -277
- package/eigen/Eigen/src/Eigenvalues/ComplexSchur.h +299 -319
- package/eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +52 -48
- package/eigen/Eigen/src/Eigenvalues/EigenSolver.h +413 -456
- package/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +309 -325
- package/eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +157 -171
- package/eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h +292 -310
- package/eigen/Eigen/src/Eigenvalues/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +89 -105
- package/eigen/Eigen/src/Eigenvalues/RealQZ.h +537 -607
- package/eigen/Eigen/src/Eigenvalues/RealSchur.h +342 -381
- package/eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +41 -35
- package/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +541 -595
- package/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +47 -44
- package/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h +430 -462
- package/eigen/Eigen/src/Geometry/AlignedBox.h +226 -227
- package/eigen/Eigen/src/Geometry/AngleAxis.h +131 -133
- package/eigen/Eigen/src/Geometry/EulerAngles.h +163 -74
- package/eigen/Eigen/src/Geometry/Homogeneous.h +285 -333
- package/eigen/Eigen/src/Geometry/Hyperplane.h +151 -160
- package/eigen/Eigen/src/Geometry/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Geometry/OrthoMethods.h +168 -146
- package/eigen/Eigen/src/Geometry/ParametrizedLine.h +127 -127
- package/eigen/Eigen/src/Geometry/Quaternion.h +566 -506
- package/eigen/Eigen/src/Geometry/Rotation2D.h +107 -105
- package/eigen/Eigen/src/Geometry/RotationBase.h +148 -145
- package/eigen/Eigen/src/Geometry/Scaling.h +113 -106
- package/eigen/Eigen/src/Geometry/Transform.h +858 -936
- package/eigen/Eigen/src/Geometry/Translation.h +94 -92
- package/eigen/Eigen/src/Geometry/Umeyama.h +79 -84
- package/eigen/Eigen/src/Geometry/arch/Geometry_SIMD.h +90 -104
- package/eigen/Eigen/src/Householder/BlockHouseholder.h +51 -46
- package/eigen/Eigen/src/Householder/Householder.h +102 -124
- package/eigen/Eigen/src/Householder/HouseholderSequence.h +412 -453
- package/eigen/Eigen/src/Householder/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +149 -162
- package/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +124 -119
- package/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +92 -104
- package/eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +251 -243
- package/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +224 -228
- package/eigen/Eigen/src/IterativeLinearSolvers/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +178 -227
- package/eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +79 -84
- package/eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +54 -60
- package/eigen/Eigen/src/Jacobi/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/Jacobi/Jacobi.h +252 -308
- package/eigen/Eigen/src/KLUSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/KLUSupport/KLUSupport.h +208 -227
- package/eigen/Eigen/src/LU/Determinant.h +50 -69
- package/eigen/Eigen/src/LU/FullPivLU.h +545 -596
- package/eigen/Eigen/src/LU/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/LU/InverseImpl.h +206 -285
- package/eigen/Eigen/src/LU/PartialPivLU.h +390 -428
- package/eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h +54 -40
- package/eigen/Eigen/src/LU/arch/InverseSize4.h +72 -70
- package/eigen/Eigen/src/MetisSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/MetisSupport/MetisSupport.h +81 -93
- package/eigen/Eigen/src/OrderingMethods/Amd.h +243 -265
- package/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h +831 -1004
- package/eigen/Eigen/src/OrderingMethods/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/OrderingMethods/Ordering.h +112 -119
- package/eigen/Eigen/src/PaStiXSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h +524 -570
- package/eigen/Eigen/src/PardisoSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/PardisoSupport/PardisoSupport.h +385 -430
- package/eigen/Eigen/src/QR/ColPivHouseholderQR.h +479 -479
- package/eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +120 -56
- package/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h +166 -153
- package/eigen/Eigen/src/QR/FullPivHouseholderQR.h +495 -475
- package/eigen/Eigen/src/QR/HouseholderQR.h +394 -285
- package/eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h +32 -23
- package/eigen/Eigen/src/QR/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SPQRSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +244 -264
- package/eigen/Eigen/src/SVD/BDCSVD.h +817 -713
- package/eigen/Eigen/src/SVD/BDCSVD_LAPACKE.h +174 -0
- package/eigen/Eigen/src/SVD/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SVD/JacobiSVD.h +577 -543
- package/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h +85 -49
- package/eigen/Eigen/src/SVD/SVDBase.h +242 -182
- package/eigen/Eigen/src/SVD/UpperBidiagonalization.h +200 -235
- package/eigen/Eigen/src/SparseCholesky/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h +765 -594
- package/eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +308 -94
- package/eigen/Eigen/src/SparseCore/AmbiVector.h +202 -251
- package/eigen/Eigen/src/SparseCore/CompressedStorage.h +184 -252
- package/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +134 -178
- package/eigen/Eigen/src/SparseCore/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseCore/SparseAssign.h +149 -140
- package/eigen/Eigen/src/SparseCore/SparseBlock.h +403 -440
- package/eigen/Eigen/src/SparseCore/SparseColEtree.h +100 -112
- package/eigen/Eigen/src/SparseCore/SparseCompressedBase.h +525 -303
- package/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +555 -339
- package/eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +100 -108
- package/eigen/Eigen/src/SparseCore/SparseDenseProduct.h +169 -197
- package/eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h +71 -71
- package/eigen/Eigen/src/SparseCore/SparseDot.h +49 -47
- package/eigen/Eigen/src/SparseCore/SparseFuzzy.h +13 -11
- package/eigen/Eigen/src/SparseCore/SparseMap.h +243 -253
- package/eigen/Eigen/src/SparseCore/SparseMatrix.h +1603 -1245
- package/eigen/Eigen/src/SparseCore/SparseMatrixBase.h +403 -350
- package/eigen/Eigen/src/SparseCore/SparsePermutation.h +186 -115
- package/eigen/Eigen/src/SparseCore/SparseProduct.h +94 -97
- package/eigen/Eigen/src/SparseCore/SparseRedux.h +22 -24
- package/eigen/Eigen/src/SparseCore/SparseRef.h +268 -295
- package/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h +370 -416
- package/eigen/Eigen/src/SparseCore/SparseSolverBase.h +78 -87
- package/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +81 -95
- package/eigen/Eigen/src/SparseCore/SparseTranspose.h +62 -71
- package/eigen/Eigen/src/SparseCore/SparseTriangularView.h +132 -144
- package/eigen/Eigen/src/SparseCore/SparseUtil.h +138 -115
- package/eigen/Eigen/src/SparseCore/SparseVector.h +426 -372
- package/eigen/Eigen/src/SparseCore/SparseView.h +164 -193
- package/eigen/Eigen/src/SparseCore/TriangularSolver.h +129 -170
- package/eigen/Eigen/src/SparseLU/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseLU/SparseLU.h +756 -710
- package/eigen/Eigen/src/SparseLU/SparseLUImpl.h +61 -48
- package/eigen/Eigen/src/SparseLU/SparseLU_Memory.h +102 -118
- package/eigen/Eigen/src/SparseLU/SparseLU_Structs.h +38 -35
- package/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +245 -301
- package/eigen/Eigen/src/SparseLU/SparseLU_Utils.h +44 -49
- package/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h +104 -108
- package/eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h +89 -100
- package/eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +57 -58
- package/eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +43 -55
- package/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +74 -71
- package/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h +124 -132
- package/eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h +136 -159
- package/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h +51 -52
- package/eigen/Eigen/src/SparseLU/SparseLU_pruneL.h +67 -73
- package/eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h +24 -26
- package/eigen/Eigen/src/SparseQR/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SparseQR/SparseQR.h +450 -502
- package/eigen/Eigen/src/StlSupport/StdDeque.h +28 -93
- package/eigen/Eigen/src/StlSupport/StdList.h +28 -84
- package/eigen/Eigen/src/StlSupport/StdVector.h +28 -108
- package/eigen/Eigen/src/StlSupport/details.h +48 -50
- package/eigen/Eigen/src/SuperLUSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h +634 -730
- package/eigen/Eigen/src/ThreadPool/Barrier.h +70 -0
- package/eigen/Eigen/src/ThreadPool/CoreThreadPoolDevice.h +336 -0
- package/eigen/Eigen/src/ThreadPool/EventCount.h +241 -0
- package/eigen/Eigen/src/ThreadPool/ForkJoin.h +140 -0
- package/eigen/Eigen/src/ThreadPool/InternalHeaderCheck.h +4 -0
- package/eigen/Eigen/src/ThreadPool/NonBlockingThreadPool.h +587 -0
- package/eigen/Eigen/src/ThreadPool/RunQueue.h +230 -0
- package/eigen/Eigen/src/ThreadPool/ThreadCancel.h +21 -0
- package/eigen/Eigen/src/ThreadPool/ThreadEnvironment.h +43 -0
- package/eigen/Eigen/src/ThreadPool/ThreadLocal.h +289 -0
- package/eigen/Eigen/src/ThreadPool/ThreadPoolInterface.h +50 -0
- package/eigen/Eigen/src/ThreadPool/ThreadYield.h +16 -0
- package/eigen/Eigen/src/UmfPackSupport/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h +428 -464
- package/eigen/Eigen/src/misc/Image.h +41 -43
- package/eigen/Eigen/src/misc/InternalHeaderCheck.h +3 -0
- package/eigen/Eigen/src/misc/Kernel.h +39 -41
- package/eigen/Eigen/src/misc/RealSvd2x2.h +19 -21
- package/eigen/Eigen/src/misc/blas.h +83 -426
- package/eigen/Eigen/src/misc/lapacke.h +9972 -16179
- package/eigen/Eigen/src/misc/lapacke_helpers.h +163 -0
- package/eigen/Eigen/src/misc/lapacke_mangling.h +4 -5
- package/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.inc +344 -0
- package/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.inc +544 -0
- package/eigen/Eigen/src/plugins/{BlockMethods.h → BlockMethods.inc} +434 -506
- package/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.inc +116 -0
- package/eigen/Eigen/src/plugins/{CommonCwiseUnaryOps.h → CommonCwiseUnaryOps.inc} +58 -68
- package/eigen/Eigen/src/plugins/IndexedViewMethods.inc +192 -0
- package/eigen/Eigen/src/plugins/InternalHeaderCheck.inc +3 -0
- package/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.inc +331 -0
- package/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.inc +118 -0
- package/eigen/Eigen/src/plugins/ReshapedMethods.inc +133 -0
- package/package.json +1 -1
- package/eigen/COPYING.APACHE +0 -203
- package/eigen/COPYING.BSD +0 -26
- package/eigen/COPYING.GPL +0 -674
- package/eigen/COPYING.LGPL +0 -502
- package/eigen/COPYING.MINPACK +0 -51
- package/eigen/COPYING.MPL2 +0 -373
- package/eigen/COPYING.README +0 -18
- package/eigen/Eigen/src/Core/BooleanRedux.h +0 -162
- package/eigen/Eigen/src/Core/arch/CUDA/Complex.h +0 -258
- package/eigen/Eigen/src/Core/arch/Default/TypeCasting.h +0 -120
- package/eigen/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +0 -694
- package/eigen/Eigen/src/Core/util/NonMPL2.h +0 -3
- package/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h +0 -67
- package/eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +0 -280
- package/eigen/Eigen/src/misc/lapack.h +0 -152
- package/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h +0 -358
- package/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h +0 -696
- package/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h +0 -115
- package/eigen/Eigen/src/plugins/IndexedViewMethods.h +0 -262
- package/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h +0 -152
- package/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h +0 -95
- package/eigen/Eigen/src/plugins/ReshapedMethods.h +0 -149
- package/eigen/README.md +0 -5
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
#ifndef EIGEN_PACKET_MATH_AVX_H
|
|
11
11
|
#define EIGEN_PACKET_MATH_AVX_H
|
|
12
12
|
|
|
13
|
+
// IWYU pragma: private
|
|
14
|
+
#include "../../InternalHeaderCheck.h"
|
|
15
|
+
|
|
13
16
|
namespace Eigen {
|
|
14
17
|
|
|
15
18
|
namespace internal {
|
|
@@ -28,85 +31,132 @@ namespace internal {
|
|
|
28
31
|
#endif
|
|
29
32
|
#endif
|
|
30
33
|
|
|
31
|
-
typedef __m256
|
|
32
|
-
typedef __m256i Packet8i;
|
|
34
|
+
typedef __m256 Packet8f;
|
|
35
|
+
typedef eigen_packet_wrapper<__m256i, 0> Packet8i;
|
|
33
36
|
typedef __m256d Packet4d;
|
|
37
|
+
#ifndef EIGEN_VECTORIZE_AVX512FP16
|
|
34
38
|
typedef eigen_packet_wrapper<__m128i, 2> Packet8h;
|
|
39
|
+
#endif
|
|
35
40
|
typedef eigen_packet_wrapper<__m128i, 3> Packet8bf;
|
|
41
|
+
typedef eigen_packet_wrapper<__m256i, 4> Packet8ui;
|
|
36
42
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
#define _EIGEN_DECLARE_CONST_Packet8f(NAME,X) \
|
|
44
|
-
const Packet8f p8f_##NAME = pset1<Packet8f>(X)
|
|
45
|
-
|
|
46
|
-
#define _EIGEN_DECLARE_CONST_Packet4d(NAME,X) \
|
|
47
|
-
const Packet4d p4d_##NAME = pset1<Packet4d>(X)
|
|
48
|
-
|
|
49
|
-
#define _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(NAME,X) \
|
|
50
|
-
const Packet8f p8f_##NAME = _mm256_castsi256_ps(pset1<Packet8i>(X))
|
|
43
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
44
|
+
// Start from 3 to be compatible with AVX512
|
|
45
|
+
typedef eigen_packet_wrapper<__m256i, 3> Packet4l;
|
|
46
|
+
typedef eigen_packet_wrapper<__m256i, 5> Packet4ul;
|
|
47
|
+
#endif
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
template <>
|
|
50
|
+
struct is_arithmetic<__m256> {
|
|
51
|
+
enum { value = true };
|
|
52
|
+
};
|
|
53
|
+
template <>
|
|
54
|
+
struct is_arithmetic<__m256i> {
|
|
55
|
+
enum { value = true };
|
|
56
|
+
};
|
|
57
|
+
template <>
|
|
58
|
+
struct is_arithmetic<__m256d> {
|
|
59
|
+
enum { value = true };
|
|
60
|
+
};
|
|
61
|
+
template <>
|
|
62
|
+
struct is_arithmetic<Packet8i> {
|
|
63
|
+
enum { value = true };
|
|
64
|
+
};
|
|
65
|
+
// Note that `Packet8ui` uses the underlying type `__m256i`, which is
|
|
66
|
+
// interpreted as a vector of _signed_ `int32`s, which breaks some arithmetic
|
|
67
|
+
// operations used in `GenericPacketMath.h`.
|
|
68
|
+
template <>
|
|
69
|
+
struct is_arithmetic<Packet8ui> {
|
|
70
|
+
enum { value = false };
|
|
71
|
+
};
|
|
72
|
+
#ifndef EIGEN_VECTORIZE_AVX512FP16
|
|
73
|
+
template <>
|
|
74
|
+
struct is_arithmetic<Packet8h> {
|
|
75
|
+
enum { value = true };
|
|
76
|
+
};
|
|
77
|
+
#endif
|
|
78
|
+
template <>
|
|
79
|
+
struct is_arithmetic<Packet8bf> {
|
|
80
|
+
enum { value = true };
|
|
81
|
+
};
|
|
82
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
83
|
+
template <>
|
|
84
|
+
struct is_arithmetic<Packet4l> {
|
|
85
|
+
enum { value = true };
|
|
86
|
+
};
|
|
87
|
+
// Note that `Packet4ul` uses the underlying type `__m256i`, which is
|
|
88
|
+
// interpreted as a vector of _signed_ `int32`s, which breaks some arithmetic
|
|
89
|
+
// operations used in `GenericPacketMath.h`.
|
|
90
|
+
template <>
|
|
91
|
+
struct is_arithmetic<Packet4ul> {
|
|
92
|
+
enum { value = false };
|
|
93
|
+
};
|
|
94
|
+
#endif
|
|
54
95
|
|
|
55
96
|
// Use the packet_traits defined in AVX512/PacketMath.h instead if we're going
|
|
56
97
|
// to leverage AVX512 instructions.
|
|
57
98
|
#ifndef EIGEN_VECTORIZE_AVX512
|
|
58
|
-
template<>
|
|
59
|
-
{
|
|
99
|
+
template <>
|
|
100
|
+
struct packet_traits<float> : default_packet_traits {
|
|
60
101
|
typedef Packet8f type;
|
|
61
102
|
typedef Packet4f half;
|
|
62
103
|
enum {
|
|
63
104
|
Vectorizable = 1,
|
|
64
105
|
AlignedOnScalar = 1,
|
|
65
106
|
size = 8,
|
|
66
|
-
HasHalfPacket = 1,
|
|
67
107
|
|
|
68
|
-
HasCmp
|
|
108
|
+
HasCmp = 1,
|
|
69
109
|
HasDiv = 1,
|
|
110
|
+
HasReciprocal = EIGEN_FAST_MATH,
|
|
70
111
|
HasSin = EIGEN_FAST_MATH,
|
|
71
112
|
HasCos = EIGEN_FAST_MATH,
|
|
113
|
+
HasACos = 1,
|
|
114
|
+
HasASin = 1,
|
|
115
|
+
HasATan = 1,
|
|
116
|
+
HasATanh = 1,
|
|
72
117
|
HasLog = 1,
|
|
73
118
|
HasLog1p = 1,
|
|
74
119
|
HasExpm1 = 1,
|
|
75
120
|
HasExp = 1,
|
|
121
|
+
HasPow = 1,
|
|
76
122
|
HasNdtri = 1,
|
|
77
123
|
HasBessel = 1,
|
|
78
124
|
HasSqrt = 1,
|
|
79
125
|
HasRsqrt = 1,
|
|
126
|
+
HasCbrt = 1,
|
|
80
127
|
HasTanh = EIGEN_FAST_MATH,
|
|
81
128
|
HasErf = EIGEN_FAST_MATH,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
HasFloor = 1,
|
|
85
|
-
HasCeil = 1,
|
|
86
|
-
HasRint = 1
|
|
129
|
+
HasErfc = EIGEN_FAST_MATH,
|
|
130
|
+
HasBlend = 1
|
|
87
131
|
};
|
|
88
132
|
};
|
|
89
|
-
template<>
|
|
90
|
-
{
|
|
133
|
+
template <>
|
|
134
|
+
struct packet_traits<double> : default_packet_traits {
|
|
91
135
|
typedef Packet4d type;
|
|
92
136
|
typedef Packet2d half;
|
|
93
137
|
enum {
|
|
94
138
|
Vectorizable = 1,
|
|
95
139
|
AlignedOnScalar = 1,
|
|
96
|
-
size=4,
|
|
97
|
-
HasHalfPacket = 1,
|
|
140
|
+
size = 4,
|
|
98
141
|
|
|
99
|
-
HasCmp
|
|
100
|
-
HasDiv
|
|
101
|
-
|
|
102
|
-
|
|
142
|
+
HasCmp = 1,
|
|
143
|
+
HasDiv = 1,
|
|
144
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
145
|
+
HasSin = EIGEN_FAST_MATH,
|
|
146
|
+
HasCos = EIGEN_FAST_MATH,
|
|
147
|
+
#endif
|
|
148
|
+
HasTanh = EIGEN_FAST_MATH,
|
|
149
|
+
HasLog = 1,
|
|
150
|
+
HasErf = 1,
|
|
151
|
+
HasErfc = 1,
|
|
152
|
+
HasExp = 1,
|
|
153
|
+
HasPow = 1,
|
|
103
154
|
HasSqrt = 1,
|
|
104
155
|
HasRsqrt = 1,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
HasRint = 1
|
|
156
|
+
HasCbrt = 1,
|
|
157
|
+
HasATan = 1,
|
|
158
|
+
HasATanh = 1,
|
|
159
|
+
HasBlend = 1
|
|
110
160
|
};
|
|
111
161
|
};
|
|
112
162
|
|
|
@@ -119,37 +169,32 @@ struct packet_traits<Eigen::half> : default_packet_traits {
|
|
|
119
169
|
Vectorizable = 1,
|
|
120
170
|
AlignedOnScalar = 1,
|
|
121
171
|
size = 8,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
HasCos = EIGEN_FAST_MATH,
|
|
172
|
+
|
|
173
|
+
HasCmp = 1,
|
|
174
|
+
HasAdd = 1,
|
|
175
|
+
HasSub = 1,
|
|
176
|
+
HasMul = 1,
|
|
177
|
+
HasDiv = 1,
|
|
178
|
+
HasSin = EIGEN_FAST_MATH,
|
|
179
|
+
HasCos = EIGEN_FAST_MATH,
|
|
131
180
|
HasNegate = 1,
|
|
132
|
-
HasAbs
|
|
133
|
-
HasAbs2
|
|
134
|
-
HasMin
|
|
135
|
-
HasMax
|
|
136
|
-
HasConj
|
|
181
|
+
HasAbs = 1,
|
|
182
|
+
HasAbs2 = 0,
|
|
183
|
+
HasMin = 1,
|
|
184
|
+
HasMax = 1,
|
|
185
|
+
HasConj = 1,
|
|
137
186
|
HasSetLinear = 0,
|
|
138
|
-
HasLog
|
|
139
|
-
HasLog1p
|
|
140
|
-
HasExpm1
|
|
141
|
-
HasExp
|
|
142
|
-
HasSqrt
|
|
143
|
-
HasRsqrt
|
|
144
|
-
HasTanh
|
|
145
|
-
HasErf
|
|
146
|
-
HasBlend
|
|
147
|
-
HasRound = 1,
|
|
148
|
-
HasFloor = 1,
|
|
149
|
-
HasCeil = 1,
|
|
150
|
-
HasRint = 1,
|
|
187
|
+
HasLog = 1,
|
|
188
|
+
HasLog1p = 1,
|
|
189
|
+
HasExpm1 = 1,
|
|
190
|
+
HasExp = 1,
|
|
191
|
+
HasSqrt = 1,
|
|
192
|
+
HasRsqrt = 1,
|
|
193
|
+
HasTanh = EIGEN_FAST_MATH,
|
|
194
|
+
HasErf = EIGEN_FAST_MATH,
|
|
195
|
+
HasBlend = 0,
|
|
151
196
|
HasBessel = 1,
|
|
152
|
-
HasNdtri
|
|
197
|
+
HasNdtri = 1
|
|
153
198
|
};
|
|
154
199
|
};
|
|
155
200
|
|
|
@@ -163,7 +208,6 @@ struct packet_traits<bfloat16> : default_packet_traits {
|
|
|
163
208
|
Vectorizable = 1,
|
|
164
209
|
AlignedOnScalar = 1,
|
|
165
210
|
size = 8,
|
|
166
|
-
HasHalfPacket = 0,
|
|
167
211
|
|
|
168
212
|
HasCmp = 1,
|
|
169
213
|
HasAdd = 1,
|
|
@@ -173,61 +217,189 @@ struct packet_traits<bfloat16> : default_packet_traits {
|
|
|
173
217
|
HasSin = EIGEN_FAST_MATH,
|
|
174
218
|
HasCos = EIGEN_FAST_MATH,
|
|
175
219
|
HasNegate = 1,
|
|
176
|
-
HasAbs
|
|
177
|
-
HasAbs2
|
|
178
|
-
HasMin
|
|
179
|
-
HasMax
|
|
180
|
-
HasConj
|
|
220
|
+
HasAbs = 1,
|
|
221
|
+
HasAbs2 = 0,
|
|
222
|
+
HasMin = 1,
|
|
223
|
+
HasMax = 1,
|
|
224
|
+
HasConj = 1,
|
|
181
225
|
HasSetLinear = 0,
|
|
182
226
|
HasLog = 1,
|
|
183
|
-
HasLog1p
|
|
184
|
-
HasExpm1
|
|
227
|
+
HasLog1p = 1,
|
|
228
|
+
HasExpm1 = 1,
|
|
185
229
|
HasExp = 1,
|
|
186
230
|
HasSqrt = 1,
|
|
187
231
|
HasRsqrt = 1,
|
|
188
232
|
HasTanh = EIGEN_FAST_MATH,
|
|
189
233
|
HasErf = EIGEN_FAST_MATH,
|
|
190
234
|
HasBlend = 0,
|
|
191
|
-
HasRound = 1,
|
|
192
|
-
HasFloor = 1,
|
|
193
|
-
HasCeil = 1,
|
|
194
|
-
HasRint = 1,
|
|
195
235
|
HasBessel = 1,
|
|
196
|
-
HasNdtri
|
|
236
|
+
HasNdtri = 1
|
|
197
237
|
};
|
|
198
238
|
};
|
|
199
|
-
#endif
|
|
200
239
|
|
|
201
|
-
template<>
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
/* Proper support for integers is only provided by AVX2. In the meantime, we'll
|
|
205
|
-
use SSE instructions and packets to deal with integers.
|
|
206
|
-
template<> struct packet_traits<int> : default_packet_traits
|
|
207
|
-
{
|
|
240
|
+
template <>
|
|
241
|
+
struct packet_traits<int> : default_packet_traits {
|
|
208
242
|
typedef Packet8i type;
|
|
243
|
+
typedef Packet4i half;
|
|
244
|
+
enum { Vectorizable = 1, AlignedOnScalar = 1, HasCmp = 1, HasDiv = 1, size = 8 };
|
|
245
|
+
};
|
|
246
|
+
template <>
|
|
247
|
+
struct packet_traits<uint32_t> : default_packet_traits {
|
|
248
|
+
typedef Packet8ui type;
|
|
249
|
+
typedef Packet4ui half;
|
|
209
250
|
enum {
|
|
210
251
|
Vectorizable = 1,
|
|
211
252
|
AlignedOnScalar = 1,
|
|
212
|
-
size=8
|
|
253
|
+
size = 8,
|
|
254
|
+
|
|
255
|
+
HasDiv = 0,
|
|
256
|
+
HasNegate = 0,
|
|
257
|
+
HasSqrt = 0,
|
|
258
|
+
|
|
259
|
+
HasCmp = 1,
|
|
260
|
+
HasMin = 1,
|
|
261
|
+
HasMax = 1,
|
|
262
|
+
HasShift = 1
|
|
213
263
|
};
|
|
214
264
|
};
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
template<>
|
|
218
|
-
|
|
219
|
-
typedef
|
|
220
|
-
typedef
|
|
221
|
-
|
|
222
|
-
|
|
265
|
+
|
|
266
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
267
|
+
template <>
|
|
268
|
+
struct packet_traits<int64_t> : default_packet_traits {
|
|
269
|
+
typedef Packet4l type;
|
|
270
|
+
typedef Packet2l half;
|
|
271
|
+
enum { Vectorizable = 1, AlignedOnScalar = 1, HasCmp = 1, size = 4 };
|
|
272
|
+
};
|
|
273
|
+
template <>
|
|
274
|
+
struct packet_traits<uint64_t> : default_packet_traits {
|
|
275
|
+
typedef Packet4ul type;
|
|
276
|
+
// There is no half-size packet for current Packet4ul.
|
|
277
|
+
// TODO: support as SSE path.
|
|
278
|
+
typedef Packet4ul half;
|
|
279
|
+
enum {
|
|
280
|
+
Vectorizable = 1,
|
|
281
|
+
AlignedOnScalar = 1,
|
|
282
|
+
size = 4,
|
|
283
|
+
|
|
284
|
+
// HasMin = 0,
|
|
285
|
+
// HasMax = 0,
|
|
286
|
+
HasDiv = 0,
|
|
287
|
+
HasBlend = 0,
|
|
288
|
+
HasTranspose = 0,
|
|
289
|
+
HasNegate = 0,
|
|
290
|
+
HasSqrt = 0,
|
|
291
|
+
HasCmp = 1,
|
|
292
|
+
HasShift = 1
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
#endif
|
|
296
|
+
|
|
297
|
+
#endif
|
|
298
|
+
|
|
299
|
+
template <>
|
|
300
|
+
struct scalar_div_cost<float, true> {
|
|
301
|
+
enum { value = 14 };
|
|
302
|
+
};
|
|
303
|
+
template <>
|
|
304
|
+
struct scalar_div_cost<double, true> {
|
|
305
|
+
enum { value = 16 };
|
|
223
306
|
};
|
|
224
|
-
|
|
307
|
+
|
|
308
|
+
template <>
|
|
309
|
+
struct unpacket_traits<Packet8f> {
|
|
310
|
+
typedef float type;
|
|
311
|
+
typedef Packet4f half;
|
|
312
|
+
typedef Packet8i integer_packet;
|
|
313
|
+
typedef uint8_t mask_t;
|
|
314
|
+
enum {
|
|
315
|
+
size = 8,
|
|
316
|
+
alignment = Aligned32,
|
|
317
|
+
vectorizable = true,
|
|
318
|
+
masked_load_available = true,
|
|
319
|
+
masked_store_available = true
|
|
320
|
+
#ifdef EIGEN_VECTORIZE_AVX512
|
|
321
|
+
,
|
|
322
|
+
masked_fpops_available = true
|
|
323
|
+
#endif
|
|
324
|
+
};
|
|
325
|
+
};
|
|
326
|
+
template <>
|
|
327
|
+
struct unpacket_traits<Packet4d> {
|
|
225
328
|
typedef double type;
|
|
226
329
|
typedef Packet2d half;
|
|
227
|
-
|
|
330
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
331
|
+
typedef Packet4l integer_packet;
|
|
332
|
+
#endif
|
|
333
|
+
enum {
|
|
334
|
+
size = 4,
|
|
335
|
+
alignment = Aligned32,
|
|
336
|
+
vectorizable = true,
|
|
337
|
+
masked_load_available = false,
|
|
338
|
+
masked_store_available = false
|
|
339
|
+
};
|
|
340
|
+
};
|
|
341
|
+
template <>
|
|
342
|
+
struct unpacket_traits<Packet8i> {
|
|
343
|
+
typedef int type;
|
|
344
|
+
typedef Packet4i half;
|
|
345
|
+
enum {
|
|
346
|
+
size = 8,
|
|
347
|
+
alignment = Aligned32,
|
|
348
|
+
vectorizable = true,
|
|
349
|
+
masked_load_available = false,
|
|
350
|
+
masked_store_available = false
|
|
351
|
+
};
|
|
352
|
+
};
|
|
353
|
+
template <>
|
|
354
|
+
struct unpacket_traits<Packet8ui> {
|
|
355
|
+
typedef uint32_t type;
|
|
356
|
+
typedef Packet4ui half;
|
|
357
|
+
enum {
|
|
358
|
+
size = 8,
|
|
359
|
+
alignment = Aligned32,
|
|
360
|
+
vectorizable = true,
|
|
361
|
+
masked_load_available = false,
|
|
362
|
+
masked_store_available = false
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
366
|
+
template <>
|
|
367
|
+
struct unpacket_traits<Packet4l> {
|
|
368
|
+
typedef int64_t type;
|
|
369
|
+
typedef Packet2l half;
|
|
370
|
+
enum {
|
|
371
|
+
size = 4,
|
|
372
|
+
alignment = Aligned32,
|
|
373
|
+
vectorizable = true,
|
|
374
|
+
masked_load_available = false,
|
|
375
|
+
masked_store_available = false
|
|
376
|
+
};
|
|
377
|
+
};
|
|
378
|
+
template <>
|
|
379
|
+
struct unpacket_traits<Packet4ul> {
|
|
380
|
+
typedef uint64_t type;
|
|
381
|
+
typedef Packet4ul half;
|
|
382
|
+
enum {
|
|
383
|
+
size = 4,
|
|
384
|
+
alignment = Aligned32,
|
|
385
|
+
vectorizable = true,
|
|
386
|
+
masked_load_available = false,
|
|
387
|
+
masked_store_available = false
|
|
388
|
+
};
|
|
389
|
+
};
|
|
390
|
+
#endif
|
|
391
|
+
template <>
|
|
392
|
+
struct unpacket_traits<Packet8bf> {
|
|
393
|
+
typedef bfloat16 type;
|
|
394
|
+
typedef Packet8bf half;
|
|
395
|
+
enum {
|
|
396
|
+
size = 8,
|
|
397
|
+
alignment = Aligned16,
|
|
398
|
+
vectorizable = true,
|
|
399
|
+
masked_load_available = false,
|
|
400
|
+
masked_store_available = false
|
|
401
|
+
};
|
|
228
402
|
};
|
|
229
|
-
template<> struct unpacket_traits<Packet8i> { typedef int type; typedef Packet4i half; enum {size=8, alignment=Aligned32, vectorizable=false, masked_load_available=false, masked_store_available=false}; };
|
|
230
|
-
template<> struct unpacket_traits<Packet8bf> { typedef bfloat16 type; typedef Packet8bf half; enum {size=8, alignment=Aligned16, vectorizable=true, masked_load_available=false, masked_store_available=false}; };
|
|
231
403
|
|
|
232
404
|
// Helper function for bit packing snippet of low precision comparison.
|
|
233
405
|
// It packs the flags from 16x16 to 8x16.
|
|
@@ -236,34 +408,425 @@ EIGEN_STRONG_INLINE __m128i Pack16To8(Packet8f rf) {
|
|
|
236
408
|
_mm256_extractf128_si256(_mm256_castps_si256(rf), 1));
|
|
237
409
|
}
|
|
238
410
|
|
|
411
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
412
|
+
template <>
|
|
413
|
+
EIGEN_STRONG_INLINE Packet4l pset1<Packet4l>(const int64_t& from) {
|
|
414
|
+
return _mm256_set1_epi64x(from);
|
|
415
|
+
}
|
|
416
|
+
template <>
|
|
417
|
+
EIGEN_STRONG_INLINE Packet4ul pset1<Packet4ul>(const uint64_t& from) {
|
|
418
|
+
return _mm256_set1_epi64x(numext::bit_cast<uint64_t>(from));
|
|
419
|
+
}
|
|
420
|
+
template <>
|
|
421
|
+
EIGEN_STRONG_INLINE Packet4l pzero(const Packet4l& /*a*/) {
|
|
422
|
+
return _mm256_setzero_si256();
|
|
423
|
+
}
|
|
424
|
+
template <>
|
|
425
|
+
EIGEN_STRONG_INLINE Packet4ul pzero(const Packet4ul& /*a*/) {
|
|
426
|
+
return _mm256_setzero_si256();
|
|
427
|
+
}
|
|
428
|
+
template <>
|
|
429
|
+
EIGEN_STRONG_INLINE Packet4l peven_mask(const Packet4l& /*a*/) {
|
|
430
|
+
return _mm256_set_epi64x(0ll, -1ll, 0ll, -1ll);
|
|
431
|
+
}
|
|
432
|
+
template <>
|
|
433
|
+
EIGEN_STRONG_INLINE Packet4ul peven_mask(const Packet4ul& /*a*/) {
|
|
434
|
+
return _mm256_set_epi64x(0ll, -1ll, 0ll, -1ll);
|
|
435
|
+
}
|
|
436
|
+
template <>
|
|
437
|
+
EIGEN_STRONG_INLINE Packet4l pload1<Packet4l>(const int64_t* from) {
|
|
438
|
+
return _mm256_set1_epi64x(*from);
|
|
439
|
+
}
|
|
440
|
+
template <>
|
|
441
|
+
EIGEN_STRONG_INLINE Packet4ul pload1<Packet4ul>(const uint64_t* from) {
|
|
442
|
+
return _mm256_set1_epi64x(*from);
|
|
443
|
+
}
|
|
444
|
+
template <>
|
|
445
|
+
EIGEN_STRONG_INLINE Packet4l padd<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
446
|
+
return _mm256_add_epi64(a, b);
|
|
447
|
+
}
|
|
448
|
+
template <>
|
|
449
|
+
EIGEN_STRONG_INLINE Packet4ul padd<Packet4ul>(const Packet4ul& a, const Packet4ul& b) {
|
|
450
|
+
return _mm256_add_epi64(a, b);
|
|
451
|
+
}
|
|
452
|
+
template <>
|
|
453
|
+
EIGEN_STRONG_INLINE Packet4l plset<Packet4l>(const int64_t& a) {
|
|
454
|
+
return padd(pset1<Packet4l>(a), Packet4l(_mm256_set_epi64x(3ll, 2ll, 1ll, 0ll)));
|
|
455
|
+
}
|
|
456
|
+
template <>
|
|
457
|
+
EIGEN_STRONG_INLINE Packet4ul plset<Packet4ul>(const uint64_t& a) {
|
|
458
|
+
return padd(pset1<Packet4ul>(a), Packet4ul(_mm256_set_epi64x(3ll, 2ll, 1ll, 0ll)));
|
|
459
|
+
}
|
|
460
|
+
template <>
|
|
461
|
+
EIGEN_STRONG_INLINE Packet4l psub<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
462
|
+
return _mm256_sub_epi64(a, b);
|
|
463
|
+
}
|
|
464
|
+
template <>
|
|
465
|
+
EIGEN_STRONG_INLINE Packet4ul psub<Packet4ul>(const Packet4ul& a, const Packet4ul& b) {
|
|
466
|
+
return _mm256_sub_epi64(a, b);
|
|
467
|
+
}
|
|
468
|
+
template <>
|
|
469
|
+
EIGEN_STRONG_INLINE Packet4l pnegate(const Packet4l& a) {
|
|
470
|
+
return psub(pzero(a), a);
|
|
471
|
+
}
|
|
472
|
+
template <>
|
|
473
|
+
EIGEN_STRONG_INLINE Packet4l pconj(const Packet4l& a) {
|
|
474
|
+
return a;
|
|
475
|
+
}
|
|
476
|
+
template <>
|
|
477
|
+
EIGEN_STRONG_INLINE Packet4l pcmp_le(const Packet4l& a, const Packet4l& b) {
|
|
478
|
+
return _mm256_xor_si256(_mm256_cmpgt_epi64(a, b), _mm256_set1_epi32(-1));
|
|
479
|
+
}
|
|
480
|
+
template <>
|
|
481
|
+
EIGEN_STRONG_INLINE Packet4ul pcmp_le(const Packet4ul& a, const Packet4ul& b) {
|
|
482
|
+
return (Packet4ul)pcmp_le((Packet4l)psub(a, pset1<Packet4ul>(0x8000000000000000UL)),
|
|
483
|
+
(Packet4l)psub(b, pset1<Packet4ul>(0x8000000000000000UL)));
|
|
484
|
+
}
|
|
485
|
+
template <>
|
|
486
|
+
EIGEN_STRONG_INLINE Packet4l pcmp_lt(const Packet4l& a, const Packet4l& b) {
|
|
487
|
+
return _mm256_cmpgt_epi64(b, a);
|
|
488
|
+
}
|
|
489
|
+
template <>
|
|
490
|
+
EIGEN_STRONG_INLINE Packet4ul pcmp_lt(const Packet4ul& a, const Packet4ul& b) {
|
|
491
|
+
return (Packet4ul)pcmp_lt((Packet4l)psub(a, pset1<Packet4ul>(0x8000000000000000UL)),
|
|
492
|
+
(Packet4l)psub(b, pset1<Packet4ul>(0x8000000000000000UL)));
|
|
493
|
+
}
|
|
494
|
+
template <>
|
|
495
|
+
EIGEN_STRONG_INLINE Packet4l pcmp_eq(const Packet4l& a, const Packet4l& b) {
|
|
496
|
+
return _mm256_cmpeq_epi64(a, b);
|
|
497
|
+
}
|
|
498
|
+
template <>
|
|
499
|
+
EIGEN_STRONG_INLINE Packet4ul pcmp_eq(const Packet4ul& a, const Packet4ul& b) {
|
|
500
|
+
return _mm256_cmpeq_epi64(a, b);
|
|
501
|
+
}
|
|
502
|
+
template <>
|
|
503
|
+
EIGEN_STRONG_INLINE Packet4l ptrue<Packet4l>(const Packet4l& a) {
|
|
504
|
+
return _mm256_cmpeq_epi64(a, a);
|
|
505
|
+
}
|
|
506
|
+
template <>
|
|
507
|
+
EIGEN_STRONG_INLINE Packet4ul ptrue<Packet4ul>(const Packet4ul& a) {
|
|
508
|
+
return _mm256_cmpeq_epi64(a, a);
|
|
509
|
+
}
|
|
510
|
+
template <>
|
|
511
|
+
EIGEN_STRONG_INLINE Packet4l pand<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
512
|
+
return _mm256_and_si256(a, b);
|
|
513
|
+
}
|
|
514
|
+
template <>
|
|
515
|
+
EIGEN_STRONG_INLINE Packet4l por<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
516
|
+
return _mm256_or_si256(a, b);
|
|
517
|
+
}
|
|
518
|
+
template <>
|
|
519
|
+
EIGEN_STRONG_INLINE Packet4l pxor<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
520
|
+
return _mm256_xor_si256(a, b);
|
|
521
|
+
}
|
|
522
|
+
template <>
|
|
523
|
+
EIGEN_STRONG_INLINE Packet4ul pxor<Packet4ul>(const Packet4ul& a, const Packet4ul& b) {
|
|
524
|
+
return _mm256_xor_si256(a, b);
|
|
525
|
+
}
|
|
526
|
+
template <>
|
|
527
|
+
EIGEN_STRONG_INLINE Packet4l pandnot<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
528
|
+
return _mm256_andnot_si256(b, a);
|
|
529
|
+
}
|
|
530
|
+
template <int N>
|
|
531
|
+
EIGEN_STRONG_INLINE Packet4l plogical_shift_right(Packet4l a) {
|
|
532
|
+
return _mm256_srli_epi64(a, N);
|
|
533
|
+
}
|
|
534
|
+
template <int N>
|
|
535
|
+
EIGEN_STRONG_INLINE Packet4l plogical_shift_left(Packet4l a) {
|
|
536
|
+
return _mm256_slli_epi64(a, N);
|
|
537
|
+
}
|
|
538
|
+
#ifdef EIGEN_VECTORIZE_AVX512FP16
|
|
539
|
+
template <int N>
|
|
540
|
+
EIGEN_STRONG_INLINE Packet4l parithmetic_shift_right(Packet4l a) {
|
|
541
|
+
return _mm256_srai_epi64(a, N);
|
|
542
|
+
}
|
|
543
|
+
#else
|
|
544
|
+
template <int N>
|
|
545
|
+
EIGEN_STRONG_INLINE std::enable_if_t<(N == 0), Packet4l> parithmetic_shift_right(Packet4l a) {
|
|
546
|
+
return a;
|
|
547
|
+
}
|
|
548
|
+
template <int N>
|
|
549
|
+
EIGEN_STRONG_INLINE std::enable_if_t<(N > 0) && (N < 32), Packet4l> parithmetic_shift_right(Packet4l a) {
|
|
550
|
+
__m256i hi_word = _mm256_srai_epi32(a, N);
|
|
551
|
+
__m256i lo_word = _mm256_srli_epi64(a, N);
|
|
552
|
+
return _mm256_blend_epi32(hi_word, lo_word, 0b01010101);
|
|
553
|
+
}
|
|
554
|
+
template <int N>
|
|
555
|
+
EIGEN_STRONG_INLINE std::enable_if_t<(N >= 32) && (N < 63), Packet4l> parithmetic_shift_right(Packet4l a) {
|
|
556
|
+
__m256i hi_word = _mm256_srai_epi32(a, 31);
|
|
557
|
+
__m256i lo_word = _mm256_shuffle_epi32(_mm256_srai_epi32(a, N - 32), (shuffle_mask<1, 1, 3, 3>::mask));
|
|
558
|
+
return _mm256_blend_epi32(hi_word, lo_word, 0b01010101);
|
|
559
|
+
}
|
|
560
|
+
template <int N>
|
|
561
|
+
EIGEN_STRONG_INLINE std::enable_if_t<(N == 63), Packet4l> parithmetic_shift_right(Packet4l a) {
|
|
562
|
+
return _mm256_cmpgt_epi64(_mm256_setzero_si256(), a);
|
|
563
|
+
}
|
|
564
|
+
template <int N>
|
|
565
|
+
EIGEN_STRONG_INLINE std::enable_if_t<(N < 0) || (N > 63), Packet4l> parithmetic_shift_right(Packet4l a) {
|
|
566
|
+
return parithmetic_shift_right<int(N & 63)>(a);
|
|
567
|
+
}
|
|
568
|
+
#endif
|
|
569
|
+
template <>
|
|
570
|
+
EIGEN_STRONG_INLINE Packet4l pload<Packet4l>(const int64_t* from) {
|
|
571
|
+
EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_si256(reinterpret_cast<const __m256i*>(from));
|
|
572
|
+
}
|
|
573
|
+
template <>
|
|
574
|
+
EIGEN_STRONG_INLINE Packet4ul pload<Packet4ul>(const uint64_t* from) {
|
|
575
|
+
EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_si256(reinterpret_cast<const __m256i*>(from));
|
|
576
|
+
}
|
|
577
|
+
template <>
|
|
578
|
+
EIGEN_STRONG_INLINE Packet4l ploadu<Packet4l>(const int64_t* from) {
|
|
579
|
+
EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_si256(reinterpret_cast<const __m256i*>(from));
|
|
580
|
+
}
|
|
581
|
+
template <>
|
|
582
|
+
EIGEN_STRONG_INLINE Packet4ul ploadu<Packet4ul>(const uint64_t* from) {
|
|
583
|
+
EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_si256(reinterpret_cast<const __m256i*>(from));
|
|
584
|
+
}
|
|
585
|
+
// Loads 2 int64_ts from memory a returns the packet {a0, a0, a1, a1}
|
|
586
|
+
template <>
|
|
587
|
+
EIGEN_STRONG_INLINE Packet4l ploaddup<Packet4l>(const int64_t* from) {
|
|
588
|
+
const Packet4l a = _mm256_castsi128_si256(_mm_loadu_si128(reinterpret_cast<const __m128i*>(from)));
|
|
589
|
+
return _mm256_permutevar8x32_epi32(a, _mm256_setr_epi32(0, 1, 0, 1, 2, 3, 2, 3));
|
|
590
|
+
}
|
|
591
|
+
// Loads 2 uint64_ts from memory a returns the packet {a0, a0, a1, a1}
|
|
592
|
+
template <>
|
|
593
|
+
EIGEN_STRONG_INLINE Packet4ul ploaddup<Packet4ul>(const uint64_t* from) {
|
|
594
|
+
const Packet4ul a = _mm256_castsi128_si256(_mm_loadu_si128(reinterpret_cast<const __m128i*>(from)));
|
|
595
|
+
return _mm256_permutevar8x32_epi32(a, _mm256_setr_epi32(0, 1, 0, 1, 2, 3, 2, 3));
|
|
596
|
+
}
|
|
597
|
+
template <>
|
|
598
|
+
EIGEN_STRONG_INLINE void pstore<int64_t>(int64_t* to, const Packet4l& from) {
|
|
599
|
+
EIGEN_DEBUG_ALIGNED_STORE _mm256_store_si256(reinterpret_cast<__m256i*>(to), from);
|
|
600
|
+
}
|
|
601
|
+
template <>
|
|
602
|
+
EIGEN_STRONG_INLINE void pstore<uint64_t>(uint64_t* to, const Packet4ul& from) {
|
|
603
|
+
EIGEN_DEBUG_ALIGNED_STORE _mm256_store_si256(reinterpret_cast<__m256i*>(to), from);
|
|
604
|
+
}
|
|
605
|
+
template <>
|
|
606
|
+
EIGEN_STRONG_INLINE void pstoreu<int64_t>(int64_t* to, const Packet4l& from) {
|
|
607
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_si256(reinterpret_cast<__m256i*>(to), from);
|
|
608
|
+
}
|
|
609
|
+
template <>
|
|
610
|
+
EIGEN_STRONG_INLINE void pstoreu<uint64_t>(uint64_t* to, const Packet4ul& from) {
|
|
611
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_si256(reinterpret_cast<__m256i*>(to), from);
|
|
612
|
+
}
|
|
613
|
+
template <>
|
|
614
|
+
EIGEN_DEVICE_FUNC inline Packet4l pgather<int64_t, Packet4l>(const int64_t* from, Index stride) {
|
|
615
|
+
return _mm256_set_epi64x(from[3 * stride], from[2 * stride], from[1 * stride], from[0 * stride]);
|
|
616
|
+
}
|
|
617
|
+
template <>
|
|
618
|
+
EIGEN_DEVICE_FUNC inline Packet4ul pgather<uint64_t, Packet4ul>(const uint64_t* from, Index stride) {
|
|
619
|
+
return _mm256_set_epi64x(from[3 * stride], from[2 * stride], from[1 * stride], from[0 * stride]);
|
|
620
|
+
}
|
|
621
|
+
template <>
|
|
622
|
+
EIGEN_DEVICE_FUNC inline void pscatter<int64_t, Packet4l>(int64_t* to, const Packet4l& from, Index stride) {
|
|
623
|
+
__m128i low = _mm256_extractf128_si256(from, 0);
|
|
624
|
+
to[stride * 0] = _mm_extract_epi64_0(low);
|
|
625
|
+
to[stride * 1] = _mm_extract_epi64_1(low);
|
|
239
626
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
627
|
+
__m128i high = _mm256_extractf128_si256(from, 1);
|
|
628
|
+
to[stride * 2] = _mm_extract_epi64_0(high);
|
|
629
|
+
to[stride * 3] = _mm_extract_epi64_1(high);
|
|
630
|
+
}
|
|
631
|
+
template <>
|
|
632
|
+
EIGEN_DEVICE_FUNC inline void pscatter<uint64_t, Packet4ul>(uint64_t* to, const Packet4ul& from, Index stride) {
|
|
633
|
+
__m128i low = _mm256_extractf128_si256(from, 0);
|
|
634
|
+
to[stride * 0] = _mm_extract_epi64_0(low);
|
|
635
|
+
to[stride * 1] = _mm_extract_epi64_1(low);
|
|
243
636
|
|
|
244
|
-
|
|
245
|
-
|
|
637
|
+
__m128i high = _mm256_extractf128_si256(from, 1);
|
|
638
|
+
to[stride * 2] = _mm_extract_epi64_0(high);
|
|
639
|
+
to[stride * 3] = _mm_extract_epi64_1(high);
|
|
640
|
+
}
|
|
641
|
+
template <>
|
|
642
|
+
EIGEN_STRONG_INLINE void pstore1<Packet4l>(int64_t* to, const int64_t& a) {
|
|
643
|
+
Packet4l pa = pset1<Packet4l>(a);
|
|
644
|
+
pstore(to, pa);
|
|
645
|
+
}
|
|
646
|
+
template <>
|
|
647
|
+
EIGEN_STRONG_INLINE void pstore1<Packet4ul>(uint64_t* to, const uint64_t& a) {
|
|
648
|
+
Packet4ul pa = pset1<Packet4ul>(a);
|
|
649
|
+
pstore(to, pa);
|
|
650
|
+
}
|
|
651
|
+
template <>
|
|
652
|
+
EIGEN_STRONG_INLINE int64_t pfirst<Packet4l>(const Packet4l& a) {
|
|
653
|
+
return _mm_extract_epi64_0(_mm256_castsi256_si128(a));
|
|
654
|
+
}
|
|
655
|
+
template <>
|
|
656
|
+
EIGEN_STRONG_INLINE uint64_t pfirst<Packet4ul>(const Packet4ul& a) {
|
|
657
|
+
return _mm_extract_epi64_0(_mm256_castsi256_si128(a));
|
|
658
|
+
}
|
|
246
659
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
660
|
+
#define MM256_SHUFFLE_EPI64(A, B, M) _mm256_shuffle_pd(_mm256_castsi256_pd(A), _mm256_castsi256_pd(B), M)
|
|
661
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4l, 4>& kernel) {
|
|
662
|
+
__m256d T0 = MM256_SHUFFLE_EPI64(kernel.packet[0], kernel.packet[1], 15);
|
|
663
|
+
__m256d T1 = MM256_SHUFFLE_EPI64(kernel.packet[0], kernel.packet[1], 0);
|
|
664
|
+
__m256d T2 = MM256_SHUFFLE_EPI64(kernel.packet[2], kernel.packet[3], 15);
|
|
665
|
+
__m256d T3 = MM256_SHUFFLE_EPI64(kernel.packet[2], kernel.packet[3], 0);
|
|
250
666
|
|
|
667
|
+
kernel.packet[1] = _mm256_castpd_si256(_mm256_permute2f128_pd(T0, T2, 32));
|
|
668
|
+
kernel.packet[3] = _mm256_castpd_si256(_mm256_permute2f128_pd(T0, T2, 49));
|
|
669
|
+
kernel.packet[0] = _mm256_castpd_si256(_mm256_permute2f128_pd(T1, T3, 32));
|
|
670
|
+
kernel.packet[2] = _mm256_castpd_si256(_mm256_permute2f128_pd(T1, T3, 49));
|
|
671
|
+
}
|
|
672
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4ul, 4>& kernel) {
|
|
673
|
+
ptranspose((PacketBlock<Packet4l, 4>&)kernel);
|
|
674
|
+
}
|
|
675
|
+
template <>
|
|
676
|
+
EIGEN_STRONG_INLINE Packet4l pmin<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
677
|
+
__m256i cmp = _mm256_cmpgt_epi64(a, b);
|
|
678
|
+
__m256i a_min = _mm256_andnot_si256(cmp, a);
|
|
679
|
+
__m256i b_min = _mm256_and_si256(cmp, b);
|
|
680
|
+
return Packet4l(_mm256_or_si256(a_min, b_min));
|
|
681
|
+
}
|
|
682
|
+
template <>
|
|
683
|
+
EIGEN_STRONG_INLINE Packet4ul pmin<Packet4ul>(const Packet4ul& a, const Packet4ul& b) {
|
|
684
|
+
return padd((Packet4ul)pmin((Packet4l)psub(a, pset1<Packet4ul>(0x8000000000000000UL)),
|
|
685
|
+
(Packet4l)psub(b, pset1<Packet4ul>(0x8000000000000000UL))),
|
|
686
|
+
pset1<Packet4ul>(0x8000000000000000UL));
|
|
687
|
+
}
|
|
688
|
+
template <>
|
|
689
|
+
EIGEN_STRONG_INLINE Packet4l pmax<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
690
|
+
__m256i cmp = _mm256_cmpgt_epi64(a, b);
|
|
691
|
+
__m256i a_min = _mm256_and_si256(cmp, a);
|
|
692
|
+
__m256i b_min = _mm256_andnot_si256(cmp, b);
|
|
693
|
+
return Packet4l(_mm256_or_si256(a_min, b_min));
|
|
694
|
+
}
|
|
695
|
+
template <>
|
|
696
|
+
EIGEN_STRONG_INLINE Packet4ul pmax<Packet4ul>(const Packet4ul& a, const Packet4ul& b) {
|
|
697
|
+
return padd((Packet4ul)pmax((Packet4l)psub(a, pset1<Packet4ul>(0x8000000000000000UL)),
|
|
698
|
+
(Packet4l)psub(b, pset1<Packet4ul>(0x8000000000000000UL))),
|
|
699
|
+
pset1<Packet4ul>(0x8000000000000000UL));
|
|
700
|
+
}
|
|
701
|
+
template <>
|
|
702
|
+
EIGEN_STRONG_INLINE Packet4l pabs<Packet4l>(const Packet4l& a) {
|
|
703
|
+
Packet4l pz = pzero<Packet4l>(a);
|
|
704
|
+
Packet4l cmp = _mm256_cmpgt_epi64(a, pz);
|
|
705
|
+
return psub(cmp, pxor(a, cmp));
|
|
706
|
+
}
|
|
707
|
+
template <>
|
|
708
|
+
EIGEN_STRONG_INLINE Packet4ul pabs<Packet4ul>(const Packet4ul& a) {
|
|
709
|
+
return a;
|
|
710
|
+
}
|
|
711
|
+
template <>
|
|
712
|
+
EIGEN_STRONG_INLINE Packet4l pmul<Packet4l>(const Packet4l& a, const Packet4l& b) {
|
|
713
|
+
// 64-bit mul requires avx512, so do this with 32-bit multiplication
|
|
714
|
+
__m256i upper32_a = _mm256_srli_epi64(a, 32);
|
|
715
|
+
__m256i upper32_b = _mm256_srli_epi64(b, 32);
|
|
716
|
+
|
|
717
|
+
// upper * lower
|
|
718
|
+
__m256i mul1 = _mm256_mul_epu32(upper32_a, b);
|
|
719
|
+
__m256i mul2 = _mm256_mul_epu32(upper32_b, a);
|
|
720
|
+
// Gives us both upper*upper and lower*lower
|
|
721
|
+
__m256i mul3 = _mm256_mul_epu32(a, b);
|
|
722
|
+
|
|
723
|
+
__m256i high = _mm256_slli_epi64(_mm256_add_epi64(mul1, mul2), 32);
|
|
724
|
+
return _mm256_add_epi64(high, mul3);
|
|
725
|
+
}
|
|
726
|
+
template <>
|
|
727
|
+
EIGEN_STRONG_INLINE Packet4ul pmul<Packet4ul>(const Packet4ul& a, const Packet4ul& b) {
|
|
728
|
+
return (Packet4ul)pmul<Packet4l>((Packet4l)a, (Packet4l)b);
|
|
729
|
+
}
|
|
730
|
+
#endif
|
|
731
|
+
|
|
732
|
+
template <>
|
|
733
|
+
EIGEN_STRONG_INLINE Packet8f pset1<Packet8f>(const float& from) {
|
|
734
|
+
return _mm256_set1_ps(from);
|
|
735
|
+
}
|
|
736
|
+
template <>
|
|
737
|
+
EIGEN_STRONG_INLINE Packet4d pset1<Packet4d>(const double& from) {
|
|
738
|
+
return _mm256_set1_pd(from);
|
|
739
|
+
}
|
|
740
|
+
template <>
|
|
741
|
+
EIGEN_STRONG_INLINE Packet8i pset1<Packet8i>(const int& from) {
|
|
742
|
+
return _mm256_set1_epi32(from);
|
|
743
|
+
}
|
|
744
|
+
template <>
|
|
745
|
+
EIGEN_STRONG_INLINE Packet8ui pset1<Packet8ui>(const uint32_t& from) {
|
|
746
|
+
return _mm256_set1_epi32(from);
|
|
747
|
+
}
|
|
251
748
|
|
|
252
|
-
template<>
|
|
253
|
-
|
|
254
|
-
|
|
749
|
+
template <>
|
|
750
|
+
EIGEN_STRONG_INLINE Packet8f pset1frombits<Packet8f>(unsigned int from) {
|
|
751
|
+
return _mm256_castsi256_ps(pset1<Packet8i>(from));
|
|
752
|
+
}
|
|
753
|
+
template <>
|
|
754
|
+
EIGEN_STRONG_INLINE Packet4d pset1frombits<Packet4d>(uint64_t from) {
|
|
755
|
+
return _mm256_castsi256_pd(_mm256_set1_epi64x(from));
|
|
756
|
+
}
|
|
255
757
|
|
|
256
|
-
template<>
|
|
257
|
-
|
|
758
|
+
template <>
|
|
759
|
+
EIGEN_STRONG_INLINE Packet8f pzero(const Packet8f& /*a*/) {
|
|
760
|
+
return _mm256_setzero_ps();
|
|
761
|
+
}
|
|
762
|
+
template <>
|
|
763
|
+
EIGEN_STRONG_INLINE Packet4d pzero(const Packet4d& /*a*/) {
|
|
764
|
+
return _mm256_setzero_pd();
|
|
765
|
+
}
|
|
766
|
+
template <>
|
|
767
|
+
EIGEN_STRONG_INLINE Packet8i pzero(const Packet8i& /*a*/) {
|
|
768
|
+
return _mm256_setzero_si256();
|
|
769
|
+
}
|
|
770
|
+
template <>
|
|
771
|
+
EIGEN_STRONG_INLINE Packet8ui pzero(const Packet8ui& /*a*/) {
|
|
772
|
+
return _mm256_setzero_si256();
|
|
773
|
+
}
|
|
258
774
|
|
|
259
|
-
template<>
|
|
260
|
-
|
|
775
|
+
template <>
|
|
776
|
+
EIGEN_STRONG_INLINE Packet8f peven_mask(const Packet8f& /*a*/) {
|
|
777
|
+
return _mm256_castsi256_ps(_mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1));
|
|
778
|
+
}
|
|
779
|
+
template <>
|
|
780
|
+
EIGEN_STRONG_INLINE Packet8i peven_mask(const Packet8i& /*a*/) {
|
|
781
|
+
return _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1);
|
|
782
|
+
}
|
|
783
|
+
template <>
|
|
784
|
+
EIGEN_STRONG_INLINE Packet8ui peven_mask(const Packet8ui& /*a*/) {
|
|
785
|
+
return _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1);
|
|
786
|
+
}
|
|
787
|
+
template <>
|
|
788
|
+
EIGEN_STRONG_INLINE Packet4d peven_mask(const Packet4d& /*a*/) {
|
|
789
|
+
return _mm256_castsi256_pd(_mm256_set_epi32(0, 0, -1, -1, 0, 0, -1, -1));
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
template <>
|
|
793
|
+
EIGEN_STRONG_INLINE Packet8f pload1<Packet8f>(const float* from) {
|
|
794
|
+
return _mm256_broadcast_ss(from);
|
|
795
|
+
}
|
|
796
|
+
template <>
|
|
797
|
+
EIGEN_STRONG_INLINE Packet4d pload1<Packet4d>(const double* from) {
|
|
798
|
+
return _mm256_broadcast_sd(from);
|
|
799
|
+
}
|
|
261
800
|
|
|
262
|
-
template<>
|
|
263
|
-
|
|
264
|
-
|
|
801
|
+
template <>
|
|
802
|
+
EIGEN_STRONG_INLINE Packet8f padd<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
803
|
+
return _mm256_add_ps(a, b);
|
|
804
|
+
}
|
|
805
|
+
#ifdef EIGEN_VECTORIZE_AVX512
|
|
806
|
+
template <>
|
|
807
|
+
EIGEN_STRONG_INLINE Packet8f padd<Packet8f>(const Packet8f& a, const Packet8f& b, uint8_t umask) {
|
|
808
|
+
__mmask16 mask = static_cast<__mmask16>(umask & 0x00FF);
|
|
809
|
+
return _mm512_castps512_ps256(_mm512_maskz_add_ps(mask, _mm512_castps256_ps512(a), _mm512_castps256_ps512(b)));
|
|
810
|
+
}
|
|
811
|
+
#endif
|
|
812
|
+
template <>
|
|
813
|
+
EIGEN_STRONG_INLINE Packet4d padd<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
814
|
+
return _mm256_add_pd(a, b);
|
|
815
|
+
}
|
|
816
|
+
template <>
|
|
817
|
+
EIGEN_STRONG_INLINE Packet8i padd<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
265
818
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
266
|
-
return _mm256_add_epi32(a,b);
|
|
819
|
+
return _mm256_add_epi32(a, b);
|
|
820
|
+
#else
|
|
821
|
+
__m128i lo = _mm_add_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
822
|
+
__m128i hi = _mm_add_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
823
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
824
|
+
#endif
|
|
825
|
+
}
|
|
826
|
+
template <>
|
|
827
|
+
EIGEN_STRONG_INLINE Packet8ui padd<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
828
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
829
|
+
return _mm256_add_epi32(a, b);
|
|
267
830
|
#else
|
|
268
831
|
__m128i lo = _mm_add_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
269
832
|
__m128i hi = _mm_add_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
@@ -271,11 +834,45 @@ template<> EIGEN_STRONG_INLINE Packet8i padd<Packet8i>(const Packet8i& a, const
|
|
|
271
834
|
#endif
|
|
272
835
|
}
|
|
273
836
|
|
|
274
|
-
template<>
|
|
275
|
-
|
|
276
|
-
|
|
837
|
+
template <>
|
|
838
|
+
EIGEN_STRONG_INLINE Packet8f plset<Packet8f>(const float& a) {
|
|
839
|
+
return padd(pset1<Packet8f>(a), _mm256_set_ps(7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0));
|
|
840
|
+
}
|
|
841
|
+
template <>
|
|
842
|
+
EIGEN_STRONG_INLINE Packet4d plset<Packet4d>(const double& a) {
|
|
843
|
+
return padd(pset1<Packet4d>(a), _mm256_set_pd(3.0, 2.0, 1.0, 0.0));
|
|
844
|
+
}
|
|
845
|
+
template <>
|
|
846
|
+
EIGEN_STRONG_INLINE Packet8i plset<Packet8i>(const int& a) {
|
|
847
|
+
return padd(pset1<Packet8i>(a), (Packet8i)_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0));
|
|
848
|
+
}
|
|
849
|
+
template <>
|
|
850
|
+
EIGEN_STRONG_INLINE Packet8ui plset<Packet8ui>(const uint32_t& a) {
|
|
851
|
+
return padd(pset1<Packet8ui>(a), (Packet8ui)_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0));
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
template <>
|
|
855
|
+
EIGEN_STRONG_INLINE Packet8f psub<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
856
|
+
return _mm256_sub_ps(a, b);
|
|
857
|
+
}
|
|
858
|
+
template <>
|
|
859
|
+
EIGEN_STRONG_INLINE Packet4d psub<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
860
|
+
return _mm256_sub_pd(a, b);
|
|
861
|
+
}
|
|
862
|
+
template <>
|
|
863
|
+
EIGEN_STRONG_INLINE Packet8i psub<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
277
864
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
278
|
-
return _mm256_sub_epi32(a,b);
|
|
865
|
+
return _mm256_sub_epi32(a, b);
|
|
866
|
+
#else
|
|
867
|
+
__m128i lo = _mm_sub_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
868
|
+
__m128i hi = _mm_sub_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
869
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
870
|
+
#endif
|
|
871
|
+
}
|
|
872
|
+
template <>
|
|
873
|
+
EIGEN_STRONG_INLINE Packet8ui psub<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
874
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
875
|
+
return _mm256_sub_epi32(a, b);
|
|
279
876
|
#else
|
|
280
877
|
__m128i lo = _mm_sub_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
281
878
|
__m128i hi = _mm_sub_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
@@ -283,24 +880,56 @@ template<> EIGEN_STRONG_INLINE Packet8i psub<Packet8i>(const Packet8i& a, const
|
|
|
283
880
|
#endif
|
|
284
881
|
}
|
|
285
882
|
|
|
286
|
-
template<>
|
|
287
|
-
{
|
|
288
|
-
|
|
883
|
+
template <>
|
|
884
|
+
EIGEN_STRONG_INLINE Packet8f pnegate(const Packet8f& a) {
|
|
885
|
+
const Packet8f mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x80000000));
|
|
886
|
+
return _mm256_xor_ps(a, mask);
|
|
289
887
|
}
|
|
290
|
-
template<>
|
|
291
|
-
{
|
|
292
|
-
|
|
888
|
+
template <>
|
|
889
|
+
EIGEN_STRONG_INLINE Packet4d pnegate(const Packet4d& a) {
|
|
890
|
+
const Packet4d mask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x8000000000000000ULL));
|
|
891
|
+
return _mm256_xor_pd(a, mask);
|
|
892
|
+
}
|
|
893
|
+
template <>
|
|
894
|
+
EIGEN_STRONG_INLINE Packet8i pnegate(const Packet8i& a) {
|
|
895
|
+
return psub(pzero(a), a);
|
|
293
896
|
}
|
|
294
897
|
|
|
295
|
-
template<>
|
|
296
|
-
|
|
297
|
-
|
|
898
|
+
template <>
|
|
899
|
+
EIGEN_STRONG_INLINE Packet8f pconj(const Packet8f& a) {
|
|
900
|
+
return a;
|
|
901
|
+
}
|
|
902
|
+
template <>
|
|
903
|
+
EIGEN_STRONG_INLINE Packet4d pconj(const Packet4d& a) {
|
|
904
|
+
return a;
|
|
905
|
+
}
|
|
906
|
+
template <>
|
|
907
|
+
EIGEN_STRONG_INLINE Packet8i pconj(const Packet8i& a) {
|
|
908
|
+
return a;
|
|
909
|
+
}
|
|
298
910
|
|
|
299
|
-
template<>
|
|
300
|
-
|
|
301
|
-
|
|
911
|
+
template <>
|
|
912
|
+
EIGEN_STRONG_INLINE Packet8f pmul<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
913
|
+
return _mm256_mul_ps(a, b);
|
|
914
|
+
}
|
|
915
|
+
template <>
|
|
916
|
+
EIGEN_STRONG_INLINE Packet4d pmul<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
917
|
+
return _mm256_mul_pd(a, b);
|
|
918
|
+
}
|
|
919
|
+
template <>
|
|
920
|
+
EIGEN_STRONG_INLINE Packet8i pmul<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
921
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
922
|
+
return _mm256_mullo_epi32(a, b);
|
|
923
|
+
#else
|
|
924
|
+
const __m128i lo = _mm_mullo_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
925
|
+
const __m128i hi = _mm_mullo_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
926
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
927
|
+
#endif
|
|
928
|
+
}
|
|
929
|
+
template <>
|
|
930
|
+
EIGEN_STRONG_INLINE Packet8ui pmul<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
302
931
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
303
|
-
return _mm256_mullo_epi32(a,b);
|
|
932
|
+
return _mm256_mullo_epi32(a, b);
|
|
304
933
|
#else
|
|
305
934
|
const __m128i lo = _mm_mullo_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
306
935
|
const __m128i hi = _mm_mullo_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
@@ -308,54 +937,142 @@ template<> EIGEN_STRONG_INLINE Packet8i pmul<Packet8i>(const Packet8i& a, const
|
|
|
308
937
|
#endif
|
|
309
938
|
}
|
|
310
939
|
|
|
311
|
-
template<>
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
940
|
+
template <>
|
|
941
|
+
EIGEN_STRONG_INLINE Packet8f pdiv<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
942
|
+
return _mm256_div_ps(a, b);
|
|
943
|
+
}
|
|
944
|
+
template <>
|
|
945
|
+
EIGEN_STRONG_INLINE Packet4d pdiv<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
946
|
+
return _mm256_div_pd(a, b);
|
|
316
947
|
}
|
|
317
948
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
#
|
|
321
|
-
|
|
322
|
-
// and even register spilling with clang>=6.0 (bug 1637).
|
|
323
|
-
// Gcc stupidly generates a vfmadd132ps instruction.
|
|
324
|
-
// So let's enforce it to generate a vfmadd231ps instruction since the most common use
|
|
325
|
-
// case is to accumulate the result of the product.
|
|
326
|
-
Packet8f res = c;
|
|
327
|
-
__asm__("vfmadd231ps %[a], %[b], %[c]" : [c] "+x" (res) : [a] "x" (a), [b] "x" (b));
|
|
328
|
-
return res;
|
|
949
|
+
template <>
|
|
950
|
+
EIGEN_STRONG_INLINE Packet8i pdiv<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
951
|
+
#ifdef EIGEN_VECTORIZE_AVX512
|
|
952
|
+
return _mm512_cvttpd_epi32(_mm512_div_pd(_mm512_cvtepi32_pd(a), _mm512_cvtepi32_pd(b)));
|
|
329
953
|
#else
|
|
330
|
-
|
|
954
|
+
Packet4i lo = pdiv<Packet4i>(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
955
|
+
Packet4i hi = pdiv<Packet4i>(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
956
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
|
|
331
957
|
#endif
|
|
332
958
|
}
|
|
333
|
-
|
|
334
|
-
#
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
959
|
+
|
|
960
|
+
#ifdef EIGEN_VECTORIZE_FMA
|
|
961
|
+
template <>
|
|
962
|
+
EIGEN_STRONG_INLINE Packet8f pmadd(const Packet8f& a, const Packet8f& b, const Packet8f& c) {
|
|
963
|
+
return _mm256_fmadd_ps(a, b, c);
|
|
964
|
+
}
|
|
965
|
+
template <>
|
|
966
|
+
EIGEN_STRONG_INLINE Packet4d pmadd(const Packet4d& a, const Packet4d& b, const Packet4d& c) {
|
|
967
|
+
return _mm256_fmadd_pd(a, b, c);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
template <>
|
|
971
|
+
EIGEN_STRONG_INLINE Packet8f pmsub(const Packet8f& a, const Packet8f& b, const Packet8f& c) {
|
|
972
|
+
return _mm256_fmsub_ps(a, b, c);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
template <>
|
|
976
|
+
EIGEN_STRONG_INLINE Packet4d pmsub(const Packet4d& a, const Packet4d& b, const Packet4d& c) {
|
|
977
|
+
return _mm256_fmsub_pd(a, b, c);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
template <>
|
|
981
|
+
EIGEN_STRONG_INLINE Packet8f pnmadd(const Packet8f& a, const Packet8f& b, const Packet8f& c) {
|
|
982
|
+
return _mm256_fnmadd_ps(a, b, c);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
template <>
|
|
986
|
+
EIGEN_STRONG_INLINE Packet4d pnmadd(const Packet4d& a, const Packet4d& b, const Packet4d& c) {
|
|
987
|
+
return _mm256_fnmadd_pd(a, b, c);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
template <>
|
|
991
|
+
EIGEN_STRONG_INLINE Packet8f pnmsub(const Packet8f& a, const Packet8f& b, const Packet8f& c) {
|
|
992
|
+
return _mm256_fnmsub_ps(a, b, c);
|
|
342
993
|
}
|
|
343
|
-
#endif
|
|
344
994
|
|
|
345
|
-
template<>
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
995
|
+
template <>
|
|
996
|
+
EIGEN_STRONG_INLINE Packet4d pnmsub(const Packet4d& a, const Packet4d& b, const Packet4d& c) {
|
|
997
|
+
return _mm256_fnmsub_pd(a, b, c);
|
|
998
|
+
}
|
|
349
999
|
|
|
350
|
-
|
|
351
|
-
template<> EIGEN_STRONG_INLINE Packet4d pcmp_lt(const Packet4d& a, const Packet4d& b) { return _mm256_cmp_pd(a,b,_CMP_LT_OQ); }
|
|
352
|
-
template<> EIGEN_STRONG_INLINE Packet4d pcmp_lt_or_nan(const Packet4d& a, const Packet4d& b) { return _mm256_cmp_pd(a, b, _CMP_NGE_UQ); }
|
|
353
|
-
template<> EIGEN_STRONG_INLINE Packet4d pcmp_eq(const Packet4d& a, const Packet4d& b) { return _mm256_cmp_pd(a,b,_CMP_EQ_OQ); }
|
|
1000
|
+
#endif
|
|
354
1001
|
|
|
1002
|
+
template <>
|
|
1003
|
+
EIGEN_STRONG_INLINE Packet8f pcmp_le(const Packet8f& a, const Packet8f& b) {
|
|
1004
|
+
return _mm256_cmp_ps(a, b, _CMP_LE_OQ);
|
|
1005
|
+
}
|
|
1006
|
+
template <>
|
|
1007
|
+
EIGEN_STRONG_INLINE Packet8f pcmp_lt(const Packet8f& a, const Packet8f& b) {
|
|
1008
|
+
return _mm256_cmp_ps(a, b, _CMP_LT_OQ);
|
|
1009
|
+
}
|
|
1010
|
+
template <>
|
|
1011
|
+
EIGEN_STRONG_INLINE Packet8f pcmp_lt_or_nan(const Packet8f& a, const Packet8f& b) {
|
|
1012
|
+
return _mm256_cmp_ps(a, b, _CMP_NGE_UQ);
|
|
1013
|
+
}
|
|
1014
|
+
template <>
|
|
1015
|
+
EIGEN_STRONG_INLINE Packet8f pcmp_eq(const Packet8f& a, const Packet8f& b) {
|
|
1016
|
+
return _mm256_cmp_ps(a, b, _CMP_EQ_OQ);
|
|
1017
|
+
}
|
|
1018
|
+
template <>
|
|
1019
|
+
EIGEN_STRONG_INLINE Packet8f pisnan(const Packet8f& a) {
|
|
1020
|
+
return _mm256_cmp_ps(a, a, _CMP_UNORD_Q);
|
|
1021
|
+
}
|
|
355
1022
|
|
|
356
|
-
template<>
|
|
1023
|
+
template <>
|
|
1024
|
+
EIGEN_STRONG_INLINE Packet4d pcmp_le(const Packet4d& a, const Packet4d& b) {
|
|
1025
|
+
return _mm256_cmp_pd(a, b, _CMP_LE_OQ);
|
|
1026
|
+
}
|
|
1027
|
+
template <>
|
|
1028
|
+
EIGEN_STRONG_INLINE Packet4d pcmp_lt(const Packet4d& a, const Packet4d& b) {
|
|
1029
|
+
return _mm256_cmp_pd(a, b, _CMP_LT_OQ);
|
|
1030
|
+
}
|
|
1031
|
+
template <>
|
|
1032
|
+
EIGEN_STRONG_INLINE Packet4d pcmp_lt_or_nan(const Packet4d& a, const Packet4d& b) {
|
|
1033
|
+
return _mm256_cmp_pd(a, b, _CMP_NGE_UQ);
|
|
1034
|
+
}
|
|
1035
|
+
template <>
|
|
1036
|
+
EIGEN_STRONG_INLINE Packet4d pcmp_eq(const Packet4d& a, const Packet4d& b) {
|
|
1037
|
+
return _mm256_cmp_pd(a, b, _CMP_EQ_OQ);
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
template <>
|
|
1041
|
+
EIGEN_STRONG_INLINE Packet8i pcmp_le(const Packet8i& a, const Packet8i& b) {
|
|
357
1042
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
358
|
-
return
|
|
1043
|
+
return _mm256_xor_si256(_mm256_cmpgt_epi32(a, b), _mm256_set1_epi32(-1));
|
|
1044
|
+
#else
|
|
1045
|
+
__m128i lo = _mm_cmpgt_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
1046
|
+
lo = _mm_xor_si128(lo, _mm_set1_epi32(-1));
|
|
1047
|
+
__m128i hi = _mm_cmpgt_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
1048
|
+
hi = _mm_xor_si128(hi, _mm_set1_epi32(-1));
|
|
1049
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
1050
|
+
#endif
|
|
1051
|
+
}
|
|
1052
|
+
template <>
|
|
1053
|
+
EIGEN_STRONG_INLINE Packet8i pcmp_lt(const Packet8i& a, const Packet8i& b) {
|
|
1054
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1055
|
+
return _mm256_cmpgt_epi32(b, a);
|
|
1056
|
+
#else
|
|
1057
|
+
__m128i lo = _mm_cmpgt_epi32(_mm256_extractf128_si256(b, 0), _mm256_extractf128_si256(a, 0));
|
|
1058
|
+
__m128i hi = _mm_cmpgt_epi32(_mm256_extractf128_si256(b, 1), _mm256_extractf128_si256(a, 1));
|
|
1059
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
1060
|
+
#endif
|
|
1061
|
+
}
|
|
1062
|
+
template <>
|
|
1063
|
+
EIGEN_STRONG_INLINE Packet8i pcmp_eq(const Packet8i& a, const Packet8i& b) {
|
|
1064
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1065
|
+
return _mm256_cmpeq_epi32(a, b);
|
|
1066
|
+
#else
|
|
1067
|
+
__m128i lo = _mm_cmpeq_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
1068
|
+
__m128i hi = _mm_cmpeq_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
1069
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
1070
|
+
#endif
|
|
1071
|
+
}
|
|
1072
|
+
template <>
|
|
1073
|
+
EIGEN_STRONG_INLINE Packet8ui pcmp_eq(const Packet8ui& a, const Packet8ui& b) {
|
|
1074
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1075
|
+
return _mm256_cmpeq_epi32(a, b);
|
|
359
1076
|
#else
|
|
360
1077
|
__m128i lo = _mm_cmpeq_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
361
1078
|
__m128i hi = _mm_cmpeq_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
@@ -363,188 +1080,353 @@ template<> EIGEN_STRONG_INLINE Packet8i pcmp_eq(const Packet8i& a, const Packet8
|
|
|
363
1080
|
#endif
|
|
364
1081
|
}
|
|
365
1082
|
|
|
366
|
-
template<>
|
|
367
|
-
|
|
1083
|
+
template <>
|
|
1084
|
+
EIGEN_STRONG_INLINE Packet8f pmin<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
1085
|
+
#if EIGEN_GNUC_STRICT_LESS_THAN(6, 3, 0)
|
|
368
1086
|
// There appears to be a bug in GCC, by which the optimizer may flip
|
|
369
1087
|
// the argument order in calls to _mm_min_ps/_mm_max_ps, so we have to
|
|
370
1088
|
// resort to inline ASM here. This is supposed to be fixed in gcc6.3,
|
|
371
1089
|
// see also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
|
|
372
1090
|
Packet8f res;
|
|
373
|
-
asm("vminps %[a], %[b], %[res]" : [res] "=x"
|
|
1091
|
+
asm("vminps %[a], %[b], %[res]" : [res] "=x"(res) : [a] "x"(a), [b] "x"(b));
|
|
374
1092
|
return res;
|
|
375
1093
|
#else
|
|
376
1094
|
// Arguments are swapped to match NaN propagation behavior of std::min.
|
|
377
|
-
return _mm256_min_ps(b,a);
|
|
1095
|
+
return _mm256_min_ps(b, a);
|
|
378
1096
|
#endif
|
|
379
1097
|
}
|
|
380
|
-
template<>
|
|
381
|
-
|
|
1098
|
+
template <>
|
|
1099
|
+
EIGEN_STRONG_INLINE Packet4d pmin<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
1100
|
+
#if EIGEN_GNUC_STRICT_LESS_THAN(6, 3, 0)
|
|
382
1101
|
// See pmin above
|
|
383
1102
|
Packet4d res;
|
|
384
|
-
asm("vminpd %[a], %[b], %[res]" : [res] "=x"
|
|
1103
|
+
asm("vminpd %[a], %[b], %[res]" : [res] "=x"(res) : [a] "x"(a), [b] "x"(b));
|
|
385
1104
|
return res;
|
|
386
1105
|
#else
|
|
387
1106
|
// Arguments are swapped to match NaN propagation behavior of std::min.
|
|
388
|
-
return _mm256_min_pd(b,a);
|
|
1107
|
+
return _mm256_min_pd(b, a);
|
|
1108
|
+
#endif
|
|
1109
|
+
}
|
|
1110
|
+
template <>
|
|
1111
|
+
EIGEN_STRONG_INLINE Packet8i pmin<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
1112
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1113
|
+
return _mm256_min_epi32(a, b);
|
|
1114
|
+
#else
|
|
1115
|
+
__m128i lo = _mm_min_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
1116
|
+
__m128i hi = _mm_min_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
1117
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
1118
|
+
#endif
|
|
1119
|
+
}
|
|
1120
|
+
template <>
|
|
1121
|
+
EIGEN_STRONG_INLINE Packet8ui pmin<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
1122
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1123
|
+
return _mm256_min_epu32(a, b);
|
|
1124
|
+
#else
|
|
1125
|
+
__m128i lo = _mm_min_epu32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
1126
|
+
__m128i hi = _mm_min_epu32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
1127
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
389
1128
|
#endif
|
|
390
1129
|
}
|
|
391
1130
|
|
|
392
|
-
template<>
|
|
393
|
-
|
|
1131
|
+
template <>
|
|
1132
|
+
EIGEN_STRONG_INLINE Packet8f pmax<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
1133
|
+
#if EIGEN_GNUC_STRICT_LESS_THAN(6, 3, 0)
|
|
394
1134
|
// See pmin above
|
|
395
1135
|
Packet8f res;
|
|
396
|
-
asm("vmaxps %[a], %[b], %[res]" : [res] "=x"
|
|
1136
|
+
asm("vmaxps %[a], %[b], %[res]" : [res] "=x"(res) : [a] "x"(a), [b] "x"(b));
|
|
397
1137
|
return res;
|
|
398
1138
|
#else
|
|
399
1139
|
// Arguments are swapped to match NaN propagation behavior of std::max.
|
|
400
|
-
return _mm256_max_ps(b,a);
|
|
1140
|
+
return _mm256_max_ps(b, a);
|
|
401
1141
|
#endif
|
|
402
1142
|
}
|
|
403
|
-
template<>
|
|
404
|
-
|
|
1143
|
+
template <>
|
|
1144
|
+
EIGEN_STRONG_INLINE Packet4d pmax<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
1145
|
+
#if EIGEN_GNUC_STRICT_LESS_THAN(6, 3, 0)
|
|
405
1146
|
// See pmin above
|
|
406
1147
|
Packet4d res;
|
|
407
|
-
asm("vmaxpd %[a], %[b], %[res]" : [res] "=x"
|
|
1148
|
+
asm("vmaxpd %[a], %[b], %[res]" : [res] "=x"(res) : [a] "x"(a), [b] "x"(b));
|
|
408
1149
|
return res;
|
|
409
1150
|
#else
|
|
410
1151
|
// Arguments are swapped to match NaN propagation behavior of std::max.
|
|
411
|
-
return _mm256_max_pd(b,a);
|
|
1152
|
+
return _mm256_max_pd(b, a);
|
|
1153
|
+
#endif
|
|
1154
|
+
}
|
|
1155
|
+
template <>
|
|
1156
|
+
EIGEN_STRONG_INLINE Packet8i pmax<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
1157
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1158
|
+
return _mm256_max_epi32(a, b);
|
|
1159
|
+
#else
|
|
1160
|
+
__m128i lo = _mm_max_epi32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
1161
|
+
__m128i hi = _mm_max_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
1162
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
1163
|
+
#endif
|
|
1164
|
+
}
|
|
1165
|
+
template <>
|
|
1166
|
+
EIGEN_STRONG_INLINE Packet8ui pmax<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
1167
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1168
|
+
return _mm256_max_epu32(a, b);
|
|
1169
|
+
#else
|
|
1170
|
+
__m128i lo = _mm_max_epu32(_mm256_extractf128_si256(a, 0), _mm256_extractf128_si256(b, 0));
|
|
1171
|
+
__m128i hi = _mm_max_epu32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1));
|
|
1172
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
412
1173
|
#endif
|
|
413
1174
|
}
|
|
414
1175
|
|
|
415
|
-
|
|
416
|
-
template<>
|
|
1176
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1177
|
+
template <>
|
|
1178
|
+
EIGEN_STRONG_INLINE Packet8i psign(const Packet8i& a) {
|
|
1179
|
+
return _mm256_sign_epi32(_mm256_set1_epi32(1), a);
|
|
1180
|
+
}
|
|
1181
|
+
#endif
|
|
1182
|
+
|
|
1183
|
+
// Add specializations for min/max with prescribed NaN propagation.
|
|
1184
|
+
template <>
|
|
417
1185
|
EIGEN_STRONG_INLINE Packet8f pmin<PropagateNumbers, Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
418
1186
|
return pminmax_propagate_numbers(a, b, pmin<Packet8f>);
|
|
419
1187
|
}
|
|
420
|
-
template<>
|
|
1188
|
+
template <>
|
|
421
1189
|
EIGEN_STRONG_INLINE Packet4d pmin<PropagateNumbers, Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
422
1190
|
return pminmax_propagate_numbers(a, b, pmin<Packet4d>);
|
|
423
1191
|
}
|
|
424
|
-
template<>
|
|
1192
|
+
template <>
|
|
425
1193
|
EIGEN_STRONG_INLINE Packet8f pmax<PropagateNumbers, Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
426
1194
|
return pminmax_propagate_numbers(a, b, pmax<Packet8f>);
|
|
427
1195
|
}
|
|
428
|
-
template<>
|
|
1196
|
+
template <>
|
|
429
1197
|
EIGEN_STRONG_INLINE Packet4d pmax<PropagateNumbers, Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
430
1198
|
return pminmax_propagate_numbers(a, b, pmax<Packet4d>);
|
|
431
1199
|
}
|
|
432
|
-
template<>
|
|
1200
|
+
template <>
|
|
433
1201
|
EIGEN_STRONG_INLINE Packet8f pmin<PropagateNaN, Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
434
1202
|
return pminmax_propagate_nan(a, b, pmin<Packet8f>);
|
|
435
1203
|
}
|
|
436
|
-
template<>
|
|
1204
|
+
template <>
|
|
437
1205
|
EIGEN_STRONG_INLINE Packet4d pmin<PropagateNaN, Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
438
1206
|
return pminmax_propagate_nan(a, b, pmin<Packet4d>);
|
|
439
1207
|
}
|
|
440
|
-
template<>
|
|
1208
|
+
template <>
|
|
441
1209
|
EIGEN_STRONG_INLINE Packet8f pmax<PropagateNaN, Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
442
1210
|
return pminmax_propagate_nan(a, b, pmax<Packet8f>);
|
|
443
1211
|
}
|
|
444
|
-
template<>
|
|
1212
|
+
template <>
|
|
445
1213
|
EIGEN_STRONG_INLINE Packet4d pmax<PropagateNaN, Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
446
1214
|
return pminmax_propagate_nan(a, b, pmax<Packet4d>);
|
|
447
1215
|
}
|
|
448
1216
|
|
|
449
|
-
template<>
|
|
450
|
-
|
|
1217
|
+
template <>
|
|
1218
|
+
EIGEN_STRONG_INLINE Packet8f print<Packet8f>(const Packet8f& a) {
|
|
1219
|
+
return _mm256_round_ps(a, _MM_FROUND_CUR_DIRECTION);
|
|
1220
|
+
}
|
|
1221
|
+
template <>
|
|
1222
|
+
EIGEN_STRONG_INLINE Packet4d print<Packet4d>(const Packet4d& a) {
|
|
1223
|
+
return _mm256_round_pd(a, _MM_FROUND_CUR_DIRECTION);
|
|
1224
|
+
}
|
|
451
1225
|
|
|
452
|
-
template<>
|
|
453
|
-
|
|
1226
|
+
template <>
|
|
1227
|
+
EIGEN_STRONG_INLINE Packet8f pceil<Packet8f>(const Packet8f& a) {
|
|
1228
|
+
return _mm256_ceil_ps(a);
|
|
1229
|
+
}
|
|
1230
|
+
template <>
|
|
1231
|
+
EIGEN_STRONG_INLINE Packet4d pceil<Packet4d>(const Packet4d& a) {
|
|
1232
|
+
return _mm256_ceil_pd(a);
|
|
1233
|
+
}
|
|
454
1234
|
|
|
455
|
-
template<>
|
|
456
|
-
|
|
1235
|
+
template <>
|
|
1236
|
+
EIGEN_STRONG_INLINE Packet8f pfloor<Packet8f>(const Packet8f& a) {
|
|
1237
|
+
return _mm256_floor_ps(a);
|
|
1238
|
+
}
|
|
1239
|
+
template <>
|
|
1240
|
+
EIGEN_STRONG_INLINE Packet4d pfloor<Packet4d>(const Packet4d& a) {
|
|
1241
|
+
return _mm256_floor_pd(a);
|
|
1242
|
+
}
|
|
457
1243
|
|
|
1244
|
+
template <>
|
|
1245
|
+
EIGEN_STRONG_INLINE Packet8f ptrunc<Packet8f>(const Packet8f& a) {
|
|
1246
|
+
return _mm256_round_ps(a, _MM_FROUND_TRUNC);
|
|
1247
|
+
}
|
|
1248
|
+
template <>
|
|
1249
|
+
EIGEN_STRONG_INLINE Packet4d ptrunc<Packet4d>(const Packet4d& a) {
|
|
1250
|
+
return _mm256_round_pd(a, _MM_FROUND_TRUNC);
|
|
1251
|
+
}
|
|
458
1252
|
|
|
459
|
-
template<>
|
|
1253
|
+
template <>
|
|
1254
|
+
EIGEN_STRONG_INLINE Packet8i ptrue<Packet8i>(const Packet8i& a) {
|
|
460
1255
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
461
1256
|
// vpcmpeqd has lower latency than the more general vcmpps
|
|
462
|
-
return _mm256_cmpeq_epi32(a,a);
|
|
1257
|
+
return _mm256_cmpeq_epi32(a, a);
|
|
463
1258
|
#else
|
|
464
1259
|
const __m256 b = _mm256_castsi256_ps(a);
|
|
465
|
-
return _mm256_castps_si256(_mm256_cmp_ps(b,b,_CMP_TRUE_UQ));
|
|
1260
|
+
return _mm256_castps_si256(_mm256_cmp_ps(b, b, _CMP_TRUE_UQ));
|
|
466
1261
|
#endif
|
|
467
1262
|
}
|
|
468
1263
|
|
|
469
|
-
template<>
|
|
1264
|
+
template <>
|
|
1265
|
+
EIGEN_STRONG_INLINE Packet8f ptrue<Packet8f>(const Packet8f& a) {
|
|
470
1266
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
471
1267
|
// vpcmpeqd has lower latency than the more general vcmpps
|
|
472
1268
|
const __m256i b = _mm256_castps_si256(a);
|
|
473
|
-
return _mm256_castsi256_ps(_mm256_cmpeq_epi32(b,b));
|
|
1269
|
+
return _mm256_castsi256_ps(_mm256_cmpeq_epi32(b, b));
|
|
474
1270
|
#else
|
|
475
|
-
return _mm256_cmp_ps(a,a,_CMP_TRUE_UQ);
|
|
1271
|
+
return _mm256_cmp_ps(a, a, _CMP_TRUE_UQ);
|
|
476
1272
|
#endif
|
|
477
1273
|
}
|
|
478
1274
|
|
|
479
|
-
template<>
|
|
1275
|
+
template <>
|
|
1276
|
+
EIGEN_STRONG_INLINE Packet4d ptrue<Packet4d>(const Packet4d& a) {
|
|
480
1277
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
481
1278
|
// vpcmpeqq has lower latency than the more general vcmppd
|
|
482
1279
|
const __m256i b = _mm256_castpd_si256(a);
|
|
483
|
-
return _mm256_castsi256_pd(_mm256_cmpeq_epi64(b,b));
|
|
1280
|
+
return _mm256_castsi256_pd(_mm256_cmpeq_epi64(b, b));
|
|
484
1281
|
#else
|
|
485
|
-
return _mm256_cmp_pd(a,a,_CMP_TRUE_UQ);
|
|
1282
|
+
return _mm256_cmp_pd(a, a, _CMP_TRUE_UQ);
|
|
486
1283
|
#endif
|
|
487
1284
|
}
|
|
488
1285
|
|
|
489
|
-
template<>
|
|
490
|
-
|
|
491
|
-
|
|
1286
|
+
template <>
|
|
1287
|
+
EIGEN_STRONG_INLINE Packet8f pand<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
1288
|
+
return _mm256_and_ps(a, b);
|
|
1289
|
+
}
|
|
1290
|
+
template <>
|
|
1291
|
+
EIGEN_STRONG_INLINE Packet4d pand<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
1292
|
+
return _mm256_and_pd(a, b);
|
|
1293
|
+
}
|
|
1294
|
+
template <>
|
|
1295
|
+
EIGEN_STRONG_INLINE Packet8i pand<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
492
1296
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
493
|
-
return _mm256_and_si256(a,b);
|
|
1297
|
+
return _mm256_and_si256(a, b);
|
|
494
1298
|
#else
|
|
495
|
-
return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(a),_mm256_castsi256_ps(b)));
|
|
1299
|
+
return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
|
|
1300
|
+
#endif
|
|
1301
|
+
}
|
|
1302
|
+
template <>
|
|
1303
|
+
EIGEN_STRONG_INLINE Packet8ui pand<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
1304
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1305
|
+
return _mm256_and_si256(a, b);
|
|
1306
|
+
#else
|
|
1307
|
+
return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
|
|
496
1308
|
#endif
|
|
497
1309
|
}
|
|
498
1310
|
|
|
499
|
-
template<>
|
|
500
|
-
|
|
501
|
-
|
|
1311
|
+
template <>
|
|
1312
|
+
EIGEN_STRONG_INLINE Packet8f por<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
1313
|
+
return _mm256_or_ps(a, b);
|
|
1314
|
+
}
|
|
1315
|
+
template <>
|
|
1316
|
+
EIGEN_STRONG_INLINE Packet4d por<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
1317
|
+
return _mm256_or_pd(a, b);
|
|
1318
|
+
}
|
|
1319
|
+
template <>
|
|
1320
|
+
EIGEN_STRONG_INLINE Packet8i por<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
1321
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1322
|
+
return _mm256_or_si256(a, b);
|
|
1323
|
+
#else
|
|
1324
|
+
return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
|
|
1325
|
+
#endif
|
|
1326
|
+
}
|
|
1327
|
+
template <>
|
|
1328
|
+
EIGEN_STRONG_INLINE Packet8ui por<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
502
1329
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
503
|
-
return _mm256_or_si256(a,b);
|
|
1330
|
+
return _mm256_or_si256(a, b);
|
|
504
1331
|
#else
|
|
505
|
-
return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(a),_mm256_castsi256_ps(b)));
|
|
1332
|
+
return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
|
|
506
1333
|
#endif
|
|
507
1334
|
}
|
|
508
1335
|
|
|
509
|
-
template<>
|
|
510
|
-
|
|
511
|
-
|
|
1336
|
+
template <>
|
|
1337
|
+
EIGEN_STRONG_INLINE Packet8f pxor<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
1338
|
+
return _mm256_xor_ps(a, b);
|
|
1339
|
+
}
|
|
1340
|
+
template <>
|
|
1341
|
+
EIGEN_STRONG_INLINE Packet4d pxor<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
1342
|
+
return _mm256_xor_pd(a, b);
|
|
1343
|
+
}
|
|
1344
|
+
template <>
|
|
1345
|
+
EIGEN_STRONG_INLINE Packet8i pxor<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
1346
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1347
|
+
return _mm256_xor_si256(a, b);
|
|
1348
|
+
#else
|
|
1349
|
+
return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
|
|
1350
|
+
#endif
|
|
1351
|
+
}
|
|
1352
|
+
template <>
|
|
1353
|
+
EIGEN_STRONG_INLINE Packet8ui pxor<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
512
1354
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
513
|
-
return _mm256_xor_si256(a,b);
|
|
1355
|
+
return _mm256_xor_si256(a, b);
|
|
514
1356
|
#else
|
|
515
|
-
return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a),_mm256_castsi256_ps(b)));
|
|
1357
|
+
return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b)));
|
|
516
1358
|
#endif
|
|
517
1359
|
}
|
|
518
1360
|
|
|
519
|
-
template<>
|
|
520
|
-
|
|
521
|
-
|
|
1361
|
+
template <>
|
|
1362
|
+
EIGEN_STRONG_INLINE Packet8f pandnot<Packet8f>(const Packet8f& a, const Packet8f& b) {
|
|
1363
|
+
return _mm256_andnot_ps(b, a);
|
|
1364
|
+
}
|
|
1365
|
+
template <>
|
|
1366
|
+
EIGEN_STRONG_INLINE Packet4d pandnot<Packet4d>(const Packet4d& a, const Packet4d& b) {
|
|
1367
|
+
return _mm256_andnot_pd(b, a);
|
|
1368
|
+
}
|
|
1369
|
+
template <>
|
|
1370
|
+
EIGEN_STRONG_INLINE Packet8i pandnot<Packet8i>(const Packet8i& a, const Packet8i& b) {
|
|
1371
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1372
|
+
return _mm256_andnot_si256(b, a);
|
|
1373
|
+
#else
|
|
1374
|
+
return _mm256_castps_si256(_mm256_andnot_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(a)));
|
|
1375
|
+
#endif
|
|
1376
|
+
}
|
|
1377
|
+
template <>
|
|
1378
|
+
EIGEN_STRONG_INLINE Packet8ui pandnot<Packet8ui>(const Packet8ui& a, const Packet8ui& b) {
|
|
522
1379
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
523
|
-
return _mm256_andnot_si256(b,a);
|
|
1380
|
+
return _mm256_andnot_si256(b, a);
|
|
524
1381
|
#else
|
|
525
|
-
return _mm256_castps_si256(_mm256_andnot_ps(_mm256_castsi256_ps(b),_mm256_castsi256_ps(a)));
|
|
1382
|
+
return _mm256_castps_si256(_mm256_andnot_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(a)));
|
|
526
1383
|
#endif
|
|
527
1384
|
}
|
|
528
1385
|
|
|
529
|
-
template<>
|
|
530
|
-
{
|
|
1386
|
+
template <>
|
|
1387
|
+
EIGEN_STRONG_INLINE Packet8ui pcmp_lt(const Packet8ui& a, const Packet8ui& b) {
|
|
1388
|
+
return pxor(pcmp_eq(a, pmax(a, b)), ptrue(a));
|
|
1389
|
+
}
|
|
1390
|
+
template <>
|
|
1391
|
+
EIGEN_STRONG_INLINE Packet8ui pcmp_le(const Packet8ui& a, const Packet8ui& b) {
|
|
1392
|
+
return pcmp_eq(a, pmin(a, b));
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
template <>
|
|
1396
|
+
EIGEN_STRONG_INLINE Packet8f pround<Packet8f>(const Packet8f& a) {
|
|
531
1397
|
const Packet8f mask = pset1frombits<Packet8f>(static_cast<numext::uint32_t>(0x80000000u));
|
|
532
1398
|
const Packet8f prev0dot5 = pset1frombits<Packet8f>(static_cast<numext::uint32_t>(0x3EFFFFFFu));
|
|
533
1399
|
return _mm256_round_ps(padd(por(pand(a, mask), prev0dot5), a), _MM_FROUND_TO_ZERO);
|
|
534
1400
|
}
|
|
535
|
-
template<>
|
|
536
|
-
{
|
|
1401
|
+
template <>
|
|
1402
|
+
EIGEN_STRONG_INLINE Packet4d pround<Packet4d>(const Packet4d& a) {
|
|
537
1403
|
const Packet4d mask = pset1frombits<Packet4d>(static_cast<numext::uint64_t>(0x8000000000000000ull));
|
|
538
1404
|
const Packet4d prev0dot5 = pset1frombits<Packet4d>(static_cast<numext::uint64_t>(0x3FDFFFFFFFFFFFFFull));
|
|
539
1405
|
return _mm256_round_pd(padd(por(pand(a, mask), prev0dot5), a), _MM_FROUND_TO_ZERO);
|
|
540
1406
|
}
|
|
541
1407
|
|
|
542
|
-
template<>
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
1408
|
+
template <>
|
|
1409
|
+
EIGEN_STRONG_INLINE Packet8f pselect<Packet8f>(const Packet8f& mask, const Packet8f& a, const Packet8f& b) {
|
|
1410
|
+
return _mm256_blendv_ps(b, a, mask);
|
|
1411
|
+
}
|
|
1412
|
+
template <>
|
|
1413
|
+
EIGEN_STRONG_INLINE Packet8i pselect<Packet8i>(const Packet8i& mask, const Packet8i& a, const Packet8i& b) {
|
|
1414
|
+
return _mm256_castps_si256(
|
|
1415
|
+
_mm256_blendv_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(a), _mm256_castsi256_ps(mask)));
|
|
1416
|
+
}
|
|
1417
|
+
template <>
|
|
1418
|
+
EIGEN_STRONG_INLINE Packet8ui pselect<Packet8ui>(const Packet8ui& mask, const Packet8ui& a, const Packet8ui& b) {
|
|
1419
|
+
return _mm256_castps_si256(
|
|
1420
|
+
_mm256_blendv_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(a), _mm256_castsi256_ps(mask)));
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
template <>
|
|
1424
|
+
EIGEN_STRONG_INLINE Packet4d pselect<Packet4d>(const Packet4d& mask, const Packet4d& a, const Packet4d& b) {
|
|
1425
|
+
return _mm256_blendv_pd(b, a, mask);
|
|
1426
|
+
}
|
|
546
1427
|
|
|
547
|
-
template<int N>
|
|
1428
|
+
template <int N>
|
|
1429
|
+
EIGEN_STRONG_INLINE Packet8i parithmetic_shift_right(Packet8i a) {
|
|
548
1430
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
549
1431
|
return _mm256_srai_epi32(a, N);
|
|
550
1432
|
#else
|
|
@@ -554,7 +1436,8 @@ template<int N> EIGEN_STRONG_INLINE Packet8i parithmetic_shift_right(Packet8i a)
|
|
|
554
1436
|
#endif
|
|
555
1437
|
}
|
|
556
1438
|
|
|
557
|
-
template<int N>
|
|
1439
|
+
template <int N>
|
|
1440
|
+
EIGEN_STRONG_INLINE Packet8i plogical_shift_right(Packet8i a) {
|
|
558
1441
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
559
1442
|
return _mm256_srli_epi32(a, N);
|
|
560
1443
|
#else
|
|
@@ -564,7 +1447,8 @@ template<int N> EIGEN_STRONG_INLINE Packet8i plogical_shift_right(Packet8i a) {
|
|
|
564
1447
|
#endif
|
|
565
1448
|
}
|
|
566
1449
|
|
|
567
|
-
template<int N>
|
|
1450
|
+
template <int N>
|
|
1451
|
+
EIGEN_STRONG_INLINE Packet8i plogical_shift_left(Packet8i a) {
|
|
568
1452
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
569
1453
|
return _mm256_slli_epi32(a, N);
|
|
570
1454
|
#else
|
|
@@ -574,174 +1458,415 @@ template<int N> EIGEN_STRONG_INLINE Packet8i plogical_shift_left(Packet8i a) {
|
|
|
574
1458
|
#endif
|
|
575
1459
|
}
|
|
576
1460
|
|
|
577
|
-
template
|
|
578
|
-
|
|
579
|
-
|
|
1461
|
+
template <int N>
|
|
1462
|
+
EIGEN_STRONG_INLINE Packet8ui parithmetic_shift_right(Packet8ui a) {
|
|
1463
|
+
return (Packet8ui)plogical_shift_right<N>((Packet8i)a);
|
|
1464
|
+
}
|
|
1465
|
+
template <int N>
|
|
1466
|
+
EIGEN_STRONG_INLINE Packet8ui plogical_shift_right(Packet8ui a) {
|
|
1467
|
+
return (Packet8ui)plogical_shift_right<N>((Packet8i)a);
|
|
1468
|
+
}
|
|
1469
|
+
template <int N>
|
|
1470
|
+
EIGEN_STRONG_INLINE Packet8ui plogical_shift_left(Packet8ui a) {
|
|
1471
|
+
return (Packet8ui)plogical_shift_left<N>((Packet8i)a);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
template <>
|
|
1475
|
+
EIGEN_STRONG_INLINE Packet8f pload<Packet8f>(const float* from) {
|
|
1476
|
+
EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_ps(from);
|
|
1477
|
+
}
|
|
1478
|
+
template <>
|
|
1479
|
+
EIGEN_STRONG_INLINE Packet4d pload<Packet4d>(const double* from) {
|
|
1480
|
+
EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_pd(from);
|
|
1481
|
+
}
|
|
1482
|
+
template <>
|
|
1483
|
+
EIGEN_STRONG_INLINE Packet8i pload<Packet8i>(const int* from) {
|
|
1484
|
+
EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_si256(reinterpret_cast<const __m256i*>(from));
|
|
1485
|
+
}
|
|
1486
|
+
template <>
|
|
1487
|
+
EIGEN_STRONG_INLINE Packet8ui pload<Packet8ui>(const uint32_t* from) {
|
|
1488
|
+
EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_si256(reinterpret_cast<const __m256i*>(from));
|
|
1489
|
+
}
|
|
580
1490
|
|
|
581
|
-
template<>
|
|
582
|
-
|
|
583
|
-
|
|
1491
|
+
template <>
|
|
1492
|
+
EIGEN_STRONG_INLINE Packet8f ploadu<Packet8f>(const float* from) {
|
|
1493
|
+
EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_ps(from);
|
|
1494
|
+
}
|
|
1495
|
+
template <>
|
|
1496
|
+
EIGEN_STRONG_INLINE Packet4d ploadu<Packet4d>(const double* from) {
|
|
1497
|
+
EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_pd(from);
|
|
1498
|
+
}
|
|
1499
|
+
template <>
|
|
1500
|
+
EIGEN_STRONG_INLINE Packet8i ploadu<Packet8i>(const int* from) {
|
|
1501
|
+
EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_si256(reinterpret_cast<const __m256i*>(from));
|
|
1502
|
+
}
|
|
1503
|
+
template <>
|
|
1504
|
+
EIGEN_STRONG_INLINE Packet8ui ploadu<Packet8ui>(const uint32_t* from) {
|
|
1505
|
+
EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_si256(reinterpret_cast<const __m256i*>(from));
|
|
1506
|
+
}
|
|
584
1507
|
|
|
585
|
-
template<>
|
|
1508
|
+
template <>
|
|
1509
|
+
EIGEN_STRONG_INLINE Packet8f ploadu<Packet8f>(const float* from, uint8_t umask) {
|
|
1510
|
+
#ifdef EIGEN_VECTORIZE_AVX512
|
|
1511
|
+
__mmask16 mask = static_cast<__mmask16>(umask & 0x00FF);
|
|
1512
|
+
EIGEN_DEBUG_UNALIGNED_LOAD return _mm512_castps512_ps256(_mm512_maskz_loadu_ps(mask, from));
|
|
1513
|
+
#else
|
|
586
1514
|
Packet8i mask = _mm256_set1_epi8(static_cast<char>(umask));
|
|
587
|
-
const Packet8i bit_mask =
|
|
1515
|
+
const Packet8i bit_mask =
|
|
1516
|
+
_mm256_set_epi32(0xffffff7f, 0xffffffbf, 0xffffffdf, 0xffffffef, 0xfffffff7, 0xfffffffb, 0xfffffffd, 0xfffffffe);
|
|
588
1517
|
mask = por<Packet8i>(mask, bit_mask);
|
|
589
1518
|
mask = pcmp_eq<Packet8i>(mask, _mm256_set1_epi32(0xffffffff));
|
|
590
1519
|
EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_maskload_ps(from, mask);
|
|
1520
|
+
#endif
|
|
591
1521
|
}
|
|
592
1522
|
|
|
593
1523
|
// Loads 4 floats from memory a returns the packet {a0, a0 a1, a1, a2, a2, a3, a3}
|
|
594
|
-
template<>
|
|
595
|
-
{
|
|
1524
|
+
template <>
|
|
1525
|
+
EIGEN_STRONG_INLINE Packet8f ploaddup<Packet8f>(const float* from) {
|
|
596
1526
|
// TODO try to find a way to avoid the need of a temporary register
|
|
597
|
-
// Packet8f tmp = _mm256_castps128_ps256(_mm_loadu_ps(from));
|
|
598
|
-
// tmp = _mm256_insertf128_ps(tmp, _mm_movehl_ps(_mm256_castps256_ps128(tmp),_mm256_castps256_ps128(tmp)), 1);
|
|
599
|
-
// return _mm256_unpacklo_ps(tmp,tmp);
|
|
1527
|
+
// Packet8f tmp = _mm256_castps128_ps256(_mm_loadu_ps(from));
|
|
1528
|
+
// tmp = _mm256_insertf128_ps(tmp, _mm_movehl_ps(_mm256_castps256_ps128(tmp),_mm256_castps256_ps128(tmp)), 1);
|
|
1529
|
+
// return _mm256_unpacklo_ps(tmp,tmp);
|
|
600
1530
|
|
|
601
1531
|
// _mm256_insertf128_ps is very slow on Haswell, thus:
|
|
602
1532
|
Packet8f tmp = _mm256_broadcast_ps((const __m128*)(const void*)from);
|
|
603
1533
|
// mimic an "inplace" permutation of the lower 128bits using a blend
|
|
604
|
-
tmp = _mm256_blend_ps(
|
|
1534
|
+
tmp = _mm256_blend_ps(
|
|
1535
|
+
tmp, _mm256_castps128_ps256(_mm_permute_ps(_mm256_castps256_ps128(tmp), _MM_SHUFFLE(1, 0, 1, 0))), 15);
|
|
605
1536
|
// then we can perform a consistent permutation on the global register to get everything in shape:
|
|
606
|
-
return
|
|
1537
|
+
return _mm256_permute_ps(tmp, _MM_SHUFFLE(3, 3, 2, 2));
|
|
607
1538
|
}
|
|
608
|
-
// Loads 2 doubles from memory a returns the packet {a0, a0
|
|
609
|
-
template<>
|
|
610
|
-
{
|
|
1539
|
+
// Loads 2 doubles from memory a returns the packet {a0, a0, a1, a1}
|
|
1540
|
+
template <>
|
|
1541
|
+
EIGEN_STRONG_INLINE Packet4d ploaddup<Packet4d>(const double* from) {
|
|
611
1542
|
Packet4d tmp = _mm256_broadcast_pd((const __m128d*)(const void*)from);
|
|
612
|
-
return
|
|
1543
|
+
return _mm256_permute_pd(tmp, 3 << 2);
|
|
1544
|
+
}
|
|
1545
|
+
// Loads 4 integers from memory a returns the packet {a0, a0, a1, a1, a2, a2, a3, a3}
|
|
1546
|
+
template <>
|
|
1547
|
+
EIGEN_STRONG_INLINE Packet8i ploaddup<Packet8i>(const int* from) {
|
|
1548
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1549
|
+
const Packet8i a = _mm256_castsi128_si256(ploadu<Packet4i>(from));
|
|
1550
|
+
return _mm256_permutevar8x32_epi32(a, _mm256_setr_epi32(0, 0, 1, 1, 2, 2, 3, 3));
|
|
1551
|
+
#else
|
|
1552
|
+
__m256 tmp = _mm256_broadcast_ps((const __m128*)(const void*)from);
|
|
1553
|
+
// mimic an "inplace" permutation of the lower 128bits using a blend
|
|
1554
|
+
tmp = _mm256_blend_ps(
|
|
1555
|
+
tmp, _mm256_castps128_ps256(_mm_permute_ps(_mm256_castps256_ps128(tmp), _MM_SHUFFLE(1, 0, 1, 0))), 15);
|
|
1556
|
+
// then we can perform a consistent permutation on the global register to get everything in shape:
|
|
1557
|
+
return _mm256_castps_si256(_mm256_permute_ps(tmp, _MM_SHUFFLE(3, 3, 2, 2)));
|
|
1558
|
+
#endif
|
|
1559
|
+
}
|
|
1560
|
+
template <>
|
|
1561
|
+
EIGEN_STRONG_INLINE Packet8ui ploaddup<Packet8ui>(const uint32_t* from) {
|
|
1562
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1563
|
+
const Packet8ui a = _mm256_castsi128_si256(ploadu<Packet4ui>(from));
|
|
1564
|
+
return _mm256_permutevar8x32_epi32(a, _mm256_setr_epi32(0, 0, 1, 1, 2, 2, 3, 3));
|
|
1565
|
+
#else
|
|
1566
|
+
__m256 tmp = _mm256_broadcast_ps((const __m128*)(const void*)from);
|
|
1567
|
+
// mimic an "inplace" permutation of the lower 128bits using a blend
|
|
1568
|
+
tmp = _mm256_blend_ps(
|
|
1569
|
+
tmp, _mm256_castps128_ps256(_mm_permute_ps(_mm256_castps256_ps128(tmp), _MM_SHUFFLE(1, 0, 1, 0))), 15);
|
|
1570
|
+
// then we can perform a consistent permutation on the global register to get
|
|
1571
|
+
// everything in shape:
|
|
1572
|
+
return _mm256_castps_si256(_mm256_permute_ps(tmp, _MM_SHUFFLE(3, 3, 2, 2)));
|
|
1573
|
+
#endif
|
|
613
1574
|
}
|
|
614
1575
|
|
|
615
1576
|
// Loads 2 floats from memory a returns the packet {a0, a0 a0, a0, a1, a1, a1, a1}
|
|
616
|
-
template<>
|
|
617
|
-
{
|
|
1577
|
+
template <>
|
|
1578
|
+
EIGEN_STRONG_INLINE Packet8f ploadquad<Packet8f>(const float* from) {
|
|
618
1579
|
Packet8f tmp = _mm256_castps128_ps256(_mm_broadcast_ss(from));
|
|
619
|
-
return _mm256_insertf128_ps(tmp, _mm_broadcast_ss(from+1), 1);
|
|
1580
|
+
return _mm256_insertf128_ps(tmp, _mm_broadcast_ss(from + 1), 1);
|
|
1581
|
+
}
|
|
1582
|
+
template <>
|
|
1583
|
+
EIGEN_STRONG_INLINE Packet8i ploadquad<Packet8i>(const int* from) {
|
|
1584
|
+
return _mm256_insertf128_si256(_mm256_set1_epi32(*from), _mm_set1_epi32(*(from + 1)), 1);
|
|
1585
|
+
}
|
|
1586
|
+
template <>
|
|
1587
|
+
EIGEN_STRONG_INLINE Packet8ui ploadquad<Packet8ui>(const uint32_t* from) {
|
|
1588
|
+
return _mm256_insertf128_si256(_mm256_set1_epi32(*from), _mm_set1_epi32(*(from + 1)), 1);
|
|
620
1589
|
}
|
|
621
1590
|
|
|
622
|
-
template<>
|
|
623
|
-
|
|
624
|
-
|
|
1591
|
+
template <>
|
|
1592
|
+
EIGEN_STRONG_INLINE void pstore<float>(float* to, const Packet8f& from) {
|
|
1593
|
+
EIGEN_DEBUG_ALIGNED_STORE _mm256_store_ps(to, from);
|
|
1594
|
+
}
|
|
1595
|
+
template <>
|
|
1596
|
+
EIGEN_STRONG_INLINE void pstore<double>(double* to, const Packet4d& from) {
|
|
1597
|
+
EIGEN_DEBUG_ALIGNED_STORE _mm256_store_pd(to, from);
|
|
1598
|
+
}
|
|
1599
|
+
template <>
|
|
1600
|
+
EIGEN_STRONG_INLINE void pstore<int>(int* to, const Packet8i& from) {
|
|
1601
|
+
EIGEN_DEBUG_ALIGNED_STORE _mm256_store_si256(reinterpret_cast<__m256i*>(to), from);
|
|
1602
|
+
}
|
|
1603
|
+
template <>
|
|
1604
|
+
EIGEN_STRONG_INLINE void pstore<uint32_t>(uint32_t* to, const Packet8ui& from) {
|
|
1605
|
+
EIGEN_DEBUG_ALIGNED_STORE _mm256_store_si256(reinterpret_cast<__m256i*>(to), from);
|
|
1606
|
+
}
|
|
625
1607
|
|
|
626
|
-
template<>
|
|
627
|
-
|
|
628
|
-
|
|
1608
|
+
template <>
|
|
1609
|
+
EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet8f& from) {
|
|
1610
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_ps(to, from);
|
|
1611
|
+
}
|
|
1612
|
+
template <>
|
|
1613
|
+
EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet4d& from) {
|
|
1614
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_pd(to, from);
|
|
1615
|
+
}
|
|
1616
|
+
template <>
|
|
1617
|
+
EIGEN_STRONG_INLINE void pstoreu<int>(int* to, const Packet8i& from) {
|
|
1618
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_si256(reinterpret_cast<__m256i*>(to), from);
|
|
1619
|
+
}
|
|
1620
|
+
template <>
|
|
1621
|
+
EIGEN_STRONG_INLINE void pstoreu<uint32_t>(uint32_t* to, const Packet8ui& from) {
|
|
1622
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_si256(reinterpret_cast<__m256i*>(to), from);
|
|
1623
|
+
}
|
|
629
1624
|
|
|
630
|
-
template<>
|
|
1625
|
+
template <>
|
|
1626
|
+
EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet8f& from, uint8_t umask) {
|
|
1627
|
+
#ifdef EIGEN_VECTORIZE_AVX512
|
|
1628
|
+
__mmask16 mask = static_cast<__mmask16>(umask & 0x00FF);
|
|
1629
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm512_mask_storeu_ps(to, mask, _mm512_castps256_ps512(from));
|
|
1630
|
+
#else
|
|
631
1631
|
Packet8i mask = _mm256_set1_epi8(static_cast<char>(umask));
|
|
632
|
-
const Packet8i bit_mask =
|
|
1632
|
+
const Packet8i bit_mask =
|
|
1633
|
+
_mm256_set_epi32(0x7f7f7f7f, 0xbfbfbfbf, 0xdfdfdfdf, 0xefefefef, 0xf7f7f7f7, 0xfbfbfbfb, 0xfdfdfdfd, 0xfefefefe);
|
|
633
1634
|
mask = por<Packet8i>(mask, bit_mask);
|
|
634
1635
|
mask = pcmp_eq<Packet8i>(mask, _mm256_set1_epi32(0xffffffff));
|
|
635
|
-
|
|
1636
|
+
#if EIGEN_COMP_MSVC
|
|
1637
|
+
// MSVC sometimes seems to use a bogus mask with maskstore.
|
|
1638
|
+
const __m256i ifrom = _mm256_castps_si256(from);
|
|
1639
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm_maskmoveu_si128(_mm256_extractf128_si256(ifrom, 0), _mm256_extractf128_si256(mask, 0),
|
|
1640
|
+
reinterpret_cast<char*>(to));
|
|
1641
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm_maskmoveu_si128(_mm256_extractf128_si256(ifrom, 1), _mm256_extractf128_si256(mask, 1),
|
|
1642
|
+
reinterpret_cast<char*>(to + 4));
|
|
1643
|
+
#else
|
|
1644
|
+
EIGEN_DEBUG_UNALIGNED_STORE _mm256_maskstore_ps(to, mask, from);
|
|
1645
|
+
#endif
|
|
1646
|
+
#endif
|
|
636
1647
|
}
|
|
637
1648
|
|
|
638
1649
|
// NOTE: leverage _mm256_i32gather_ps and _mm256_i32gather_pd if AVX2 instructions are available
|
|
639
|
-
// NOTE: for the record the following seems to be slower: return _mm256_i32gather_ps(from, _mm256_set1_epi32(stride),
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
1650
|
+
// NOTE: for the record the following seems to be slower: return _mm256_i32gather_ps(from, _mm256_set1_epi32(stride),
|
|
1651
|
+
// 4);
|
|
1652
|
+
template <>
|
|
1653
|
+
EIGEN_DEVICE_FUNC inline Packet8f pgather<float, Packet8f>(const float* from, Index stride) {
|
|
1654
|
+
return _mm256_set_ps(from[7 * stride], from[6 * stride], from[5 * stride], from[4 * stride], from[3 * stride],
|
|
1655
|
+
from[2 * stride], from[1 * stride], from[0 * stride]);
|
|
1656
|
+
}
|
|
1657
|
+
template <>
|
|
1658
|
+
EIGEN_DEVICE_FUNC inline Packet4d pgather<double, Packet4d>(const double* from, Index stride) {
|
|
1659
|
+
return _mm256_set_pd(from[3 * stride], from[2 * stride], from[1 * stride], from[0 * stride]);
|
|
1660
|
+
}
|
|
1661
|
+
template <>
|
|
1662
|
+
EIGEN_DEVICE_FUNC inline Packet8i pgather<int, Packet8i>(const int* from, Index stride) {
|
|
1663
|
+
return _mm256_set_epi32(from[7 * stride], from[6 * stride], from[5 * stride], from[4 * stride], from[3 * stride],
|
|
1664
|
+
from[2 * stride], from[1 * stride], from[0 * stride]);
|
|
644
1665
|
}
|
|
645
|
-
template<>
|
|
646
|
-
{
|
|
647
|
-
return
|
|
1666
|
+
template <>
|
|
1667
|
+
EIGEN_DEVICE_FUNC inline Packet8ui pgather<uint32_t, Packet8ui>(const uint32_t* from, Index stride) {
|
|
1668
|
+
return (Packet8ui)pgather<int, Packet8i>((int*)from, stride);
|
|
648
1669
|
}
|
|
649
1670
|
|
|
650
|
-
template<>
|
|
651
|
-
{
|
|
1671
|
+
template <>
|
|
1672
|
+
EIGEN_DEVICE_FUNC inline void pscatter<float, Packet8f>(float* to, const Packet8f& from, Index stride) {
|
|
652
1673
|
__m128 low = _mm256_extractf128_ps(from, 0);
|
|
653
|
-
to[stride*0] = _mm_cvtss_f32(low);
|
|
654
|
-
to[stride*1] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 1));
|
|
655
|
-
to[stride*2] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 2));
|
|
656
|
-
to[stride*3] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 3));
|
|
1674
|
+
to[stride * 0] = _mm_cvtss_f32(low);
|
|
1675
|
+
to[stride * 1] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 1));
|
|
1676
|
+
to[stride * 2] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 2));
|
|
1677
|
+
to[stride * 3] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 3));
|
|
657
1678
|
|
|
658
1679
|
__m128 high = _mm256_extractf128_ps(from, 1);
|
|
659
|
-
to[stride*4] = _mm_cvtss_f32(high);
|
|
660
|
-
to[stride*5] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 1));
|
|
661
|
-
to[stride*6] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 2));
|
|
662
|
-
to[stride*7] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 3));
|
|
1680
|
+
to[stride * 4] = _mm_cvtss_f32(high);
|
|
1681
|
+
to[stride * 5] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 1));
|
|
1682
|
+
to[stride * 6] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 2));
|
|
1683
|
+
to[stride * 7] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 3));
|
|
663
1684
|
}
|
|
664
|
-
template<>
|
|
665
|
-
{
|
|
1685
|
+
template <>
|
|
1686
|
+
EIGEN_DEVICE_FUNC inline void pscatter<double, Packet4d>(double* to, const Packet4d& from, Index stride) {
|
|
666
1687
|
__m128d low = _mm256_extractf128_pd(from, 0);
|
|
667
|
-
to[stride*0] = _mm_cvtsd_f64(low);
|
|
668
|
-
to[stride*1] = _mm_cvtsd_f64(_mm_shuffle_pd(low, low, 1));
|
|
1688
|
+
to[stride * 0] = _mm_cvtsd_f64(low);
|
|
1689
|
+
to[stride * 1] = _mm_cvtsd_f64(_mm_shuffle_pd(low, low, 1));
|
|
669
1690
|
__m128d high = _mm256_extractf128_pd(from, 1);
|
|
670
|
-
to[stride*2] = _mm_cvtsd_f64(high);
|
|
671
|
-
to[stride*3] = _mm_cvtsd_f64(_mm_shuffle_pd(high, high, 1));
|
|
1691
|
+
to[stride * 2] = _mm_cvtsd_f64(high);
|
|
1692
|
+
to[stride * 3] = _mm_cvtsd_f64(_mm_shuffle_pd(high, high, 1));
|
|
1693
|
+
}
|
|
1694
|
+
template <>
|
|
1695
|
+
EIGEN_DEVICE_FUNC inline void pscatter<int, Packet8i>(int* to, const Packet8i& from, Index stride) {
|
|
1696
|
+
__m128i low = _mm256_extractf128_si256(from, 0);
|
|
1697
|
+
to[stride * 0] = _mm_extract_epi32(low, 0);
|
|
1698
|
+
to[stride * 1] = _mm_extract_epi32(low, 1);
|
|
1699
|
+
to[stride * 2] = _mm_extract_epi32(low, 2);
|
|
1700
|
+
to[stride * 3] = _mm_extract_epi32(low, 3);
|
|
1701
|
+
|
|
1702
|
+
__m128i high = _mm256_extractf128_si256(from, 1);
|
|
1703
|
+
to[stride * 4] = _mm_extract_epi32(high, 0);
|
|
1704
|
+
to[stride * 5] = _mm_extract_epi32(high, 1);
|
|
1705
|
+
to[stride * 6] = _mm_extract_epi32(high, 2);
|
|
1706
|
+
to[stride * 7] = _mm_extract_epi32(high, 3);
|
|
1707
|
+
}
|
|
1708
|
+
template <>
|
|
1709
|
+
EIGEN_DEVICE_FUNC inline void pscatter<uint32_t, Packet8ui>(uint32_t* to, const Packet8ui& from, Index stride) {
|
|
1710
|
+
pscatter<int, Packet8i>((int*)to, (Packet8i)from, stride);
|
|
672
1711
|
}
|
|
673
1712
|
|
|
674
|
-
template<>
|
|
675
|
-
{
|
|
1713
|
+
template <>
|
|
1714
|
+
EIGEN_STRONG_INLINE void pstore1<Packet8f>(float* to, const float& a) {
|
|
676
1715
|
Packet8f pa = pset1<Packet8f>(a);
|
|
677
1716
|
pstore(to, pa);
|
|
678
1717
|
}
|
|
679
|
-
template<>
|
|
680
|
-
{
|
|
1718
|
+
template <>
|
|
1719
|
+
EIGEN_STRONG_INLINE void pstore1<Packet4d>(double* to, const double& a) {
|
|
681
1720
|
Packet4d pa = pset1<Packet4d>(a);
|
|
682
1721
|
pstore(to, pa);
|
|
683
1722
|
}
|
|
684
|
-
template<>
|
|
685
|
-
{
|
|
1723
|
+
template <>
|
|
1724
|
+
EIGEN_STRONG_INLINE void pstore1<Packet8i>(int* to, const int& a) {
|
|
686
1725
|
Packet8i pa = pset1<Packet8i>(a);
|
|
687
1726
|
pstore(to, pa);
|
|
688
1727
|
}
|
|
689
1728
|
|
|
690
1729
|
#ifndef EIGEN_VECTORIZE_AVX512
|
|
691
|
-
template<>
|
|
692
|
-
|
|
693
|
-
|
|
1730
|
+
template <>
|
|
1731
|
+
EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) {
|
|
1732
|
+
_mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0);
|
|
1733
|
+
}
|
|
1734
|
+
template <>
|
|
1735
|
+
EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) {
|
|
1736
|
+
_mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0);
|
|
1737
|
+
}
|
|
1738
|
+
template <>
|
|
1739
|
+
EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) {
|
|
1740
|
+
_mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0);
|
|
1741
|
+
}
|
|
1742
|
+
template <>
|
|
1743
|
+
EIGEN_STRONG_INLINE void prefetch<uint32_t>(const uint32_t* addr) {
|
|
1744
|
+
_mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0);
|
|
1745
|
+
}
|
|
694
1746
|
#endif
|
|
695
1747
|
|
|
696
|
-
template<>
|
|
1748
|
+
template <>
|
|
1749
|
+
EIGEN_STRONG_INLINE float pfirst<Packet8f>(const Packet8f& a) {
|
|
697
1750
|
return _mm_cvtss_f32(_mm256_castps256_ps128(a));
|
|
698
1751
|
}
|
|
699
|
-
template<>
|
|
1752
|
+
template <>
|
|
1753
|
+
EIGEN_STRONG_INLINE double pfirst<Packet4d>(const Packet4d& a) {
|
|
700
1754
|
return _mm_cvtsd_f64(_mm256_castpd256_pd128(a));
|
|
701
1755
|
}
|
|
702
|
-
template<>
|
|
1756
|
+
template <>
|
|
1757
|
+
EIGEN_STRONG_INLINE int pfirst<Packet8i>(const Packet8i& a) {
|
|
703
1758
|
return _mm_cvtsi128_si32(_mm256_castsi256_si128(a));
|
|
704
1759
|
}
|
|
1760
|
+
template <>
|
|
1761
|
+
EIGEN_STRONG_INLINE uint32_t pfirst<Packet8ui>(const Packet8ui& a) {
|
|
1762
|
+
return numext::bit_cast<uint32_t>(_mm_cvtsi128_si32(_mm256_castsi256_si128(a)));
|
|
1763
|
+
}
|
|
705
1764
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
__m256 tmp = _mm256_shuffle_ps(a,a,0x1b);
|
|
1765
|
+
template <>
|
|
1766
|
+
EIGEN_STRONG_INLINE Packet8f preverse(const Packet8f& a) {
|
|
1767
|
+
__m256 tmp = _mm256_shuffle_ps(a, a, 0x1b);
|
|
710
1768
|
return _mm256_permute2f128_ps(tmp, tmp, 1);
|
|
711
1769
|
}
|
|
712
|
-
template<>
|
|
713
|
-
{
|
|
714
|
-
|
|
1770
|
+
template <>
|
|
1771
|
+
EIGEN_STRONG_INLINE Packet4d preverse(const Packet4d& a) {
|
|
1772
|
+
__m256d tmp = _mm256_shuffle_pd(a, a, 5);
|
|
715
1773
|
return _mm256_permute2f128_pd(tmp, tmp, 1);
|
|
716
|
-
|
|
1774
|
+
#if 0
|
|
717
1775
|
// This version is unlikely to be faster as _mm256_shuffle_ps and _mm256_permute_pd
|
|
718
1776
|
// exhibit the same latency/throughput, but it is here for future reference/benchmarking...
|
|
719
1777
|
__m256d swap_halves = _mm256_permute2f128_pd(a,a,1);
|
|
720
1778
|
return _mm256_permute_pd(swap_halves,5);
|
|
721
|
-
|
|
1779
|
+
#endif
|
|
1780
|
+
}
|
|
1781
|
+
template <>
|
|
1782
|
+
EIGEN_STRONG_INLINE Packet8i preverse(const Packet8i& a) {
|
|
1783
|
+
return _mm256_castps_si256(preverse(_mm256_castsi256_ps(a)));
|
|
1784
|
+
}
|
|
1785
|
+
template <>
|
|
1786
|
+
EIGEN_STRONG_INLINE Packet8ui preverse(const Packet8ui& a) {
|
|
1787
|
+
return _mm256_castps_si256(preverse(_mm256_castsi256_ps(a)));
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1791
|
+
template <>
|
|
1792
|
+
EIGEN_STRONG_INLINE Packet4l preverse(const Packet4l& a) {
|
|
1793
|
+
return _mm256_castpd_si256(preverse(_mm256_castsi256_pd(a)));
|
|
1794
|
+
}
|
|
1795
|
+
template <>
|
|
1796
|
+
EIGEN_STRONG_INLINE Packet4ul preverse(const Packet4ul& a) {
|
|
1797
|
+
return _mm256_castpd_si256(preverse(_mm256_castsi256_pd(a)));
|
|
722
1798
|
}
|
|
1799
|
+
#endif
|
|
723
1800
|
|
|
724
1801
|
// pabs should be ok
|
|
725
|
-
template<>
|
|
726
|
-
{
|
|
727
|
-
const Packet8f mask = _mm256_castsi256_ps(
|
|
728
|
-
return _mm256_and_ps(a,mask);
|
|
1802
|
+
template <>
|
|
1803
|
+
EIGEN_STRONG_INLINE Packet8f pabs(const Packet8f& a) {
|
|
1804
|
+
const Packet8f mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF));
|
|
1805
|
+
return _mm256_and_ps(a, mask);
|
|
1806
|
+
}
|
|
1807
|
+
template <>
|
|
1808
|
+
EIGEN_STRONG_INLINE Packet4d pabs(const Packet4d& a) {
|
|
1809
|
+
const Packet4d mask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x7FFFFFFFFFFFFFFF));
|
|
1810
|
+
return _mm256_and_pd(a, mask);
|
|
1811
|
+
}
|
|
1812
|
+
template <>
|
|
1813
|
+
EIGEN_STRONG_INLINE Packet8i pabs(const Packet8i& a) {
|
|
1814
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1815
|
+
return _mm256_abs_epi32(a);
|
|
1816
|
+
#else
|
|
1817
|
+
__m128i lo = _mm_abs_epi32(_mm256_extractf128_si256(a, 0));
|
|
1818
|
+
__m128i hi = _mm_abs_epi32(_mm256_extractf128_si256(a, 1));
|
|
1819
|
+
return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
|
|
1820
|
+
#endif
|
|
1821
|
+
}
|
|
1822
|
+
template <>
|
|
1823
|
+
EIGEN_STRONG_INLINE Packet8ui pabs(const Packet8ui& a) {
|
|
1824
|
+
return a;
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
#ifndef EIGEN_VECTORIZE_AVX512FP16
|
|
1828
|
+
template <>
|
|
1829
|
+
EIGEN_STRONG_INLINE Packet8h psignbit(const Packet8h& a) {
|
|
1830
|
+
return _mm_cmpgt_epi16(_mm_setzero_si128(), a);
|
|
1831
|
+
}
|
|
1832
|
+
#endif // EIGEN_VECTORIZE_AVX512FP16
|
|
1833
|
+
|
|
1834
|
+
template <>
|
|
1835
|
+
EIGEN_STRONG_INLINE Packet8bf psignbit(const Packet8bf& a) {
|
|
1836
|
+
return _mm_cmpgt_epi16(_mm_setzero_si128(), a);
|
|
1837
|
+
}
|
|
1838
|
+
template <>
|
|
1839
|
+
EIGEN_STRONG_INLINE Packet8f psignbit(const Packet8f& a) {
|
|
1840
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1841
|
+
return _mm256_castsi256_ps(_mm256_cmpgt_epi32(_mm256_setzero_si256(), _mm256_castps_si256(a)));
|
|
1842
|
+
#else
|
|
1843
|
+
return _mm256_castsi256_ps(parithmetic_shift_right<31>(Packet8i(_mm256_castps_si256(a))));
|
|
1844
|
+
#endif
|
|
1845
|
+
}
|
|
1846
|
+
template <>
|
|
1847
|
+
EIGEN_STRONG_INLINE Packet8ui psignbit(const Packet8ui& /*unused*/) {
|
|
1848
|
+
return _mm256_setzero_si256();
|
|
1849
|
+
}
|
|
1850
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
1851
|
+
template <>
|
|
1852
|
+
EIGEN_STRONG_INLINE Packet4d psignbit(const Packet4d& a) {
|
|
1853
|
+
return _mm256_castsi256_pd(_mm256_cmpgt_epi64(_mm256_setzero_si256(), _mm256_castpd_si256(a)));
|
|
729
1854
|
}
|
|
730
|
-
template<>
|
|
731
|
-
{
|
|
732
|
-
|
|
733
|
-
return _mm256_and_pd(a,mask);
|
|
1855
|
+
template <>
|
|
1856
|
+
EIGEN_STRONG_INLINE Packet4ul psignbit(const Packet4ul& /*unused*/) {
|
|
1857
|
+
return _mm256_setzero_si256();
|
|
734
1858
|
}
|
|
1859
|
+
#endif
|
|
735
1860
|
|
|
736
|
-
template<>
|
|
737
|
-
|
|
1861
|
+
template <>
|
|
1862
|
+
EIGEN_STRONG_INLINE Packet8f pfrexp<Packet8f>(const Packet8f& a, Packet8f& exponent) {
|
|
1863
|
+
return pfrexp_generic(a, exponent);
|
|
738
1864
|
}
|
|
739
1865
|
|
|
740
1866
|
// Extract exponent without existence of Packet4l.
|
|
741
|
-
template<>
|
|
742
|
-
EIGEN_STRONG_INLINE
|
|
743
|
-
Packet4d
|
|
744
|
-
const Packet4d cst_exp_mask = pset1frombits<Packet4d>(static_cast<uint64_t>(0x7ff0000000000000ull));
|
|
1867
|
+
template <>
|
|
1868
|
+
EIGEN_STRONG_INLINE Packet4d pfrexp_generic_get_biased_exponent(const Packet4d& a) {
|
|
1869
|
+
const Packet4d cst_exp_mask = pset1frombits<Packet4d>(static_cast<uint64_t>(0x7ff0000000000000ull));
|
|
745
1870
|
__m256i a_expo = _mm256_castpd_si256(pand(a, cst_exp_mask));
|
|
746
1871
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
747
1872
|
a_expo = _mm256_srli_epi64(a_expo, 52);
|
|
@@ -760,107 +1885,73 @@ Packet4d pfrexp_generic_get_biased_exponent(const Packet4d& a) {
|
|
|
760
1885
|
return exponent;
|
|
761
1886
|
}
|
|
762
1887
|
|
|
763
|
-
|
|
764
|
-
|
|
1888
|
+
template <>
|
|
1889
|
+
EIGEN_STRONG_INLINE Packet4d pfrexp<Packet4d>(const Packet4d& a, Packet4d& exponent) {
|
|
765
1890
|
return pfrexp_generic(a, exponent);
|
|
766
1891
|
}
|
|
767
1892
|
|
|
768
|
-
template<>
|
|
1893
|
+
template <>
|
|
1894
|
+
EIGEN_STRONG_INLINE Packet8f pldexp<Packet8f>(const Packet8f& a, const Packet8f& exponent) {
|
|
769
1895
|
return pldexp_generic(a, exponent);
|
|
770
1896
|
}
|
|
771
1897
|
|
|
772
|
-
template<>
|
|
1898
|
+
template <>
|
|
1899
|
+
EIGEN_STRONG_INLINE Packet4d pldexp<Packet4d>(const Packet4d& a, const Packet4d& exponent) {
|
|
773
1900
|
// Clamp exponent to [-2099, 2099]
|
|
774
1901
|
const Packet4d max_exponent = pset1<Packet4d>(2099.0);
|
|
775
1902
|
const Packet4i e = _mm256_cvtpd_epi32(pmin(pmax(exponent, pnegate(max_exponent)), max_exponent));
|
|
776
|
-
|
|
1903
|
+
|
|
777
1904
|
// Split 2^e into four factors and multiply.
|
|
778
1905
|
const Packet4i bias = pset1<Packet4i>(1023);
|
|
779
1906
|
Packet4i b = parithmetic_shift_right<2>(e); // floor(e/4)
|
|
780
|
-
|
|
1907
|
+
|
|
781
1908
|
// 2^b
|
|
782
1909
|
Packet4i hi = vec4i_swizzle1(padd(b, bias), 0, 2, 1, 3);
|
|
783
1910
|
Packet4i lo = _mm_slli_epi64(hi, 52);
|
|
784
1911
|
hi = _mm_slli_epi64(_mm_srli_epi64(hi, 32), 52);
|
|
785
1912
|
Packet4d c = _mm256_castsi256_pd(_mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1));
|
|
786
1913
|
Packet4d out = pmul(pmul(pmul(a, c), c), c); // a * 2^(3b)
|
|
787
|
-
|
|
1914
|
+
|
|
788
1915
|
// 2^(e - 3b)
|
|
789
1916
|
b = psub(psub(psub(e, b), b), b); // e - 3b
|
|
790
1917
|
hi = vec4i_swizzle1(padd(b, bias), 0, 2, 1, 3);
|
|
791
1918
|
lo = _mm_slli_epi64(hi, 52);
|
|
792
1919
|
hi = _mm_slli_epi64(_mm_srli_epi64(hi, 32), 52);
|
|
793
1920
|
c = _mm256_castsi256_pd(_mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1));
|
|
794
|
-
out = pmul(out, c);
|
|
1921
|
+
out = pmul(out, c); // a * 2^e
|
|
795
1922
|
return out;
|
|
796
1923
|
}
|
|
797
1924
|
|
|
798
|
-
template<>
|
|
799
|
-
{
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
template<> EIGEN_STRONG_INLINE Packet4f predux_half_dowto4<Packet8f>(const Packet8f& a)
|
|
808
|
-
{
|
|
809
|
-
return _mm_add_ps(_mm256_castps256_ps128(a),_mm256_extractf128_ps(a,1));
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
template<> EIGEN_STRONG_INLINE float predux_mul<Packet8f>(const Packet8f& a)
|
|
813
|
-
{
|
|
814
|
-
Packet8f tmp;
|
|
815
|
-
tmp = _mm256_mul_ps(a, _mm256_permute2f128_ps(a,a,1));
|
|
816
|
-
tmp = _mm256_mul_ps(tmp, _mm256_shuffle_ps(tmp,tmp,_MM_SHUFFLE(1,0,3,2)));
|
|
817
|
-
return pfirst(_mm256_mul_ps(tmp, _mm256_shuffle_ps(tmp,tmp,1)));
|
|
818
|
-
}
|
|
819
|
-
template<> EIGEN_STRONG_INLINE double predux_mul<Packet4d>(const Packet4d& a)
|
|
820
|
-
{
|
|
821
|
-
Packet4d tmp;
|
|
822
|
-
tmp = _mm256_mul_pd(a, _mm256_permute2f128_pd(a,a,1));
|
|
823
|
-
return pfirst(_mm256_mul_pd(tmp, _mm256_shuffle_pd(tmp,tmp,1)));
|
|
824
|
-
}
|
|
1925
|
+
template <>
|
|
1926
|
+
EIGEN_STRONG_INLINE Packet4d pldexp_fast<Packet4d>(const Packet4d& a, const Packet4d& exponent) {
|
|
1927
|
+
// Clamp exponent to [-1024, 1024]
|
|
1928
|
+
const Packet4d min_exponent = pset1<Packet4d>(-1023.0);
|
|
1929
|
+
const Packet4d max_exponent = pset1<Packet4d>(1024.0);
|
|
1930
|
+
const Packet4i e = _mm256_cvtpd_epi32(pmin(pmax(exponent, min_exponent), max_exponent));
|
|
1931
|
+
const Packet4i bias = pset1<Packet4i>(1023);
|
|
825
1932
|
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
template<> EIGEN_STRONG_INLINE double predux_min<Packet4d>(const Packet4d& a)
|
|
833
|
-
{
|
|
834
|
-
Packet4d tmp = _mm256_min_pd(a, _mm256_permute2f128_pd(a,a,1));
|
|
835
|
-
return pfirst(_mm256_min_pd(tmp, _mm256_shuffle_pd(tmp, tmp, 1)));
|
|
1933
|
+
// 2^e
|
|
1934
|
+
Packet4i hi = vec4i_swizzle1(padd(e, bias), 0, 2, 1, 3);
|
|
1935
|
+
const Packet4i lo = _mm_slli_epi64(hi, 52);
|
|
1936
|
+
hi = _mm_slli_epi64(_mm_srli_epi64(hi, 32), 52);
|
|
1937
|
+
const Packet4d c = _mm256_castsi256_pd(_mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1));
|
|
1938
|
+
return pmul(a, c); // a * 2^e
|
|
836
1939
|
}
|
|
837
1940
|
|
|
838
|
-
template<>
|
|
839
|
-
{
|
|
840
|
-
|
|
841
|
-
tmp = _mm256_max_ps(tmp, _mm256_shuffle_ps(tmp,tmp,_MM_SHUFFLE(1,0,3,2)));
|
|
842
|
-
return pfirst(_mm256_max_ps(tmp, _mm256_shuffle_ps(tmp,tmp,1)));
|
|
1941
|
+
template <>
|
|
1942
|
+
EIGEN_STRONG_INLINE Packet4f predux_half_dowto4<Packet8f>(const Packet8f& a) {
|
|
1943
|
+
return _mm_add_ps(_mm256_castps256_ps128(a), _mm256_extractf128_ps(a, 1));
|
|
843
1944
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
Packet4d tmp = _mm256_max_pd(a, _mm256_permute2f128_pd(a,a,1));
|
|
848
|
-
return pfirst(_mm256_max_pd(tmp, _mm256_shuffle_pd(tmp, tmp, 1)));
|
|
1945
|
+
template <>
|
|
1946
|
+
EIGEN_STRONG_INLINE Packet4i predux_half_dowto4<Packet8i>(const Packet8i& a) {
|
|
1947
|
+
return _mm_add_epi32(_mm256_castsi256_si128(a), _mm256_extractf128_si256(a, 1));
|
|
849
1948
|
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
// {
|
|
854
|
-
// return _mm256_movemask_ps(x)==0xFF;
|
|
855
|
-
// }
|
|
856
|
-
|
|
857
|
-
template<> EIGEN_STRONG_INLINE bool predux_any(const Packet8f& x)
|
|
858
|
-
{
|
|
859
|
-
return _mm256_movemask_ps(x)!=0;
|
|
1949
|
+
template <>
|
|
1950
|
+
EIGEN_STRONG_INLINE Packet4ui predux_half_dowto4<Packet8ui>(const Packet8ui& a) {
|
|
1951
|
+
return _mm_add_epi32(_mm256_castsi256_si128(a), _mm256_extractf128_si256(a, 1));
|
|
860
1952
|
}
|
|
861
1953
|
|
|
862
|
-
EIGEN_DEVICE_FUNC inline void
|
|
863
|
-
ptranspose(PacketBlock<Packet8f,8>& kernel) {
|
|
1954
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet8f, 8>& kernel) {
|
|
864
1955
|
__m256 T0 = _mm256_unpacklo_ps(kernel.packet[0], kernel.packet[1]);
|
|
865
1956
|
__m256 T1 = _mm256_unpackhi_ps(kernel.packet[0], kernel.packet[1]);
|
|
866
1957
|
__m256 T2 = _mm256_unpacklo_ps(kernel.packet[2], kernel.packet[3]);
|
|
@@ -869,14 +1960,14 @@ ptranspose(PacketBlock<Packet8f,8>& kernel) {
|
|
|
869
1960
|
__m256 T5 = _mm256_unpackhi_ps(kernel.packet[4], kernel.packet[5]);
|
|
870
1961
|
__m256 T6 = _mm256_unpacklo_ps(kernel.packet[6], kernel.packet[7]);
|
|
871
1962
|
__m256 T7 = _mm256_unpackhi_ps(kernel.packet[6], kernel.packet[7]);
|
|
872
|
-
__m256 S0 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(1,0,1,0));
|
|
873
|
-
__m256 S1 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(3,2,3,2));
|
|
874
|
-
__m256 S2 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(1,0,1,0));
|
|
875
|
-
__m256 S3 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(3,2,3,2));
|
|
876
|
-
__m256 S4 = _mm256_shuffle_ps(T4,T6,_MM_SHUFFLE(1,0,1,0));
|
|
877
|
-
__m256 S5 = _mm256_shuffle_ps(T4,T6,_MM_SHUFFLE(3,2,3,2));
|
|
878
|
-
__m256 S6 = _mm256_shuffle_ps(T5,T7,_MM_SHUFFLE(1,0,1,0));
|
|
879
|
-
__m256 S7 = _mm256_shuffle_ps(T5,T7,_MM_SHUFFLE(3,2,3,2));
|
|
1963
|
+
__m256 S0 = _mm256_shuffle_ps(T0, T2, _MM_SHUFFLE(1, 0, 1, 0));
|
|
1964
|
+
__m256 S1 = _mm256_shuffle_ps(T0, T2, _MM_SHUFFLE(3, 2, 3, 2));
|
|
1965
|
+
__m256 S2 = _mm256_shuffle_ps(T1, T3, _MM_SHUFFLE(1, 0, 1, 0));
|
|
1966
|
+
__m256 S3 = _mm256_shuffle_ps(T1, T3, _MM_SHUFFLE(3, 2, 3, 2));
|
|
1967
|
+
__m256 S4 = _mm256_shuffle_ps(T4, T6, _MM_SHUFFLE(1, 0, 1, 0));
|
|
1968
|
+
__m256 S5 = _mm256_shuffle_ps(T4, T6, _MM_SHUFFLE(3, 2, 3, 2));
|
|
1969
|
+
__m256 S6 = _mm256_shuffle_ps(T5, T7, _MM_SHUFFLE(1, 0, 1, 0));
|
|
1970
|
+
__m256 S7 = _mm256_shuffle_ps(T5, T7, _MM_SHUFFLE(3, 2, 3, 2));
|
|
880
1971
|
kernel.packet[0] = _mm256_permute2f128_ps(S0, S4, 0x20);
|
|
881
1972
|
kernel.packet[1] = _mm256_permute2f128_ps(S1, S5, 0x20);
|
|
882
1973
|
kernel.packet[2] = _mm256_permute2f128_ps(S2, S6, 0x20);
|
|
@@ -887,17 +1978,16 @@ ptranspose(PacketBlock<Packet8f,8>& kernel) {
|
|
|
887
1978
|
kernel.packet[7] = _mm256_permute2f128_ps(S3, S7, 0x31);
|
|
888
1979
|
}
|
|
889
1980
|
|
|
890
|
-
EIGEN_DEVICE_FUNC inline void
|
|
891
|
-
ptranspose(PacketBlock<Packet8f,4>& kernel) {
|
|
1981
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet8f, 4>& kernel) {
|
|
892
1982
|
__m256 T0 = _mm256_unpacklo_ps(kernel.packet[0], kernel.packet[1]);
|
|
893
1983
|
__m256 T1 = _mm256_unpackhi_ps(kernel.packet[0], kernel.packet[1]);
|
|
894
1984
|
__m256 T2 = _mm256_unpacklo_ps(kernel.packet[2], kernel.packet[3]);
|
|
895
1985
|
__m256 T3 = _mm256_unpackhi_ps(kernel.packet[2], kernel.packet[3]);
|
|
896
1986
|
|
|
897
|
-
__m256 S0 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(1,0,1,0));
|
|
898
|
-
__m256 S1 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(3,2,3,2));
|
|
899
|
-
__m256 S2 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(1,0,1,0));
|
|
900
|
-
__m256 S3 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(3,2,3,2));
|
|
1987
|
+
__m256 S0 = _mm256_shuffle_ps(T0, T2, _MM_SHUFFLE(1, 0, 1, 0));
|
|
1988
|
+
__m256 S1 = _mm256_shuffle_ps(T0, T2, _MM_SHUFFLE(3, 2, 3, 2));
|
|
1989
|
+
__m256 S2 = _mm256_shuffle_ps(T1, T3, _MM_SHUFFLE(1, 0, 1, 0));
|
|
1990
|
+
__m256 S3 = _mm256_shuffle_ps(T1, T3, _MM_SHUFFLE(3, 2, 3, 2));
|
|
901
1991
|
|
|
902
1992
|
kernel.packet[0] = _mm256_permute2f128_ps(S0, S1, 0x20);
|
|
903
1993
|
kernel.packet[1] = _mm256_permute2f128_ps(S2, S3, 0x20);
|
|
@@ -905,8 +1995,70 @@ ptranspose(PacketBlock<Packet8f,4>& kernel) {
|
|
|
905
1995
|
kernel.packet[3] = _mm256_permute2f128_ps(S2, S3, 0x31);
|
|
906
1996
|
}
|
|
907
1997
|
|
|
908
|
-
|
|
909
|
-
|
|
1998
|
+
#define MM256_SHUFFLE_EPI32(A, B, M) \
|
|
1999
|
+
_mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(A), _mm256_castsi256_ps(B), M))
|
|
2000
|
+
|
|
2001
|
+
#ifndef EIGEN_VECTORIZE_AVX2
|
|
2002
|
+
#define MM256_UNPACKLO_EPI32(A, B) \
|
|
2003
|
+
_mm256_castps_si256(_mm256_unpacklo_ps(_mm256_castsi256_ps(A), _mm256_castsi256_ps(B)))
|
|
2004
|
+
#define MM256_UNPACKHI_EPI32(A, B) \
|
|
2005
|
+
_mm256_castps_si256(_mm256_unpackhi_ps(_mm256_castsi256_ps(A), _mm256_castsi256_ps(B)))
|
|
2006
|
+
#else
|
|
2007
|
+
#define MM256_UNPACKLO_EPI32(A, B) _mm256_unpacklo_epi32(A, B)
|
|
2008
|
+
#define MM256_UNPACKHI_EPI32(A, B) _mm256_unpackhi_epi32(A, B)
|
|
2009
|
+
#endif
|
|
2010
|
+
|
|
2011
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet8i, 8>& kernel) {
|
|
2012
|
+
__m256i T0 = MM256_UNPACKLO_EPI32(kernel.packet[0], kernel.packet[1]);
|
|
2013
|
+
__m256i T1 = MM256_UNPACKHI_EPI32(kernel.packet[0], kernel.packet[1]);
|
|
2014
|
+
__m256i T2 = MM256_UNPACKLO_EPI32(kernel.packet[2], kernel.packet[3]);
|
|
2015
|
+
__m256i T3 = MM256_UNPACKHI_EPI32(kernel.packet[2], kernel.packet[3]);
|
|
2016
|
+
__m256i T4 = MM256_UNPACKLO_EPI32(kernel.packet[4], kernel.packet[5]);
|
|
2017
|
+
__m256i T5 = MM256_UNPACKHI_EPI32(kernel.packet[4], kernel.packet[5]);
|
|
2018
|
+
__m256i T6 = MM256_UNPACKLO_EPI32(kernel.packet[6], kernel.packet[7]);
|
|
2019
|
+
__m256i T7 = MM256_UNPACKHI_EPI32(kernel.packet[6], kernel.packet[7]);
|
|
2020
|
+
__m256i S0 = MM256_SHUFFLE_EPI32(T0, T2, _MM_SHUFFLE(1, 0, 1, 0));
|
|
2021
|
+
__m256i S1 = MM256_SHUFFLE_EPI32(T0, T2, _MM_SHUFFLE(3, 2, 3, 2));
|
|
2022
|
+
__m256i S2 = MM256_SHUFFLE_EPI32(T1, T3, _MM_SHUFFLE(1, 0, 1, 0));
|
|
2023
|
+
__m256i S3 = MM256_SHUFFLE_EPI32(T1, T3, _MM_SHUFFLE(3, 2, 3, 2));
|
|
2024
|
+
__m256i S4 = MM256_SHUFFLE_EPI32(T4, T6, _MM_SHUFFLE(1, 0, 1, 0));
|
|
2025
|
+
__m256i S5 = MM256_SHUFFLE_EPI32(T4, T6, _MM_SHUFFLE(3, 2, 3, 2));
|
|
2026
|
+
__m256i S6 = MM256_SHUFFLE_EPI32(T5, T7, _MM_SHUFFLE(1, 0, 1, 0));
|
|
2027
|
+
__m256i S7 = MM256_SHUFFLE_EPI32(T5, T7, _MM_SHUFFLE(3, 2, 3, 2));
|
|
2028
|
+
kernel.packet[0] = _mm256_permute2f128_si256(S0, S4, 0x20);
|
|
2029
|
+
kernel.packet[1] = _mm256_permute2f128_si256(S1, S5, 0x20);
|
|
2030
|
+
kernel.packet[2] = _mm256_permute2f128_si256(S2, S6, 0x20);
|
|
2031
|
+
kernel.packet[3] = _mm256_permute2f128_si256(S3, S7, 0x20);
|
|
2032
|
+
kernel.packet[4] = _mm256_permute2f128_si256(S0, S4, 0x31);
|
|
2033
|
+
kernel.packet[5] = _mm256_permute2f128_si256(S1, S5, 0x31);
|
|
2034
|
+
kernel.packet[6] = _mm256_permute2f128_si256(S2, S6, 0x31);
|
|
2035
|
+
kernel.packet[7] = _mm256_permute2f128_si256(S3, S7, 0x31);
|
|
2036
|
+
}
|
|
2037
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet8ui, 8>& kernel) {
|
|
2038
|
+
ptranspose((PacketBlock<Packet8i, 8>&)kernel);
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet8i, 4>& kernel) {
|
|
2042
|
+
__m256i T0 = MM256_UNPACKLO_EPI32(kernel.packet[0], kernel.packet[1]);
|
|
2043
|
+
__m256i T1 = MM256_UNPACKHI_EPI32(kernel.packet[0], kernel.packet[1]);
|
|
2044
|
+
__m256i T2 = MM256_UNPACKLO_EPI32(kernel.packet[2], kernel.packet[3]);
|
|
2045
|
+
__m256i T3 = MM256_UNPACKHI_EPI32(kernel.packet[2], kernel.packet[3]);
|
|
2046
|
+
|
|
2047
|
+
__m256i S0 = MM256_SHUFFLE_EPI32(T0, T2, _MM_SHUFFLE(1, 0, 1, 0));
|
|
2048
|
+
__m256i S1 = MM256_SHUFFLE_EPI32(T0, T2, _MM_SHUFFLE(3, 2, 3, 2));
|
|
2049
|
+
__m256i S2 = MM256_SHUFFLE_EPI32(T1, T3, _MM_SHUFFLE(1, 0, 1, 0));
|
|
2050
|
+
__m256i S3 = MM256_SHUFFLE_EPI32(T1, T3, _MM_SHUFFLE(3, 2, 3, 2));
|
|
2051
|
+
|
|
2052
|
+
kernel.packet[0] = _mm256_permute2f128_si256(S0, S1, 0x20);
|
|
2053
|
+
kernel.packet[1] = _mm256_permute2f128_si256(S2, S3, 0x20);
|
|
2054
|
+
kernel.packet[2] = _mm256_permute2f128_si256(S0, S1, 0x31);
|
|
2055
|
+
kernel.packet[3] = _mm256_permute2f128_si256(S2, S3, 0x31);
|
|
2056
|
+
}
|
|
2057
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet8ui, 4>& kernel) {
|
|
2058
|
+
ptranspose((PacketBlock<Packet8i, 4>&)kernel);
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet4d, 4>& kernel) {
|
|
910
2062
|
__m256d T0 = _mm256_shuffle_pd(kernel.packet[0], kernel.packet[1], 15);
|
|
911
2063
|
__m256d T1 = _mm256_shuffle_pd(kernel.packet[0], kernel.packet[1], 0);
|
|
912
2064
|
__m256d T2 = _mm256_shuffle_pd(kernel.packet[2], kernel.packet[3], 15);
|
|
@@ -918,49 +2070,78 @@ ptranspose(PacketBlock<Packet4d,4>& kernel) {
|
|
|
918
2070
|
kernel.packet[2] = _mm256_permute2f128_pd(T1, T3, 49);
|
|
919
2071
|
}
|
|
920
2072
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
__m256 false_mask = _mm256_cmp_ps(select, zero, _CMP_EQ_UQ);
|
|
925
|
-
return _mm256_blendv_ps(thenPacket, elsePacket, false_mask);
|
|
2073
|
+
EIGEN_STRONG_INLINE __m256i avx_blend_mask(const Selector<4>& ifPacket) {
|
|
2074
|
+
return _mm256_set_epi64x(0 - ifPacket.select[3], 0 - ifPacket.select[2], 0 - ifPacket.select[1],
|
|
2075
|
+
0 - ifPacket.select[0]);
|
|
926
2076
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
2077
|
+
|
|
2078
|
+
EIGEN_STRONG_INLINE __m256i avx_blend_mask(const Selector<8>& ifPacket) {
|
|
2079
|
+
return _mm256_set_epi32(0 - ifPacket.select[7], 0 - ifPacket.select[6], 0 - ifPacket.select[5],
|
|
2080
|
+
0 - ifPacket.select[4], 0 - ifPacket.select[3], 0 - ifPacket.select[2],
|
|
2081
|
+
0 - ifPacket.select[1], 0 - ifPacket.select[0]);
|
|
932
2082
|
}
|
|
933
2083
|
|
|
934
|
-
|
|
2084
|
+
template <>
|
|
2085
|
+
EIGEN_STRONG_INLINE Packet8f pblend(const Selector<8>& ifPacket, const Packet8f& thenPacket,
|
|
2086
|
+
const Packet8f& elsePacket) {
|
|
2087
|
+
const __m256 true_mask = _mm256_castsi256_ps(avx_blend_mask(ifPacket));
|
|
2088
|
+
return pselect<Packet8f>(true_mask, thenPacket, elsePacket);
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
template <>
|
|
2092
|
+
EIGEN_STRONG_INLINE Packet4d pblend(const Selector<4>& ifPacket, const Packet4d& thenPacket,
|
|
2093
|
+
const Packet4d& elsePacket) {
|
|
2094
|
+
const __m256d true_mask = _mm256_castsi256_pd(avx_blend_mask(ifPacket));
|
|
2095
|
+
return pselect<Packet4d>(true_mask, thenPacket, elsePacket);
|
|
2096
|
+
}
|
|
935
2097
|
|
|
936
|
-
|
|
2098
|
+
// Packet math for Eigen::half
|
|
2099
|
+
#ifndef EIGEN_VECTORIZE_AVX512FP16
|
|
2100
|
+
template <>
|
|
2101
|
+
struct unpacket_traits<Packet8h> {
|
|
2102
|
+
typedef Eigen::half type;
|
|
2103
|
+
enum {
|
|
2104
|
+
size = 8,
|
|
2105
|
+
alignment = Aligned16,
|
|
2106
|
+
vectorizable = true,
|
|
2107
|
+
masked_load_available = false,
|
|
2108
|
+
masked_store_available = false
|
|
2109
|
+
};
|
|
2110
|
+
typedef Packet8h half;
|
|
2111
|
+
};
|
|
937
2112
|
|
|
938
|
-
template<>
|
|
2113
|
+
template <>
|
|
2114
|
+
EIGEN_STRONG_INLINE Packet8h pset1<Packet8h>(const Eigen::half& from) {
|
|
939
2115
|
return _mm_set1_epi16(numext::bit_cast<numext::uint16_t>(from));
|
|
940
2116
|
}
|
|
941
2117
|
|
|
942
|
-
template<>
|
|
2118
|
+
template <>
|
|
2119
|
+
EIGEN_STRONG_INLINE Eigen::half pfirst<Packet8h>(const Packet8h& from) {
|
|
943
2120
|
return numext::bit_cast<Eigen::half>(static_cast<numext::uint16_t>(_mm_extract_epi16(from, 0)));
|
|
944
2121
|
}
|
|
945
2122
|
|
|
946
|
-
template<>
|
|
2123
|
+
template <>
|
|
2124
|
+
EIGEN_STRONG_INLINE Packet8h pload<Packet8h>(const Eigen::half* from) {
|
|
947
2125
|
return _mm_load_si128(reinterpret_cast<const __m128i*>(from));
|
|
948
2126
|
}
|
|
949
2127
|
|
|
950
|
-
template<>
|
|
2128
|
+
template <>
|
|
2129
|
+
EIGEN_STRONG_INLINE Packet8h ploadu<Packet8h>(const Eigen::half* from) {
|
|
951
2130
|
return _mm_loadu_si128(reinterpret_cast<const __m128i*>(from));
|
|
952
2131
|
}
|
|
953
2132
|
|
|
954
|
-
template<>
|
|
2133
|
+
template <>
|
|
2134
|
+
EIGEN_STRONG_INLINE void pstore<Eigen::half>(Eigen::half* to, const Packet8h& from) {
|
|
955
2135
|
_mm_store_si128(reinterpret_cast<__m128i*>(to), from);
|
|
956
2136
|
}
|
|
957
2137
|
|
|
958
|
-
template<>
|
|
2138
|
+
template <>
|
|
2139
|
+
EIGEN_STRONG_INLINE void pstoreu<Eigen::half>(Eigen::half* to, const Packet8h& from) {
|
|
959
2140
|
_mm_storeu_si128(reinterpret_cast<__m128i*>(to), from);
|
|
960
2141
|
}
|
|
961
2142
|
|
|
962
|
-
template<>
|
|
963
|
-
ploaddup<Packet8h>(const Eigen::half*
|
|
2143
|
+
template <>
|
|
2144
|
+
EIGEN_STRONG_INLINE Packet8h ploaddup<Packet8h>(const Eigen::half* from) {
|
|
964
2145
|
const numext::uint16_t a = numext::bit_cast<numext::uint16_t>(from[0]);
|
|
965
2146
|
const numext::uint16_t b = numext::bit_cast<numext::uint16_t>(from[1]);
|
|
966
2147
|
const numext::uint16_t c = numext::bit_cast<numext::uint16_t>(from[2]);
|
|
@@ -968,15 +2149,16 @@ ploaddup<Packet8h>(const Eigen::half* from) {
|
|
|
968
2149
|
return _mm_set_epi16(d, d, c, c, b, b, a, a);
|
|
969
2150
|
}
|
|
970
2151
|
|
|
971
|
-
template<>
|
|
972
|
-
ploadquad<Packet8h>(const Eigen::half* from) {
|
|
2152
|
+
template <>
|
|
2153
|
+
EIGEN_STRONG_INLINE Packet8h ploadquad<Packet8h>(const Eigen::half* from) {
|
|
973
2154
|
const numext::uint16_t a = numext::bit_cast<numext::uint16_t>(from[0]);
|
|
974
2155
|
const numext::uint16_t b = numext::bit_cast<numext::uint16_t>(from[1]);
|
|
975
2156
|
return _mm_set_epi16(b, b, b, b, a, a, a, a);
|
|
976
2157
|
}
|
|
977
2158
|
|
|
978
|
-
template<>
|
|
979
|
-
|
|
2159
|
+
template <>
|
|
2160
|
+
EIGEN_STRONG_INLINE Packet8h ptrue(const Packet8h& a) {
|
|
2161
|
+
return _mm_cmpeq_epi32(a, a);
|
|
980
2162
|
}
|
|
981
2163
|
|
|
982
2164
|
template <>
|
|
@@ -989,48 +2171,29 @@ EIGEN_STRONG_INLINE Packet8f half2float(const Packet8h& a) {
|
|
|
989
2171
|
#ifdef EIGEN_HAS_FP16_C
|
|
990
2172
|
return _mm256_cvtph_ps(a);
|
|
991
2173
|
#else
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
float f1(aux[1]);
|
|
996
|
-
float f2(aux[2]);
|
|
997
|
-
float f3(aux[3]);
|
|
998
|
-
float f4(aux[4]);
|
|
999
|
-
float f5(aux[5]);
|
|
1000
|
-
float f6(aux[6]);
|
|
1001
|
-
float f7(aux[7]);
|
|
1002
|
-
|
|
1003
|
-
return _mm256_set_ps(f7, f6, f5, f4, f3, f2, f1, f0);
|
|
2174
|
+
Eigen::internal::Packet8f pp = _mm256_castsi256_ps(
|
|
2175
|
+
_mm256_insertf128_si256(_mm256_castsi128_si256(half2floatsse(a)), half2floatsse(_mm_srli_si128(a, 8)), 1));
|
|
2176
|
+
return pp;
|
|
1004
2177
|
#endif
|
|
1005
2178
|
}
|
|
1006
2179
|
|
|
1007
2180
|
EIGEN_STRONG_INLINE Packet8h float2half(const Packet8f& a) {
|
|
1008
2181
|
#ifdef EIGEN_HAS_FP16_C
|
|
1009
|
-
return _mm256_cvtps_ph(a, _MM_FROUND_TO_NEAREST_INT
|
|
2182
|
+
return _mm256_cvtps_ph(a, _MM_FROUND_TO_NEAREST_INT);
|
|
1010
2183
|
#else
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
const numext::uint16_t s1 = numext::bit_cast<numext::uint16_t>(Eigen::half(aux[1]));
|
|
1015
|
-
const numext::uint16_t s2 = numext::bit_cast<numext::uint16_t>(Eigen::half(aux[2]));
|
|
1016
|
-
const numext::uint16_t s3 = numext::bit_cast<numext::uint16_t>(Eigen::half(aux[3]));
|
|
1017
|
-
const numext::uint16_t s4 = numext::bit_cast<numext::uint16_t>(Eigen::half(aux[4]));
|
|
1018
|
-
const numext::uint16_t s5 = numext::bit_cast<numext::uint16_t>(Eigen::half(aux[5]));
|
|
1019
|
-
const numext::uint16_t s6 = numext::bit_cast<numext::uint16_t>(Eigen::half(aux[6]));
|
|
1020
|
-
const numext::uint16_t s7 = numext::bit_cast<numext::uint16_t>(Eigen::half(aux[7]));
|
|
1021
|
-
return _mm_set_epi16(s7, s6, s5, s4, s3, s2, s1, s0);
|
|
2184
|
+
__m128i lo = float2half(_mm256_extractf128_ps(a, 0));
|
|
2185
|
+
__m128i hi = float2half(_mm256_extractf128_ps(a, 1));
|
|
2186
|
+
return _mm_packus_epi32(lo, hi);
|
|
1022
2187
|
#endif
|
|
1023
2188
|
}
|
|
1024
2189
|
|
|
1025
2190
|
template <>
|
|
1026
|
-
EIGEN_STRONG_INLINE Packet8h pmin<Packet8h>(const Packet8h& a,
|
|
1027
|
-
const Packet8h& b) {
|
|
2191
|
+
EIGEN_STRONG_INLINE Packet8h pmin<Packet8h>(const Packet8h& a, const Packet8h& b) {
|
|
1028
2192
|
return float2half(pmin<Packet8f>(half2float(a), half2float(b)));
|
|
1029
2193
|
}
|
|
1030
2194
|
|
|
1031
2195
|
template <>
|
|
1032
|
-
EIGEN_STRONG_INLINE Packet8h pmax<Packet8h>(const Packet8h& a,
|
|
1033
|
-
const Packet8h& b) {
|
|
2196
|
+
EIGEN_STRONG_INLINE Packet8h pmax<Packet8h>(const Packet8h& a, const Packet8h& b) {
|
|
1034
2197
|
return float2half(pmax<Packet8f>(half2float(a), half2float(b)));
|
|
1035
2198
|
}
|
|
1036
2199
|
|
|
@@ -1039,151 +2202,214 @@ EIGEN_STRONG_INLINE Packet8h plset<Packet8h>(const half& a) {
|
|
|
1039
2202
|
return float2half(plset<Packet8f>(static_cast<float>(a)));
|
|
1040
2203
|
}
|
|
1041
2204
|
|
|
1042
|
-
template<>
|
|
2205
|
+
template <>
|
|
2206
|
+
EIGEN_STRONG_INLINE Packet8h por(const Packet8h& a, const Packet8h& b) {
|
|
1043
2207
|
// in some cases Packet4i is a wrapper around __m128i, so we either need to
|
|
1044
2208
|
// cast to Packet4i to directly call the intrinsics as below:
|
|
1045
|
-
return _mm_or_si128(a,b);
|
|
2209
|
+
return _mm_or_si128(a, b);
|
|
1046
2210
|
}
|
|
1047
|
-
template<>
|
|
1048
|
-
|
|
2211
|
+
template <>
|
|
2212
|
+
EIGEN_STRONG_INLINE Packet8h pxor(const Packet8h& a, const Packet8h& b) {
|
|
2213
|
+
return _mm_xor_si128(a, b);
|
|
1049
2214
|
}
|
|
1050
|
-
template<>
|
|
1051
|
-
|
|
2215
|
+
template <>
|
|
2216
|
+
EIGEN_STRONG_INLINE Packet8h pand(const Packet8h& a, const Packet8h& b) {
|
|
2217
|
+
return _mm_and_si128(a, b);
|
|
1052
2218
|
}
|
|
1053
|
-
template<>
|
|
1054
|
-
|
|
2219
|
+
template <>
|
|
2220
|
+
EIGEN_STRONG_INLINE Packet8h pandnot(const Packet8h& a, const Packet8h& b) {
|
|
2221
|
+
return _mm_andnot_si128(b, a);
|
|
1055
2222
|
}
|
|
1056
2223
|
|
|
1057
|
-
template<>
|
|
2224
|
+
template <>
|
|
2225
|
+
EIGEN_STRONG_INLINE Packet8h pselect(const Packet8h& mask, const Packet8h& a, const Packet8h& b) {
|
|
1058
2226
|
return _mm_blendv_epi8(b, a, mask);
|
|
1059
2227
|
}
|
|
1060
2228
|
|
|
1061
|
-
template<>
|
|
2229
|
+
template <>
|
|
2230
|
+
EIGEN_STRONG_INLINE Packet8h pround<Packet8h>(const Packet8h& a) {
|
|
1062
2231
|
return float2half(pround<Packet8f>(half2float(a)));
|
|
1063
2232
|
}
|
|
1064
2233
|
|
|
1065
|
-
template<>
|
|
2234
|
+
template <>
|
|
2235
|
+
EIGEN_STRONG_INLINE Packet8h print<Packet8h>(const Packet8h& a) {
|
|
1066
2236
|
return float2half(print<Packet8f>(half2float(a)));
|
|
1067
2237
|
}
|
|
1068
2238
|
|
|
1069
|
-
template<>
|
|
2239
|
+
template <>
|
|
2240
|
+
EIGEN_STRONG_INLINE Packet8h pceil<Packet8h>(const Packet8h& a) {
|
|
1070
2241
|
return float2half(pceil<Packet8f>(half2float(a)));
|
|
1071
2242
|
}
|
|
1072
2243
|
|
|
1073
|
-
template<>
|
|
2244
|
+
template <>
|
|
2245
|
+
EIGEN_STRONG_INLINE Packet8h pfloor<Packet8h>(const Packet8h& a) {
|
|
1074
2246
|
return float2half(pfloor<Packet8f>(half2float(a)));
|
|
1075
2247
|
}
|
|
1076
2248
|
|
|
1077
|
-
template<>
|
|
1078
|
-
|
|
2249
|
+
template <>
|
|
2250
|
+
EIGEN_STRONG_INLINE Packet8h ptrunc<Packet8h>(const Packet8h& a) {
|
|
2251
|
+
return float2half(ptrunc<Packet8f>(half2float(a)));
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
template <>
|
|
2255
|
+
EIGEN_STRONG_INLINE Packet8h pisinf<Packet8h>(const Packet8h& a) {
|
|
2256
|
+
constexpr uint16_t kInf = ((1 << 5) - 1) << 10;
|
|
2257
|
+
constexpr uint16_t kAbsMask = (1 << 15) - 1;
|
|
2258
|
+
return _mm_cmpeq_epi16(_mm_and_si128(a.m_val, _mm_set1_epi16(kAbsMask)), _mm_set1_epi16(kInf));
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
template <>
|
|
2262
|
+
EIGEN_STRONG_INLINE Packet8h pisnan<Packet8h>(const Packet8h& a) {
|
|
2263
|
+
constexpr uint16_t kInf = ((1 << 5) - 1) << 10;
|
|
2264
|
+
constexpr uint16_t kAbsMask = (1 << 15) - 1;
|
|
2265
|
+
return _mm_cmpgt_epi16(_mm_and_si128(a.m_val, _mm_set1_epi16(kAbsMask)), _mm_set1_epi16(kInf));
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
// convert the sign-magnitude representation to two's complement
|
|
2269
|
+
EIGEN_STRONG_INLINE __m128i pmaptosigned(const __m128i& a) {
|
|
2270
|
+
constexpr uint16_t kAbsMask = (1 << 15) - 1;
|
|
2271
|
+
// if 'a' has the sign bit set, clear the sign bit and negate the result as if it were an integer
|
|
2272
|
+
return _mm_sign_epi16(_mm_and_si128(a, _mm_set1_epi16(kAbsMask)), a);
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
// return true if both `a` and `b` are not NaN
|
|
2276
|
+
EIGEN_STRONG_INLINE Packet8h pisordered(const Packet8h& a, const Packet8h& b) {
|
|
2277
|
+
constexpr uint16_t kInf = ((1 << 5) - 1) << 10;
|
|
2278
|
+
constexpr uint16_t kAbsMask = (1 << 15) - 1;
|
|
2279
|
+
__m128i abs_a = _mm_and_si128(a.m_val, _mm_set1_epi16(kAbsMask));
|
|
2280
|
+
__m128i abs_b = _mm_and_si128(b.m_val, _mm_set1_epi16(kAbsMask));
|
|
2281
|
+
// check if both `abs_a <= kInf` and `abs_b <= kInf` by checking if max(abs_a, abs_b) <= kInf
|
|
2282
|
+
// SSE has no `lesser or equal` instruction for integers, but comparing against kInf + 1 accomplishes the same goal
|
|
2283
|
+
return _mm_cmplt_epi16(_mm_max_epu16(abs_a, abs_b), _mm_set1_epi16(kInf + 1));
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
template <>
|
|
2287
|
+
EIGEN_STRONG_INLINE Packet8h pcmp_eq(const Packet8h& a, const Packet8h& b) {
|
|
2288
|
+
__m128i isOrdered = pisordered(a, b);
|
|
2289
|
+
__m128i isEqual = _mm_cmpeq_epi16(pmaptosigned(a.m_val), pmaptosigned(b.m_val));
|
|
2290
|
+
return _mm_and_si128(isOrdered, isEqual);
|
|
1079
2291
|
}
|
|
1080
2292
|
|
|
1081
|
-
template<>
|
|
1082
|
-
|
|
2293
|
+
template <>
|
|
2294
|
+
EIGEN_STRONG_INLINE Packet8h pcmp_le(const Packet8h& a, const Packet8h& b) {
|
|
2295
|
+
__m128i isOrdered = pisordered(a, b);
|
|
2296
|
+
__m128i isGreater = _mm_cmpgt_epi16(pmaptosigned(a.m_val), pmaptosigned(b.m_val));
|
|
2297
|
+
return _mm_andnot_si128(isGreater, isOrdered);
|
|
1083
2298
|
}
|
|
1084
2299
|
|
|
1085
|
-
template<>
|
|
1086
|
-
|
|
2300
|
+
template <>
|
|
2301
|
+
EIGEN_STRONG_INLINE Packet8h pcmp_lt(const Packet8h& a, const Packet8h& b) {
|
|
2302
|
+
__m128i isOrdered = pisordered(a, b);
|
|
2303
|
+
__m128i isLess = _mm_cmplt_epi16(pmaptosigned(a.m_val), pmaptosigned(b.m_val));
|
|
2304
|
+
return _mm_and_si128(isOrdered, isLess);
|
|
1087
2305
|
}
|
|
1088
2306
|
|
|
1089
|
-
template<>
|
|
1090
|
-
|
|
2307
|
+
template <>
|
|
2308
|
+
EIGEN_STRONG_INLINE Packet8h pcmp_lt_or_nan(const Packet8h& a, const Packet8h& b) {
|
|
2309
|
+
__m128i isUnordered = por(pisnan(a), pisnan(b));
|
|
2310
|
+
__m128i isLess = _mm_cmplt_epi16(pmaptosigned(a.m_val), pmaptosigned(b.m_val));
|
|
2311
|
+
return _mm_or_si128(isUnordered, isLess);
|
|
1091
2312
|
}
|
|
1092
2313
|
|
|
1093
|
-
template<>
|
|
2314
|
+
template <>
|
|
2315
|
+
EIGEN_STRONG_INLINE Packet8h pconj(const Packet8h& a) {
|
|
2316
|
+
return a;
|
|
2317
|
+
}
|
|
1094
2318
|
|
|
1095
|
-
template<>
|
|
2319
|
+
template <>
|
|
2320
|
+
EIGEN_STRONG_INLINE Packet8h pnegate(const Packet8h& a) {
|
|
1096
2321
|
Packet8h sign_mask = _mm_set1_epi16(static_cast<numext::uint16_t>(0x8000));
|
|
1097
2322
|
return _mm_xor_si128(a, sign_mask);
|
|
1098
2323
|
}
|
|
1099
2324
|
|
|
1100
|
-
|
|
2325
|
+
#ifndef EIGEN_VECTORIZE_AVX512FP16
|
|
2326
|
+
template <>
|
|
2327
|
+
EIGEN_STRONG_INLINE Packet8h padd<Packet8h>(const Packet8h& a, const Packet8h& b) {
|
|
1101
2328
|
Packet8f af = half2float(a);
|
|
1102
2329
|
Packet8f bf = half2float(b);
|
|
1103
2330
|
Packet8f rf = padd(af, bf);
|
|
1104
2331
|
return float2half(rf);
|
|
1105
2332
|
}
|
|
1106
2333
|
|
|
1107
|
-
template<>
|
|
2334
|
+
template <>
|
|
2335
|
+
EIGEN_STRONG_INLINE Packet8h psub<Packet8h>(const Packet8h& a, const Packet8h& b) {
|
|
1108
2336
|
Packet8f af = half2float(a);
|
|
1109
2337
|
Packet8f bf = half2float(b);
|
|
1110
2338
|
Packet8f rf = psub(af, bf);
|
|
1111
2339
|
return float2half(rf);
|
|
1112
2340
|
}
|
|
1113
2341
|
|
|
1114
|
-
template<>
|
|
2342
|
+
template <>
|
|
2343
|
+
EIGEN_STRONG_INLINE Packet8h pmul<Packet8h>(const Packet8h& a, const Packet8h& b) {
|
|
1115
2344
|
Packet8f af = half2float(a);
|
|
1116
2345
|
Packet8f bf = half2float(b);
|
|
1117
2346
|
Packet8f rf = pmul(af, bf);
|
|
1118
2347
|
return float2half(rf);
|
|
1119
2348
|
}
|
|
1120
2349
|
|
|
1121
|
-
template<>
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
Packet8f rf = pdiv(af, bf);
|
|
1125
|
-
return float2half(rf);
|
|
2350
|
+
template <>
|
|
2351
|
+
EIGEN_STRONG_INLINE Packet8h pmadd<Packet8h>(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
|
|
2352
|
+
return float2half(pmadd(half2float(a), half2float(b), half2float(c)));
|
|
1126
2353
|
}
|
|
1127
2354
|
|
|
1128
|
-
template<>
|
|
1129
|
-
{
|
|
1130
|
-
|
|
1131
|
-
const numext::uint16_t s1 = numext::bit_cast<numext::uint16_t>(from[1*stride]);
|
|
1132
|
-
const numext::uint16_t s2 = numext::bit_cast<numext::uint16_t>(from[2*stride]);
|
|
1133
|
-
const numext::uint16_t s3 = numext::bit_cast<numext::uint16_t>(from[3*stride]);
|
|
1134
|
-
const numext::uint16_t s4 = numext::bit_cast<numext::uint16_t>(from[4*stride]);
|
|
1135
|
-
const numext::uint16_t s5 = numext::bit_cast<numext::uint16_t>(from[5*stride]);
|
|
1136
|
-
const numext::uint16_t s6 = numext::bit_cast<numext::uint16_t>(from[6*stride]);
|
|
1137
|
-
const numext::uint16_t s7 = numext::bit_cast<numext::uint16_t>(from[7*stride]);
|
|
1138
|
-
return _mm_set_epi16(s7, s6, s5, s4, s3, s2, s1, s0);
|
|
2355
|
+
template <>
|
|
2356
|
+
EIGEN_STRONG_INLINE Packet8h pmsub<Packet8h>(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
|
|
2357
|
+
return float2half(pmsub(half2float(a), half2float(b), half2float(c)));
|
|
1139
2358
|
}
|
|
1140
2359
|
|
|
1141
|
-
template<>
|
|
1142
|
-
{
|
|
1143
|
-
|
|
1144
|
-
pstore(aux, from);
|
|
1145
|
-
to[stride*0] = aux[0];
|
|
1146
|
-
to[stride*1] = aux[1];
|
|
1147
|
-
to[stride*2] = aux[2];
|
|
1148
|
-
to[stride*3] = aux[3];
|
|
1149
|
-
to[stride*4] = aux[4];
|
|
1150
|
-
to[stride*5] = aux[5];
|
|
1151
|
-
to[stride*6] = aux[6];
|
|
1152
|
-
to[stride*7] = aux[7];
|
|
2360
|
+
template <>
|
|
2361
|
+
EIGEN_STRONG_INLINE Packet8h pnmadd<Packet8h>(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
|
|
2362
|
+
return float2half(pnmadd(half2float(a), half2float(b), half2float(c)));
|
|
1153
2363
|
}
|
|
1154
2364
|
|
|
1155
|
-
template<>
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
return Eigen::half(reduced);
|
|
2365
|
+
template <>
|
|
2366
|
+
EIGEN_STRONG_INLINE Packet8h pnmsub<Packet8h>(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
|
|
2367
|
+
return float2half(pnmsub(half2float(a), half2float(b), half2float(c)));
|
|
1159
2368
|
}
|
|
1160
2369
|
|
|
1161
|
-
template<>
|
|
2370
|
+
template <>
|
|
2371
|
+
EIGEN_STRONG_INLINE Packet8h pdiv<Packet8h>(const Packet8h& a, const Packet8h& b) {
|
|
1162
2372
|
Packet8f af = half2float(a);
|
|
1163
|
-
|
|
1164
|
-
|
|
2373
|
+
Packet8f bf = half2float(b);
|
|
2374
|
+
Packet8f rf = pdiv(af, bf);
|
|
2375
|
+
return float2half(rf);
|
|
1165
2376
|
}
|
|
2377
|
+
#endif
|
|
1166
2378
|
|
|
1167
|
-
template<>
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
2379
|
+
template <>
|
|
2380
|
+
EIGEN_STRONG_INLINE Packet8h pgather<Eigen::half, Packet8h>(const Eigen::half* from, Index stride) {
|
|
2381
|
+
const numext::uint16_t s0 = numext::bit_cast<numext::uint16_t>(from[0 * stride]);
|
|
2382
|
+
const numext::uint16_t s1 = numext::bit_cast<numext::uint16_t>(from[1 * stride]);
|
|
2383
|
+
const numext::uint16_t s2 = numext::bit_cast<numext::uint16_t>(from[2 * stride]);
|
|
2384
|
+
const numext::uint16_t s3 = numext::bit_cast<numext::uint16_t>(from[3 * stride]);
|
|
2385
|
+
const numext::uint16_t s4 = numext::bit_cast<numext::uint16_t>(from[4 * stride]);
|
|
2386
|
+
const numext::uint16_t s5 = numext::bit_cast<numext::uint16_t>(from[5 * stride]);
|
|
2387
|
+
const numext::uint16_t s6 = numext::bit_cast<numext::uint16_t>(from[6 * stride]);
|
|
2388
|
+
const numext::uint16_t s7 = numext::bit_cast<numext::uint16_t>(from[7 * stride]);
|
|
2389
|
+
return _mm_set_epi16(s7, s6, s5, s4, s3, s2, s1, s0);
|
|
1171
2390
|
}
|
|
1172
2391
|
|
|
1173
|
-
template<>
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
2392
|
+
template <>
|
|
2393
|
+
EIGEN_STRONG_INLINE void pscatter<Eigen::half, Packet8h>(Eigen::half* to, const Packet8h& from, Index stride) {
|
|
2394
|
+
EIGEN_ALIGN32 Eigen::half aux[8];
|
|
2395
|
+
pstore(aux, from);
|
|
2396
|
+
to[stride * 0] = aux[0];
|
|
2397
|
+
to[stride * 1] = aux[1];
|
|
2398
|
+
to[stride * 2] = aux[2];
|
|
2399
|
+
to[stride * 3] = aux[3];
|
|
2400
|
+
to[stride * 4] = aux[4];
|
|
2401
|
+
to[stride * 5] = aux[5];
|
|
2402
|
+
to[stride * 6] = aux[6];
|
|
2403
|
+
to[stride * 7] = aux[7];
|
|
1177
2404
|
}
|
|
1178
2405
|
|
|
1179
|
-
template<>
|
|
1180
|
-
{
|
|
1181
|
-
__m128i m = _mm_setr_epi8(14,15,12,13,10,11,8,9,6,7,4,5,2,3,0,1);
|
|
1182
|
-
return _mm_shuffle_epi8(a,m);
|
|
2406
|
+
template <>
|
|
2407
|
+
EIGEN_STRONG_INLINE Packet8h preverse(const Packet8h& a) {
|
|
2408
|
+
__m128i m = _mm_setr_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
|
|
2409
|
+
return _mm_shuffle_epi8(a, m);
|
|
1183
2410
|
}
|
|
1184
2411
|
|
|
1185
|
-
EIGEN_STRONG_INLINE void
|
|
1186
|
-
ptranspose(PacketBlock<Packet8h,8>& kernel) {
|
|
2412
|
+
EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet8h, 8>& kernel) {
|
|
1187
2413
|
__m128i a = kernel.packet[0];
|
|
1188
2414
|
__m128i b = kernel.packet[1];
|
|
1189
2415
|
__m128i c = kernel.packet[2];
|
|
@@ -1230,8 +2456,7 @@ ptranspose(PacketBlock<Packet8h,8>& kernel) {
|
|
|
1230
2456
|
kernel.packet[7] = a7b7c7d7e7f7g7h7;
|
|
1231
2457
|
}
|
|
1232
2458
|
|
|
1233
|
-
EIGEN_STRONG_INLINE void
|
|
1234
|
-
ptranspose(PacketBlock<Packet8h,4>& kernel) {
|
|
2459
|
+
EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet8h, 4>& kernel) {
|
|
1235
2460
|
EIGEN_ALIGN32 Eigen::half in[4][8];
|
|
1236
2461
|
pstore<Eigen::half>(in[0], kernel.packet[0]);
|
|
1237
2462
|
pstore<Eigen::half>(in[1], kernel.packet[1]);
|
|
@@ -1242,10 +2467,10 @@ ptranspose(PacketBlock<Packet8h,4>& kernel) {
|
|
|
1242
2467
|
|
|
1243
2468
|
for (int i = 0; i < 4; ++i) {
|
|
1244
2469
|
for (int j = 0; j < 4; ++j) {
|
|
1245
|
-
out[i][j] = in[j][2*i];
|
|
2470
|
+
out[i][j] = in[j][2 * i];
|
|
1246
2471
|
}
|
|
1247
2472
|
for (int j = 0; j < 4; ++j) {
|
|
1248
|
-
out[i][j+4] = in[j][2*i+1];
|
|
2473
|
+
out[i][j + 4] = in[j][2 * i + 1];
|
|
1249
2474
|
}
|
|
1250
2475
|
}
|
|
1251
2476
|
|
|
@@ -1255,6 +2480,8 @@ ptranspose(PacketBlock<Packet8h,4>& kernel) {
|
|
|
1255
2480
|
kernel.packet[3] = pload<Packet8h>(out[3]);
|
|
1256
2481
|
}
|
|
1257
2482
|
|
|
2483
|
+
#endif
|
|
2484
|
+
|
|
1258
2485
|
// BFloat16 implementation.
|
|
1259
2486
|
|
|
1260
2487
|
EIGEN_STRONG_INLINE Packet8f Bf16ToF32(const Packet8bf& a) {
|
|
@@ -1272,8 +2499,6 @@ EIGEN_STRONG_INLINE Packet8f Bf16ToF32(const Packet8bf& a) {
|
|
|
1272
2499
|
|
|
1273
2500
|
// Convert float to bfloat16 according to round-to-nearest-even/denormals algorithm.
|
|
1274
2501
|
EIGEN_STRONG_INLINE Packet8bf F32ToBf16(const Packet8f& a) {
|
|
1275
|
-
Packet8bf r;
|
|
1276
|
-
|
|
1277
2502
|
__m256i input = _mm256_castps_si256(a);
|
|
1278
2503
|
|
|
1279
2504
|
#ifdef EIGEN_VECTORIZE_AVX2
|
|
@@ -1292,8 +2517,7 @@ EIGEN_STRONG_INLINE Packet8bf F32ToBf16(const Packet8f& a) {
|
|
|
1292
2517
|
__m256i nan = _mm256_set1_epi32(0x7fc0);
|
|
1293
2518
|
t = _mm256_blendv_epi8(nan, t, _mm256_castps_si256(mask));
|
|
1294
2519
|
// output = numext::bit_cast<uint16_t>(input);
|
|
1295
|
-
return _mm_packus_epi32(_mm256_extractf128_si256(t, 0),
|
|
1296
|
-
_mm256_extractf128_si256(t, 1));
|
|
2520
|
+
return _mm_packus_epi32(_mm256_extractf128_si256(t, 0), _mm256_extractf128_si256(t, 1));
|
|
1297
2521
|
#else
|
|
1298
2522
|
// uint32_t lsb = (input >> 16);
|
|
1299
2523
|
__m128i lo = _mm_srli_epi32(_mm256_extractf128_si256(input, 0), 16);
|
|
@@ -1320,32 +2544,38 @@ EIGEN_STRONG_INLINE Packet8bf F32ToBf16(const Packet8f& a) {
|
|
|
1320
2544
|
#endif
|
|
1321
2545
|
}
|
|
1322
2546
|
|
|
1323
|
-
template<>
|
|
2547
|
+
template <>
|
|
2548
|
+
EIGEN_STRONG_INLINE Packet8bf pset1<Packet8bf>(const bfloat16& from) {
|
|
1324
2549
|
return _mm_set1_epi16(numext::bit_cast<numext::uint16_t>(from));
|
|
1325
2550
|
}
|
|
1326
2551
|
|
|
1327
|
-
template<>
|
|
2552
|
+
template <>
|
|
2553
|
+
EIGEN_STRONG_INLINE bfloat16 pfirst<Packet8bf>(const Packet8bf& from) {
|
|
1328
2554
|
return numext::bit_cast<bfloat16>(static_cast<numext::uint16_t>(_mm_extract_epi16(from, 0)));
|
|
1329
2555
|
}
|
|
1330
2556
|
|
|
1331
|
-
template<>
|
|
2557
|
+
template <>
|
|
2558
|
+
EIGEN_STRONG_INLINE Packet8bf pload<Packet8bf>(const bfloat16* from) {
|
|
1332
2559
|
return _mm_load_si128(reinterpret_cast<const __m128i*>(from));
|
|
1333
2560
|
}
|
|
1334
2561
|
|
|
1335
|
-
template<>
|
|
2562
|
+
template <>
|
|
2563
|
+
EIGEN_STRONG_INLINE Packet8bf ploadu<Packet8bf>(const bfloat16* from) {
|
|
1336
2564
|
return _mm_loadu_si128(reinterpret_cast<const __m128i*>(from));
|
|
1337
2565
|
}
|
|
1338
2566
|
|
|
1339
|
-
template<>
|
|
2567
|
+
template <>
|
|
2568
|
+
EIGEN_STRONG_INLINE void pstore<bfloat16>(bfloat16* to, const Packet8bf& from) {
|
|
1340
2569
|
_mm_store_si128(reinterpret_cast<__m128i*>(to), from);
|
|
1341
2570
|
}
|
|
1342
2571
|
|
|
1343
|
-
template<>
|
|
2572
|
+
template <>
|
|
2573
|
+
EIGEN_STRONG_INLINE void pstoreu<bfloat16>(bfloat16* to, const Packet8bf& from) {
|
|
1344
2574
|
_mm_storeu_si128(reinterpret_cast<__m128i*>(to), from);
|
|
1345
2575
|
}
|
|
1346
2576
|
|
|
1347
|
-
template<>
|
|
1348
|
-
ploaddup<Packet8bf>(const bfloat16* from) {
|
|
2577
|
+
template <>
|
|
2578
|
+
EIGEN_STRONG_INLINE Packet8bf ploaddup<Packet8bf>(const bfloat16* from) {
|
|
1349
2579
|
const numext::uint16_t a = numext::bit_cast<numext::uint16_t>(from[0]);
|
|
1350
2580
|
const numext::uint16_t b = numext::bit_cast<numext::uint16_t>(from[1]);
|
|
1351
2581
|
const numext::uint16_t c = numext::bit_cast<numext::uint16_t>(from[2]);
|
|
@@ -1353,15 +2583,16 @@ ploaddup<Packet8bf>(const bfloat16* from) {
|
|
|
1353
2583
|
return _mm_set_epi16(d, d, c, c, b, b, a, a);
|
|
1354
2584
|
}
|
|
1355
2585
|
|
|
1356
|
-
template<>
|
|
1357
|
-
ploadquad<Packet8bf>(const bfloat16* from) {
|
|
2586
|
+
template <>
|
|
2587
|
+
EIGEN_STRONG_INLINE Packet8bf ploadquad<Packet8bf>(const bfloat16* from) {
|
|
1358
2588
|
const numext::uint16_t a = numext::bit_cast<numext::uint16_t>(from[0]);
|
|
1359
2589
|
const numext::uint16_t b = numext::bit_cast<numext::uint16_t>(from[1]);
|
|
1360
2590
|
return _mm_set_epi16(b, b, b, b, a, a, a, a);
|
|
1361
2591
|
}
|
|
1362
2592
|
|
|
1363
|
-
template<>
|
|
1364
|
-
|
|
2593
|
+
template <>
|
|
2594
|
+
EIGEN_STRONG_INLINE Packet8bf ptrue(const Packet8bf& a) {
|
|
2595
|
+
return _mm_cmpeq_epi32(a, a);
|
|
1365
2596
|
}
|
|
1366
2597
|
|
|
1367
2598
|
template <>
|
|
@@ -1371,14 +2602,12 @@ EIGEN_STRONG_INLINE Packet8bf pabs(const Packet8bf& a) {
|
|
|
1371
2602
|
}
|
|
1372
2603
|
|
|
1373
2604
|
template <>
|
|
1374
|
-
EIGEN_STRONG_INLINE Packet8bf pmin<Packet8bf>(const Packet8bf& a,
|
|
1375
|
-
const Packet8bf& b) {
|
|
2605
|
+
EIGEN_STRONG_INLINE Packet8bf pmin<Packet8bf>(const Packet8bf& a, const Packet8bf& b) {
|
|
1376
2606
|
return F32ToBf16(pmin<Packet8f>(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1377
2607
|
}
|
|
1378
2608
|
|
|
1379
2609
|
template <>
|
|
1380
|
-
EIGEN_STRONG_INLINE Packet8bf pmax<Packet8bf>(const Packet8bf& a,
|
|
1381
|
-
const Packet8bf& b) {
|
|
2610
|
+
EIGEN_STRONG_INLINE Packet8bf pmax<Packet8bf>(const Packet8bf& a, const Packet8bf& b) {
|
|
1382
2611
|
return F32ToBf16(pmax<Packet8f>(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1383
2612
|
}
|
|
1384
2613
|
|
|
@@ -1387,131 +2616,158 @@ EIGEN_STRONG_INLINE Packet8bf plset<Packet8bf>(const bfloat16& a) {
|
|
|
1387
2616
|
return F32ToBf16(plset<Packet8f>(static_cast<float>(a)));
|
|
1388
2617
|
}
|
|
1389
2618
|
|
|
1390
|
-
template<>
|
|
1391
|
-
|
|
2619
|
+
template <>
|
|
2620
|
+
EIGEN_STRONG_INLINE Packet8bf por(const Packet8bf& a, const Packet8bf& b) {
|
|
2621
|
+
return _mm_or_si128(a, b);
|
|
1392
2622
|
}
|
|
1393
|
-
template<>
|
|
1394
|
-
|
|
2623
|
+
template <>
|
|
2624
|
+
EIGEN_STRONG_INLINE Packet8bf pxor(const Packet8bf& a, const Packet8bf& b) {
|
|
2625
|
+
return _mm_xor_si128(a, b);
|
|
1395
2626
|
}
|
|
1396
|
-
template<>
|
|
1397
|
-
|
|
2627
|
+
template <>
|
|
2628
|
+
EIGEN_STRONG_INLINE Packet8bf pand(const Packet8bf& a, const Packet8bf& b) {
|
|
2629
|
+
return _mm_and_si128(a, b);
|
|
1398
2630
|
}
|
|
1399
|
-
template<>
|
|
1400
|
-
|
|
2631
|
+
template <>
|
|
2632
|
+
EIGEN_STRONG_INLINE Packet8bf pandnot(const Packet8bf& a, const Packet8bf& b) {
|
|
2633
|
+
return _mm_andnot_si128(b, a);
|
|
1401
2634
|
}
|
|
1402
2635
|
|
|
1403
|
-
template<>
|
|
2636
|
+
template <>
|
|
2637
|
+
EIGEN_STRONG_INLINE Packet8bf pselect(const Packet8bf& mask, const Packet8bf& a, const Packet8bf& b) {
|
|
1404
2638
|
return _mm_blendv_epi8(b, a, mask);
|
|
1405
2639
|
}
|
|
1406
2640
|
|
|
1407
|
-
template<>
|
|
1408
|
-
{
|
|
2641
|
+
template <>
|
|
2642
|
+
EIGEN_STRONG_INLINE Packet8bf pround<Packet8bf>(const Packet8bf& a) {
|
|
1409
2643
|
return F32ToBf16(pround<Packet8f>(Bf16ToF32(a)));
|
|
1410
2644
|
}
|
|
1411
2645
|
|
|
1412
|
-
template<>
|
|
2646
|
+
template <>
|
|
2647
|
+
EIGEN_STRONG_INLINE Packet8bf print<Packet8bf>(const Packet8bf& a) {
|
|
1413
2648
|
return F32ToBf16(print<Packet8f>(Bf16ToF32(a)));
|
|
1414
2649
|
}
|
|
1415
2650
|
|
|
1416
|
-
template<>
|
|
2651
|
+
template <>
|
|
2652
|
+
EIGEN_STRONG_INLINE Packet8bf pceil<Packet8bf>(const Packet8bf& a) {
|
|
1417
2653
|
return F32ToBf16(pceil<Packet8f>(Bf16ToF32(a)));
|
|
1418
2654
|
}
|
|
1419
2655
|
|
|
1420
|
-
template<>
|
|
2656
|
+
template <>
|
|
2657
|
+
EIGEN_STRONG_INLINE Packet8bf pfloor<Packet8bf>(const Packet8bf& a) {
|
|
1421
2658
|
return F32ToBf16(pfloor<Packet8f>(Bf16ToF32(a)));
|
|
1422
2659
|
}
|
|
1423
2660
|
|
|
1424
|
-
template<>
|
|
2661
|
+
template <>
|
|
2662
|
+
EIGEN_STRONG_INLINE Packet8bf ptrunc<Packet8bf>(const Packet8bf& a) {
|
|
2663
|
+
return F32ToBf16(ptrunc<Packet8f>(Bf16ToF32(a)));
|
|
2664
|
+
}
|
|
2665
|
+
|
|
2666
|
+
template <>
|
|
2667
|
+
EIGEN_STRONG_INLINE Packet8bf pcmp_eq(const Packet8bf& a, const Packet8bf& b) {
|
|
1425
2668
|
return Pack16To8(pcmp_eq(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1426
2669
|
}
|
|
1427
2670
|
|
|
1428
|
-
template<>
|
|
2671
|
+
template <>
|
|
2672
|
+
EIGEN_STRONG_INLINE Packet8bf pcmp_le(const Packet8bf& a, const Packet8bf& b) {
|
|
1429
2673
|
return Pack16To8(pcmp_le(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1430
2674
|
}
|
|
1431
2675
|
|
|
1432
|
-
template<>
|
|
2676
|
+
template <>
|
|
2677
|
+
EIGEN_STRONG_INLINE Packet8bf pcmp_lt(const Packet8bf& a, const Packet8bf& b) {
|
|
1433
2678
|
return Pack16To8(pcmp_lt(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1434
2679
|
}
|
|
1435
2680
|
|
|
1436
|
-
template<>
|
|
2681
|
+
template <>
|
|
2682
|
+
EIGEN_STRONG_INLINE Packet8bf pcmp_lt_or_nan(const Packet8bf& a, const Packet8bf& b) {
|
|
1437
2683
|
return Pack16To8(pcmp_lt_or_nan(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1438
2684
|
}
|
|
1439
2685
|
|
|
1440
|
-
template<>
|
|
2686
|
+
template <>
|
|
2687
|
+
EIGEN_STRONG_INLINE Packet8bf pconj(const Packet8bf& a) {
|
|
2688
|
+
return a;
|
|
2689
|
+
}
|
|
1441
2690
|
|
|
1442
|
-
template<>
|
|
2691
|
+
template <>
|
|
2692
|
+
EIGEN_STRONG_INLINE Packet8bf pnegate(const Packet8bf& a) {
|
|
1443
2693
|
Packet8bf sign_mask = _mm_set1_epi16(static_cast<numext::uint16_t>(0x8000));
|
|
1444
2694
|
return _mm_xor_si128(a, sign_mask);
|
|
1445
2695
|
}
|
|
1446
2696
|
|
|
1447
|
-
template<>
|
|
2697
|
+
template <>
|
|
2698
|
+
EIGEN_STRONG_INLINE Packet8bf padd<Packet8bf>(const Packet8bf& a, const Packet8bf& b) {
|
|
1448
2699
|
return F32ToBf16(padd<Packet8f>(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1449
2700
|
}
|
|
1450
2701
|
|
|
1451
|
-
template<>
|
|
2702
|
+
template <>
|
|
2703
|
+
EIGEN_STRONG_INLINE Packet8bf psub<Packet8bf>(const Packet8bf& a, const Packet8bf& b) {
|
|
1452
2704
|
return F32ToBf16(psub<Packet8f>(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1453
2705
|
}
|
|
1454
2706
|
|
|
1455
|
-
template<>
|
|
2707
|
+
template <>
|
|
2708
|
+
EIGEN_STRONG_INLINE Packet8bf pmul<Packet8bf>(const Packet8bf& a, const Packet8bf& b) {
|
|
1456
2709
|
return F32ToBf16(pmul<Packet8f>(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1457
2710
|
}
|
|
1458
2711
|
|
|
1459
|
-
template<>
|
|
1460
|
-
|
|
2712
|
+
template <>
|
|
2713
|
+
EIGEN_STRONG_INLINE Packet8bf pmadd<Packet8bf>(const Packet8bf& a, const Packet8bf& b, const Packet8bf& c) {
|
|
2714
|
+
return F32ToBf16(pmadd(Bf16ToF32(a), Bf16ToF32(b), Bf16ToF32(c)));
|
|
1461
2715
|
}
|
|
1462
2716
|
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
const numext::uint16_t s0 = numext::bit_cast<numext::uint16_t>(from[0*stride]);
|
|
1467
|
-
const numext::uint16_t s1 = numext::bit_cast<numext::uint16_t>(from[1*stride]);
|
|
1468
|
-
const numext::uint16_t s2 = numext::bit_cast<numext::uint16_t>(from[2*stride]);
|
|
1469
|
-
const numext::uint16_t s3 = numext::bit_cast<numext::uint16_t>(from[3*stride]);
|
|
1470
|
-
const numext::uint16_t s4 = numext::bit_cast<numext::uint16_t>(from[4*stride]);
|
|
1471
|
-
const numext::uint16_t s5 = numext::bit_cast<numext::uint16_t>(from[5*stride]);
|
|
1472
|
-
const numext::uint16_t s6 = numext::bit_cast<numext::uint16_t>(from[6*stride]);
|
|
1473
|
-
const numext::uint16_t s7 = numext::bit_cast<numext::uint16_t>(from[7*stride]);
|
|
1474
|
-
return _mm_set_epi16(s7, s6, s5, s4, s3, s2, s1, s0);
|
|
2717
|
+
template <>
|
|
2718
|
+
EIGEN_STRONG_INLINE Packet8bf pmsub<Packet8bf>(const Packet8bf& a, const Packet8bf& b, const Packet8bf& c) {
|
|
2719
|
+
return F32ToBf16(pmsub(Bf16ToF32(a), Bf16ToF32(b), Bf16ToF32(c)));
|
|
1475
2720
|
}
|
|
1476
2721
|
|
|
1477
|
-
template<>
|
|
1478
|
-
{
|
|
1479
|
-
|
|
1480
|
-
pstore(aux, from);
|
|
1481
|
-
to[stride*0] = aux[0];
|
|
1482
|
-
to[stride*1] = aux[1];
|
|
1483
|
-
to[stride*2] = aux[2];
|
|
1484
|
-
to[stride*3] = aux[3];
|
|
1485
|
-
to[stride*4] = aux[4];
|
|
1486
|
-
to[stride*5] = aux[5];
|
|
1487
|
-
to[stride*6] = aux[6];
|
|
1488
|
-
to[stride*7] = aux[7];
|
|
2722
|
+
template <>
|
|
2723
|
+
EIGEN_STRONG_INLINE Packet8bf pnmadd<Packet8bf>(const Packet8bf& a, const Packet8bf& b, const Packet8bf& c) {
|
|
2724
|
+
return F32ToBf16(pnmadd(Bf16ToF32(a), Bf16ToF32(b), Bf16ToF32(c)));
|
|
1489
2725
|
}
|
|
1490
2726
|
|
|
1491
|
-
template<>
|
|
1492
|
-
|
|
2727
|
+
template <>
|
|
2728
|
+
EIGEN_STRONG_INLINE Packet8bf pnmsub<Packet8bf>(const Packet8bf& a, const Packet8bf& b, const Packet8bf& c) {
|
|
2729
|
+
return F32ToBf16(pnmsub(Bf16ToF32(a), Bf16ToF32(b), Bf16ToF32(c)));
|
|
1493
2730
|
}
|
|
1494
2731
|
|
|
1495
|
-
template<>
|
|
1496
|
-
|
|
2732
|
+
template <>
|
|
2733
|
+
EIGEN_STRONG_INLINE Packet8bf pdiv<Packet8bf>(const Packet8bf& a, const Packet8bf& b) {
|
|
2734
|
+
return F32ToBf16(pdiv<Packet8f>(Bf16ToF32(a), Bf16ToF32(b)));
|
|
1497
2735
|
}
|
|
1498
2736
|
|
|
1499
|
-
template<>
|
|
1500
|
-
|
|
2737
|
+
template <>
|
|
2738
|
+
EIGEN_STRONG_INLINE Packet8bf pgather<bfloat16, Packet8bf>(const bfloat16* from, Index stride) {
|
|
2739
|
+
const numext::uint16_t s0 = numext::bit_cast<numext::uint16_t>(from[0 * stride]);
|
|
2740
|
+
const numext::uint16_t s1 = numext::bit_cast<numext::uint16_t>(from[1 * stride]);
|
|
2741
|
+
const numext::uint16_t s2 = numext::bit_cast<numext::uint16_t>(from[2 * stride]);
|
|
2742
|
+
const numext::uint16_t s3 = numext::bit_cast<numext::uint16_t>(from[3 * stride]);
|
|
2743
|
+
const numext::uint16_t s4 = numext::bit_cast<numext::uint16_t>(from[4 * stride]);
|
|
2744
|
+
const numext::uint16_t s5 = numext::bit_cast<numext::uint16_t>(from[5 * stride]);
|
|
2745
|
+
const numext::uint16_t s6 = numext::bit_cast<numext::uint16_t>(from[6 * stride]);
|
|
2746
|
+
const numext::uint16_t s7 = numext::bit_cast<numext::uint16_t>(from[7 * stride]);
|
|
2747
|
+
return _mm_set_epi16(s7, s6, s5, s4, s3, s2, s1, s0);
|
|
1501
2748
|
}
|
|
1502
2749
|
|
|
1503
|
-
template<>
|
|
1504
|
-
|
|
2750
|
+
template <>
|
|
2751
|
+
EIGEN_STRONG_INLINE void pscatter<bfloat16, Packet8bf>(bfloat16* to, const Packet8bf& from, Index stride) {
|
|
2752
|
+
EIGEN_ALIGN32 bfloat16 aux[8];
|
|
2753
|
+
pstore(aux, from);
|
|
2754
|
+
to[stride * 0] = aux[0];
|
|
2755
|
+
to[stride * 1] = aux[1];
|
|
2756
|
+
to[stride * 2] = aux[2];
|
|
2757
|
+
to[stride * 3] = aux[3];
|
|
2758
|
+
to[stride * 4] = aux[4];
|
|
2759
|
+
to[stride * 5] = aux[5];
|
|
2760
|
+
to[stride * 6] = aux[6];
|
|
2761
|
+
to[stride * 7] = aux[7];
|
|
1505
2762
|
}
|
|
1506
2763
|
|
|
1507
|
-
template<>
|
|
1508
|
-
{
|
|
1509
|
-
__m128i m = _mm_setr_epi8(14,15,12,13,10,11,8,9,6,7,4,5,2,3,0,1);
|
|
1510
|
-
return _mm_shuffle_epi8(a,m);
|
|
2764
|
+
template <>
|
|
2765
|
+
EIGEN_STRONG_INLINE Packet8bf preverse(const Packet8bf& a) {
|
|
2766
|
+
__m128i m = _mm_setr_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
|
|
2767
|
+
return _mm_shuffle_epi8(a, m);
|
|
1511
2768
|
}
|
|
1512
2769
|
|
|
1513
|
-
EIGEN_STRONG_INLINE void
|
|
1514
|
-
ptranspose(PacketBlock<Packet8bf,8>& kernel) {
|
|
2770
|
+
EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet8bf, 8>& kernel) {
|
|
1515
2771
|
__m128i a = kernel.packet[0];
|
|
1516
2772
|
__m128i b = kernel.packet[1];
|
|
1517
2773
|
__m128i c = kernel.packet[2];
|
|
@@ -1549,8 +2805,7 @@ ptranspose(PacketBlock<Packet8bf,8>& kernel) {
|
|
|
1549
2805
|
kernel.packet[7] = _mm_unpackhi_epi64(a67b67c67d67, e67f67g67h67);
|
|
1550
2806
|
}
|
|
1551
2807
|
|
|
1552
|
-
EIGEN_STRONG_INLINE void
|
|
1553
|
-
ptranspose(PacketBlock<Packet8bf,4>& kernel) {
|
|
2808
|
+
EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet8bf, 4>& kernel) {
|
|
1554
2809
|
__m128i a = kernel.packet[0];
|
|
1555
2810
|
__m128i b = kernel.packet[1];
|
|
1556
2811
|
__m128i c = kernel.packet[2];
|
|
@@ -1567,8 +2822,260 @@ ptranspose(PacketBlock<Packet8bf,4>& kernel) {
|
|
|
1567
2822
|
kernel.packet[3] = _mm_unpackhi_epi32(ab_47, cd_47);
|
|
1568
2823
|
}
|
|
1569
2824
|
|
|
1570
|
-
|
|
2825
|
+
/*---------------- load/store segment support ----------------*/
|
|
2826
|
+
|
|
2827
|
+
// returns a mask of 8-bit elements (at most 4) that are all 1's in the range [begin, begin + count) and 0 elsewhere.
|
|
2828
|
+
inline __m128i segment_mask_4x8(Index begin, Index count) {
|
|
2829
|
+
eigen_assert(begin >= 0 && begin + count <= 4);
|
|
2830
|
+
long long mask = 1;
|
|
2831
|
+
mask <<= CHAR_BIT * count;
|
|
2832
|
+
mask--;
|
|
2833
|
+
mask <<= CHAR_BIT * begin;
|
|
2834
|
+
#if !EIGEN_ARCH_x86_64
|
|
2835
|
+
return _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&mask));
|
|
2836
|
+
#else
|
|
2837
|
+
return _mm_cvtsi64_si128(mask);
|
|
2838
|
+
#endif
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2841
|
+
// returns a mask of 8-bit elements (at most 8) that are all 1's in the range [begin, begin + count) and 0 elsewhere.
|
|
2842
|
+
inline __m128i segment_mask_8x8(Index begin, Index count) {
|
|
2843
|
+
eigen_assert(begin >= 0 && begin + count <= 8);
|
|
2844
|
+
long long mask = 1;
|
|
2845
|
+
// avoid UB when count == 8
|
|
2846
|
+
mask <<= (CHAR_BIT / 2) * count;
|
|
2847
|
+
mask <<= (CHAR_BIT / 2) * count;
|
|
2848
|
+
mask--;
|
|
2849
|
+
mask <<= CHAR_BIT * begin;
|
|
2850
|
+
#if !EIGEN_ARCH_x86_64
|
|
2851
|
+
return _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&mask));
|
|
2852
|
+
#else
|
|
2853
|
+
return _mm_cvtsi64_si128(mask);
|
|
2854
|
+
#endif
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
// returns a mask of 32-bit elements (at most 4) that are all 1's in the range [begin, begin + count) and 0 elsewhere.
|
|
2858
|
+
inline __m128i segment_mask_4x32(Index begin, Index count) {
|
|
2859
|
+
eigen_assert(begin >= 0 && begin + count <= 4);
|
|
2860
|
+
return _mm_cvtepi8_epi32(segment_mask_4x8(begin, count));
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
// returns a mask of 64-bit elements (at most 2) that are all 1's in the range [begin, begin + count) and 0 elsewhere.
|
|
2864
|
+
inline __m128i segment_mask_2x64(Index begin, Index count) {
|
|
2865
|
+
eigen_assert(begin >= 0 && begin + count <= 2);
|
|
2866
|
+
return _mm_cvtepi8_epi64(segment_mask_4x8(begin, count));
|
|
2867
|
+
}
|
|
2868
|
+
|
|
2869
|
+
// returns a mask of 32-bit elements (at most 8) that are all 1's in the range [begin, begin + count) and 0 elsewhere.
|
|
2870
|
+
inline __m256i segment_mask_8x32(Index begin, Index count) {
|
|
2871
|
+
__m128i mask_epi8 = segment_mask_8x8(begin, count);
|
|
2872
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
2873
|
+
__m256i mask_epi32 = _mm256_cvtepi8_epi32(mask_epi8);
|
|
2874
|
+
#else
|
|
2875
|
+
__m128i mask_epi32_lo = _mm_cvtepi8_epi32(mask_epi8);
|
|
2876
|
+
__m128i mask_epi32_hi = _mm_cvtepi8_epi32(_mm_srli_epi64(mask_epi8, 32));
|
|
2877
|
+
__m256i mask_epi32 = _mm256_insertf128_si256(_mm256_castsi128_si256(mask_epi32_lo), mask_epi32_hi, 1);
|
|
2878
|
+
#endif
|
|
2879
|
+
return mask_epi32;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
// returns a mask of 64-bit elements (at most 4) that are all 1's in the range [begin, begin + count) and 0 elsewhere.
|
|
2883
|
+
inline __m256i segment_mask_4x64(Index begin, Index count) {
|
|
2884
|
+
__m128i mask_epi8 = segment_mask_4x8(begin, count);
|
|
2885
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
2886
|
+
__m256i mask_epi64 = _mm256_cvtepi8_epi64(mask_epi8);
|
|
2887
|
+
#else
|
|
2888
|
+
__m128i mask_epi64_lo = _mm_cvtepi8_epi64(mask_epi8);
|
|
2889
|
+
__m128i mask_epi64_hi = _mm_cvtepi8_epi64(_mm_srli_epi64(mask_epi8, 16));
|
|
2890
|
+
__m256i mask_epi64 = _mm256_insertf128_si256(_mm256_castsi128_si256(mask_epi64_lo), mask_epi64_hi, 1);
|
|
2891
|
+
#endif
|
|
2892
|
+
return mask_epi64;
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
/*---------------- float ----------------*/
|
|
2896
|
+
|
|
2897
|
+
template <>
|
|
2898
|
+
struct has_packet_segment<Packet4f> : std::true_type {};
|
|
2899
|
+
|
|
2900
|
+
template <>
|
|
2901
|
+
struct has_packet_segment<Packet8f> : std::true_type {};
|
|
2902
|
+
|
|
2903
|
+
template <>
|
|
2904
|
+
inline Packet4f ploaduSegment<Packet4f>(const float* from, Index begin, Index count) {
|
|
2905
|
+
return _mm_maskload_ps(from, segment_mask_4x32(begin, count));
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2908
|
+
template <>
|
|
2909
|
+
inline void pstoreuSegment<float, Packet4f>(float* to, const Packet4f& from, Index begin, Index count) {
|
|
2910
|
+
_mm_maskstore_ps(to, segment_mask_4x32(begin, count), from);
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
template <>
|
|
2914
|
+
inline Packet8f ploaduSegment<Packet8f>(const float* from, Index begin, Index count) {
|
|
2915
|
+
return _mm256_maskload_ps(from, segment_mask_8x32(begin, count));
|
|
2916
|
+
}
|
|
2917
|
+
|
|
2918
|
+
template <>
|
|
2919
|
+
inline void pstoreuSegment<float, Packet8f>(float* to, const Packet8f& from, Index begin, Index count) {
|
|
2920
|
+
_mm256_maskstore_ps(to, segment_mask_8x32(begin, count), from);
|
|
2921
|
+
}
|
|
2922
|
+
|
|
2923
|
+
/*---------------- int32 ----------------*/
|
|
2924
|
+
|
|
2925
|
+
template <>
|
|
2926
|
+
struct has_packet_segment<Packet4i> : std::true_type {};
|
|
2927
|
+
|
|
2928
|
+
template <>
|
|
2929
|
+
struct has_packet_segment<Packet8i> : std::true_type {};
|
|
2930
|
+
|
|
2931
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
2932
|
+
|
|
2933
|
+
template <>
|
|
2934
|
+
inline Packet4i ploaduSegment<Packet4i>(const int* from, Index begin, Index count) {
|
|
2935
|
+
return _mm_maskload_epi32(from, segment_mask_4x32(begin, count));
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
template <>
|
|
2939
|
+
inline void pstoreuSegment<int, Packet4i>(int* to, const Packet4i& from, Index begin, Index count) {
|
|
2940
|
+
_mm_maskstore_epi32(to, segment_mask_4x32(begin, count), from);
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
template <>
|
|
2944
|
+
inline Packet8i ploaduSegment<Packet8i>(const int* from, Index begin, Index count) {
|
|
2945
|
+
return _mm256_maskload_epi32(from, segment_mask_8x32(begin, count));
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
template <>
|
|
2949
|
+
inline void pstoreuSegment<int, Packet8i>(int* to, const Packet8i& from, Index begin, Index count) {
|
|
2950
|
+
_mm256_maskstore_epi32(to, segment_mask_8x32(begin, count), from);
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
#else
|
|
2954
|
+
|
|
2955
|
+
template <>
|
|
2956
|
+
inline Packet4i ploaduSegment<Packet4i>(const int* from, Index begin, Index count) {
|
|
2957
|
+
return _mm_castps_si128(ploaduSegment<Packet4f>(reinterpret_cast<const float*>(from), begin, count));
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
template <>
|
|
2961
|
+
inline void pstoreuSegment<int, Packet4i>(int* to, const Packet4i& from, Index begin, Index count) {
|
|
2962
|
+
pstoreuSegment<float, Packet4f>(reinterpret_cast<float*>(to), _mm_castsi128_ps(from), begin, count);
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2965
|
+
template <>
|
|
2966
|
+
inline Packet8i ploaduSegment<Packet8i>(const int* from, Index begin, Index count) {
|
|
2967
|
+
return _mm256_castps_si256(ploaduSegment<Packet8f>(reinterpret_cast<const float*>(from), begin, count));
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2970
|
+
template <>
|
|
2971
|
+
inline void pstoreuSegment<int, Packet8i>(int* to, const Packet8i& from, Index begin, Index count) {
|
|
2972
|
+
pstoreuSegment<float, Packet8f>(reinterpret_cast<float*>(to), _mm256_castsi256_ps(from), begin, count);
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
#endif
|
|
2976
|
+
|
|
2977
|
+
/*---------------- uint32 ----------------*/
|
|
2978
|
+
|
|
2979
|
+
template <>
|
|
2980
|
+
struct has_packet_segment<Packet4ui> : std::true_type {};
|
|
2981
|
+
|
|
2982
|
+
template <>
|
|
2983
|
+
struct has_packet_segment<Packet8ui> : std::true_type {};
|
|
2984
|
+
|
|
2985
|
+
template <>
|
|
2986
|
+
inline Packet4ui ploaduSegment<Packet4ui>(const uint32_t* from, Index begin, Index count) {
|
|
2987
|
+
return Packet4ui(ploaduSegment<Packet4i>(reinterpret_cast<const int*>(from), begin, count));
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2990
|
+
template <>
|
|
2991
|
+
inline void pstoreuSegment<uint32_t, Packet4ui>(uint32_t* to, const Packet4ui& from, Index begin, Index count) {
|
|
2992
|
+
pstoreuSegment<int, Packet4i>(reinterpret_cast<int*>(to), Packet4i(from), begin, count);
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
template <>
|
|
2996
|
+
inline Packet8ui ploaduSegment<Packet8ui>(const uint32_t* from, Index begin, Index count) {
|
|
2997
|
+
return Packet8ui(ploaduSegment<Packet8i>(reinterpret_cast<const int*>(from), begin, count));
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
template <>
|
|
3001
|
+
inline void pstoreuSegment<uint32_t, Packet8ui>(uint32_t* to, const Packet8ui& from, Index begin, Index count) {
|
|
3002
|
+
pstoreuSegment<int, Packet8i>(reinterpret_cast<int*>(to), Packet8i(from), begin, count);
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
/*---------------- double ----------------*/
|
|
3006
|
+
|
|
3007
|
+
template <>
|
|
3008
|
+
struct has_packet_segment<Packet2d> : std::true_type {};
|
|
3009
|
+
|
|
3010
|
+
template <>
|
|
3011
|
+
struct has_packet_segment<Packet4d> : std::true_type {};
|
|
3012
|
+
|
|
3013
|
+
template <>
|
|
3014
|
+
inline Packet2d ploaduSegment<Packet2d>(const double* from, Index begin, Index count) {
|
|
3015
|
+
return _mm_maskload_pd(from, segment_mask_2x64(begin, count));
|
|
3016
|
+
}
|
|
3017
|
+
|
|
3018
|
+
template <>
|
|
3019
|
+
inline void pstoreuSegment<double, Packet2d>(double* to, const Packet2d& from, Index begin, Index count) {
|
|
3020
|
+
_mm_maskstore_pd(to, segment_mask_2x64(begin, count), from);
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
template <>
|
|
3024
|
+
inline Packet4d ploaduSegment<Packet4d>(const double* from, Index begin, Index count) {
|
|
3025
|
+
return _mm256_maskload_pd(from, segment_mask_4x64(begin, count));
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
template <>
|
|
3029
|
+
inline void pstoreuSegment<double, Packet4d>(double* to, const Packet4d& from, Index begin, Index count) {
|
|
3030
|
+
_mm256_maskstore_pd(to, segment_mask_4x64(begin, count), from);
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
#ifdef EIGEN_VECTORIZE_AVX2
|
|
3034
|
+
|
|
3035
|
+
/*---------------- int64_t ----------------*/
|
|
3036
|
+
|
|
3037
|
+
template <>
|
|
3038
|
+
struct has_packet_segment<Packet2l> : std::true_type {};
|
|
3039
|
+
|
|
3040
|
+
template <>
|
|
3041
|
+
struct has_packet_segment<Packet4l> : std::true_type {};
|
|
3042
|
+
|
|
3043
|
+
template <>
|
|
3044
|
+
inline Packet2l ploaduSegment<Packet2l>(const int64_t* from, Index begin, Index count) {
|
|
3045
|
+
return _mm_maskload_epi64(reinterpret_cast<const long long*>(from), segment_mask_2x64(begin, count));
|
|
3046
|
+
}
|
|
3047
|
+
template <>
|
|
3048
|
+
inline void pstoreuSegment<int64_t, Packet2l>(int64_t* to, const Packet2l& from, Index begin, Index count) {
|
|
3049
|
+
_mm_maskstore_epi64(reinterpret_cast<long long*>(to), segment_mask_2x64(begin, count), from);
|
|
3050
|
+
}
|
|
3051
|
+
template <>
|
|
3052
|
+
inline Packet4l ploaduSegment<Packet4l>(const int64_t* from, Index begin, Index count) {
|
|
3053
|
+
return _mm256_maskload_epi64(reinterpret_cast<const long long*>(from), segment_mask_4x64(begin, count));
|
|
3054
|
+
}
|
|
3055
|
+
template <>
|
|
3056
|
+
inline void pstoreuSegment<int64_t, Packet4l>(int64_t* to, const Packet4l& from, Index begin, Index count) {
|
|
3057
|
+
_mm256_maskstore_epi64(reinterpret_cast<long long*>(to), segment_mask_4x64(begin, count), from);
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
/*---------------- uint64_t ----------------*/
|
|
3061
|
+
|
|
3062
|
+
template <>
|
|
3063
|
+
struct has_packet_segment<Packet4ul> : std::true_type {};
|
|
3064
|
+
|
|
3065
|
+
template <>
|
|
3066
|
+
inline Packet4ul ploaduSegment<Packet4ul>(const uint64_t* from, Index begin, Index count) {
|
|
3067
|
+
return Packet4ul(ploaduSegment<Packet4l>(reinterpret_cast<const int64_t*>(from), begin, count));
|
|
3068
|
+
}
|
|
3069
|
+
template <>
|
|
3070
|
+
inline void pstoreuSegment<uint64_t, Packet4ul>(uint64_t* to, const Packet4ul& from, Index begin, Index count) {
|
|
3071
|
+
pstoreuSegment<int64_t, Packet4l>(reinterpret_cast<int64_t*>(to), Packet4l(from), begin, count);
|
|
3072
|
+
}
|
|
3073
|
+
#endif
|
|
3074
|
+
|
|
3075
|
+
/*---------------- end load/store segment support ----------------*/
|
|
3076
|
+
|
|
3077
|
+
} // end namespace internal
|
|
1571
3078
|
|
|
1572
|
-
}
|
|
3079
|
+
} // end namespace Eigen
|
|
1573
3080
|
|
|
1574
|
-
#endif
|
|
3081
|
+
#endif // EIGEN_PACKET_MATH_AVX_H
|