4#ifndef EIGEN_SPARSE_SCATTER_H
5#define EIGEN_SPARSE_SCATTER_H
8#include "./InternalHeaderCheck.h"
13constexpr Index kSparseScatterPacketMinSize = 32;
15template <
typename Scalar,
bool Vectorize>
16struct sparse_scatter_sub_impl {
17 template <
typename StorageIndex,
typename ValuesEvaluator>
18 static EIGEN_STRONG_INLINE Index run(Scalar*,
const StorageIndex*,
const ValuesEvaluator&, Index) {
23template <
typename Scalar>
24struct sparse_scatter_sub_impl<Scalar, true> {
26 template <
typename StorageIndex,
typename ValuesEvaluator>
27 static EIGEN_DONT_INLINE Index run(Scalar* EIGEN_RESTRICT dense,
const StorageIndex* indices,
28 const ValuesEvaluator& values, Index size) {
30 using Packet =
typename find_best_packet<Scalar, 4>::type;
31 constexpr Index PacketSize = unpacket_traits<Packet>::size;
32 const Index end = size - size % PacketSize;
33 for (Index i = 0; i < end; i += PacketSize) {
34 EIGEN_ALIGN_MAX Scalar gathered[PacketSize];
35 for (Index lane = 0; lane < PacketSize; ++lane) gathered[lane] = dense[indices[i + lane]];
36 pstoreu(gathered, psub(ploadu<Packet>(gathered), values.template packet<Unaligned, Packet>(i)));
37 for (Index lane = 0; lane < PacketSize; ++lane) dense[indices[i + lane]] = gathered[lane];
46template <
typename Scalar,
typename StorageIndex,
typename Values>
47EIGEN_STRONG_INLINE Index sparse_scatter_sub_packets(Scalar* EIGEN_RESTRICT dense,
const StorageIndex* indices,
48 const MatrixBase<Values>& values) {
49 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Values)
50 EIGEN_STATIC_ASSERT((std::is_same<Scalar, typename Values::Scalar>::value), YOU_MIXED_DIFFERENT_NUMERIC_TYPES)
51 constexpr bool Vectorize = (evaluator<Values>::Flags &
PacketAccessBit) &&
52 (evaluator<Values>::Flags &
LinearAccessBit) && packet_traits<Scalar>::HasSub &&
53 !NumTraits<Scalar>::IsComplex;
54 if (!Vectorize || values.size() < kSparseScatterPacketMinSize)
return 0;
55 evaluator<Values> valuesEval(values.derived());
56 return sparse_scatter_sub_impl<Scalar, Vectorize>::run(dense, indices, valuesEval, values.size());
59template <
bool Conjugate,
typename Scalar,
typename StorageIndex>
60EIGEN_STRONG_INLINE Index sparse_scatter_sub_packets(Scalar* dense,
const StorageIndex* indices,
const Scalar* values,
61 Index size,
const Scalar& scale) {
62 constexpr bool Vectorize = packet_traits<Scalar>::Vectorizable && packet_traits<Scalar>::HasMul &&
63 packet_traits<Scalar>::HasSub && !NumTraits<Scalar>::IsComplex;
64 if (!Vectorize || size < kSparseScatterPacketMinSize)
return 0;
65 const Map<const Matrix<Scalar, Dynamic, 1>> mappedValues(values, size);
66 return sparse_scatter_sub_packets(dense, indices, mappedValues.template conjugateIf<Conjugate>() * scale);
constexpr unsigned int PacketAccessBit
Definition Constants.h:98
constexpr unsigned int LinearAccessBit
Definition Constants.h:134