mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-11 19:29:02 +08:00
Merged eigen/eigen into default
This commit is contained in:
commit
7d39c6d50a
@ -1613,9 +1613,7 @@ struct evaluator<Diagonal<ArgType, DiagIndex> >
|
||||
{ }
|
||||
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
// FIXME having to check whether ArgType is sparse here i not very nice.
|
||||
typedef typename internal::conditional<!internal::is_same<typename ArgType::StorageKind,Sparse>::value,
|
||||
typename XprType::CoeffReturnType,Scalar>::type CoeffReturnType;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
CoeffReturnType coeff(Index row, Index) const
|
||||
|
@ -93,8 +93,8 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/true>
|
||||
linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
|
||||
m_low(low),
|
||||
m_multiplier((high-low)/convert_index<Scalar>(num_steps<=1 ? 1 : num_steps-1)),
|
||||
m_divisor(convert_index<Scalar>(num_steps+high-low)/(high-low+1)),
|
||||
m_use_divisor((high+1)<(low+num_steps))
|
||||
m_divisor(convert_index<Scalar>((high>=low?num_steps:-num_steps)+(high-low))/((numext::abs(high-low)+1)==0?1:(numext::abs(high-low)+1))),
|
||||
m_use_divisor(num_steps>1 && (numext::abs(high-low)+1)<num_steps)
|
||||
{}
|
||||
|
||||
template<typename IndexType>
|
||||
|
@ -74,6 +74,41 @@ inline void throw_std_bad_alloc()
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void fast_memcpy(void* dst, const void* src, size_t size) {
|
||||
#if defined(__CUDA__) || defined(__ANDROID__)
|
||||
::memcpy(dst, src, size);
|
||||
#else
|
||||
switch(size) {
|
||||
// Most compilers will generate inline code for fixed sizes,
|
||||
// which is significantly faster for small copies.
|
||||
case 1: memcpy(dst, src, 1); break;
|
||||
case 2: memcpy(dst, src, 2); break;
|
||||
case 3: memcpy(dst, src, 3); break;
|
||||
case 4: memcpy(dst, src, 4); break;
|
||||
case 5: memcpy(dst, src, 5); break;
|
||||
case 6: memcpy(dst, src, 6); break;
|
||||
case 7: memcpy(dst, src, 7); break;
|
||||
case 8: memcpy(dst, src, 8); break;
|
||||
case 9: memcpy(dst, src, 9); break;
|
||||
case 10: memcpy(dst, src, 10); break;
|
||||
case 11: memcpy(dst, src, 11); break;
|
||||
case 12: memcpy(dst, src, 12); break;
|
||||
case 13: memcpy(dst, src, 13); break;
|
||||
case 14: memcpy(dst, src, 14); break;
|
||||
case 15: memcpy(dst, src, 15); break;
|
||||
case 16: memcpy(dst, src, 16); break;
|
||||
#ifdef EIGEN_OS_LINUX
|
||||
// On Linux, memmove appears to be faster than memcpy for
|
||||
// large sizes, strangely enough.
|
||||
default: memmove(dst, src, size); break;
|
||||
#else
|
||||
default: memcpy(dst, src, size); break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of handmade aligned functions ***
|
||||
*****************************************************************************/
|
||||
@ -493,7 +528,7 @@ template<typename T> struct smart_copy_helper<T,true> {
|
||||
IntPtr size = IntPtr(end)-IntPtr(start);
|
||||
if(size==0) return;
|
||||
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||
memcpy(target, start, size);
|
||||
fast_memcpy(target, start, size);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -638,7 +638,7 @@ struct plain_constant_type
|
||||
template<typename ExpressionType>
|
||||
struct is_lvalue
|
||||
{
|
||||
enum { value = !bool(is_const<ExpressionType>::value) &&
|
||||
enum { value = (!bool(is_const<ExpressionType>::value)) &&
|
||||
bool(traits<ExpressionType>::Flags & LvalueBit) };
|
||||
};
|
||||
|
||||
|
@ -295,11 +295,11 @@ struct evaluator<SparseCompressedBase<Derived> >
|
||||
Flags = Derived::Flags
|
||||
};
|
||||
|
||||
evaluator() : m_matrix(0)
|
||||
evaluator() : m_matrix(0), m_zero(0)
|
||||
{
|
||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||
}
|
||||
explicit evaluator(const Derived &mat) : m_matrix(&mat)
|
||||
explicit evaluator(const Derived &mat) : m_matrix(&mat), m_zero(0)
|
||||
{
|
||||
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
|
||||
}
|
||||
@ -312,10 +312,26 @@ struct evaluator<SparseCompressedBase<Derived> >
|
||||
operator const Derived&() const { return *m_matrix; }
|
||||
|
||||
typedef typename DenseCoeffsBase<Derived,ReadOnlyAccessors>::CoeffReturnType CoeffReturnType;
|
||||
Scalar coeff(Index row, Index col) const
|
||||
{ return m_matrix->coeff(row,col); }
|
||||
const Scalar& coeff(Index row, Index col) const
|
||||
{
|
||||
Index p = find(row,col);
|
||||
|
||||
if(p==Dynamic)
|
||||
return m_zero;
|
||||
else
|
||||
return m_matrix->const_cast_derived().valuePtr()[p];
|
||||
}
|
||||
|
||||
Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
Index p = find(row,col);
|
||||
eigen_assert(p!=Dynamic && "written coefficient does not exist");
|
||||
return m_matrix->const_cast_derived().valuePtr()[p];
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Index find(Index row, Index col) const
|
||||
{
|
||||
eigen_internal_assert(row>=0 && row<m_matrix->rows() && col>=0 && col<m_matrix->cols());
|
||||
|
||||
@ -324,14 +340,14 @@ struct evaluator<SparseCompressedBase<Derived> >
|
||||
|
||||
Index start = m_matrix->outerIndexPtr()[outer];
|
||||
Index end = m_matrix->isCompressed() ? m_matrix->outerIndexPtr()[outer+1] : m_matrix->outerIndexPtr()[outer] + m_matrix->innerNonZeroPtr()[outer];
|
||||
eigen_assert(end>start && "you are using a non finalized sparse matrix or written coefficient does not exist");
|
||||
const Index p = std::lower_bound(m_matrix->innerIndexPtr()+start, m_matrix->innerIndexPtr()+end,inner)
|
||||
- m_matrix->innerIndexPtr();
|
||||
eigen_assert((p<end) && (m_matrix->innerIndexPtr()[p]==inner) && "written coefficient does not exist");
|
||||
return m_matrix->const_cast_derived().valuePtr()[p];
|
||||
eigen_assert(end>=start && "you are using a non finalized sparse matrix or written coefficient does not exist");
|
||||
const Index p = std::lower_bound(m_matrix->innerIndexPtr()+start, m_matrix->innerIndexPtr()+end,inner) - m_matrix->innerIndexPtr();
|
||||
|
||||
return ((p<end) && (m_matrix->innerIndexPtr()[p]==inner)) ? p : Dynamic;
|
||||
}
|
||||
|
||||
const Derived *m_matrix;
|
||||
const Scalar m_zero;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -152,6 +152,45 @@ void testVectorType(const VectorType& base)
|
||||
m.tail(size-1).setLinSpaced(low, high);
|
||||
VERIFY_IS_APPROX(m(size-1), high);
|
||||
}
|
||||
|
||||
// regression test for bug 1383 (LinSpaced with empty size/range)
|
||||
{
|
||||
Index n0 = VectorType::SizeAtCompileTime==Dynamic ? 0 : VectorType::SizeAtCompileTime;
|
||||
low = internal::random<Scalar>();
|
||||
m = VectorType::LinSpaced(n0,low,low-1);
|
||||
VERIFY(m.size()==n0);
|
||||
|
||||
if(VectorType::SizeAtCompileTime==Dynamic)
|
||||
{
|
||||
VERIFY_IS_EQUAL(VectorType::LinSpaced(n0,0,Scalar(n0-1)).sum(),Scalar(0));
|
||||
VERIFY_IS_EQUAL(VectorType::LinSpaced(n0,low,low-1).sum(),Scalar(0));
|
||||
}
|
||||
|
||||
m.setLinSpaced(n0,0,Scalar(n0-1));
|
||||
VERIFY(m.size()==n0);
|
||||
m.setLinSpaced(n0,low,low-1);
|
||||
VERIFY(m.size()==n0);
|
||||
|
||||
// empty range only:
|
||||
VERIFY_IS_APPROX(VectorType::LinSpaced(size,low,low),VectorType::Constant(size,low));
|
||||
m.setLinSpaced(size,low,low);
|
||||
VERIFY_IS_APPROX(m,VectorType::Constant(size,low));
|
||||
|
||||
if(NumTraits<Scalar>::IsInteger)
|
||||
{
|
||||
VERIFY_IS_APPROX( VectorType::LinSpaced(size,low,Scalar(low+size-1)), VectorType::LinSpaced(size,Scalar(low+size-1),low).reverse() );
|
||||
|
||||
if(VectorType::SizeAtCompileTime==Dynamic)
|
||||
{
|
||||
// Check negative multiplicator path:
|
||||
for(Index k=1; k<5; ++k)
|
||||
VERIFY_IS_APPROX( VectorType::LinSpaced(size,low,Scalar(low+(size-1)*k)), VectorType::LinSpaced(size,Scalar(low+(size-1)*k),low).reverse() );
|
||||
// Check negative divisor path:
|
||||
for(Index k=1; k<5; ++k)
|
||||
VERIFY_IS_APPROX( VectorType::LinSpaced(size*k,low,Scalar(low+size-1)), VectorType::LinSpaced(size*k,Scalar(low+size-1),low).reverse() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
@ -198,7 +237,8 @@ void test_nullary()
|
||||
CALL_SUBTEST_8( testVectorType(Matrix<float,8,1>()) );
|
||||
CALL_SUBTEST_8( testVectorType(Matrix<float,1,1>()) );
|
||||
|
||||
CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(1,300))) );
|
||||
CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(1,10))) );
|
||||
CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(9,300))) );
|
||||
CALL_SUBTEST_9( testVectorType(Matrix<int,1,1>()) );
|
||||
}
|
||||
|
||||
|
@ -485,6 +485,10 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
|
||||
SparseMatrixType m2(rows, cols);
|
||||
initSparse<Scalar>(density, refMat2, m2);
|
||||
VERIFY_IS_APPROX(m2.diagonal(), refMat2.diagonal().eval());
|
||||
DenseVector d = m2.diagonal();
|
||||
VERIFY_IS_APPROX(d, refMat2.diagonal().eval());
|
||||
d = m2.diagonal().array();
|
||||
VERIFY_IS_APPROX(d, refMat2.diagonal().eval());
|
||||
VERIFY_IS_APPROX(const_cast<const SparseMatrixType&>(m2).diagonal(), refMat2.diagonal().eval());
|
||||
|
||||
initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag);
|
||||
|
@ -56,7 +56,7 @@ void pack_simple(Scalar * dst, const Scalar * src, Index cols, Index rows, Index
|
||||
} else {
|
||||
// Naive memcpy calls
|
||||
for (Index col = 0; col < cols; ++col) {
|
||||
memcpy(dst + col*lddst, src + col*ldsrc, rows*sizeof(Scalar));
|
||||
internal::fast_memcpy(dst + col*lddst, src + col*ldsrc, rows*sizeof(Scalar));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ struct DefaultDevice {
|
||||
internal::aligned_free(buffer);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void memcpy(void* dst, const void* src, size_t n) const {
|
||||
::memcpy(dst, src, n);
|
||||
internal::fast_memcpy(dst, src, n);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void memcpyHostToDevice(void* dst, const void* src, size_t n) const {
|
||||
memcpy(dst, src, n);
|
||||
|
@ -106,7 +106,7 @@ struct ThreadPoolDevice {
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE void memcpy(void* dst, const void* src, size_t n) const {
|
||||
::memcpy(dst, src, n);
|
||||
internal::fast_memcpy(dst, src, n);
|
||||
}
|
||||
EIGEN_STRONG_INLINE void memcpyHostToDevice(void* dst, const void* src, size_t n) const {
|
||||
memcpy(dst, src, n);
|
||||
|
@ -253,7 +253,7 @@ struct TensorEvaluator<const TensorFFTOp<FFT, ArgType, FFTResultType, FFTDir>, D
|
||||
// get data into line_buf
|
||||
const Index stride = m_strides[dim];
|
||||
if (stride == 1) {
|
||||
memcpy(line_buf, &buf[base_offset], line_len*sizeof(ComplexScalar));
|
||||
m_device.memcpy(line_buf, &buf[base_offset], line_len*sizeof(ComplexScalar));
|
||||
} else {
|
||||
Index offset = base_offset;
|
||||
for (int j = 0; j < line_len; ++j, offset += stride) {
|
||||
@ -271,7 +271,7 @@ struct TensorEvaluator<const TensorFFTOp<FFT, ArgType, FFTResultType, FFTDir>, D
|
||||
|
||||
// write back
|
||||
if (FFTDir == FFT_FORWARD && stride == 1) {
|
||||
memcpy(&buf[base_offset], line_buf, line_len*sizeof(ComplexScalar));
|
||||
m_device.memcpy(&buf[base_offset], line_buf, line_len*sizeof(ComplexScalar));
|
||||
} else {
|
||||
Index offset = base_offset;
|
||||
const ComplexScalar div_factor = ComplexScalar(1.0 / line_len, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user