mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-22 08:52:15 +08:00
Added suppor for in place evaluation to simple tensor expressions.
Use mempy to speedup tensor copies whenever possible.
This commit is contained in:
parent
439feca139
commit
b1892ab14d
@ -102,6 +102,7 @@ struct TensorEvaluator<const TensorAssignOp<LeftArgType, RightArgType>, Device>
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
typedef typename XprType::Index Index;
|
typedef typename XprType::Index Index;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||||
typedef typename TensorEvaluator<RightArgType, Device>::Dimensions Dimensions;
|
typedef typename TensorEvaluator<RightArgType, Device>::Dimensions Dimensions;
|
||||||
@ -112,9 +113,14 @@ struct TensorEvaluator<const TensorAssignOp<LeftArgType, RightArgType>, Device>
|
|||||||
return m_rightImpl.dimensions();
|
return m_rightImpl.dimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeeded() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar*) {
|
||||||
m_leftImpl.evalSubExprsIfNeeded();
|
eigen_assert(internal::dimensions_match(m_leftImpl.dimensions(), m_rightImpl.dimensions()));
|
||||||
m_rightImpl.evalSubExprsIfNeeded();
|
m_leftImpl.evalSubExprsIfNeeded(NULL);
|
||||||
|
// If the lhs provides raw access to its storage area (i.e. if m_leftImpl.data() returns a non
|
||||||
|
// null value), attempt to evaluate the rhs expression in place. Returns true iff in place
|
||||||
|
// evaluation isn't supported and the caller still needs to manually assign the values generated
|
||||||
|
// by the rhs to the lhs.
|
||||||
|
return m_rightImpl.evalSubExprsIfNeeded(m_leftImpl.data());
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
||||||
m_leftImpl.cleanup();
|
m_leftImpl.cleanup();
|
||||||
|
@ -39,13 +39,20 @@ struct TensorEvaluator
|
|||||||
PacketAccess = Derived::PacketAccess,
|
PacketAccess = Derived::PacketAccess,
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const Derived& m, const Device&)
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const Derived& m, const Device& device)
|
||||||
: m_data(const_cast<Scalar*>(m.data())), m_dims(m.dimensions())
|
: m_data(const_cast<Scalar*>(m.data())), m_dims(m.dimensions()), m_device(device)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dims; }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dims; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeeded() { }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar* dest) {
|
||||||
|
if (dest) {
|
||||||
|
m_device.memcpy((void*)dest, m_data, sizeof(Scalar) * m_dims.TotalSize());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const {
|
||||||
@ -70,9 +77,12 @@ struct TensorEvaluator
|
|||||||
return internal::pstoret<Scalar, Packet, StoreMode>(m_data + index, x);
|
return internal::pstoret<Scalar, Packet, StoreMode>(m_data + index, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scalar* data() const { return m_data; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Scalar* m_data;
|
Scalar* m_data;
|
||||||
Dimensions m_dims;
|
Dimensions m_dims;
|
||||||
|
const Device& m_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -98,7 +108,7 @@ struct TensorEvaluator<const Derived, Device>
|
|||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dims; }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dims; }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeeded() { }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar*) { return true; }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const {
|
||||||
@ -112,6 +122,8 @@ struct TensorEvaluator<const Derived, Device>
|
|||||||
return internal::ploadt<Packet, LoadMode>(m_data + index);
|
return internal::ploadt<Packet, LoadMode>(m_data + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Scalar* data() const { return m_data; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Scalar* m_data;
|
const Scalar* m_data;
|
||||||
Dimensions m_dims;
|
Dimensions m_dims;
|
||||||
@ -138,13 +150,14 @@ struct TensorEvaluator<const TensorCwiseNullaryOp<NullaryOp, ArgType>, Device>
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
typedef typename XprType::Index Index;
|
typedef typename XprType::Index Index;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||||
typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
|
typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_argImpl.dimensions(); }
|
EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_argImpl.dimensions(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeeded() { }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar*) { return true; }
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { }
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index index) const
|
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index index) const
|
||||||
@ -158,6 +171,8 @@ struct TensorEvaluator<const TensorCwiseNullaryOp<NullaryOp, ArgType>, Device>
|
|||||||
return m_functor.packetOp(index);
|
return m_functor.packetOp(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scalar* data() const { return NULL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const NullaryOp m_functor;
|
const NullaryOp m_functor;
|
||||||
TensorEvaluator<ArgType, Device> m_argImpl;
|
TensorEvaluator<ArgType, Device> m_argImpl;
|
||||||
@ -183,14 +198,16 @@ struct TensorEvaluator<const TensorCwiseUnaryOp<UnaryOp, ArgType>, Device>
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
typedef typename XprType::Index Index;
|
typedef typename XprType::Index Index;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||||
typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
|
typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_argImpl.dimensions(); }
|
EIGEN_DEVICE_FUNC const Dimensions& dimensions() const { return m_argImpl.dimensions(); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeeded() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar*) {
|
||||||
m_argImpl.evalSubExprsIfNeeded();
|
m_argImpl.evalSubExprsIfNeeded(NULL);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
||||||
m_argImpl.cleanup();
|
m_argImpl.cleanup();
|
||||||
@ -207,6 +224,8 @@ struct TensorEvaluator<const TensorCwiseUnaryOp<UnaryOp, ArgType>, Device>
|
|||||||
return m_functor.packetOp(m_argImpl.template packet<LoadMode>(index));
|
return m_functor.packetOp(m_argImpl.template packet<LoadMode>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scalar* data() const { return NULL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const UnaryOp m_functor;
|
const UnaryOp m_functor;
|
||||||
TensorEvaluator<ArgType, Device> m_argImpl;
|
TensorEvaluator<ArgType, Device> m_argImpl;
|
||||||
@ -233,6 +252,7 @@ struct TensorEvaluator<const TensorCwiseBinaryOp<BinaryOp, LeftArgType, RightArg
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
typedef typename XprType::Index Index;
|
typedef typename XprType::Index Index;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||||
typedef typename TensorEvaluator<LeftArgType, Device>::Dimensions Dimensions;
|
typedef typename TensorEvaluator<LeftArgType, Device>::Dimensions Dimensions;
|
||||||
@ -243,9 +263,10 @@ struct TensorEvaluator<const TensorCwiseBinaryOp<BinaryOp, LeftArgType, RightArg
|
|||||||
return m_leftImpl.dimensions();
|
return m_leftImpl.dimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeeded() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar*) {
|
||||||
m_leftImpl.evalSubExprsIfNeeded();
|
m_leftImpl.evalSubExprsIfNeeded(NULL);
|
||||||
m_rightImpl.evalSubExprsIfNeeded();
|
m_rightImpl.evalSubExprsIfNeeded(NULL);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
||||||
m_leftImpl.cleanup();
|
m_leftImpl.cleanup();
|
||||||
@ -262,6 +283,8 @@ struct TensorEvaluator<const TensorCwiseBinaryOp<BinaryOp, LeftArgType, RightArg
|
|||||||
return m_functor.packetOp(m_leftImpl.template packet<LoadMode>(index), m_rightImpl.template packet<LoadMode>(index));
|
return m_functor.packetOp(m_leftImpl.template packet<LoadMode>(index), m_rightImpl.template packet<LoadMode>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scalar* data() const { return NULL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const BinaryOp m_functor;
|
const BinaryOp m_functor;
|
||||||
TensorEvaluator<LeftArgType, Device> m_leftImpl;
|
TensorEvaluator<LeftArgType, Device> m_leftImpl;
|
||||||
@ -289,6 +312,7 @@ struct TensorEvaluator<const TensorSelectOp<IfArgType, ThenArgType, ElseArgType>
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
typedef typename XprType::Index Index;
|
typedef typename XprType::Index Index;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||||
typedef typename TensorEvaluator<IfArgType, Device>::Dimensions Dimensions;
|
typedef typename TensorEvaluator<IfArgType, Device>::Dimensions Dimensions;
|
||||||
@ -299,10 +323,11 @@ struct TensorEvaluator<const TensorSelectOp<IfArgType, ThenArgType, ElseArgType>
|
|||||||
return m_condImpl.dimensions();
|
return m_condImpl.dimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeeded() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar*) {
|
||||||
m_condImpl.evalSubExprsIfNeeded();
|
m_condImpl.evalSubExprsIfNeeded(NULL);
|
||||||
m_thenImpl.evalSubExprsIfNeeded();
|
m_thenImpl.evalSubExprsIfNeeded(NULL);
|
||||||
m_elseImpl.evalSubExprsIfNeeded();
|
m_elseImpl.evalSubExprsIfNeeded(NULL);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
|
||||||
m_condImpl.cleanup();
|
m_condImpl.cleanup();
|
||||||
@ -327,6 +352,8 @@ struct TensorEvaluator<const TensorSelectOp<IfArgType, ThenArgType, ElseArgType>
|
|||||||
m_elseImpl.template packet<LoadMode>(index));
|
m_elseImpl.template packet<LoadMode>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scalar* data() const { return NULL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TensorEvaluator<IfArgType, Device> m_condImpl;
|
TensorEvaluator<IfArgType, Device> m_condImpl;
|
||||||
TensorEvaluator<ThenArgType, Device> m_thenImpl;
|
TensorEvaluator<ThenArgType, Device> m_thenImpl;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user