mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3dc3a0ea2d | ||
|
|
79120a4c63 | ||
|
|
e0412f18fd | ||
|
|
40b0c43bda | ||
|
|
72f3e20e74 | ||
|
|
676a7a3271 | ||
|
|
f843239452 | ||
|
|
a4ab0c6b6a | ||
|
|
ef955ea8e5 | ||
|
|
3ec11d8f17 | ||
|
|
ec067ac5e3 | ||
|
|
316969d839 | ||
|
|
7a0a9581b5 | ||
|
|
8880be60fa | ||
|
|
e41713d52e | ||
|
|
b69e465d7a | ||
|
|
0db83fc571 | ||
|
|
1ac703f641 | ||
|
|
2c32368642 | ||
|
|
db40309e70 | ||
|
|
e36c1f7501 | ||
|
|
3aef5c1a2f | ||
|
|
ab6bb89980 | ||
|
|
983ace99d4 | ||
|
|
72fa6775e8 | ||
|
|
9f25cdf4f6 | ||
|
|
6e5edd68d3 | ||
|
|
e8978ffa99 | ||
|
|
c753fe7cc3 | ||
|
|
e59e345720 | ||
|
|
07c2244440 | ||
|
|
1865dccd58 | ||
|
|
f2e6ee9687 | ||
|
|
9219307e13 | ||
|
|
f2e8f96151 | ||
|
|
faf8af25ed | ||
|
|
106ba41c2a | ||
|
|
87939ea0dd | ||
|
|
e813640aa1 | ||
|
|
612b8f2749 | ||
|
|
ead8e1b796 | ||
|
|
3d4265f2d5 | ||
|
|
d66586ac90 | ||
|
|
44920624fb | ||
|
|
208058b9ad | ||
|
|
b4218b8473 | ||
|
|
3c2f0812f6 | ||
|
|
17bbd82f7d | ||
|
|
e1385337ff | ||
|
|
d367ecb475 | ||
|
|
c3b658b2c9 | ||
|
|
f9d655a8c8 | ||
|
|
ad3e4d1a49 | ||
|
|
222ed66f79 | ||
|
|
6bceebfabf | ||
|
|
2ca3eb8407 | ||
|
|
698205cddf | ||
|
|
2ecb33820f | ||
|
|
a0de6eb4ce | ||
|
|
7962ac1a58 | ||
|
|
9c97b053f3 | ||
|
|
f61b0d56f0 | ||
|
|
5087e016eb | ||
|
|
fa9f5d7170 | ||
|
|
6975534cb2 | ||
|
|
95c6d8db75 | ||
|
|
e0548e9ff3 | ||
|
|
c289ef20f3 | ||
|
|
b8cf157e8c | ||
|
|
b4d2b404b0 | ||
|
|
70fcaf9bd8 | ||
|
|
2f31c6b1d8 | ||
|
|
9e55467b4c | ||
|
|
35bf99c63e | ||
|
|
f9b8729597 | ||
|
|
4b2e7f26aa | ||
|
|
5202bc92e6 | ||
|
|
9d83411cc4 | ||
|
|
556c03a09d | ||
|
|
ce463b9fa4 | ||
|
|
477d1e8192 | ||
|
|
0eaff8fdf2 | ||
|
|
582c96691b | ||
|
|
0b22158d9f | ||
|
|
dafdb0d8a8 | ||
|
|
1d1686c62b | ||
|
|
ad95b924d0 | ||
|
|
9499684320 | ||
|
|
5b6a31626b | ||
|
|
bc3fee2d8e | ||
|
|
eaa9223277 | ||
|
|
c9ba1165e7 | ||
|
|
dd2d5d67ff | ||
|
|
404322b64f | ||
|
|
ce37bae2cd | ||
|
|
3900dbc341 | ||
|
|
5f586c2bd0 | ||
|
|
215f88a417 | ||
|
|
2257f40f4a | ||
|
|
9e0fa0ef6d | ||
|
|
0fddbf3dc7 | ||
|
|
eda635bd58 | ||
|
|
26197bb467 | ||
|
|
772e59d475 | ||
|
|
e8f83cbb5d | ||
|
|
dce584d799 | ||
|
|
0bcef9557d | ||
|
|
2b3c876b2a | ||
|
|
a05f6aad0e | ||
|
|
59187285e1 | ||
|
|
1dd074ea7e | ||
|
|
24fa7a01bd | ||
|
|
e236d3443c | ||
|
|
4ec8833220 | ||
|
|
23aca8a586 | ||
|
|
28bf2bf070 | ||
|
|
a9bb9796e0 | ||
|
|
449883be74 | ||
|
|
91864f85d3 | ||
|
|
723ed92e0e | ||
|
|
d6b9bc1ccd | ||
|
|
0eff51e2ed | ||
|
|
1b7dd46d94 | ||
|
|
b2eb1bf3dc | ||
|
|
fe48c25682 | ||
|
|
0ba6da3470 |
@@ -541,7 +541,8 @@ if (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||
set (_Eigen3_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
|
||||
unset (CMAKE_SIZEOF_VOID_P)
|
||||
write_basic_package_version_file (Eigen3ConfigVersion.cmake
|
||||
VERSION ${EIGEN_VERSION_NUMBER} COMPATIBILITY SameMajorVersion)
|
||||
VERSION ${EIGEN_VERSION_NUMBER}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
set (CMAKE_SIZEOF_VOID_P ${_Eigen3_CMAKE_SIZEOF_VOID_P})
|
||||
|
||||
# The Eigen target will be located in the Eigen3 namespace. Other CMake
|
||||
@@ -551,13 +552,8 @@ if (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||
# CMake even if it has not been installed to a standard directory.
|
||||
export (PACKAGE Eigen3)
|
||||
|
||||
install (EXPORT Eigen3Targets NAMESPACE Eigen3:: DESTINATION
|
||||
${CMAKEPACKAGE_INSTALL_DIR})
|
||||
install (FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3ConfigVersion.cmake
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/UseEigen3.cmake
|
||||
DESTINATION ${CMAKEPACKAGE_INSTALL_DIR})
|
||||
install (EXPORT Eigen3Targets NAMESPACE Eigen3:: DESTINATION ${CMAKEPACKAGE_INSTALL_DIR})
|
||||
|
||||
else (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||
# Fallback to legacy Eigen3Config.cmake without the imported target
|
||||
|
||||
@@ -581,16 +577,20 @@ else (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||
set(PACKAGE_EIGEN_ROOT_DIR ${EIGEN_ROOT_DIR})
|
||||
configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Eigen3ConfigLegacy.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
||||
@ONLY ESCAPE_QUOTES
|
||||
)
|
||||
@ONLY ESCAPE_QUOTES )
|
||||
endif()
|
||||
|
||||
install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UseEigen3.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
||||
DESTINATION ${CMAKEPACKAGE_INSTALL_DIR}
|
||||
)
|
||||
write_basic_package_version_file( Eigen3ConfigVersion.cmake
|
||||
VERSION ${EIGEN_VERSION_NUMBER}
|
||||
COMPATIBILITY SameMajorVersion )
|
||||
|
||||
endif (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||
|
||||
install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UseEigen3.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3ConfigVersion.cmake
|
||||
DESTINATION ${CMAKEPACKAGE_INSTALL_DIR} )
|
||||
|
||||
# Add uninstall target
|
||||
add_custom_target ( uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EigenUninstall.cmake)
|
||||
|
||||
@@ -321,12 +321,16 @@ inline static const char *SimdInstructionSetsInUse(void) {
|
||||
#error Eigen2-support is only available up to version 3.2. Please go to "http://eigen.tuxfamily.org/index.php?title=Eigen2" for further information
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
|
||||
// ensure QNX/QCC support
|
||||
using std::size_t;
|
||||
// gcc 4.6.0 wants std:: for ptrdiff_t
|
||||
using std::ptrdiff_t;
|
||||
|
||||
}
|
||||
|
||||
/** \defgroup Core_Module Core module
|
||||
* This is the main module of Eigen providing dense matrix and vector support
|
||||
* (both fixed and dynamic size) with all the features corresponding to a BLAS library
|
||||
@@ -405,6 +409,7 @@ using std::ptrdiff_t;
|
||||
// on CUDA devices
|
||||
#include "src/Core/arch/CUDA/Complex.h"
|
||||
|
||||
#include "src/Core/IO.h"
|
||||
#include "src/Core/DenseCoeffsBase.h"
|
||||
#include "src/Core/DenseBase.h"
|
||||
#include "src/Core/MatrixBase.h"
|
||||
@@ -452,7 +457,6 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/Redux.h"
|
||||
#include "src/Core/Visitor.h"
|
||||
#include "src/Core/Fuzzy.h"
|
||||
#include "src/Core/IO.h"
|
||||
#include "src/Core/Swap.h"
|
||||
#include "src/Core/CommaInitializer.h"
|
||||
#include "src/Core/GeneralProduct.h"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "src/Core/util/DisableStupidWarnings.h"
|
||||
|
||||
void *qMalloc(size_t size)
|
||||
void *qMalloc(std::size_t size)
|
||||
{
|
||||
return Eigen::internal::aligned_malloc(size);
|
||||
}
|
||||
@@ -24,7 +24,7 @@ void qFree(void *ptr)
|
||||
Eigen::internal::aligned_free(ptr);
|
||||
}
|
||||
|
||||
void *qRealloc(void *ptr, size_t size)
|
||||
void *qRealloc(void *ptr, std::size_t size)
|
||||
{
|
||||
void* newPtr = Eigen::internal::aligned_malloc(size);
|
||||
memcpy(newPtr, ptr, size);
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
|
||||
#include "SparseCore"
|
||||
#include "OrderingMethods"
|
||||
#ifndef EIGEN_MPL2_ONLY
|
||||
#include "SparseCholesky"
|
||||
#endif
|
||||
#include "SparseLU"
|
||||
#include "SparseQR"
|
||||
#include "IterativeLinearSolvers"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "Core"
|
||||
#include <deque>
|
||||
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
|
||||
|
||||
#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "Core"
|
||||
#include <list>
|
||||
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
|
||||
|
||||
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "Core"
|
||||
#include <vector>
|
||||
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
|
||||
|
||||
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
|
||||
|
||||
|
||||
@@ -231,10 +231,16 @@ class Array
|
||||
: Base(other)
|
||||
{ }
|
||||
|
||||
private:
|
||||
struct PrivateType {};
|
||||
public:
|
||||
|
||||
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
|
||||
EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other,
|
||||
typename internal::enable_if<internal::is_convertible<typename OtherDerived::Scalar,Scalar>::value,
|
||||
PrivateType>::type = PrivateType())
|
||||
: Base(other.derived())
|
||||
{ }
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ template<typename Derived> class ArrayBase
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
@@ -188,7 +188,7 @@ ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
@@ -201,7 +201,7 @@ ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::mul_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
@@ -214,7 +214,7 @@ ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::div_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
|
||||
@@ -32,7 +32,8 @@ struct traits<ArrayWrapper<ExpressionType> >
|
||||
// Let's remove NestByRefBit
|
||||
enum {
|
||||
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
|
||||
Flags = Flags0 & ~NestByRefBit
|
||||
LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
|
||||
Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -129,7 +130,8 @@ struct traits<MatrixWrapper<ExpressionType> >
|
||||
// Let's remove NestByRefBit
|
||||
enum {
|
||||
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
|
||||
Flags = Flags0 & ~NestByRefBit
|
||||
LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
|
||||
Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -515,7 +515,7 @@ struct dense_assignment_loop<Kernel, LinearTraversal, CompleteUnrolling>
|
||||
template<typename Kernel>
|
||||
struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC static inline void run(Kernel &kernel)
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
|
||||
{
|
||||
typedef typename Kernel::Scalar Scalar;
|
||||
typedef typename Kernel::PacketType PacketType;
|
||||
@@ -563,7 +563,7 @@ struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, NoUnrolling>
|
||||
template<typename Kernel>
|
||||
struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, InnerUnrolling>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC static inline void run(Kernel &kernel)
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
|
||||
{
|
||||
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
|
||||
typedef typename Kernel::PacketType PacketType;
|
||||
@@ -701,6 +701,26 @@ protected:
|
||||
* Part 5 : Entry point for dense rectangular assignment
|
||||
***************************************************************************/
|
||||
|
||||
template<typename DstXprType,typename SrcXprType, typename Functor>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const Functor &/*func*/)
|
||||
{
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(dst);
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(src);
|
||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||
}
|
||||
|
||||
template<typename DstXprType,typename SrcXprType, typename T1, typename T2>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const internal::assign_op<T1,T2> &/*func*/)
|
||||
{
|
||||
Index dstRows = src.rows();
|
||||
Index dstCols = src.cols();
|
||||
if(((dst.rows()!=dstRows) || (dst.cols()!=dstCols)))
|
||||
dst.resize(dstRows, dstCols);
|
||||
eigen_assert(dst.rows() == dstRows && dst.cols() == dstCols);
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType, typename Functor>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
|
||||
{
|
||||
@@ -711,10 +731,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType
|
||||
|
||||
// NOTE To properly handle A = (A*A.transpose())/s with A rectangular,
|
||||
// we need to resize the destination after the source evaluator has been created.
|
||||
Index dstRows = src.rows();
|
||||
Index dstCols = src.cols();
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
resize_if_allowed(dst, src, func);
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
|
||||
|
||||
@@ -1556,9 +1556,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
|
||||
|
||||
@@ -46,7 +46,7 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
typedef typename remove_reference<LhsNested>::type _LhsNested;
|
||||
typedef typename remove_reference<RhsNested>::type _RhsNested;
|
||||
enum {
|
||||
Flags = _LhsNested::Flags & RowMajorBit
|
||||
Flags = cwise_promote_storage_order<typename traits<Lhs>::StorageKind,typename traits<Rhs>::StorageKind,_LhsNested::Flags & RowMajorBit,_RhsNested::Flags & RowMajorBit>::value
|
||||
};
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
@@ -105,7 +105,7 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename CustomNullaryOp>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
|
||||
{
|
||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
|
||||
@@ -150,7 +150,7 @@ DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename CustomNullaryOp>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
||||
{
|
||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
|
||||
@@ -192,7 +192,7 @@ DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
|
||||
* \sa class CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Constant(Index size, const Scalar& value)
|
||||
{
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value));
|
||||
@@ -208,7 +208,7 @@ DenseBase<Derived>::Constant(Index size, const Scalar& value)
|
||||
* \sa class CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Constant(const Scalar& value)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
@@ -220,7 +220,7 @@ DenseBase<Derived>::Constant(const Scalar& value)
|
||||
* \sa LinSpaced(Index,Scalar,Scalar), setLinSpaced(Index,const Scalar&,const Scalar&)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
@@ -232,7 +232,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const
|
||||
* \sa LinSpaced(Scalar,Scalar)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
@@ -264,7 +264,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig
|
||||
* \sa setLinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
@@ -276,7 +276,7 @@ DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
||||
* Special version for fixed size types which does not require the size parameter.
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
@@ -286,7 +286,7 @@ DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
|
||||
|
||||
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
|
||||
template<typename Derived>
|
||||
bool DenseBase<Derived>::isApproxToConstant
|
||||
EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isApproxToConstant
|
||||
(const Scalar& val, const RealScalar& prec) const
|
||||
{
|
||||
typename internal::nested_eval<Derived,1>::type self(derived());
|
||||
@@ -301,7 +301,7 @@ bool DenseBase<Derived>::isApproxToConstant
|
||||
*
|
||||
* \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
|
||||
template<typename Derived>
|
||||
bool DenseBase<Derived>::isConstant
|
||||
EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isConstant
|
||||
(const Scalar& val, const RealScalar& prec) const
|
||||
{
|
||||
return isApproxToConstant(val, prec);
|
||||
@@ -312,7 +312,7 @@ bool DenseBase<Derived>::isConstant
|
||||
* \sa setConstant(), Constant(), class CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
|
||||
{
|
||||
setConstant(val);
|
||||
}
|
||||
@@ -322,7 +322,7 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
|
||||
* \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
|
||||
{
|
||||
return derived() = Constant(rows(), cols(), val);
|
||||
}
|
||||
@@ -337,7 +337,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
|
||||
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
|
||||
{
|
||||
resize(size);
|
||||
@@ -356,7 +356,7 @@ PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
|
||||
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
|
||||
{
|
||||
resize(rows, cols);
|
||||
@@ -380,7 +380,7 @@ PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
|
||||
* \sa LinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,PacketScalar>(low,high,newSize));
|
||||
@@ -400,7 +400,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, con
|
||||
* \sa LinSpaced(Index,const Scalar&,const Scalar&), setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return setLinSpaced(size(), low, high);
|
||||
@@ -423,7 +423,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low,
|
||||
* \sa Zero(), Zero(Index)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Zero(Index rows, Index cols)
|
||||
{
|
||||
return Constant(rows, cols, Scalar(0));
|
||||
@@ -446,7 +446,7 @@ DenseBase<Derived>::Zero(Index rows, Index cols)
|
||||
* \sa Zero(), Zero(Index,Index)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Zero(Index size)
|
||||
{
|
||||
return Constant(size, Scalar(0));
|
||||
@@ -463,7 +463,7 @@ DenseBase<Derived>::Zero(Index size)
|
||||
* \sa Zero(Index), Zero(Index,Index)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Zero()
|
||||
{
|
||||
return Constant(Scalar(0));
|
||||
@@ -478,7 +478,7 @@ DenseBase<Derived>::Zero()
|
||||
* \sa class CwiseNullaryOp, Zero()
|
||||
*/
|
||||
template<typename Derived>
|
||||
bool DenseBase<Derived>::isZero(const RealScalar& prec) const
|
||||
EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isZero(const RealScalar& prec) const
|
||||
{
|
||||
typename internal::nested_eval<Derived,1>::type self(derived());
|
||||
for(Index j = 0; j < cols(); ++j)
|
||||
@@ -496,7 +496,7 @@ bool DenseBase<Derived>::isZero(const RealScalar& prec) const
|
||||
* \sa class CwiseNullaryOp, Zero()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
|
||||
{
|
||||
return setConstant(Scalar(0));
|
||||
}
|
||||
@@ -511,7 +511,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
|
||||
* \sa DenseBase::setZero(), setZero(Index,Index), class CwiseNullaryOp, DenseBase::Zero()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setZero(Index newSize)
|
||||
{
|
||||
resize(newSize);
|
||||
@@ -529,7 +529,7 @@ PlainObjectBase<Derived>::setZero(Index newSize)
|
||||
* \sa DenseBase::setZero(), setZero(Index), class CwiseNullaryOp, DenseBase::Zero()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setZero(Index rows, Index cols)
|
||||
{
|
||||
resize(rows, cols);
|
||||
@@ -553,7 +553,7 @@ PlainObjectBase<Derived>::setZero(Index rows, Index cols)
|
||||
* \sa Ones(), Ones(Index), isOnes(), class Ones
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Ones(Index rows, Index cols)
|
||||
{
|
||||
return Constant(rows, cols, Scalar(1));
|
||||
@@ -576,7 +576,7 @@ DenseBase<Derived>::Ones(Index rows, Index cols)
|
||||
* \sa Ones(), Ones(Index,Index), isOnes(), class Ones
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Ones(Index newSize)
|
||||
{
|
||||
return Constant(newSize, Scalar(1));
|
||||
@@ -593,7 +593,7 @@ DenseBase<Derived>::Ones(Index newSize)
|
||||
* \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Ones()
|
||||
{
|
||||
return Constant(Scalar(1));
|
||||
@@ -608,7 +608,7 @@ DenseBase<Derived>::Ones()
|
||||
* \sa class CwiseNullaryOp, Ones()
|
||||
*/
|
||||
template<typename Derived>
|
||||
bool DenseBase<Derived>::isOnes
|
||||
EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isOnes
|
||||
(const RealScalar& prec) const
|
||||
{
|
||||
return isApproxToConstant(Scalar(1), prec);
|
||||
@@ -622,7 +622,7 @@ bool DenseBase<Derived>::isOnes
|
||||
* \sa class CwiseNullaryOp, Ones()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
|
||||
{
|
||||
return setConstant(Scalar(1));
|
||||
}
|
||||
@@ -637,7 +637,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
|
||||
* \sa MatrixBase::setOnes(), setOnes(Index,Index), class CwiseNullaryOp, MatrixBase::Ones()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setOnes(Index newSize)
|
||||
{
|
||||
resize(newSize);
|
||||
@@ -655,7 +655,7 @@ PlainObjectBase<Derived>::setOnes(Index newSize)
|
||||
* \sa MatrixBase::setOnes(), setOnes(Index), class CwiseNullaryOp, MatrixBase::Ones()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
|
||||
{
|
||||
resize(rows, cols);
|
||||
@@ -679,7 +679,7 @@ PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
|
||||
* \sa Identity(), setIdentity(), isIdentity()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
|
||||
MatrixBase<Derived>::Identity(Index rows, Index cols)
|
||||
{
|
||||
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
|
||||
@@ -696,7 +696,7 @@ MatrixBase<Derived>::Identity(Index rows, Index cols)
|
||||
* \sa Identity(Index,Index), setIdentity(), isIdentity()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
|
||||
MatrixBase<Derived>::Identity()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
@@ -771,7 +771,7 @@ struct setIdentity_impl<Derived, true>
|
||||
* \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
|
||||
{
|
||||
return internal::setIdentity_impl<Derived>::run(derived());
|
||||
}
|
||||
@@ -787,7 +787,7 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
|
||||
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
|
||||
{
|
||||
derived().resize(rows, cols);
|
||||
return setIdentity();
|
||||
@@ -800,7 +800,7 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index
|
||||
* \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i);
|
||||
@@ -815,7 +815,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
|
||||
* \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return BasisReturnType(SquareMatrixType::Identity(),i);
|
||||
@@ -828,7 +828,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
|
||||
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
|
||||
{ return Derived::Unit(0); }
|
||||
|
||||
/** \returns an expression of the Y axis unit vector (0,1{,0}^*)
|
||||
@@ -838,7 +838,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
|
||||
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
|
||||
{ return Derived::Unit(1); }
|
||||
|
||||
/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*)
|
||||
@@ -848,7 +848,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
|
||||
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
|
||||
{ return Derived::Unit(2); }
|
||||
|
||||
/** \returns an expression of the W axis unit vector (0,0,0,1)
|
||||
@@ -858,7 +858,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
|
||||
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
|
||||
{ return Derived::Unit(3); }
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -296,7 +296,7 @@ template<typename Derived> class DenseBase
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
||||
|
||||
/** \ínternal
|
||||
/** \internal
|
||||
* Copies \a other into *this without evaluating other. \returns a reference to *this.
|
||||
* \deprecated */
|
||||
template<typename OtherDerived>
|
||||
@@ -463,7 +463,17 @@ template<typename Derived> class DenseBase
|
||||
EIGEN_DEVICE_FUNC
|
||||
void visit(Visitor& func) const;
|
||||
|
||||
inline const WithFormat<Derived> format(const IOFormat& fmt) const;
|
||||
/** \returns a WithFormat proxy object allowing to print a matrix the with given
|
||||
* format \a fmt.
|
||||
*
|
||||
* See class IOFormat for some examples.
|
||||
*
|
||||
* \sa class IOFormat, class WithFormat
|
||||
*/
|
||||
inline const WithFormat<Derived> format(const IOFormat& fmt) const
|
||||
{
|
||||
return WithFormat<Derived>(derived(), fmt);
|
||||
}
|
||||
|
||||
/** \returns the unique coefficient of a 1x1 expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
@@ -474,9 +484,9 @@ template<typename Derived> class DenseBase
|
||||
return derived().coeff(0,0);
|
||||
}
|
||||
|
||||
bool all() const;
|
||||
bool any() const;
|
||||
Index count() const;
|
||||
EIGEN_DEVICE_FUNC bool all() const;
|
||||
EIGEN_DEVICE_FUNC bool any() const;
|
||||
EIGEN_DEVICE_FUNC Index count() const;
|
||||
|
||||
typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
|
||||
typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#define EIGEN_MATRIXSTORAGE_H
|
||||
|
||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
|
||||
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X) X; EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
|
||||
#else
|
||||
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
#define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X)
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
@@ -184,12 +184,16 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||
{
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC DenseStorage() {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage() {
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {}
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
@@ -197,7 +201,7 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||
return *this;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||
eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
|
||||
EIGEN_UNUSED_VARIABLE(size);
|
||||
EIGEN_UNUSED_VARIABLE(rows);
|
||||
@@ -343,7 +347,7 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols)
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||
eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
||||
@@ -351,6 +355,7 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||
, m_rows(other.m_rows)
|
||||
, m_cols(other.m_cols)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*m_cols)
|
||||
internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
@@ -403,7 +408,7 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||
else
|
||||
m_data = 0;
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||
}
|
||||
m_rows = rows;
|
||||
m_cols = cols;
|
||||
@@ -422,7 +427,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||
eigen_internal_assert(size==rows*cols && rows==_Rows && cols >=0);
|
||||
EIGEN_UNUSED_VARIABLE(rows);
|
||||
}
|
||||
@@ -430,6 +435,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(_Rows*other.m_cols))
|
||||
, m_cols(other.m_cols)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*_Rows)
|
||||
internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
@@ -477,7 +483,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||
else
|
||||
m_data = 0;
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||
}
|
||||
m_cols = cols;
|
||||
}
|
||||
@@ -495,7 +501,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||
eigen_internal_assert(size==rows*cols && rows>=0 && cols == _Cols);
|
||||
EIGEN_UNUSED_VARIABLE(cols);
|
||||
}
|
||||
@@ -503,6 +509,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*_Cols))
|
||||
, m_rows(other.m_rows)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*_Cols)
|
||||
internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
@@ -550,7 +557,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
|
||||
else
|
||||
m_data = 0;
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
|
||||
}
|
||||
m_rows = rows;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Eigen {
|
||||
* \param MatrixType the type of the object in which we are taking a sub/main/super diagonal
|
||||
* \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal.
|
||||
* A positive value means a superdiagonal, a negative value means a subdiagonal.
|
||||
* You can also use Dynamic so the index can be set at runtime.
|
||||
* You can also use DynamicIndex so the index can be set at runtime.
|
||||
*
|
||||
* The matrix is not required to be square.
|
||||
*
|
||||
|
||||
@@ -51,7 +51,8 @@ struct dot_nocheck<T, U, true>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \returns the dot product of *this with other.
|
||||
/** \fn MatrixBase::dot
|
||||
* \returns the dot product of *this with other.
|
||||
*
|
||||
* \only_for_vectors
|
||||
*
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
namespace Eigen {
|
||||
|
||||
/** \class EigenBase
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
||||
*
|
||||
@@ -128,6 +129,7 @@ template<typename Derived> struct EigenBase
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
call_assignment(derived(), other.derived());
|
||||
@@ -136,6 +138,7 @@ Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
@@ -144,6 +147,7 @@ Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
|
||||
@@ -224,50 +224,65 @@ template<> struct gemv_dense_selector<OnTheRight,ColMajor,true>
|
||||
// on, the other hand it is good for the cache to pack the vector anyways...
|
||||
EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
|
||||
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
|
||||
MightCannotUseDest = (ActualDest::InnerStrideAtCompileTime!=1) || ComplexByReal
|
||||
MightCannotUseDest = (!EvalToDestAtCompileTime) || ComplexByReal
|
||||
};
|
||||
|
||||
gemv_static_vector_if<ResScalar,ActualDest::SizeAtCompileTime,ActualDest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
||||
|
||||
const bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
|
||||
const bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
||||
|
||||
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
||||
|
||||
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
||||
evalToDest ? dest.data() : static_dest.data());
|
||||
|
||||
if(!evalToDest)
|
||||
{
|
||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
Index size = dest.size();
|
||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
#endif
|
||||
if(!alphaIsCompatible)
|
||||
{
|
||||
MappedDest(actualDestPtr, dest.size()).setZero();
|
||||
compatibleAlpha = RhsScalar(1);
|
||||
}
|
||||
else
|
||||
MappedDest(actualDestPtr, dest.size()) = dest;
|
||||
}
|
||||
|
||||
typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
|
||||
typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
|
||||
general_matrix_vector_product
|
||||
<Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
|
||||
actualLhs.rows(), actualLhs.cols(),
|
||||
LhsMapper(actualLhs.data(), actualLhs.outerStride()),
|
||||
RhsMapper(actualRhs.data(), actualRhs.innerStride()),
|
||||
actualDestPtr, 1,
|
||||
compatibleAlpha);
|
||||
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
||||
|
||||
if (!evalToDest)
|
||||
if(!MightCannotUseDest)
|
||||
{
|
||||
if(!alphaIsCompatible)
|
||||
dest.matrix() += actualAlpha * MappedDest(actualDestPtr, dest.size());
|
||||
else
|
||||
dest = MappedDest(actualDestPtr, dest.size());
|
||||
// shortcut if we are sure to be able to use dest directly,
|
||||
// this ease the compiler to generate cleaner and more optimzized code for most common cases
|
||||
general_matrix_vector_product
|
||||
<Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
|
||||
actualLhs.rows(), actualLhs.cols(),
|
||||
LhsMapper(actualLhs.data(), actualLhs.outerStride()),
|
||||
RhsMapper(actualRhs.data(), actualRhs.innerStride()),
|
||||
dest.data(), 1,
|
||||
compatibleAlpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
gemv_static_vector_if<ResScalar,ActualDest::SizeAtCompileTime,ActualDest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
||||
|
||||
const bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
|
||||
const bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
||||
|
||||
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
||||
evalToDest ? dest.data() : static_dest.data());
|
||||
|
||||
if(!evalToDest)
|
||||
{
|
||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
Index size = dest.size();
|
||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
#endif
|
||||
if(!alphaIsCompatible)
|
||||
{
|
||||
MappedDest(actualDestPtr, dest.size()).setZero();
|
||||
compatibleAlpha = RhsScalar(1);
|
||||
}
|
||||
else
|
||||
MappedDest(actualDestPtr, dest.size()) = dest;
|
||||
}
|
||||
|
||||
general_matrix_vector_product
|
||||
<Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
|
||||
actualLhs.rows(), actualLhs.cols(),
|
||||
LhsMapper(actualLhs.data(), actualLhs.outerStride()),
|
||||
RhsMapper(actualRhs.data(), actualRhs.innerStride()),
|
||||
actualDestPtr, 1,
|
||||
compatibleAlpha);
|
||||
|
||||
if (!evalToDest)
|
||||
{
|
||||
if(!alphaIsCompatible)
|
||||
dest.matrix() += actualAlpha * MappedDest(actualDestPtr, dest.size());
|
||||
else
|
||||
dest = MappedDest(actualDestPtr, dest.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -230,7 +230,7 @@ pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(
|
||||
* duplicated to form: {from[0],from[0],from[1],from[1],from[2],from[2],from[3],from[3]}
|
||||
* Currently, this function is only used for scalar * complex products.
|
||||
*/
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
|
||||
ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
||||
/** \internal \returns a packet with elements of \a *from quadrupled.
|
||||
@@ -278,7 +278,7 @@ inline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
|
||||
}
|
||||
|
||||
/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
|
||||
plset(const typename unpacket_traits<Packet>::type& a) { return a; }
|
||||
|
||||
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
|
||||
@@ -482,7 +482,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& fro
|
||||
* by the current computation.
|
||||
*/
|
||||
template<typename Packet, int LoadMode>
|
||||
inline Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
|
||||
{
|
||||
return ploadt<Packet, LoadMode>(from);
|
||||
}
|
||||
|
||||
@@ -105,24 +105,10 @@ class WithFormat
|
||||
}
|
||||
|
||||
protected:
|
||||
const typename ExpressionType::Nested m_matrix;
|
||||
typename ExpressionType::Nested m_matrix;
|
||||
IOFormat m_format;
|
||||
};
|
||||
|
||||
/** \returns a WithFormat proxy object allowing to print a matrix the with given
|
||||
* format \a fmt.
|
||||
*
|
||||
* See class IOFormat for some examples.
|
||||
*
|
||||
* \sa class IOFormat, class WithFormat
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const WithFormat<Derived>
|
||||
DenseBase<Derived>::format(const IOFormat& fmt) const
|
||||
{
|
||||
return WithFormat<Derived>(derived(), fmt);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// NOTE: This helper is kept for backward compatibility with previous code specializing
|
||||
|
||||
@@ -45,6 +45,7 @@ class Inverse : public InverseImpl<XprType,typename internal::traits<XprType>::S
|
||||
public:
|
||||
typedef typename XprType::StorageIndex StorageIndex;
|
||||
typedef typename XprType::PlainObject PlainObject;
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
||||
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
||||
typedef typename internal::ref_selector<Inverse>::type Nested;
|
||||
|
||||
@@ -1061,11 +1061,24 @@ double log(const double &x) { return ::log(x); }
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
|
||||
typename NumTraits<T>::Real abs(const T &x) {
|
||||
typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>::type
|
||||
abs(const T &x) {
|
||||
EIGEN_USING_STD_MATH(abs);
|
||||
return abs(x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
|
||||
typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>::type
|
||||
abs(const T &x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
#if defined(__SYCL_DEVICE_ONLY__)
|
||||
EIGEN_ALWAYS_INLINE float abs(float x) { return cl::sycl::fabs(x); }
|
||||
EIGEN_ALWAYS_INLINE double abs(double x) { return cl::sycl::fabs(x); }
|
||||
#endif // defined(__SYCL_DEVICE_ONLY__)
|
||||
|
||||
#ifdef __CUDACC__
|
||||
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
|
||||
float abs(const float &x) { return ::fabsf(x); }
|
||||
|
||||
@@ -294,7 +294,7 @@ template<typename Derived> class MatrixBase
|
||||
* fuzzy comparison such as isApprox()
|
||||
* \sa isApprox(), operator!= */
|
||||
template<typename OtherDerived>
|
||||
inline bool operator==(const MatrixBase<OtherDerived>& other) const
|
||||
EIGEN_DEVICE_FUNC inline bool operator==(const MatrixBase<OtherDerived>& other) const
|
||||
{ return cwiseEqual(other).all(); }
|
||||
|
||||
/** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other.
|
||||
@@ -302,7 +302,7 @@ template<typename Derived> class MatrixBase
|
||||
* fuzzy comparison such as isApprox()
|
||||
* \sa isApprox(), operator== */
|
||||
template<typename OtherDerived>
|
||||
inline bool operator!=(const MatrixBase<OtherDerived>& other) const
|
||||
EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
|
||||
{ return cwiseNotEqual(other).any(); }
|
||||
|
||||
NoAlias<Derived,Eigen::MatrixBase > noalias();
|
||||
|
||||
@@ -215,6 +215,8 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
|
||||
|
||||
static inline int digits10() { return NumTraits<Scalar>::digits10(); }
|
||||
};
|
||||
|
||||
template<> struct NumTraits<std::string>
|
||||
|
||||
@@ -41,7 +41,7 @@ template<> struct check_rows_cols_for_overflow<Dynamic> {
|
||||
{
|
||||
// http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
|
||||
// we assume Index is signed
|
||||
Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
|
||||
Index max_index = (std::size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
|
||||
bool error = (rows == 0 || cols == 0) ? false
|
||||
: (rows > max_index / cols);
|
||||
if (error)
|
||||
@@ -58,6 +58,28 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct m
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
namespace doxygen {
|
||||
|
||||
// This is a workaround to doxygen not being able to understand the inheritance logic
|
||||
// when it is hidden by the dense_xpr_base helper struct.
|
||||
// Moreover, doxygen fails to include members that are not documented in the declaration body of
|
||||
// MatrixBase if we inherits MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >,
|
||||
// this is why we simply inherits MatrixBase, though this does not make sense.
|
||||
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename Derived> struct dense_xpr_base_dispatcher;
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct dense_xpr_base_dispatcher<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
: public MatrixBase {};
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct dense_xpr_base_dispatcher<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
: public ArrayBase {};
|
||||
|
||||
} // namespace doxygen
|
||||
|
||||
/** \class PlainObjectBase
|
||||
* \ingroup Core_Module
|
||||
* \brief %Dense storage base class for matrices and arrays.
|
||||
@@ -65,26 +87,10 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct m
|
||||
* This class can be extended with the help of the plugin mechanism described on the page
|
||||
* \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN.
|
||||
*
|
||||
* \tparam Derived is the derived type, e.g., a Matrix or Array
|
||||
*
|
||||
* \sa \ref TopicClassHierarchy
|
||||
*/
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
namespace doxygen {
|
||||
|
||||
// this is a workaround to doxygen not being able to understand the inheritance logic
|
||||
// when it is hidden by the dense_xpr_base helper struct.
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename Derived> struct dense_xpr_base_dispatcher;
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct dense_xpr_base_dispatcher<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
: public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct dense_xpr_base_dispatcher<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
: public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
|
||||
|
||||
} // namespace doxygen
|
||||
|
||||
template<typename Derived>
|
||||
class PlainObjectBase : public doxygen::dense_xpr_base_dispatcher<Derived>
|
||||
#else
|
||||
@@ -554,7 +560,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
|
||||
public:
|
||||
|
||||
/** \copydoc DenseBase::operator=(const EigenBase<OtherDerived>&)
|
||||
/** \brief Copies the generic expression \a other into *this.
|
||||
* \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
@@ -805,6 +812,13 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
this->_set_noalias(other);
|
||||
}
|
||||
|
||||
// Initialize an arbitrary matrix from an object convertible to the Derived type.
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Derived& other){
|
||||
this->_set_noalias(other);
|
||||
}
|
||||
|
||||
// Initialize an arbitrary matrix from a generic Eigen expression
|
||||
template<typename T, typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
@@ -827,7 +841,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
this->derived() = r;
|
||||
}
|
||||
|
||||
// For fixed -size arrays:
|
||||
// For fixed-size Array<Scalar,...>
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
|
||||
@@ -839,6 +853,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
Base::setConstant(val0);
|
||||
}
|
||||
|
||||
// For fixed-size Array<Index,...>
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Index& val0,
|
||||
|
||||
@@ -158,10 +158,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<
|
||||
static EIGEN_STRONG_INLINE
|
||||
void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,Scalar> &)
|
||||
{
|
||||
Index dstRows = src.rows();
|
||||
Index dstCols = src.cols();
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||
// FIXME shall we handle nested_eval here?
|
||||
generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs());
|
||||
}
|
||||
@@ -176,10 +173,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::sub_assign_op<
|
||||
static EIGEN_STRONG_INLINE
|
||||
void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,Scalar> &)
|
||||
{
|
||||
Index dstRows = src.rows();
|
||||
Index dstCols = src.cols();
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||
// FIXME shall we handle nested_eval here?
|
||||
generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs());
|
||||
}
|
||||
@@ -213,6 +207,12 @@ struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_sum_op<typename
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<typename OtherXpr, typename Lhs, typename Rhs>
|
||||
struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_difference_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
|
||||
const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename OtherXpr, typename ProductType, typename Func1, typename Func2>
|
||||
struct assignment_from_xpr_op_product
|
||||
{
|
||||
@@ -377,7 +377,6 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct>
|
||||
{
|
||||
LhsNested actual_lhs(lhs);
|
||||
RhsNested actual_rhs(rhs);
|
||||
|
||||
internal::gemv_dense_selector<Side,
|
||||
(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
|
||||
bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)
|
||||
|
||||
@@ -45,7 +45,7 @@ struct traits<SelfAdjointView<MatrixType, UpLo> > : traits<MatrixType>
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME could also be called SelfAdjointWrapper to be consistent with DiagonalWrapper ??
|
||||
|
||||
template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
: public TriangularBase<SelfAdjointView<_MatrixType, UpLo> >
|
||||
{
|
||||
@@ -60,10 +60,12 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
/** \brief The type of coefficients in this matrix */
|
||||
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||
typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
|
||||
|
||||
enum {
|
||||
Mode = internal::traits<SelfAdjointView>::Mode,
|
||||
Flags = internal::traits<SelfAdjointView>::Flags
|
||||
Flags = internal::traits<SelfAdjointView>::Flags,
|
||||
TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0)
|
||||
};
|
||||
typedef typename MatrixType::PlainObject PlainObject;
|
||||
|
||||
@@ -187,6 +189,36 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
TriangularView<typename MatrixType::AdjointReturnType,TriMode> >::type(tmp2);
|
||||
}
|
||||
|
||||
typedef SelfAdjointView<const MatrixConjugateReturnType,Mode> ConjugateReturnType;
|
||||
/** \sa MatrixBase::conjugate() const */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const ConjugateReturnType conjugate() const
|
||||
{ return ConjugateReturnType(m_matrix.conjugate()); }
|
||||
|
||||
typedef SelfAdjointView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
|
||||
/** \sa MatrixBase::adjoint() const */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const AdjointReturnType adjoint() const
|
||||
{ return AdjointReturnType(m_matrix.adjoint()); }
|
||||
|
||||
typedef SelfAdjointView<typename MatrixType::TransposeReturnType,TransposeMode> TransposeReturnType;
|
||||
/** \sa MatrixBase::transpose() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline TransposeReturnType transpose()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
||||
typename MatrixType::TransposeReturnType tmp(m_matrix);
|
||||
return TransposeReturnType(tmp);
|
||||
}
|
||||
|
||||
typedef SelfAdjointView<const typename MatrixType::ConstTransposeReturnType,TransposeMode> ConstTransposeReturnType;
|
||||
/** \sa MatrixBase::transpose() const */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const ConstTransposeReturnType transpose() const
|
||||
{
|
||||
return ConstTransposeReturnType(m_matrix.transpose());
|
||||
}
|
||||
|
||||
/** \returns a const expression of the main diagonal of the matrix \c *this
|
||||
*
|
||||
* This method simply returns the diagonal of the nested expression, thus by-passing the SelfAdjointView decorator.
|
||||
@@ -287,6 +319,7 @@ public:
|
||||
* Implementation of MatrixBase methods
|
||||
***************************************************************************/
|
||||
|
||||
/** This is the const version of MatrixBase::selfadjointView() */
|
||||
template<typename Derived>
|
||||
template<unsigned int UpLo>
|
||||
typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
|
||||
@@ -295,6 +328,15 @@ MatrixBase<Derived>::selfadjointView() const
|
||||
return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived());
|
||||
}
|
||||
|
||||
/** \returns an expression of a symmetric/self-adjoint view extracted from the upper or lower triangular part of the current matrix
|
||||
*
|
||||
* The parameter \a UpLo can be either \c #Upper or \c #Lower
|
||||
*
|
||||
* Example: \include MatrixBase_selfadjointView.cpp
|
||||
* Output: \verbinclude MatrixBase_selfadjointView.out
|
||||
*
|
||||
* \sa class SelfAdjointView
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<unsigned int UpLo>
|
||||
typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Eigen {
|
||||
// TODO generalize the scalar type of 'other'
|
||||
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
||||
{
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::mul_assign_op<Scalar,Scalar>());
|
||||
@@ -23,7 +23,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
|
||||
{
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::add_assign_op<Scalar,Scalar>());
|
||||
@@ -31,7 +31,7 @@ EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
|
||||
{
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::sub_assign_op<Scalar,Scalar>());
|
||||
@@ -39,7 +39,7 @@ EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator/=(const Scalar& other)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator/=(const Scalar& other)
|
||||
{
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::div_assign_op<Scalar,Scalar>());
|
||||
|
||||
@@ -34,12 +34,12 @@ template<typename Decomposition, typename RhsType,typename StorageKind> struct s
|
||||
template<typename Decomposition, typename RhsType>
|
||||
struct solve_traits<Decomposition,RhsType,Dense>
|
||||
{
|
||||
typedef Matrix<typename RhsType::Scalar,
|
||||
typedef typename make_proper_matrix_type<typename RhsType::Scalar,
|
||||
Decomposition::ColsAtCompileTime,
|
||||
RhsType::ColsAtCompileTime,
|
||||
RhsType::PlainObject::Options,
|
||||
Decomposition::MaxColsAtCompileTime,
|
||||
RhsType::MaxColsAtCompileTime> PlainObject;
|
||||
RhsType::MaxColsAtCompileTime>::type PlainObject;
|
||||
};
|
||||
|
||||
template<typename Decomposition, typename RhsType>
|
||||
|
||||
@@ -161,6 +161,7 @@ struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
|
||||
* TriangularView methods
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename MatrixType, unsigned int Mode>
|
||||
template<int Side, typename OtherDerived>
|
||||
void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
|
||||
@@ -188,6 +189,7 @@ TriangularViewImpl<Derived,Mode,Dense>::solve(const MatrixBase<Other>& other) co
|
||||
{
|
||||
return internal::triangular_solve_retval<Side,TriangularViewType,Other>(derived(), other.derived());
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
@@ -170,7 +170,8 @@ MatrixBase<Derived>::stableNorm() const
|
||||
enum {
|
||||
CanAlign = ( (int(DerivedCopyClean::Flags)&DirectAccessBit)
|
||||
|| (int(internal::evaluator<DerivedCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
|
||||
) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT) // ifwe cannot allocate on the stack, then let's not bother about this optimization
|
||||
) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
|
||||
&& (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
|
||||
};
|
||||
typedef typename internal::conditional<CanAlign, Ref<const Matrix<Scalar,Dynamic,1,0,blockSize,1>, internal::evaluator<DerivedCopyClean>::Alignment>,
|
||||
typename DerivedCopyClean::ConstSegmentReturnType>::type SegmentWrapper;
|
||||
|
||||
@@ -470,6 +470,8 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||
* \a Side==OnTheLeft (the default), or the right-inverse-multiply \a other * inverse(\c *this) if
|
||||
* \a Side==OnTheRight.
|
||||
*
|
||||
* Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
|
||||
*
|
||||
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
|
||||
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
|
||||
* is an upper (resp. lower) triangular matrix.
|
||||
@@ -495,6 +497,8 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||
* \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
|
||||
* This function will const_cast it, so constness isn't honored here.
|
||||
*
|
||||
* Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
|
||||
*
|
||||
* See TriangularView:solve() for the details.
|
||||
*/
|
||||
template<int Side, typename OtherDerived>
|
||||
@@ -539,13 +543,14 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
||||
|
||||
template<typename ProductType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha);
|
||||
EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha, bool beta);
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Implementation of triangular evaluation/assignment
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
// FIXME should we keep that possibility
|
||||
template<typename MatrixType, unsigned int Mode>
|
||||
template<typename OtherDerived>
|
||||
@@ -583,6 +588,7 @@ void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBas
|
||||
eigen_assert(Mode == int(OtherDerived::Mode));
|
||||
internal::call_assignment_no_alias(derived(), other.derived());
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* Implementation of TriangularBase methods
|
||||
@@ -944,8 +950,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
|
||||
dst.setZero();
|
||||
dst._assignProduct(src, 1);
|
||||
dst._assignProduct(src, 1, 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -956,7 +961,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_ass
|
||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
||||
{
|
||||
dst._assignProduct(src, 1);
|
||||
dst._assignProduct(src, 1, 1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -967,7 +972,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_ass
|
||||
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
|
||||
{
|
||||
dst._assignProduct(src, -1);
|
||||
dst._assignProduct(src, -1, 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -194,7 +194,8 @@ struct functor_traits<max_coeff_visitor<Scalar> > {
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \returns the minimum of all coefficients of *this and puts in *row and *col its location.
|
||||
/** \fn DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||
* \returns the minimum of all coefficients of *this and puts in *row and *col its location.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visit(), DenseBase::minCoeff()
|
||||
@@ -230,7 +231,8 @@ DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||
return minVisitor.res;
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of *this and puts in *row and *col its location.
|
||||
/** \fn DenseBase<Derived>::maxCoeff(IndexType* rowId, IndexType* colId) const
|
||||
* \returns the maximum of all coefficients of *this and puts in *row and *col its location.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::maxCoeff()
|
||||
|
||||
@@ -395,14 +395,11 @@ template<> EIGEN_STRONG_INLINE Packet4d preduxp<Packet4d>(const Packet4d* vecs)
|
||||
|
||||
template<> EIGEN_STRONG_INLINE float predux<Packet8f>(const Packet8f& a)
|
||||
{
|
||||
Packet8f tmp0 = _mm256_hadd_ps(a,_mm256_permute2f128_ps(a,a,1));
|
||||
tmp0 = _mm256_hadd_ps(tmp0,tmp0);
|
||||
return pfirst(_mm256_hadd_ps(tmp0, tmp0));
|
||||
return predux(Packet4f(_mm_add_ps(_mm256_castps256_ps128(a),_mm256_extractf128_ps(a,1))));
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE double predux<Packet4d>(const Packet4d& a)
|
||||
{
|
||||
Packet4d tmp0 = _mm256_hadd_pd(a,_mm256_permute2f128_pd(a,a,1));
|
||||
return pfirst(_mm256_hadd_pd(tmp0,tmp0));
|
||||
return predux(Packet2d(_mm_add_pd(_mm256_castpd256_pd128(a),_mm256_extractf128_pd(a,1))));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f predux_downto4<Packet8f>(const Packet8f& a)
|
||||
|
||||
@@ -15,14 +15,14 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
static Packet4ui p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_ZERO_);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
|
||||
static Packet4ui p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_MZERO);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
|
||||
#ifdef __VSX__
|
||||
#if defined(_BIG_ENDIAN)
|
||||
static Packet2ul p2ul_CONJ_XOR1 = (Packet2ul) vec_sld((Packet4ui) p2d_ZERO_, (Packet4ui) p2l_ZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
static Packet2ul p2ul_CONJ_XOR2 = (Packet2ul) vec_sld((Packet4ui) p2l_ZERO, (Packet4ui) p2d_ZERO_, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
static Packet2ul p2ul_CONJ_XOR1 = (Packet2ul) vec_sld((Packet4ui) p2d_MZERO, (Packet4ui) p2l_ZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
static Packet2ul p2ul_CONJ_XOR2 = (Packet2ul) vec_sld((Packet4ui) p2l_ZERO, (Packet4ui) p2d_MZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
#else
|
||||
static Packet2ul p2ul_CONJ_XOR1 = (Packet2ul) vec_sld((Packet4ui) p2l_ZERO, (Packet4ui) p2d_ZERO_, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
static Packet2ul p2ul_CONJ_XOR2 = (Packet2ul) vec_sld((Packet4ui) p2d_ZERO_, (Packet4ui) p2l_ZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
static Packet2ul p2ul_CONJ_XOR1 = (Packet2ul) vec_sld((Packet4ui) p2l_ZERO, (Packet4ui) p2d_MZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
static Packet2ul p2ul_CONJ_XOR2 = (Packet2ul) vec_sld((Packet4ui) p2d_MZERO, (Packet4ui) p2l_ZERO, 8);//{ 0x8000000000000000, 0x0000000000000000 };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -65,7 +65,7 @@ template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type;
|
||||
template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
|
||||
{
|
||||
Packet2cf res;
|
||||
if((ptrdiff_t(&from) % 16) == 0)
|
||||
if((std::ptrdiff_t(&from) % 16) == 0)
|
||||
res.v = pload<Packet4f>((const float *)&from);
|
||||
else
|
||||
res.v = ploadu<Packet4f>((const float *)&from);
|
||||
|
||||
@@ -84,8 +84,10 @@ static _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q3, 2.00000000000000000009e0);
|
||||
static _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C1, 0.693145751953125);
|
||||
static _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C2, 1.42860682030941723212e-6);
|
||||
|
||||
#ifdef __POWER8_VECTOR__
|
||||
static Packet2l p2l_1023 = { 1023, 1023 };
|
||||
static Packet2ul p2ul_52 = { 52, 52 };
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ static _EIGEN_DECLARE_CONST_FAST_Packet4i(ZERO, 0); //{ 0, 0, 0, 0,}
|
||||
static _EIGEN_DECLARE_CONST_FAST_Packet4i(ONE,1); //{ 1, 1, 1, 1}
|
||||
static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS16,-16); //{ -16, -16, -16, -16}
|
||||
static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS1,-1); //{ -1, -1, -1, -1}
|
||||
static Packet4f p4f_ZERO_ = (Packet4f) vec_sl((Packet4ui)p4i_MINUS1, (Packet4ui)p4i_MINUS1); //{ 0x80000000, 0x80000000, 0x80000000, 0x80000000}
|
||||
static Packet4f p4f_MZERO = (Packet4f) vec_sl((Packet4ui)p4i_MINUS1, (Packet4ui)p4i_MINUS1); //{ 0x80000000, 0x80000000, 0x80000000, 0x80000000}
|
||||
#ifndef __VSX__
|
||||
static Packet4f p4f_ONE = vec_ctf(p4i_ONE, 0); //{ 1.0, 1.0, 1.0, 1.0}
|
||||
#endif
|
||||
@@ -90,7 +90,7 @@ static Packet16uc p16uc_DUPLICATE32_HI = { 0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7 };
|
||||
#define _EIGEN_MASK_ALIGNMENT 0xfffffff0
|
||||
#endif
|
||||
|
||||
#define _EIGEN_ALIGNED_PTR(x) ((ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT)
|
||||
#define _EIGEN_ALIGNED_PTR(x) ((std::ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT)
|
||||
|
||||
// Handle endianness properly while loading constants
|
||||
// Define global static constants:
|
||||
@@ -358,7 +358,7 @@ template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return p4i_
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_madd(a,b, p4f_ZERO); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_madd(a,b, p4f_MZERO); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b) { return a * b; }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const Packet4f& b)
|
||||
@@ -373,7 +373,7 @@ template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const
|
||||
t = vec_nmsub(y_0, b, p4f_ONE);
|
||||
y_1 = vec_madd(y_0, t, y_0);
|
||||
|
||||
return vec_madd(a, y_1, p4f_ZERO);
|
||||
return vec_madd(a, y_1, p4f_MZERO);
|
||||
#else
|
||||
return vec_div(a, b);
|
||||
#endif
|
||||
@@ -450,15 +450,15 @@ template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from)
|
||||
template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
|
||||
{
|
||||
Packet4f p;
|
||||
if((ptrdiff_t(from) % 16) == 0) p = pload<Packet4f>(from);
|
||||
else p = ploadu<Packet4f>(from);
|
||||
if((std::ptrdiff_t(from) % 16) == 0) p = pload<Packet4f>(from);
|
||||
else p = ploadu<Packet4f>(from);
|
||||
return vec_perm(p, p, p16uc_DUPLICATE32_HI);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
|
||||
{
|
||||
Packet4i p;
|
||||
if((ptrdiff_t(from) % 16) == 0) p = pload<Packet4i>(from);
|
||||
else p = ploadu<Packet4i>(from);
|
||||
if((std::ptrdiff_t(from) % 16) == 0) p = pload<Packet4i>(from);
|
||||
else p = ploadu<Packet4i>(from);
|
||||
return vec_perm(p, p, p16uc_DUPLICATE32_HI);
|
||||
}
|
||||
|
||||
@@ -766,7 +766,7 @@ static Packet2l p2l_ONE = { 1, 1 };
|
||||
static Packet2l p2l_ZERO = reinterpret_cast<Packet2l>(p4i_ZERO);
|
||||
static Packet2d p2d_ONE = { 1.0, 1.0 };
|
||||
static Packet2d p2d_ZERO = reinterpret_cast<Packet2d>(p4f_ZERO);
|
||||
static Packet2d p2d_ZERO_ = { -0.0, -0.0 };
|
||||
static Packet2d p2d_MZERO = { -0.0, -0.0 };
|
||||
|
||||
#ifdef _BIG_ENDIAN
|
||||
static Packet2d p2d_COUNTDOWN = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4f>(p2d_ZERO), reinterpret_cast<Packet4f>(p2d_ONE), 8));
|
||||
@@ -904,7 +904,7 @@ template<> EIGEN_STRONG_INLINE Packet2d pnegate(const Packet2d& a) { return p2d_
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pconj(const Packet2d& a) { return a; }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_madd(a,b,p2d_ZERO); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_madd(a,b,p2d_MZERO); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pdiv<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_div(a,b); }
|
||||
|
||||
// for some weird raisons, it has to be overloaded for packet of integers
|
||||
@@ -935,8 +935,8 @@ template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from)
|
||||
template<> EIGEN_STRONG_INLINE Packet2d ploaddup<Packet2d>(const double* from)
|
||||
{
|
||||
Packet2d p;
|
||||
if((ptrdiff_t(from) % 16) == 0) p = pload<Packet2d>(from);
|
||||
else p = ploadu<Packet2d>(from);
|
||||
if((std::ptrdiff_t(from) % 16) == 0) p = pload<Packet2d>(from);
|
||||
else p = ploadu<Packet2d>(from);
|
||||
return vec_splat_dbl<0>(p);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted.
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
@@ -474,9 +474,59 @@ template<> struct is_arithmetic<half> { enum { value = true }; };
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct numeric_limits<Eigen::half> {
|
||||
static const bool is_specialized = true;
|
||||
static const bool is_signed = true;
|
||||
static const bool is_integer = false;
|
||||
static const bool is_exact = false;
|
||||
static const bool has_infinity = true;
|
||||
static const bool has_quiet_NaN = true;
|
||||
static const bool has_signaling_NaN = true;
|
||||
static const float_denorm_style has_denorm = denorm_present;
|
||||
static const bool has_denorm_loss = false;
|
||||
static const std::float_round_style round_style = std::round_to_nearest;
|
||||
static const bool is_iec559 = false;
|
||||
static const bool is_bounded = false;
|
||||
static const bool is_modulo = false;
|
||||
static const int digits = 11;
|
||||
static const int digits10 = 2;
|
||||
//static const int max_digits10 = ;
|
||||
static const int radix = 2;
|
||||
static const int min_exponent = -13;
|
||||
static const int min_exponent10 = -4;
|
||||
static const int max_exponent = 16;
|
||||
static const int max_exponent10 = 4;
|
||||
static const bool traps = true;
|
||||
static const bool tinyness_before = false;
|
||||
|
||||
static Eigen::half (min)() { return Eigen::half_impl::raw_uint16_to_half(0x400); }
|
||||
static Eigen::half lowest() { return Eigen::half_impl::raw_uint16_to_half(0xfbff); }
|
||||
static Eigen::half (max)() { return Eigen::half_impl::raw_uint16_to_half(0x7bff); }
|
||||
static Eigen::half epsilon() { return Eigen::half_impl::raw_uint16_to_half(0x0800); }
|
||||
static Eigen::half round_error() { return Eigen::half(0.5); }
|
||||
static Eigen::half infinity() { return Eigen::half_impl::raw_uint16_to_half(0x7c00); }
|
||||
static Eigen::half quiet_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
|
||||
static Eigen::half signaling_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
|
||||
static Eigen::half denorm_min() { return Eigen::half_impl::raw_uint16_to_half(0x1); }
|
||||
};
|
||||
}
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<> struct NumTraits<Eigen::half>
|
||||
: GenericNumTraits<Eigen::half>
|
||||
{
|
||||
enum {
|
||||
IsSigned = true,
|
||||
IsInteger = false,
|
||||
IsComplex = false,
|
||||
RequireInitialization = false
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Eigen::half epsilon() {
|
||||
return half_impl::raw_uint16_to_half(0x0800);
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ template<> EIGEN_DEVICE_FUNC inline double2 pabs<double2>(const double2& a) {
|
||||
|
||||
EIGEN_DEVICE_FUNC inline void
|
||||
ptranspose(PacketBlock<float4,4>& kernel) {
|
||||
double tmp = kernel.packet[0].y;
|
||||
float tmp = kernel.packet[0].y;
|
||||
kernel.packet[0].y = kernel.packet[1].x;
|
||||
kernel.packet[1].x = tmp;
|
||||
|
||||
|
||||
@@ -28,11 +28,13 @@ namespace internal {
|
||||
#define EIGEN_HAS_SINGLE_INSTRUCTION_CJMADD
|
||||
#endif
|
||||
|
||||
// FIXME NEON has 16 quad registers, but since the current register allocator
|
||||
// is so bad, it is much better to reduce it to 8
|
||||
#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS
|
||||
#if EIGEN_ARCH_ARM64
|
||||
#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 32
|
||||
#else
|
||||
#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 16
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef float32x2_t Packet2f;
|
||||
typedef float32x4_t Packet4f;
|
||||
@@ -44,19 +46,22 @@ typedef uint32x4_t Packet4ui;
|
||||
const Packet4f p4f_##NAME = pset1<Packet4f>(X)
|
||||
|
||||
#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \
|
||||
const Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1<int>(X))
|
||||
const Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1<int32_t>(X))
|
||||
|
||||
#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \
|
||||
const Packet4i p4i_##NAME = pset1<Packet4i>(X)
|
||||
|
||||
// arm64 does have the pld instruction. If available, let's trust the __builtin_prefetch built-in function
|
||||
// which available on LLVM and GCC (at least)
|
||||
#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC
|
||||
#if EIGEN_ARCH_ARM64
|
||||
// __builtin_prefetch tends to do nothing on ARM64 compilers because the
|
||||
// prefetch instructions there are too detailed for __builtin_prefetch to map
|
||||
// meaningfully to them.
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__("prfm pldl1keep, [%[addr]]\n" ::[addr] "r"(ADDR) : );
|
||||
#elif EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR);
|
||||
#elif defined __pld
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR)
|
||||
#elif !EIGEN_ARCH_ARM64
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ( " pld [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" );
|
||||
#elif EIGEN_ARCH_ARM32
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ("pld [%[addr]]\n" :: [addr] "r" (ADDR) : );
|
||||
#else
|
||||
// by default no explicit prefetching
|
||||
#define EIGEN_ARM_PREFETCH(ADDR)
|
||||
@@ -81,7 +86,7 @@ template<> struct packet_traits<float> : default_packet_traits
|
||||
HasSqrt = 0
|
||||
};
|
||||
};
|
||||
template<> struct packet_traits<int> : default_packet_traits
|
||||
template<> struct packet_traits<int32_t> : default_packet_traits
|
||||
{
|
||||
typedef Packet4i type;
|
||||
typedef Packet4i half; // Packet2i intrinsics not implemented yet
|
||||
@@ -103,19 +108,19 @@ EIGEN_STRONG_INLINE void vst1q_f32(float* to, float32x4_t from) { ::vst1q
|
||||
EIGEN_STRONG_INLINE void vst1_f32 (float* to, float32x2_t from) { ::vst1_f32 ((float32_t*)to,from); }
|
||||
#endif
|
||||
|
||||
template<> struct unpacket_traits<Packet4f> { typedef float type; enum {size=4, alignment=Aligned16}; typedef Packet4f half; };
|
||||
template<> struct unpacket_traits<Packet4i> { typedef int type; enum {size=4, alignment=Aligned16}; typedef Packet4i half; };
|
||||
template<> struct unpacket_traits<Packet4f> { typedef float type; enum {size=4, alignment=Aligned16}; typedef Packet4f half; };
|
||||
template<> struct unpacket_traits<Packet4i> { typedef int32_t type; enum {size=4, alignment=Aligned16}; typedef Packet4i half; };
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float& from) { return vdupq_n_f32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int& from) { return vdupq_n_s32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int32_t& from) { return vdupq_n_s32(from); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f plset<Packet4f>(const float& a)
|
||||
{
|
||||
const float32_t f[] = {0, 1, 2, 3};
|
||||
const float f[] = {0, 1, 2, 3};
|
||||
Packet4f countdown = vld1q_f32(f);
|
||||
return vaddq_f32(pset1<Packet4f>(a), countdown);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i plset<Packet4i>(const int& a)
|
||||
template<> EIGEN_STRONG_INLINE Packet4i plset<Packet4i>(const int32_t& a)
|
||||
{
|
||||
const int32_t i[] = {0, 1, 2, 3};
|
||||
Packet4i countdown = vld1q_s32(i);
|
||||
@@ -238,20 +243,20 @@ template<> EIGEN_STRONG_INLINE Packet4f pandnot<Packet4f>(const Packet4f& a, con
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pandnot<Packet4i>(const Packet4i& a, const Packet4i& b) { return vbicq_s32(a,b); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int32_t* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_s32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f32(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int32_t* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_s32(from); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
|
||||
template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
|
||||
{
|
||||
float32x2_t lo, hi;
|
||||
lo = vld1_dup_f32(from);
|
||||
hi = vld1_dup_f32(from+1);
|
||||
return vcombine_f32(lo, hi);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
|
||||
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int32_t* from)
|
||||
{
|
||||
int32x2_t lo, hi;
|
||||
lo = vld1_dup_s32(from);
|
||||
@@ -259,11 +264,11 @@ template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
|
||||
return vcombine_s32(lo, hi);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE void pstore<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); }
|
||||
template<> EIGEN_STRONG_INLINE void pstore<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); }
|
||||
template<> EIGEN_STRONG_INLINE void pstore<float> (float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); }
|
||||
template<> EIGEN_STRONG_INLINE void pstore<int32_t>(int32_t* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<float> (float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<int32_t>(int32_t* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); }
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline Packet4f pgather<float, Packet4f>(const float* from, Index stride)
|
||||
{
|
||||
@@ -274,7 +279,7 @@ template<> EIGEN_DEVICE_FUNC inline Packet4f pgather<float, Packet4f>(const floa
|
||||
res = vsetq_lane_f32(from[3*stride], res, 3);
|
||||
return res;
|
||||
}
|
||||
template<> EIGEN_DEVICE_FUNC inline Packet4i pgather<int, Packet4i>(const int* from, Index stride)
|
||||
template<> EIGEN_DEVICE_FUNC inline Packet4i pgather<int32_t, Packet4i>(const int32_t* from, Index stride)
|
||||
{
|
||||
Packet4i res = pset1<Packet4i>(0);
|
||||
res = vsetq_lane_s32(from[0*stride], res, 0);
|
||||
@@ -291,7 +296,7 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter<float, Packet4f>(float* to, co
|
||||
to[stride*2] = vgetq_lane_f32(from, 2);
|
||||
to[stride*3] = vgetq_lane_f32(from, 3);
|
||||
}
|
||||
template<> EIGEN_DEVICE_FUNC inline void pscatter<int, Packet4i>(int* to, const Packet4i& from, Index stride)
|
||||
template<> EIGEN_DEVICE_FUNC inline void pscatter<int32_t, Packet4i>(int32_t* to, const Packet4i& from, Index stride)
|
||||
{
|
||||
to[stride*0] = vgetq_lane_s32(from, 0);
|
||||
to[stride*1] = vgetq_lane_s32(from, 1);
|
||||
@@ -299,12 +304,12 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter<int, Packet4i>(int* to, const
|
||||
to[stride*3] = vgetq_lane_s32(from, 3);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { EIGEN_ARM_PREFETCH(addr); }
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { EIGEN_ARM_PREFETCH(addr); }
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<float> (const float* addr) { EIGEN_ARM_PREFETCH(addr); }
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<int32_t>(const int32_t* addr) { EIGEN_ARM_PREFETCH(addr); }
|
||||
|
||||
// FIXME only store the 2 first elements ?
|
||||
template<> EIGEN_STRONG_INLINE float pfirst<Packet4f>(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; }
|
||||
template<> EIGEN_STRONG_INLINE int pfirst<Packet4i>(const Packet4i& a) { int EIGEN_ALIGN16 x[4]; vst1q_s32(x, a); return x[0]; }
|
||||
template<> EIGEN_STRONG_INLINE float pfirst<Packet4f>(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; }
|
||||
template<> EIGEN_STRONG_INLINE int32_t pfirst<Packet4i>(const Packet4i& a) { int32_t EIGEN_ALIGN16 x[4]; vst1q_s32(x, a); return x[0]; }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) {
|
||||
float32x2_t a_lo, a_hi;
|
||||
@@ -359,7 +364,7 @@ template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE int predux<Packet4i>(const Packet4i& a)
|
||||
template<> EIGEN_STRONG_INLINE int32_t predux<Packet4i>(const Packet4i& a)
|
||||
{
|
||||
int32x2_t a_lo, a_hi, sum;
|
||||
|
||||
@@ -406,7 +411,7 @@ template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a)
|
||||
|
||||
return vget_lane_f32(prod, 0);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE int predux_mul<Packet4i>(const Packet4i& a)
|
||||
template<> EIGEN_STRONG_INLINE int32_t predux_mul<Packet4i>(const Packet4i& a)
|
||||
{
|
||||
int32x2_t a_lo, a_hi, prod;
|
||||
|
||||
@@ -434,7 +439,7 @@ template<> EIGEN_STRONG_INLINE float predux_min<Packet4f>(const Packet4f& a)
|
||||
return vget_lane_f32(min, 0);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE int predux_min<Packet4i>(const Packet4i& a)
|
||||
template<> EIGEN_STRONG_INLINE int32_t predux_min<Packet4i>(const Packet4i& a)
|
||||
{
|
||||
int32x2_t a_lo, a_hi, min;
|
||||
|
||||
@@ -459,7 +464,7 @@ template<> EIGEN_STRONG_INLINE float predux_max<Packet4f>(const Packet4f& a)
|
||||
return vget_lane_f32(max, 0);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a)
|
||||
template<> EIGEN_STRONG_INLINE int32_t predux_max<Packet4i>(const Packet4i& a)
|
||||
{
|
||||
int32x2_t a_lo, a_hi, max;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace internal {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined EIGEN_VECTORIZE_AVX) && EIGEN_COMP_GNUC_STRICT && (__GXX_ABI_VERSION < 1004)
|
||||
#if (defined EIGEN_VECTORIZE_AVX) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_MINGW) && (__GXX_ABI_VERSION < 1004)
|
||||
// With GCC's default ABI version, a __m128 or __m256 are the same types and therefore we cannot
|
||||
// have overloads for both types without linking error.
|
||||
// One solution is to increase ABI version using -fabi-version=4 (or greater).
|
||||
@@ -504,30 +504,13 @@ template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
|
||||
{
|
||||
return _mm_hadd_ps(_mm_hadd_ps(vecs[0], vecs[1]),_mm_hadd_ps(vecs[2], vecs[3]));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs)
|
||||
{
|
||||
return _mm_hadd_pd(vecs[0], vecs[1]);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
Packet4f tmp0 = _mm_hadd_ps(a,a);
|
||||
return pfirst<Packet4f>(_mm_hadd_ps(tmp0, tmp0));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a) { return pfirst<Packet2d>(_mm_hadd_pd(a, a)); }
|
||||
#else
|
||||
// SSE2 versions
|
||||
template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
Packet4f tmp = _mm_add_ps(a, _mm_movehl_ps(a,a));
|
||||
return pfirst<Packet4f>(_mm_add_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a)
|
||||
{
|
||||
return pfirst<Packet2d>(_mm_add_sd(a, _mm_unpackhi_pd(a,a)));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
|
||||
{
|
||||
Packet4f tmp0, tmp1, tmp2;
|
||||
@@ -548,6 +531,29 @@ template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs)
|
||||
}
|
||||
#endif // SSE3
|
||||
|
||||
template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a)
|
||||
{
|
||||
// Disable SSE3 _mm_hadd_pd that is extremely slow on all existing Intel's architectures
|
||||
// (from Nehalem to Haswell)
|
||||
// #ifdef EIGEN_VECTORIZE_SSE3
|
||||
// Packet4f tmp = _mm_add_ps(a, vec4f_swizzle1(a,2,3,2,3));
|
||||
// return pfirst<Packet4f>(_mm_hadd_ps(tmp, tmp));
|
||||
// #else
|
||||
Packet4f tmp = _mm_add_ps(a, _mm_movehl_ps(a,a));
|
||||
return pfirst<Packet4f>(_mm_add_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
|
||||
// #endif
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a)
|
||||
{
|
||||
// Disable SSE3 _mm_hadd_pd that is extremely slow on all existing Intel's architectures
|
||||
// (from Nehalem to Haswell)
|
||||
// #ifdef EIGEN_VECTORIZE_SSE3
|
||||
// return pfirst<Packet2d>(_mm_hadd_pd(a, a));
|
||||
// #else
|
||||
return pfirst<Packet2d>(_mm_add_sd(a, _mm_unpackhi_pd(a,a)));
|
||||
// #endif
|
||||
}
|
||||
|
||||
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||
template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs)
|
||||
|
||||
@@ -100,7 +100,7 @@ static Packet16uc p16uc_DUPLICATE32_HI = { 0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7 };
|
||||
// Mask alignment
|
||||
#define _EIGEN_MASK_ALIGNMENT 0xfffffffffffffff0
|
||||
|
||||
#define _EIGEN_ALIGNED_PTR(x) ((ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT)
|
||||
#define _EIGEN_ALIGNED_PTR(x) ((std::ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT)
|
||||
|
||||
// Handle endianness properly while loading constants
|
||||
// Define global static constants:
|
||||
|
||||
@@ -28,7 +28,7 @@ template<typename DstScalar,typename SrcScalar> struct assign_op {
|
||||
{ internal::pstoret<DstScalar,Packet,Alignment>(a,b); }
|
||||
};
|
||||
|
||||
// Empty overload for void type (used by PermutationMatrix
|
||||
// Empty overload for void type (used by PermutationMatrix)
|
||||
template<typename DstScalar> struct assign_op<DstScalar,void> {};
|
||||
|
||||
template<typename DstScalar,typename SrcScalar>
|
||||
|
||||
@@ -44,16 +44,16 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
|
||||
{
|
||||
linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
|
||||
m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)),
|
||||
m_interPacket(plset<Packet>(0)),
|
||||
m_flip(numext::abs(high)<numext::abs(low))
|
||||
{}
|
||||
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const {
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
if(m_flip)
|
||||
return (i==0)? m_low : (m_high - (m_size1-i)*m_step);
|
||||
return (i==0)? m_low : (m_high - RealScalar(m_size1-i)*m_step);
|
||||
else
|
||||
return (i==m_size1)? m_high : (m_low + i*m_step);
|
||||
return (i==m_size1)? m_high : (m_low + RealScalar(i)*m_step);
|
||||
}
|
||||
|
||||
template<typename IndexType>
|
||||
@@ -63,7 +63,7 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
|
||||
// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
|
||||
if(m_flip)
|
||||
{
|
||||
Packet pi = padd(pset1<Packet>(Scalar(i-m_size1)),m_interPacket);
|
||||
Packet pi = plset<Packet>(Scalar(i-m_size1));
|
||||
Packet res = padd(pset1<Packet>(m_high), pmul(pset1<Packet>(m_step), pi));
|
||||
if(i==0)
|
||||
res = pinsertfirst(res, m_low);
|
||||
@@ -71,7 +71,7 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
|
||||
}
|
||||
else
|
||||
{
|
||||
Packet pi = padd(pset1<Packet>(Scalar(i)),m_interPacket);
|
||||
Packet pi = plset<Packet>(Scalar(i));
|
||||
Packet res = padd(pset1<Packet>(m_low), pmul(pset1<Packet>(m_step), pi));
|
||||
if(i==m_size1-unpacket_traits<Packet>::size+1)
|
||||
res = pinsertlast(res, m_high);
|
||||
@@ -83,7 +83,6 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
|
||||
const Scalar m_high;
|
||||
const Index m_size1;
|
||||
const Scalar m_step;
|
||||
const Packet m_interPacket;
|
||||
const bool m_flip;
|
||||
};
|
||||
|
||||
@@ -93,8 +92,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>
|
||||
|
||||
@@ -72,7 +72,7 @@ template<typename T>
|
||||
struct functor_traits<std::not_equal_to<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
#if(__cplusplus < 201103L)
|
||||
#if (__cplusplus < 201103L) && (EIGEN_COMP_MSVC <= 1900)
|
||||
// std::binder* are deprecated since c++11 and will be removed in c++17
|
||||
template<typename T>
|
||||
struct functor_traits<std::binder2nd<T> >
|
||||
|
||||
@@ -83,8 +83,8 @@ static void run(Index rows, Index cols, Index depth,
|
||||
if(info)
|
||||
{
|
||||
// this is the parallel version!
|
||||
Index tid = omp_get_thread_num();
|
||||
Index threads = omp_get_num_threads();
|
||||
int tid = omp_get_thread_num();
|
||||
int threads = omp_get_num_threads();
|
||||
|
||||
LhsScalar* blockA = blocking.blockA();
|
||||
eigen_internal_assert(blockA!=0);
|
||||
@@ -116,9 +116,9 @@ static void run(Index rows, Index cols, Index depth,
|
||||
info[tid].sync = k;
|
||||
|
||||
// Computes C_i += A' * B' per A'_i
|
||||
for(Index shift=0; shift<threads; ++shift)
|
||||
for(int shift=0; shift<threads; ++shift)
|
||||
{
|
||||
Index i = (tid+shift)%threads;
|
||||
int i = (tid+shift)%threads;
|
||||
|
||||
// At this point we have to make sure that A'_i has been updated by the thread i,
|
||||
// we use testAndSetOrdered to mimic a volatile access.
|
||||
|
||||
@@ -148,7 +148,7 @@ struct tribb_kernel
|
||||
ResMapper res(_res, resStride);
|
||||
gebp_kernel<LhsScalar, RhsScalar, Index, ResMapper, mr, nr, ConjLhs, ConjRhs> gebp_kernel;
|
||||
|
||||
Matrix<ResScalar,BlockSize,BlockSize,ColMajor> buffer;
|
||||
Matrix<ResScalar,BlockSize,BlockSize,ColMajor> buffer((internal::constructor_without_unaligned_array_assert()));
|
||||
|
||||
// let's process the block per panel of actual_mc x BlockSize,
|
||||
// again, each is split into three parts, etc.
|
||||
@@ -199,7 +199,7 @@ struct general_product_to_triangular_selector;
|
||||
template<typename MatrixType, typename ProductType, int UpLo>
|
||||
struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,true>
|
||||
{
|
||||
static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha)
|
||||
static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha, bool beta)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
|
||||
@@ -217,6 +217,9 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,true>
|
||||
|
||||
Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived());
|
||||
|
||||
if(!beta)
|
||||
mat.template triangularView<UpLo>().setZero();
|
||||
|
||||
enum {
|
||||
StorageOrder = (internal::traits<MatrixType>::Flags&RowMajorBit) ? RowMajor : ColMajor,
|
||||
UseLhsDirectly = _ActualLhs::InnerStrideAtCompileTime==1,
|
||||
@@ -244,7 +247,7 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,true>
|
||||
template<typename MatrixType, typename ProductType, int UpLo>
|
||||
struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
|
||||
{
|
||||
static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha)
|
||||
static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha, bool beta)
|
||||
{
|
||||
typedef typename internal::remove_all<typename ProductType::LhsNested>::type Lhs;
|
||||
typedef internal::blas_traits<Lhs> LhsBlasTraits;
|
||||
@@ -260,13 +263,19 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
|
||||
|
||||
typename ProductType::Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived());
|
||||
|
||||
if(!beta)
|
||||
mat.template triangularView<UpLo>().setZero();
|
||||
|
||||
enum {
|
||||
IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0,
|
||||
LhsIsRowMajor = _ActualLhs::Flags&RowMajorBit ? 1 : 0,
|
||||
RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0
|
||||
RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0,
|
||||
SkipDiag = (UpLo&(UnitDiag|ZeroDiag))!=0
|
||||
};
|
||||
|
||||
Index size = mat.cols();
|
||||
if(SkipDiag)
|
||||
size--;
|
||||
Index depth = actualLhs.cols();
|
||||
|
||||
typedef internal::gemm_blocking_space<IsRowMajor ? RowMajor : ColMajor,typename Lhs::Scalar,typename Rhs::Scalar,
|
||||
@@ -277,20 +286,22 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
|
||||
internal::general_matrix_matrix_triangular_product<Index,
|
||||
typename Lhs::Scalar, LhsIsRowMajor ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
|
||||
typename Rhs::Scalar, RhsIsRowMajor ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
|
||||
IsRowMajor ? RowMajor : ColMajor, UpLo>
|
||||
IsRowMajor ? RowMajor : ColMajor, UpLo&(Lower|Upper)>
|
||||
::run(size, depth,
|
||||
&actualLhs.coeffRef(0,0), actualLhs.outerStride(), &actualRhs.coeffRef(0,0), actualRhs.outerStride(),
|
||||
mat.data(), mat.outerStride(), actualAlpha, blocking);
|
||||
&actualLhs.coeffRef(SkipDiag&&(UpLo&Lower)==Lower ? 1 : 0,0), actualLhs.outerStride(),
|
||||
&actualRhs.coeffRef(0,SkipDiag&&(UpLo&Upper)==Upper ? 1 : 0), actualRhs.outerStride(),
|
||||
mat.data() + (SkipDiag ? (bool(IsRowMajor) != ((UpLo&Lower)==Lower) ? 1 : mat.outerStride() ) : 0), mat.outerStride(), actualAlpha, blocking);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename MatrixType, unsigned int UpLo>
|
||||
template<typename ProductType>
|
||||
TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha)
|
||||
TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha, bool beta)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((UpLo&UnitDiag)==0, WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED);
|
||||
eigen_assert(derived().nestedExpression().rows() == prod.rows() && derived().cols() == prod.cols());
|
||||
|
||||
general_product_to_triangular_selector<MatrixType, ProductType, UpLo, internal::traits<ProductType>::InnerSize==1>::run(derived().nestedExpression().const_cast_derived(), prod, alpha);
|
||||
general_product_to_triangular_selector<MatrixType, ProductType, UpLo, internal::traits<ProductType>::InnerSize==1>::run(derived().nestedExpression().const_cast_derived(), prod, alpha, beta);
|
||||
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_BLAS_H
|
||||
#define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_BLAS_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -52,7 +52,7 @@ struct general_matrix_matrix_triangular_product<Index,Scalar,LhsStorageOrder,Con
|
||||
static EIGEN_STRONG_INLINE void run(Index size, Index depth,const Scalar* lhs, Index lhsStride, \
|
||||
const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha, level3_blocking<Scalar, Scalar>& blocking) \
|
||||
{ \
|
||||
if (lhs==rhs) { \
|
||||
if ( lhs==rhs && ((UpLo&(Lower|Upper)==UpLo)) ) { \
|
||||
general_matrix_matrix_rankupdate<Index,Scalar,LhsStorageOrder,ConjugateLhs,ColMajor,UpLo> \
|
||||
::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha,blocking); \
|
||||
} else { \
|
||||
@@ -86,8 +86,8 @@ struct general_matrix_matrix_rankupdate<Index,EIGTYPE,AStorageOrder,ConjugateA,C
|
||||
/* typedef Matrix<EIGTYPE, Dynamic, Dynamic, RhsStorageOrder> MatrixRhs;*/ \
|
||||
\
|
||||
BlasIndex lda=convert_index<BlasIndex>(lhsStride), ldc=convert_index<BlasIndex>(resStride), n=convert_index<BlasIndex>(size), k=convert_index<BlasIndex>(depth); \
|
||||
char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'T':'N'; \
|
||||
EIGTYPE beta; \
|
||||
char uplo=((IsLower) ? 'L' : 'U'), trans=((AStorageOrder==RowMajor) ? 'T':'N'); \
|
||||
EIGTYPE beta(1); \
|
||||
BLASFUNC(&uplo, &trans, &n, &k, &numext::real_ref(alpha), lhs, &lda, &numext::real_ref(beta), res, &ldc); \
|
||||
} \
|
||||
};
|
||||
@@ -107,7 +107,7 @@ struct general_matrix_matrix_rankupdate<Index,EIGTYPE,AStorageOrder,ConjugateA,C
|
||||
typedef Matrix<EIGTYPE, Dynamic, Dynamic, AStorageOrder> MatrixType; \
|
||||
\
|
||||
BlasIndex lda=convert_index<BlasIndex>(lhsStride), ldc=convert_index<BlasIndex>(resStride), n=convert_index<BlasIndex>(size), k=convert_index<BlasIndex>(depth); \
|
||||
char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'C':'N'; \
|
||||
char uplo=((IsLower) ? 'L' : 'U'), trans=((AStorageOrder==RowMajor) ? 'C':'N'); \
|
||||
RTYPE alpha_, beta_; \
|
||||
const EIGTYPE* a_ptr; \
|
||||
\
|
||||
|
||||
@@ -75,7 +75,7 @@ template<typename Index> struct GemmParallelInfo
|
||||
{
|
||||
GemmParallelInfo() : sync(-1), users(0), lhs_start(0), lhs_length(0) {}
|
||||
|
||||
int volatile sync;
|
||||
Index volatile sync;
|
||||
int volatile users;
|
||||
|
||||
Index lhs_start;
|
||||
@@ -104,13 +104,14 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, Index depth,
|
||||
// - the sizes are large enough
|
||||
|
||||
// compute the maximal number of threads from the size of the product:
|
||||
// FIXME this has to be fine tuned
|
||||
// This first heuristic takes into account that the product kernel is fully optimized when working with nr columns at once.
|
||||
Index size = transpose ? rows : cols;
|
||||
Index pb_max_threads = std::max<Index>(1,size / 32);
|
||||
Index pb_max_threads = std::max<Index>(1,size / Functor::Traits::nr);
|
||||
|
||||
// compute the maximal number of threads from the total amount of work:
|
||||
double work = static_cast<double>(rows) * static_cast<double>(cols) *
|
||||
static_cast<double>(depth);
|
||||
double kMinTaskSize = 50000; // Heuristic.
|
||||
double kMinTaskSize = 50000; // FIXME improve this heuristic.
|
||||
pb_max_threads = std::max<Index>(1, std::min<Index>(pb_max_threads, work / kMinTaskSize));
|
||||
|
||||
// compute the number of threads we are going to use
|
||||
|
||||
@@ -83,10 +83,10 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
|
||||
Scalar t3(0);
|
||||
Packet ptmp3 = pset1<Packet>(t3);
|
||||
|
||||
size_t starti = FirstTriangular ? 0 : j+2;
|
||||
size_t endi = FirstTriangular ? j : size;
|
||||
size_t alignedStart = (starti) + internal::first_default_aligned(&res[starti], endi-starti);
|
||||
size_t alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize);
|
||||
Index starti = FirstTriangular ? 0 : j+2;
|
||||
Index endi = FirstTriangular ? j : size;
|
||||
Index alignedStart = (starti) + internal::first_default_aligned(&res[starti], endi-starti);
|
||||
Index alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize);
|
||||
|
||||
res[j] += cjd.pmul(numext::real(A0[j]), t0);
|
||||
res[j+1] += cjd.pmul(numext::real(A1[j+1]), t1);
|
||||
@@ -101,7 +101,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
|
||||
t2 += cj1.pmul(A0[j+1], rhs[j+1]);
|
||||
}
|
||||
|
||||
for (size_t i=starti; i<alignedStart; ++i)
|
||||
for (Index i=starti; i<alignedStart; ++i)
|
||||
{
|
||||
res[i] += cj0.pmul(A0[i], t0) + cj0.pmul(A1[i],t1);
|
||||
t2 += cj1.pmul(A0[i], rhs[i]);
|
||||
@@ -113,7 +113,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
|
||||
const Scalar* EIGEN_RESTRICT a1It = A1 + alignedStart;
|
||||
const Scalar* EIGEN_RESTRICT rhsIt = rhs + alignedStart;
|
||||
Scalar* EIGEN_RESTRICT resIt = res + alignedStart;
|
||||
for (size_t i=alignedStart; i<alignedEnd; i+=PacketSize)
|
||||
for (Index i=alignedStart; i<alignedEnd; i+=PacketSize)
|
||||
{
|
||||
Packet A0i = ploadu<Packet>(a0It); a0It += PacketSize;
|
||||
Packet A1i = ploadu<Packet>(a1It); a1It += PacketSize;
|
||||
@@ -125,7 +125,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
|
||||
ptmp3 = pcj1.pmadd(A1i, Bi, ptmp3);
|
||||
pstore(resIt,Xi); resIt += PacketSize;
|
||||
}
|
||||
for (size_t i=alignedEnd; i<endi; i++)
|
||||
for (Index i=alignedEnd; i<endi; i++)
|
||||
{
|
||||
res[i] += cj0.pmul(A0[i], t0) + cj0.pmul(A1[i],t1);
|
||||
t2 += cj1.pmul(A0[i], rhs[i]);
|
||||
|
||||
@@ -137,7 +137,7 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,true,
|
||||
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
|
||||
ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
|
||||
|
||||
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer;
|
||||
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer((internal::constructor_without_unaligned_array_assert()));
|
||||
triangularBuffer.setZero();
|
||||
if((Mode&ZeroDiag)==ZeroDiag)
|
||||
triangularBuffer.diagonal().setZero();
|
||||
@@ -284,7 +284,7 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,false,
|
||||
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
|
||||
ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
|
||||
|
||||
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer;
|
||||
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer((internal::constructor_without_unaligned_array_assert()));
|
||||
triangularBuffer.setZero();
|
||||
if((Mode&ZeroDiag)==ZeroDiag)
|
||||
triangularBuffer.diagonal().setZero();
|
||||
|
||||
@@ -183,7 +183,7 @@ EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conju
|
||||
}
|
||||
}
|
||||
|
||||
/* Optimized triangular solver with multiple left hand sides and the trinagular matrix on the right
|
||||
/* Optimized triangular solver with multiple left hand sides and the triangular matrix on the right
|
||||
*/
|
||||
template <typename Scalar, typename Index, int Mode, bool Conjugate, int TriStorageOrder>
|
||||
struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorageOrder,ColMajor>
|
||||
@@ -202,6 +202,7 @@ EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conj
|
||||
level3_blocking<Scalar,Scalar>& blocking)
|
||||
{
|
||||
Index rows = otherSize;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
typedef blas_data_mapper<Scalar, Index, ColMajor> LhsMapper;
|
||||
typedef const_blas_data_mapper<Scalar, Index, TriStorageOrder> RhsMapper;
|
||||
@@ -306,9 +307,9 @@ EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conj
|
||||
}
|
||||
if((Mode & UnitDiag)==0)
|
||||
{
|
||||
Scalar b = conj(rhs(j,j));
|
||||
Scalar inv_rjj = RealScalar(1)/conj(rhs(j,j));
|
||||
for (Index i=0; i<actual_mc; ++i)
|
||||
r[i] /= b;
|
||||
r[i] *= inv_rjj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#define EIGEN_WORLD_VERSION 3
|
||||
#define EIGEN_MAJOR_VERSION 3
|
||||
#define EIGEN_MINOR_VERSION 1
|
||||
#define EIGEN_MINOR_VERSION 4
|
||||
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
@@ -80,8 +80,8 @@
|
||||
// 2015 14 1900
|
||||
// "15" 15 1900
|
||||
|
||||
/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC
|
||||
#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC)
|
||||
/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC or clang-cl
|
||||
#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC || EIGEN_COMP_LLVM || EIGEN_COMP_CLANG)
|
||||
#define EIGEN_COMP_MSVC_STRICT _MSC_VER
|
||||
#else
|
||||
#define EIGEN_COMP_MSVC_STRICT 0
|
||||
@@ -356,7 +356,7 @@
|
||||
#define EIGEN_MAX_CPP_VER 99
|
||||
#endif
|
||||
|
||||
#if EIGEN_MAX_CPP_VER>=11 && defined(__cplusplus) && (__cplusplus >= 201103L)
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (defined(__cplusplus) && (__cplusplus >= 201103L) || EIGEN_COMP_MSVC >= 1900)
|
||||
#define EIGEN_HAS_CXX11 1
|
||||
#else
|
||||
#define EIGEN_HAS_CXX11 0
|
||||
@@ -497,10 +497,11 @@
|
||||
// attribute to maximize inlining. This should only be used when really necessary: in particular,
|
||||
// it uses __attribute__((always_inline)) on GCC, which most of the time is useless and can severely harm compile times.
|
||||
// FIXME with the always_inline attribute,
|
||||
// gcc 3.4.x reports the following compilation error:
|
||||
// gcc 3.4.x and 4.1 reports the following compilation error:
|
||||
// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const'
|
||||
// : function body not available
|
||||
#if EIGEN_GNUC_AT_LEAST(4,0)
|
||||
// See also bug 1367
|
||||
#if EIGEN_GNUC_AT_LEAST(4,2)
|
||||
#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) inline
|
||||
#else
|
||||
#define EIGEN_ALWAYS_INLINE EIGEN_STRONG_INLINE
|
||||
@@ -811,7 +812,7 @@ namespace Eigen {
|
||||
// just an empty macro !
|
||||
#define EIGEN_EMPTY
|
||||
|
||||
#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || __CUDACC_VER__) // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
|
||||
#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || defined(__CUDACC_VER__)) // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =;
|
||||
#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
|
||||
|
||||
@@ -150,7 +150,7 @@ EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
|
||||
/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 or 32 bytes alignment depending on the requirements.
|
||||
* On allocation error, the returned pointer is null, and std::bad_alloc is thrown.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC inline void* aligned_malloc(size_t size)
|
||||
EIGEN_DEVICE_FUNC inline void* aligned_malloc(std::size_t size)
|
||||
{
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
@@ -185,7 +185,7 @@ EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
|
||||
* \brief Reallocates an aligned block of memory.
|
||||
* \throws std::bad_alloc on allocation failure
|
||||
*/
|
||||
inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
inline void* aligned_realloc(void *ptr, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(old_size);
|
||||
|
||||
@@ -209,12 +209,12 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
/** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
|
||||
* On allocation error, the returned pointer is null, and a std::bad_alloc is thrown.
|
||||
*/
|
||||
template<bool Align> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(size_t size)
|
||||
template<bool Align> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(std::size_t size)
|
||||
{
|
||||
return aligned_malloc(size);
|
||||
}
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc<false>(size_t size)
|
||||
template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc<false>(std::size_t size)
|
||||
{
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
@@ -235,12 +235,12 @@ template<> EIGEN_DEVICE_FUNC inline void conditional_aligned_free<false>(void *p
|
||||
std::free(ptr);
|
||||
}
|
||||
|
||||
template<bool Align> inline void* conditional_aligned_realloc(void* ptr, size_t new_size, size_t old_size)
|
||||
template<bool Align> inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
return aligned_realloc(ptr, new_size, old_size);
|
||||
}
|
||||
|
||||
template<> inline void* conditional_aligned_realloc<false>(void* ptr, size_t new_size, size_t)
|
||||
template<> inline void* conditional_aligned_realloc<false>(void* ptr, std::size_t new_size, std::size_t)
|
||||
{
|
||||
return std::realloc(ptr, new_size);
|
||||
}
|
||||
@@ -252,7 +252,7 @@ template<> inline void* conditional_aligned_realloc<false>(void* ptr, size_t new
|
||||
/** \internal Destructs the elements of an array.
|
||||
* The \a size parameters tells on how many objects to call the destructor of T.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T *ptr, size_t size)
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T *ptr, std::size_t size)
|
||||
{
|
||||
// always destruct an array starting from the end.
|
||||
if(ptr)
|
||||
@@ -262,9 +262,9 @@ template<typename T> EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T
|
||||
/** \internal Constructs the elements of an array.
|
||||
* The \a size parameter tells on how many objects to call the constructor of T.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *ptr, size_t size)
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *ptr, std::size_t size)
|
||||
{
|
||||
size_t i;
|
||||
std::size_t i;
|
||||
EIGEN_TRY
|
||||
{
|
||||
for (i = 0; i < size; ++i) ::new (ptr + i) T;
|
||||
@@ -283,9 +283,9 @@ template<typename T> EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *
|
||||
*****************************************************************************/
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(size_t size)
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(std::size_t size)
|
||||
{
|
||||
if(size > size_t(-1) / sizeof(T))
|
||||
if(size > std::size_t(-1) / sizeof(T))
|
||||
throw_std_bad_alloc();
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(size_t size)
|
||||
* On allocation error, the returned pointer is undefined, but a std::bad_alloc is thrown.
|
||||
* The default constructor of T is called.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline T* aligned_new(size_t size)
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline T* aligned_new(std::size_t size)
|
||||
{
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
|
||||
@@ -309,7 +309,7 @@ template<typename T> EIGEN_DEVICE_FUNC inline T* aligned_new(size_t size)
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new(size_t size)
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new(std::size_t size)
|
||||
{
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||
@@ -328,7 +328,7 @@ template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned
|
||||
/** \internal Deletes objects constructed with aligned_new
|
||||
* The \a size parameters tells on how many objects to call the destructor of T.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, size_t size)
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, std::size_t size)
|
||||
{
|
||||
destruct_elements_of_array<T>(ptr, size);
|
||||
aligned_free(ptr);
|
||||
@@ -337,13 +337,13 @@ template<typename T> EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, size_t
|
||||
/** \internal Deletes objects constructed with conditional_aligned_new
|
||||
* The \a size parameters tells on how many objects to call the destructor of T.
|
||||
*/
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete(T *ptr, size_t size)
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete(T *ptr, std::size_t size)
|
||||
{
|
||||
destruct_elements_of_array<T>(ptr, size);
|
||||
conditional_aligned_free<Align>(ptr);
|
||||
}
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_realloc_new(T* pts, size_t new_size, size_t old_size)
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_realloc_new(T* pts, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
check_size_for_overflow<T>(new_size);
|
||||
check_size_for_overflow<T>(old_size);
|
||||
@@ -366,7 +366,7 @@ template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned
|
||||
}
|
||||
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new_auto(size_t size)
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new_auto(std::size_t size)
|
||||
{
|
||||
if(size==0)
|
||||
return 0; // short-cut. Also fixes Bug 884
|
||||
@@ -387,7 +387,7 @@ template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(T* pts, size_t new_size, size_t old_size)
|
||||
template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(T* pts, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
check_size_for_overflow<T>(new_size);
|
||||
check_size_for_overflow<T>(old_size);
|
||||
@@ -409,7 +409,7 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete_auto(T *ptr, size_t size)
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete_auto(T *ptr, std::size_t size)
|
||||
{
|
||||
if(NumTraits<T>::RequireInitialization)
|
||||
destruct_elements_of_array<T>(ptr, size);
|
||||
@@ -561,7 +561,7 @@ template<typename T> class aligned_stack_memory_handler : noncopyable
|
||||
* In this case, the buffer elements will also be destructed when this handler will be destructed.
|
||||
* Finally, if \a dealloc is true, then the pointer \a ptr is freed.
|
||||
**/
|
||||
aligned_stack_memory_handler(T* ptr, size_t size, bool dealloc)
|
||||
aligned_stack_memory_handler(T* ptr, std::size_t size, bool dealloc)
|
||||
: m_ptr(ptr), m_size(size), m_deallocate(dealloc)
|
||||
{
|
||||
if(NumTraits<T>::RequireInitialization && m_ptr)
|
||||
@@ -576,7 +576,7 @@ template<typename T> class aligned_stack_memory_handler : noncopyable
|
||||
}
|
||||
protected:
|
||||
T* m_ptr;
|
||||
size_t m_size;
|
||||
std::size_t m_size;
|
||||
bool m_deallocate;
|
||||
};
|
||||
|
||||
@@ -655,15 +655,15 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
|
||||
#if EIGEN_MAX_ALIGN_BYTES!=0
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
|
||||
void* operator new(size_t size, const std::nothrow_t&) EIGEN_NO_THROW { \
|
||||
void* operator new(std::size_t size, const std::nothrow_t&) EIGEN_NO_THROW { \
|
||||
EIGEN_TRY { return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); } \
|
||||
EIGEN_CATCH (...) { return 0; } \
|
||||
}
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
|
||||
void *operator new(size_t size) { \
|
||||
void *operator new(std::size_t size) { \
|
||||
return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
|
||||
} \
|
||||
void *operator new[](size_t size) { \
|
||||
void *operator new[](std::size_t size) { \
|
||||
return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
|
||||
} \
|
||||
void operator delete(void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
@@ -673,8 +673,8 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
/* in-place new and delete. since (at least afaik) there is no actual */ \
|
||||
/* memory allocated we can safely let the default implementation handle */ \
|
||||
/* this particular case. */ \
|
||||
static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \
|
||||
static void *operator new[](size_t size, void* ptr) { return ::operator new[](size,ptr); } \
|
||||
static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \
|
||||
static void *operator new[](std::size_t size, void* ptr) { return ::operator new[](size,ptr); } \
|
||||
void operator delete(void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete(memory,ptr); } \
|
||||
void operator delete[](void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete[](memory,ptr); } \
|
||||
/* nothrow-new (returns zero instead of std::bad_alloc) */ \
|
||||
@@ -713,7 +713,7 @@ template<class T>
|
||||
class aligned_allocator : public std::allocator<T>
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
@@ -532,6 +532,15 @@ template <typename B, typename Functor> struct cwise_promote_s
|
||||
template <typename Functor> struct cwise_promote_storage_type<Sparse,Dense,Functor> { typedef Sparse ret; };
|
||||
template <typename Functor> struct cwise_promote_storage_type<Dense,Sparse,Functor> { typedef Sparse ret; };
|
||||
|
||||
template <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order {
|
||||
enum { value = LhsOrder };
|
||||
};
|
||||
|
||||
template <typename LhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder> { enum { value = RhsOrder }; };
|
||||
template <typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder> { enum { value = LhsOrder }; };
|
||||
template <int Order> struct cwise_promote_storage_order<Sparse,Sparse,Order,Order> { enum { value = Order }; };
|
||||
|
||||
|
||||
/** \internal Specify the "storage kind" of multiplying an expression of kind A with kind B.
|
||||
* The template parameter ProductTag permits to specialize the resulting storage kind wrt to
|
||||
* some compile-time properties of the product: GemmProduct, GemvProduct, OuterProduct, InnerProduct.
|
||||
@@ -629,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) };
|
||||
};
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ template<typename _MatrixType> class ComplexEigenSolver
|
||||
EigenvectorType m_matX;
|
||||
|
||||
private:
|
||||
void doComputeEigenvectors(const RealScalar& matrixnorm);
|
||||
void doComputeEigenvectors(RealScalar matrixnorm);
|
||||
void sortEigenvalues(bool computeEigenvectors);
|
||||
};
|
||||
|
||||
@@ -284,10 +284,12 @@ ComplexEigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix, bool
|
||||
|
||||
|
||||
template<typename MatrixType>
|
||||
void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(const RealScalar& matrixnorm)
|
||||
void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(RealScalar matrixnorm)
|
||||
{
|
||||
const Index n = m_eivalues.size();
|
||||
|
||||
matrixnorm = numext::maxi(matrixnorm,(std::numeric_limits<RealScalar>::min)());
|
||||
|
||||
// Compute X such that T = X D X^(-1), where D is the diagonal of T.
|
||||
// The matrix X is unit triangular.
|
||||
m_matX = EigenvectorType::Zero(n, n);
|
||||
|
||||
@@ -248,12 +248,24 @@ template<typename MatrixType>
|
||||
template<typename InputType>
|
||||
RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeU)
|
||||
{
|
||||
const Scalar considerAsZero = (std::numeric_limits<Scalar>::min)();
|
||||
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
Index maxIters = m_maxIters;
|
||||
if (maxIters == -1)
|
||||
maxIters = m_maxIterationsPerRow * matrix.rows();
|
||||
|
||||
Scalar scale = matrix.derived().cwiseAbs().maxCoeff();
|
||||
if(scale<considerAsZero)
|
||||
{
|
||||
m_matT.setZero(matrix.rows(),matrix.cols());
|
||||
if(computeU)
|
||||
m_matU.setIdentity(matrix.rows(),matrix.cols());
|
||||
m_info = Success;
|
||||
m_isInitialized = true;
|
||||
m_matUisUptodate = computeU;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Step 1. Reduce to Hessenberg form
|
||||
m_hess.compute(matrix.derived()/scale);
|
||||
|
||||
@@ -414,7 +414,8 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
|
||||
if(n==1)
|
||||
{
|
||||
m_eivalues.coeffRef(0,0) = numext::real(matrix.diagonal()[0]);
|
||||
m_eivec = matrix;
|
||||
m_eivalues.coeffRef(0,0) = numext::real(m_eivec.coeff(0,0));
|
||||
if(computeEigenvectors)
|
||||
m_eivec.setOnes(n,n);
|
||||
m_info = Success;
|
||||
|
||||
@@ -217,7 +217,10 @@ public:
|
||||
EIGEN_DEVICE_FUNC inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine)
|
||||
{
|
||||
if (traits==Affine)
|
||||
{
|
||||
normal() = mat.inverse().transpose() * normal();
|
||||
m_coeffs /= normal().norm();
|
||||
}
|
||||
else if (traits==Isometry)
|
||||
normal() = mat * normal();
|
||||
else
|
||||
|
||||
@@ -423,7 +423,7 @@ typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;
|
||||
// Generic Quaternion * Quaternion product
|
||||
// This product can be specialized for a given architecture via the Arch template argument.
|
||||
namespace internal {
|
||||
template<int Arch, class Derived1, class Derived2, typename Scalar, int _Options> struct quat_product
|
||||
template<int Arch, class Derived1, class Derived2, typename Scalar> struct quat_product
|
||||
{
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
|
||||
return Quaternion<Scalar>
|
||||
@@ -446,8 +446,7 @@ QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) c
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename OtherDerived::Scalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
return internal::quat_product<Architecture::Target, Derived, OtherDerived,
|
||||
typename internal::traits<Derived>::Scalar,
|
||||
EIGEN_PLAIN_ENUM_MIN(internal::traits<Derived>::Alignment, internal::traits<OtherDerived>::Alignment)>::run(*this, other);
|
||||
typename internal::traits<Derived>::Scalar>::run(*this, other);
|
||||
}
|
||||
|
||||
/** \sa operator*(Quaternion) */
|
||||
@@ -672,7 +671,7 @@ EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar>
|
||||
|
||||
// Generic conjugate of a Quaternion
|
||||
namespace internal {
|
||||
template<int Arch, class Derived, typename Scalar, int _Options> struct quat_conj
|
||||
template<int Arch, class Derived, typename Scalar> struct quat_conj
|
||||
{
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived>& q){
|
||||
return Quaternion<Scalar>(q.w(),-q.x(),-q.y(),-q.z());
|
||||
@@ -691,8 +690,7 @@ EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar>
|
||||
QuaternionBase<Derived>::conjugate() const
|
||||
{
|
||||
return internal::quat_conj<Architecture::Target, Derived,
|
||||
typename internal::traits<Derived>::Scalar,
|
||||
internal::traits<Derived>::Alignment>::run(*this);
|
||||
typename internal::traits<Derived>::Scalar>::run(*this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -16,17 +16,23 @@ namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
template<class Derived, class OtherDerived>
|
||||
struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned16>
|
||||
struct quat_product<Architecture::SSE, Derived, OtherDerived, float>
|
||||
{
|
||||
enum {
|
||||
AAlignment = traits<Derived>::Alignment,
|
||||
BAlignment = traits<OtherDerived>::Alignment,
|
||||
ResAlignment = traits<Quaternion<float> >::Alignment
|
||||
};
|
||||
static inline Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
|
||||
{
|
||||
Quaternion<float> res;
|
||||
const __m128 mask = _mm_setr_ps(0.f,0.f,0.f,-0.f);
|
||||
__m128 a = _a.coeffs().template packet<Aligned16>(0);
|
||||
__m128 b = _b.coeffs().template packet<Aligned16>(0);
|
||||
__m128 a = _a.coeffs().template packet<AAlignment>(0);
|
||||
__m128 b = _b.coeffs().template packet<BAlignment>(0);
|
||||
__m128 s1 = _mm_mul_ps(vec4f_swizzle1(a,1,2,0,2),vec4f_swizzle1(b,2,0,1,2));
|
||||
__m128 s2 = _mm_mul_ps(vec4f_swizzle1(a,3,3,3,1),vec4f_swizzle1(b,0,1,2,1));
|
||||
pstore(&res.x(),
|
||||
pstoret<float,Packet4f,ResAlignment>(
|
||||
&res.x(),
|
||||
_mm_add_ps(_mm_sub_ps(_mm_mul_ps(a,vec4f_swizzle1(b,3,3,3,3)),
|
||||
_mm_mul_ps(vec4f_swizzle1(a,2,0,1,0),
|
||||
vec4f_swizzle1(b,1,2,0,0))),
|
||||
@@ -36,14 +42,17 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned16>
|
||||
}
|
||||
};
|
||||
|
||||
template<class Derived, int Alignment>
|
||||
struct quat_conj<Architecture::SSE, Derived, float, Alignment>
|
||||
template<class Derived>
|
||||
struct quat_conj<Architecture::SSE, Derived, float>
|
||||
{
|
||||
enum {
|
||||
ResAlignment = traits<Quaternion<float> >::Alignment
|
||||
};
|
||||
static inline Quaternion<float> run(const QuaternionBase<Derived>& q)
|
||||
{
|
||||
Quaternion<float> res;
|
||||
const __m128 mask = _mm_setr_ps(-0.f,-0.f,-0.f,0.f);
|
||||
pstore(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet<Alignment>(0)));
|
||||
pstoret<float,Packet4f,ResAlignment>(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet<traits<Derived>::Alignment>(0)));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
@@ -52,6 +61,9 @@ struct quat_conj<Architecture::SSE, Derived, float, Alignment>
|
||||
template<typename VectorLhs,typename VectorRhs>
|
||||
struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
|
||||
{
|
||||
enum {
|
||||
ResAlignment = traits<typename plain_matrix_type<VectorLhs>::type>::Alignment
|
||||
};
|
||||
static inline typename plain_matrix_type<VectorLhs>::type
|
||||
run(const VectorLhs& lhs, const VectorRhs& rhs)
|
||||
{
|
||||
@@ -60,7 +72,7 @@ struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
|
||||
__m128 mul1=_mm_mul_ps(vec4f_swizzle1(a,1,2,0,3),vec4f_swizzle1(b,2,0,1,3));
|
||||
__m128 mul2=_mm_mul_ps(vec4f_swizzle1(a,2,0,1,3),vec4f_swizzle1(b,1,2,0,3));
|
||||
typename plain_matrix_type<VectorLhs>::type res;
|
||||
pstore(&res.x(),_mm_sub_ps(mul1,mul2));
|
||||
pstoret<float,Packet4f,ResAlignment>(&res.x(),_mm_sub_ps(mul1,mul2));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
@@ -68,9 +80,14 @@ struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
|
||||
|
||||
|
||||
|
||||
template<class Derived, class OtherDerived, int Alignment>
|
||||
struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
|
||||
template<class Derived, class OtherDerived>
|
||||
struct quat_product<Architecture::SSE, Derived, OtherDerived, double>
|
||||
{
|
||||
enum {
|
||||
BAlignment = traits<OtherDerived>::Alignment,
|
||||
ResAlignment = traits<Quaternion<double> >::Alignment
|
||||
};
|
||||
|
||||
static inline Quaternion<double> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
|
||||
{
|
||||
const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));
|
||||
@@ -78,8 +95,8 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
|
||||
Quaternion<double> res;
|
||||
|
||||
const double* a = _a.coeffs().data();
|
||||
Packet2d b_xy = _b.coeffs().template packet<Alignment>(0);
|
||||
Packet2d b_zw = _b.coeffs().template packet<Alignment>(2);
|
||||
Packet2d b_xy = _b.coeffs().template packet<BAlignment>(0);
|
||||
Packet2d b_zw = _b.coeffs().template packet<BAlignment>(2);
|
||||
Packet2d a_xx = pset1<Packet2d>(a[0]);
|
||||
Packet2d a_yy = pset1<Packet2d>(a[1]);
|
||||
Packet2d a_zz = pset1<Packet2d>(a[2]);
|
||||
@@ -97,9 +114,9 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
|
||||
t2 = psub(pmul(a_zz, b_xy), pmul(a_xx, b_zw));
|
||||
#ifdef EIGEN_VECTORIZE_SSE3
|
||||
EIGEN_UNUSED_VARIABLE(mask)
|
||||
pstore(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
|
||||
pstoret<double,Packet2d,ResAlignment>(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
|
||||
#else
|
||||
pstore(&res.x(), padd(t1, pxor(mask,preverse(t2))));
|
||||
pstoret<double,Packet2d,ResAlignment>(&res.x(), padd(t1, pxor(mask,preverse(t2))));
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -111,25 +128,28 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
|
||||
t2 = padd(pmul(a_zz, b_zw), pmul(a_xx, b_xy));
|
||||
#ifdef EIGEN_VECTORIZE_SSE3
|
||||
EIGEN_UNUSED_VARIABLE(mask)
|
||||
pstore(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
|
||||
pstoret<double,Packet2d,ResAlignment>(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
|
||||
#else
|
||||
pstore(&res.z(), psub(t1, pxor(mask,preverse(t2))));
|
||||
pstoret<double,Packet2d,ResAlignment>(&res.z(), psub(t1, pxor(mask,preverse(t2))));
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Derived, int Alignment>
|
||||
struct quat_conj<Architecture::SSE, Derived, double, Alignment>
|
||||
template<class Derived>
|
||||
struct quat_conj<Architecture::SSE, Derived, double>
|
||||
{
|
||||
enum {
|
||||
ResAlignment = traits<Quaternion<double> >::Alignment
|
||||
};
|
||||
static inline Quaternion<double> run(const QuaternionBase<Derived>& q)
|
||||
{
|
||||
Quaternion<double> res;
|
||||
const __m128d mask0 = _mm_setr_pd(-0.,-0.);
|
||||
const __m128d mask2 = _mm_setr_pd(-0.,0.);
|
||||
pstore(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet<Alignment>(0)));
|
||||
pstore(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet<Alignment>(2)));
|
||||
pstoret<double,Packet2d,ResAlignment>(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet<traits<Derived>::Alignment>(0)));
|
||||
pstoret<double,Packet2d,ResAlignment>(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet<traits<Derived>::Alignment>(2)));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -87,7 +87,8 @@ void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vec
|
||||
const TriangularView<const VectorsType, UnitLower> V(vectors);
|
||||
|
||||
// A -= V T V^* A
|
||||
Matrix<typename MatrixType::Scalar,VectorsType::ColsAtCompileTime,MatrixType::ColsAtCompileTime,0,
|
||||
Matrix<typename MatrixType::Scalar,VectorsType::ColsAtCompileTime,MatrixType::ColsAtCompileTime,
|
||||
(VectorsType::MaxColsAtCompileTime==1 && MatrixType::MaxColsAtCompileTime!=1)?RowMajor:ColMajor,
|
||||
VectorsType::MaxColsAtCompileTime,MatrixType::MaxColsAtCompileTime> tmp = V.adjoint() * mat;
|
||||
// FIXME add .noalias() once the triangular product can work inplace
|
||||
if(forward) tmp = T.template triangularView<Upper>() * tmp;
|
||||
|
||||
@@ -152,13 +152,28 @@ class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<_Scalar>
|
||||
{
|
||||
// Compute the inverse squared-norm of each column of mat
|
||||
m_invdiag.resize(mat.cols());
|
||||
for(Index j=0; j<mat.outerSize(); ++j)
|
||||
if(MatType::IsRowMajor)
|
||||
{
|
||||
RealScalar sum = mat.innerVector(j).squaredNorm();
|
||||
if(sum>0)
|
||||
m_invdiag(j) = RealScalar(1)/sum;
|
||||
else
|
||||
m_invdiag(j) = RealScalar(1);
|
||||
m_invdiag.setZero();
|
||||
for(Index j=0; j<mat.outerSize(); ++j)
|
||||
{
|
||||
for(typename MatType::InnerIterator it(mat,j); it; ++it)
|
||||
m_invdiag(it.index()) += numext::abs2(it.value());
|
||||
}
|
||||
for(Index j=0; j<mat.cols(); ++j)
|
||||
if(numext::real(m_invdiag(j))>RealScalar(0))
|
||||
m_invdiag(j) = RealScalar(1)/numext::real(m_invdiag(j));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(Index j=0; j<mat.outerSize(); ++j)
|
||||
{
|
||||
RealScalar sum = mat.innerVector(j).squaredNorm();
|
||||
if(sum>RealScalar(0))
|
||||
m_invdiag(j) = RealScalar(1)/sum;
|
||||
else
|
||||
m_invdiag(j) = RealScalar(1);
|
||||
}
|
||||
}
|
||||
Base::m_isInitialized = true;
|
||||
return *this;
|
||||
|
||||
@@ -302,8 +302,12 @@ template<typename VectorX, typename VectorY, typename OtherScalar>
|
||||
void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
|
||||
{
|
||||
typedef typename VectorX::Scalar Scalar;
|
||||
enum { PacketSize = packet_traits<Scalar>::size };
|
||||
enum {
|
||||
PacketSize = packet_traits<Scalar>::size,
|
||||
OtherPacketSize = packet_traits<OtherScalar>::size
|
||||
};
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
typedef typename packet_traits<OtherScalar>::type OtherPacket;
|
||||
eigen_assert(xpr_x.size() == xpr_y.size());
|
||||
Index size = xpr_x.size();
|
||||
Index incrx = xpr_x.derived().innerStride();
|
||||
@@ -321,6 +325,7 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
|
||||
|
||||
if(VectorX::SizeAtCompileTime == Dynamic &&
|
||||
(VectorX::Flags & VectorY::Flags & PacketAccessBit) &&
|
||||
(PacketSize == OtherPacketSize) &&
|
||||
((incrx==1 && incry==1) || PacketSize == 1))
|
||||
{
|
||||
// both vectors are sequentially stored in memory => vectorization
|
||||
@@ -329,9 +334,10 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
|
||||
Index alignedStart = internal::first_default_aligned(y, size);
|
||||
Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize;
|
||||
|
||||
const Packet pc = pset1<Packet>(c);
|
||||
const Packet ps = pset1<Packet>(s);
|
||||
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
|
||||
const OtherPacket pc = pset1<OtherPacket>(c);
|
||||
const OtherPacket ps = pset1<OtherPacket>(s);
|
||||
conj_helper<OtherPacket,Packet,NumTraits<OtherScalar>::IsComplex,false> pcj;
|
||||
conj_helper<OtherPacket,Packet,false,false> pm;
|
||||
|
||||
for(Index i=0; i<alignedStart; ++i)
|
||||
{
|
||||
@@ -350,8 +356,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
|
||||
{
|
||||
Packet xi = pload<Packet>(px);
|
||||
Packet yi = pload<Packet>(py);
|
||||
pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
|
||||
pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
|
||||
px += PacketSize;
|
||||
py += PacketSize;
|
||||
}
|
||||
@@ -365,10 +371,10 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
|
||||
Packet xi1 = ploadu<Packet>(px+PacketSize);
|
||||
Packet yi = pload <Packet>(py);
|
||||
Packet yi1 = pload <Packet>(py+PacketSize);
|
||||
pstoreu(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstoreu(px+PacketSize, padd(pmul(pc,xi1),pcj.pmul(ps,yi1)));
|
||||
pstore (py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
|
||||
pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pmul(ps,xi1)));
|
||||
pstoreu(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstoreu(px+PacketSize, padd(pm.pmul(pc,xi1),pcj.pmul(ps,yi1)));
|
||||
pstore (py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
|
||||
pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pm.pmul(ps,xi1)));
|
||||
px += Peeling*PacketSize;
|
||||
py += Peeling*PacketSize;
|
||||
}
|
||||
@@ -376,8 +382,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
|
||||
{
|
||||
Packet xi = ploadu<Packet>(x+peelingEnd);
|
||||
Packet yi = pload <Packet>(y+peelingEnd);
|
||||
pstoreu(x+peelingEnd, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
|
||||
pstoreu(x+peelingEnd, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,19 +399,21 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x
|
||||
/*** fixed-size vectorized path ***/
|
||||
else if(VectorX::SizeAtCompileTime != Dynamic &&
|
||||
(VectorX::Flags & VectorY::Flags & PacketAccessBit) &&
|
||||
(PacketSize == OtherPacketSize) &&
|
||||
(EIGEN_PLAIN_ENUM_MIN(evaluator<VectorX>::Alignment, evaluator<VectorY>::Alignment)>0)) // FIXME should be compared to the required alignment
|
||||
{
|
||||
const Packet pc = pset1<Packet>(c);
|
||||
const Packet ps = pset1<Packet>(s);
|
||||
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
|
||||
const OtherPacket pc = pset1<OtherPacket>(c);
|
||||
const OtherPacket ps = pset1<OtherPacket>(s);
|
||||
conj_helper<OtherPacket,Packet,NumTraits<OtherPacket>::IsComplex,false> pcj;
|
||||
conj_helper<OtherPacket,Packet,false,false> pm;
|
||||
Scalar* EIGEN_RESTRICT px = x;
|
||||
Scalar* EIGEN_RESTRICT py = y;
|
||||
for(Index i=0; i<size; i+=PacketSize)
|
||||
{
|
||||
Packet xi = pload<Packet>(px);
|
||||
Packet yi = pload<Packet>(py);
|
||||
pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
|
||||
pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
|
||||
pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
|
||||
px += PacketSize;
|
||||
py += PacketSize;
|
||||
}
|
||||
|
||||
@@ -1004,7 +1004,7 @@ static IndexType find_ordering /* return the number of garbage collections */
|
||||
COLAMD_ASSERT (head [min_score] >= COLAMD_EMPTY) ;
|
||||
|
||||
/* get pivot column from head of minimum degree list */
|
||||
while (head [min_score] == COLAMD_EMPTY && min_score < n_col)
|
||||
while (min_score < n_col && head [min_score] == COLAMD_EMPTY)
|
||||
{
|
||||
min_score++ ;
|
||||
}
|
||||
|
||||
@@ -506,8 +506,8 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
|
||||
m_colNormsUpdated.coeffRef(k) = m_colNormsDirect.coeffRef(k);
|
||||
}
|
||||
|
||||
RealScalar threshold_helper = numext::abs2<Scalar>(m_colNormsUpdated.maxCoeff() * NumTraits<Scalar>::epsilon()) / RealScalar(rows);
|
||||
RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<Scalar>::epsilon());
|
||||
RealScalar threshold_helper = numext::abs2<RealScalar>(m_colNormsUpdated.maxCoeff() * NumTraits<RealScalar>::epsilon()) / RealScalar(rows);
|
||||
RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<RealScalar>::epsilon());
|
||||
|
||||
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
||||
m_maxpivot = RealScalar(0);
|
||||
@@ -553,12 +553,12 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
|
||||
// http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
|
||||
// and used in LAPACK routines xGEQPF and xGEQP3.
|
||||
// See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html
|
||||
if (m_colNormsUpdated.coeffRef(j) != 0) {
|
||||
if (m_colNormsUpdated.coeffRef(j) != RealScalar(0)) {
|
||||
RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j);
|
||||
temp = (RealScalar(1) + temp) * (RealScalar(1) - temp);
|
||||
temp = temp < 0 ? 0 : temp;
|
||||
RealScalar temp2 = temp * numext::abs2<Scalar>(m_colNormsUpdated.coeffRef(j) /
|
||||
m_colNormsDirect.coeffRef(j));
|
||||
temp = temp < RealScalar(0) ? RealScalar(0) : temp;
|
||||
RealScalar temp2 = temp * numext::abs2<RealScalar>(m_colNormsUpdated.coeffRef(j) /
|
||||
m_colNormsDirect.coeffRef(j));
|
||||
if (temp2 <= norm_downdate_threshold) {
|
||||
// The updated norm has become too inaccurate so re-compute the column
|
||||
// norm directly.
|
||||
|
||||
@@ -138,7 +138,7 @@ class CompleteOrthogonalDecomposition {
|
||||
* problem \f[\mathrm{minimize} \|A X - B\|, \f] where \b A is the matrix of
|
||||
* which \c *this is the complete orthogonal decomposition.
|
||||
*
|
||||
* \param B the right-hand sides of the problem to solve.
|
||||
* \param b the right-hand sides of the problem to solve.
|
||||
*
|
||||
* \returns a solution.
|
||||
*
|
||||
|
||||
@@ -77,6 +77,7 @@ public:
|
||||
typedef _MatrixType MatrixType;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||
typedef typename NumTraits<RealScalar>::Literal Literal;
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
@@ -259,7 +260,7 @@ BDCSVD<MatrixType>& BDCSVD<MatrixType>::compute(const MatrixType& matrix, unsign
|
||||
|
||||
//**** step 0 - Copy the input matrix and apply scaling to reduce over/under-flows
|
||||
RealScalar scale = matrix.cwiseAbs().maxCoeff();
|
||||
if(scale==RealScalar(0)) scale = RealScalar(1);
|
||||
if(scale==Literal(0)) scale = Literal(1);
|
||||
MatrixX copy;
|
||||
if (m_isTranspose) copy = matrix.adjoint()/scale;
|
||||
else copy = matrix/scale;
|
||||
@@ -351,13 +352,13 @@ void BDCSVD<MatrixType>::structured_update(Block<MatrixXr,Dynamic,Dynamic> A, co
|
||||
Index k1=0, k2=0;
|
||||
for(Index j=0; j<n; ++j)
|
||||
{
|
||||
if( (A.col(j).head(n1).array()!=0).any() )
|
||||
if( (A.col(j).head(n1).array()!=Literal(0)).any() )
|
||||
{
|
||||
A1.col(k1) = A.col(j).head(n1);
|
||||
B1.row(k1) = B.row(j);
|
||||
++k1;
|
||||
}
|
||||
if( (A.col(j).tail(n2).array()!=0).any() )
|
||||
if( (A.col(j).tail(n2).array()!=Literal(0)).any() )
|
||||
{
|
||||
A2.col(k2) = A.col(j).tail(n2);
|
||||
B2.row(k2) = B.row(j);
|
||||
@@ -449,11 +450,11 @@ void BDCSVD<MatrixType>::divide (Index firstCol, Index lastCol, Index firstRowW,
|
||||
l = m_naiveU.row(1).segment(firstCol, k);
|
||||
f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1);
|
||||
}
|
||||
if (m_compV) m_naiveV(firstRowW+k, firstColW) = 1;
|
||||
if (m_compV) m_naiveV(firstRowW+k, firstColW) = Literal(1);
|
||||
if (r0<considerZero)
|
||||
{
|
||||
c0 = 1;
|
||||
s0 = 0;
|
||||
c0 = Literal(1);
|
||||
s0 = Literal(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -574,7 +575,7 @@ void BDCSVD<MatrixType>::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec
|
||||
ArrayRef col0 = m_computed.col(firstCol).segment(firstCol, n);
|
||||
m_workspace.head(n) = m_computed.block(firstCol, firstCol, n, n).diagonal();
|
||||
ArrayRef diag = m_workspace.head(n);
|
||||
diag(0) = 0;
|
||||
diag(0) = Literal(0);
|
||||
|
||||
// Allocate space for singular values and vectors
|
||||
singVals.resize(n);
|
||||
@@ -590,7 +591,7 @@ void BDCSVD<MatrixType>::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec
|
||||
// but others are interleaved and we must ignore them at this stage.
|
||||
// To this end, let's compute a permutation skipping them:
|
||||
Index actual_n = n;
|
||||
while(actual_n>1 && diag(actual_n-1)==0) --actual_n;
|
||||
while(actual_n>1 && diag(actual_n-1)==Literal(0)) --actual_n;
|
||||
Index m = 0; // size of the deflated problem
|
||||
for(Index k=0;k<actual_n;++k)
|
||||
if(abs(col0(k))>considerZero)
|
||||
@@ -691,7 +692,7 @@ template <typename MatrixType>
|
||||
typename BDCSVD<MatrixType>::RealScalar BDCSVD<MatrixType>::secularEq(RealScalar mu, const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm, const ArrayRef& diagShifted, RealScalar shift)
|
||||
{
|
||||
Index m = perm.size();
|
||||
RealScalar res = 1;
|
||||
RealScalar res = Literal(1);
|
||||
for(Index i=0; i<m; ++i)
|
||||
{
|
||||
Index j = perm(i);
|
||||
@@ -710,16 +711,16 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
|
||||
|
||||
Index n = col0.size();
|
||||
Index actual_n = n;
|
||||
while(actual_n>1 && col0(actual_n-1)==0) --actual_n;
|
||||
while(actual_n>1 && col0(actual_n-1)==Literal(0)) --actual_n;
|
||||
|
||||
for (Index k = 0; k < n; ++k)
|
||||
{
|
||||
if (col0(k) == 0 || actual_n==1)
|
||||
if (col0(k) == Literal(0) || actual_n==1)
|
||||
{
|
||||
// if col0(k) == 0, then entry is deflated, so singular value is on diagonal
|
||||
// if actual_n==1, then the deflated problem is already diagonalized
|
||||
singVals(k) = k==0 ? col0(0) : diag(k);
|
||||
mus(k) = 0;
|
||||
mus(k) = Literal(0);
|
||||
shifts(k) = k==0 ? col0(0) : diag(k);
|
||||
continue;
|
||||
}
|
||||
@@ -733,13 +734,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
|
||||
{
|
||||
// Skip deflated singular values
|
||||
Index l = k+1;
|
||||
while(col0(l)==0) { ++l; eigen_internal_assert(l<actual_n); }
|
||||
while(col0(l)==Literal(0)) { ++l; eigen_internal_assert(l<actual_n); }
|
||||
right = diag(l);
|
||||
}
|
||||
|
||||
// first decide whether it's closer to the left end or the right end
|
||||
RealScalar mid = left + (right-left) / 2;
|
||||
RealScalar fMid = secularEq(mid, col0, diag, perm, diag, 0);
|
||||
RealScalar mid = left + (right-left) / Literal(2);
|
||||
RealScalar fMid = secularEq(mid, col0, diag, perm, diag, Literal(0));
|
||||
#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
|
||||
std::cout << right-left << "\n";
|
||||
std::cout << "fMid = " << fMid << " " << secularEq(mid-left, col0, diag, perm, diag-left, left) << " " << secularEq(mid-right, col0, diag, perm, diag-right, right) << "\n";
|
||||
@@ -755,7 +756,7 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
|
||||
<< " " << secularEq(0.8*(left+right), col0, diag, perm, diag, 0)
|
||||
<< " " << secularEq(0.9*(left+right), col0, diag, perm, diag, 0) << "\n";
|
||||
#endif
|
||||
RealScalar shift = (k == actual_n-1 || fMid > 0) ? left : right;
|
||||
RealScalar shift = (k == actual_n-1 || fMid > Literal(0)) ? left : right;
|
||||
|
||||
// measure everything relative to shift
|
||||
Map<ArrayXr> diagShifted(m_workspace.data()+4*n, n);
|
||||
@@ -785,13 +786,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
|
||||
|
||||
// rational interpolation: fit a function of the form a / mu + b through the two previous
|
||||
// iterates and use its zero to compute the next iterate
|
||||
bool useBisection = fPrev*fCur>0;
|
||||
while (fCur!=0 && abs(muCur - muPrev) > 8 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits<RealScalar>::epsilon() && !useBisection)
|
||||
bool useBisection = fPrev*fCur>Literal(0);
|
||||
while (fCur!=Literal(0) && abs(muCur - muPrev) > Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits<RealScalar>::epsilon() && !useBisection)
|
||||
{
|
||||
++m_numIters;
|
||||
|
||||
// Find a and b such that the function f(mu) = a / mu + b matches the current and previous samples.
|
||||
RealScalar a = (fCur - fPrev) / (1/muCur - 1/muPrev);
|
||||
RealScalar a = (fCur - fPrev) / (Literal(1)/muCur - Literal(1)/muPrev);
|
||||
RealScalar b = fCur - a / muCur;
|
||||
// And find mu such that f(mu)==0:
|
||||
RealScalar muZero = -a/b;
|
||||
@@ -803,8 +804,8 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
|
||||
fCur = fZero;
|
||||
|
||||
|
||||
if (shift == left && (muCur < 0 || muCur > right - left)) useBisection = true;
|
||||
if (shift == right && (muCur < -(right - left) || muCur > 0)) useBisection = true;
|
||||
if (shift == left && (muCur < Literal(0) || muCur > right - left)) useBisection = true;
|
||||
if (shift == right && (muCur < -(right - left) || muCur > Literal(0))) useBisection = true;
|
||||
if (abs(fCur)>abs(fPrev)) useBisection = true;
|
||||
}
|
||||
|
||||
@@ -841,13 +842,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
|
||||
std::cout << k << " : " << fLeft << " * " << fRight << " == " << fLeft * fRight << " ; " << left << " - " << right << " -> " << leftShifted << " " << rightShifted << " shift=" << shift << "\n";
|
||||
}
|
||||
#endif
|
||||
eigen_internal_assert(fLeft * fRight < 0);
|
||||
eigen_internal_assert(fLeft * fRight < Literal(0));
|
||||
|
||||
while (rightShifted - leftShifted > 2 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted)))
|
||||
while (rightShifted - leftShifted > Literal(2) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted)))
|
||||
{
|
||||
RealScalar midShifted = (leftShifted + rightShifted) / 2;
|
||||
RealScalar midShifted = (leftShifted + rightShifted) / Literal(2);
|
||||
fMid = secularEq(midShifted, col0, diag, perm, diagShifted, shift);
|
||||
if (fLeft * fMid < 0)
|
||||
if (fLeft * fMid < Literal(0))
|
||||
{
|
||||
rightShifted = midShifted;
|
||||
}
|
||||
@@ -858,7 +859,7 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
|
||||
}
|
||||
}
|
||||
|
||||
muCur = (leftShifted + rightShifted) / 2;
|
||||
muCur = (leftShifted + rightShifted) / Literal(2);
|
||||
}
|
||||
|
||||
singVals[k] = shift + muCur;
|
||||
@@ -892,8 +893,8 @@ void BDCSVD<MatrixType>::perturbCol0
|
||||
// The offset permits to skip deflated entries while computing zhat
|
||||
for (Index k = 0; k < n; ++k)
|
||||
{
|
||||
if (col0(k) == 0) // deflated
|
||||
zhat(k) = 0;
|
||||
if (col0(k) == Literal(0)) // deflated
|
||||
zhat(k) = Literal(0);
|
||||
else
|
||||
{
|
||||
// see equation (3.6)
|
||||
@@ -918,7 +919,7 @@ void BDCSVD<MatrixType>::perturbCol0
|
||||
std::cout << "zhat(" << k << ") = sqrt( " << prod << ") ; " << (singVals(last) + dk) << " * " << mus(last) + shifts(last) << " - " << dk << "\n";
|
||||
#endif
|
||||
RealScalar tmp = sqrt(prod);
|
||||
zhat(k) = col0(k) > 0 ? tmp : -tmp;
|
||||
zhat(k) = col0(k) > Literal(0) ? tmp : -tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -934,7 +935,7 @@ void BDCSVD<MatrixType>::computeSingVecs
|
||||
|
||||
for (Index k = 0; k < n; ++k)
|
||||
{
|
||||
if (zhat(k) == 0)
|
||||
if (zhat(k) == Literal(0))
|
||||
{
|
||||
U.col(k) = VectorType::Unit(n+1, k);
|
||||
if (m_compV) V.col(k) = VectorType::Unit(n, k);
|
||||
@@ -947,7 +948,7 @@ void BDCSVD<MatrixType>::computeSingVecs
|
||||
Index i = perm(l);
|
||||
U(i,k) = zhat(i)/(((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
|
||||
}
|
||||
U(n,k) = 0;
|
||||
U(n,k) = Literal(0);
|
||||
U.col(k).normalize();
|
||||
|
||||
if (m_compV)
|
||||
@@ -958,7 +959,7 @@ void BDCSVD<MatrixType>::computeSingVecs
|
||||
Index i = perm(l);
|
||||
V(i,k) = diag(i) * zhat(i) / (((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
|
||||
}
|
||||
V(0,k) = -1;
|
||||
V(0,k) = Literal(-1);
|
||||
V.col(k).normalize();
|
||||
}
|
||||
}
|
||||
@@ -980,14 +981,14 @@ void BDCSVD<MatrixType>::deflation43(Index firstCol, Index shift, Index i, Index
|
||||
RealScalar c = m_computed(start, start);
|
||||
RealScalar s = m_computed(start+i, start);
|
||||
RealScalar r = sqrt(numext::abs2(c) + numext::abs2(s));
|
||||
if (r == 0)
|
||||
if (r == Literal(0))
|
||||
{
|
||||
m_computed(start+i, start+i) = 0;
|
||||
m_computed(start+i, start+i) = Literal(0);
|
||||
return;
|
||||
}
|
||||
m_computed(start,start) = r;
|
||||
m_computed(start+i, start) = 0;
|
||||
m_computed(start+i, start+i) = 0;
|
||||
m_computed(start+i, start) = Literal(0);
|
||||
m_computed(start+i, start+i) = Literal(0);
|
||||
|
||||
JacobiRotation<RealScalar> J(c/r,-s/r);
|
||||
if (m_compU) m_naiveU.middleRows(firstCol, size+1).applyOnTheRight(firstCol, firstCol+i, J);
|
||||
@@ -1020,7 +1021,7 @@ void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index fi
|
||||
<< m_computed(firstColm + i+1, firstColm+i+1) << " "
|
||||
<< m_computed(firstColm + i+2, firstColm+i+2) << "\n";
|
||||
#endif
|
||||
if (r==0)
|
||||
if (r==Literal(0))
|
||||
{
|
||||
m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);
|
||||
return;
|
||||
@@ -1029,7 +1030,7 @@ void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index fi
|
||||
s/=r;
|
||||
m_computed(firstColm + i, firstColm) = r;
|
||||
m_computed(firstColm + j, firstColm + j) = m_computed(firstColm + i, firstColm + i);
|
||||
m_computed(firstColm + j, firstColm) = 0;
|
||||
m_computed(firstColm + j, firstColm) = Literal(0);
|
||||
|
||||
JacobiRotation<RealScalar> J(c,-s);
|
||||
if (m_compU) m_naiveU.middleRows(firstColu, size+1).applyOnTheRight(firstColu + i, firstColu + j, J);
|
||||
@@ -1053,7 +1054,7 @@ void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index
|
||||
const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
|
||||
RealScalar maxDiag = diag.tail((std::max)(Index(1),length-1)).cwiseAbs().maxCoeff();
|
||||
RealScalar epsilon_strict = numext::maxi<RealScalar>(considerZero,NumTraits<RealScalar>::epsilon() * maxDiag);
|
||||
RealScalar epsilon_coarse = 8 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
|
||||
RealScalar epsilon_coarse = Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
|
||||
|
||||
#ifdef EIGEN_BDCSVD_SANITY_CHECKS
|
||||
assert(m_naiveU.allFinite());
|
||||
@@ -1081,7 +1082,7 @@ void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index
|
||||
#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
|
||||
std::cout << "deflation 4.2, set z(" << i << ") to zero because " << abs(col0(i)) << " < " << epsilon_strict << " (diag(" << i << ")=" << diag(i) << ")\n";
|
||||
#endif
|
||||
col0(i) = 0;
|
||||
col0(i) = Literal(0);
|
||||
}
|
||||
|
||||
//condition 4.3
|
||||
|
||||
@@ -112,9 +112,11 @@ public:
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||
Options = MatrixType::Options
|
||||
TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(RowMajor))
|
||||
: ColsAtCompileTime==1 ? (MatrixType::Options | RowMajor)
|
||||
: MatrixType::Options
|
||||
};
|
||||
typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
|
||||
typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, TrOptions, MaxColsAtCompileTime, MaxRowsAtCompileTime>
|
||||
TransposeTypeWithSameStorageOrder;
|
||||
|
||||
void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
|
||||
@@ -200,10 +202,12 @@ public:
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||
Options = MatrixType::Options
|
||||
TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(RowMajor))
|
||||
: ColsAtCompileTime==1 ? (MatrixType::Options | RowMajor)
|
||||
: MatrixType::Options
|
||||
};
|
||||
|
||||
typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
|
||||
typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, TrOptions, MaxColsAtCompileTime, MaxRowsAtCompileTime>
|
||||
TransposeTypeWithSameStorageOrder;
|
||||
|
||||
void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
|
||||
|
||||
@@ -159,6 +159,8 @@ void upperbidiagonalization_blocked_helper(MatrixType& A,
|
||||
traits<MatrixType>::Flags & RowMajorBit> > Y)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef typename NumTraits<RealScalar>::Literal Literal;
|
||||
enum { StorageOrder = traits<MatrixType>::Flags & RowMajorBit };
|
||||
typedef InnerStride<int(StorageOrder) == int(ColMajor) ? 1 : Dynamic> ColInnerStride;
|
||||
typedef InnerStride<int(StorageOrder) == int(ColMajor) ? Dynamic : 1> RowInnerStride;
|
||||
@@ -263,7 +265,7 @@ void upperbidiagonalization_blocked_helper(MatrixType& A,
|
||||
SubMatType A10( A.block(bs,0, brows-bs,bs) );
|
||||
SubMatType A01( A.block(0,bs, bs,bcols-bs) );
|
||||
Scalar tmp = A01(bs-1,0);
|
||||
A01(bs-1,0) = 1;
|
||||
A01(bs-1,0) = Literal(1);
|
||||
A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint();
|
||||
A11.noalias() -= X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01;
|
||||
A01(bs-1,0) = tmp;
|
||||
|
||||
@@ -336,7 +336,7 @@ class AmbiVector<_Scalar,_StorageIndex>::Iterator
|
||||
{
|
||||
do {
|
||||
++m_cachedIndex;
|
||||
} while (m_cachedIndex<m_vector.m_end && abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon);
|
||||
} while (m_cachedIndex<m_vector.m_end && abs(m_vector.m_buffer[m_cachedIndex])<=m_epsilon);
|
||||
if (m_cachedIndex<m_vector.m_end)
|
||||
m_cachedValue = m_vector.m_buffer[m_cachedIndex];
|
||||
else
|
||||
@@ -347,7 +347,7 @@ class AmbiVector<_Scalar,_StorageIndex>::Iterator
|
||||
ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
|
||||
do {
|
||||
m_currentEl = llElements[m_currentEl].next;
|
||||
} while (m_currentEl>=0 && abs(llElements[m_currentEl].value)<m_epsilon);
|
||||
} while (m_currentEl>=0 && abs(llElements[m_currentEl].value)<=m_epsilon);
|
||||
if (m_currentEl<0)
|
||||
{
|
||||
m_cachedIndex = -1;
|
||||
@@ -363,9 +363,9 @@ class AmbiVector<_Scalar,_StorageIndex>::Iterator
|
||||
|
||||
protected:
|
||||
const AmbiVector& m_vector; // the target vector
|
||||
StorageIndex m_currentEl; // the current element in sparse/linked-list mode
|
||||
StorageIndex m_currentEl; // the current element in sparse/linked-list mode
|
||||
RealScalar m_epsilon; // epsilon used to prune zero coefficients
|
||||
StorageIndex m_cachedIndex; // current coordinate
|
||||
StorageIndex m_cachedIndex; // current coordinate
|
||||
Scalar m_cachedValue; // current value
|
||||
bool m_isDense; // mode of the vector
|
||||
};
|
||||
|
||||
@@ -143,10 +143,7 @@ struct Assignment<DstXprType, SrcXprType, Functor, Sparse2Dense>
|
||||
dst.setZero();
|
||||
|
||||
internal::evaluator<SrcXprType> srcEval(src);
|
||||
Index dstRows = src.rows();
|
||||
Index dstCols = src.cols();
|
||||
if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
|
||||
dst.resize(dstRows, dstCols);
|
||||
resize_if_allowed(dst, src, func);
|
||||
internal::evaluator<DstXprType> dstEval(dst);
|
||||
|
||||
const Index outerEvaluationSize = (internal::evaluator<SrcXprType>::Flags&RowMajorBit) ? src.rows() : src.cols();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -279,11 +279,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);
|
||||
}
|
||||
@@ -296,26 +296,42 @@ 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());
|
||||
|
||||
|
||||
const Index outer = Derived::IsRowMajor ? row : col;
|
||||
const Index inner = Derived::IsRowMajor ? col : row;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
|
||||
EIGEN_STATIC_ASSERT((
|
||||
(!internal::is_same<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::value)
|
||||
|| ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))),
|
||||
|| ((internal::evaluator<Lhs>::Flags&RowMajorBit) == (internal::evaluator<Rhs>::Flags&RowMajorBit))),
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
|
||||
}
|
||||
};
|
||||
@@ -110,6 +110,7 @@ public:
|
||||
EIGEN_STRONG_INLINE Scalar value() const { return m_value; }
|
||||
|
||||
EIGEN_STRONG_INLINE StorageIndex index() const { return m_id; }
|
||||
EIGEN_STRONG_INLINE Index outer() const { return m_lhsIter.outer(); }
|
||||
EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
|
||||
EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
|
||||
|
||||
@@ -193,6 +194,7 @@ public:
|
||||
EIGEN_STRONG_INLINE Scalar value() const { eigen_internal_assert(m_id<m_innerSize); return m_value; }
|
||||
|
||||
EIGEN_STRONG_INLINE StorageIndex index() const { return m_id; }
|
||||
EIGEN_STRONG_INLINE Index outer() const { return m_rhsIter.outer(); }
|
||||
EIGEN_STRONG_INLINE Index row() const { return IsRowMajor ? m_rhsIter.outer() : m_id; }
|
||||
EIGEN_STRONG_INLINE Index col() const { return IsRowMajor ? m_id : m_rhsIter.outer(); }
|
||||
|
||||
@@ -280,6 +282,7 @@ public:
|
||||
EIGEN_STRONG_INLINE Scalar value() const { eigen_internal_assert(m_id<m_innerSize); return m_value; }
|
||||
|
||||
EIGEN_STRONG_INLINE StorageIndex index() const { return m_id; }
|
||||
EIGEN_STRONG_INLINE Index outer() const { return m_lhsIter.outer(); }
|
||||
EIGEN_STRONG_INLINE Index row() const { return IsRowMajor ? m_lhsIter.outer() : m_id; }
|
||||
EIGEN_STRONG_INLINE Index col() const { return IsRowMajor ? m_id : m_lhsIter.outer(); }
|
||||
|
||||
@@ -356,6 +359,16 @@ struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1,T2>, Lhs, Rhs>, Itera
|
||||
explicit binary_evaluator(const XprType& xpr) : Base(xpr) {}
|
||||
};
|
||||
|
||||
// "sparse ./ dense"
|
||||
template<typename T1, typename T2, typename Lhs, typename Rhs>
|
||||
struct binary_evaluator<CwiseBinaryOp<scalar_quotient_op<T1,T2>, Lhs, Rhs>, IteratorBased, IndexBased>
|
||||
: sparse_conjunction_evaluator<CwiseBinaryOp<scalar_quotient_op<T1,T2>, Lhs, Rhs> >
|
||||
{
|
||||
typedef CwiseBinaryOp<scalar_quotient_op<T1,T2>, Lhs, Rhs> XprType;
|
||||
typedef sparse_conjunction_evaluator<XprType> Base;
|
||||
explicit binary_evaluator(const XprType& xpr) : Base(xpr) {}
|
||||
};
|
||||
|
||||
// "sparse && sparse"
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct binary_evaluator<CwiseBinaryOp<scalar_boolean_and_op, Lhs, Rhs>, IteratorBased, IteratorBased>
|
||||
@@ -432,6 +445,7 @@ public:
|
||||
EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
|
||||
|
||||
EIGEN_STRONG_INLINE StorageIndex index() const { return m_lhsIter.index(); }
|
||||
EIGEN_STRONG_INLINE Index outer() const { return m_lhsIter.outer(); }
|
||||
EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
|
||||
EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
|
||||
|
||||
@@ -503,6 +517,7 @@ public:
|
||||
{ return m_functor(m_lhsEval.coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
|
||||
|
||||
EIGEN_STRONG_INLINE StorageIndex index() const { return m_rhsIter.index(); }
|
||||
EIGEN_STRONG_INLINE Index outer() const { return m_rhsIter.outer(); }
|
||||
EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); }
|
||||
EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); }
|
||||
|
||||
@@ -577,6 +592,7 @@ public:
|
||||
m_rhsEval.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
|
||||
|
||||
EIGEN_STRONG_INLINE StorageIndex index() const { return m_lhsIter.index(); }
|
||||
EIGEN_STRONG_INLINE Index outer() const { return m_lhsIter.outer(); }
|
||||
EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
|
||||
EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
|
||||
|
||||
@@ -621,6 +637,22 @@ protected:
|
||||
* Implementation of SparseMatrixBase and SparseCwise functions/operators
|
||||
***************************************************************************/
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& SparseMatrixBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& SparseMatrixBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
call_assignment(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
|
||||
@@ -123,8 +123,10 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
SparseMatrixBase<Derived>::operator*=(const Scalar& other)
|
||||
{
|
||||
typedef typename internal::evaluator<Derived>::InnerIterator EvalIterator;
|
||||
internal::evaluator<Derived> thisEval(derived());
|
||||
for (Index j=0; j<outerSize(); ++j)
|
||||
for (typename Derived::InnerIterator i(derived(),j); i; ++i)
|
||||
for (EvalIterator i(thisEval,j); i; ++i)
|
||||
i.valueRef() *= other;
|
||||
return derived();
|
||||
}
|
||||
@@ -133,8 +135,10 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
SparseMatrixBase<Derived>::operator/=(const Scalar& other)
|
||||
{
|
||||
typedef typename internal::evaluator<Derived>::InnerIterator EvalIterator;
|
||||
internal::evaluator<Derived> thisEval(derived());
|
||||
for (Index j=0; j<outerSize(); ++j)
|
||||
for (typename Derived::InnerIterator i(derived(),j); i; ++i)
|
||||
for (EvalIterator i(thisEval,j); i; ++i)
|
||||
i.valueRef() /= other;
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -80,6 +80,8 @@ public:
|
||||
sparse_diagonal_product_evaluator(const SparseXprType &sparseXpr, const DiagonalCoeffType &diagCoeff)
|
||||
: m_sparseXprImpl(sparseXpr), m_diagCoeffImpl(diagCoeff)
|
||||
{}
|
||||
|
||||
Index nonZerosEstimate() const { return m_sparseXprImpl.nonZerosEstimate(); }
|
||||
|
||||
protected:
|
||||
evaluator<SparseXprType> m_sparseXprImpl;
|
||||
@@ -121,6 +123,8 @@ struct sparse_diagonal_product_evaluator<SparseXprType, DiagCoeffType, SDP_AsCwi
|
||||
sparse_diagonal_product_evaluator(const SparseXprType &sparseXpr, const DiagCoeffType &diagCoeff)
|
||||
: m_sparseXprEval(sparseXpr), m_diagCoeffNested(diagCoeff)
|
||||
{}
|
||||
|
||||
Index nonZerosEstimate() const { return m_sparseXprEval.nonZerosEstimate(); }
|
||||
|
||||
protected:
|
||||
evaluator<SparseXprType> m_sparseXprEval;
|
||||
|
||||
@@ -32,18 +32,22 @@ namespace Eigen {
|
||||
* \tparam _Scalar the scalar type, i.e. the type of the coefficients
|
||||
* \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility
|
||||
* is ColMajor or RowMajor. The default is 0 which means column-major.
|
||||
* \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int.
|
||||
* \tparam _StorageIndex the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int.
|
||||
*
|
||||
* \warning In %Eigen 3.2, the undocumented type \c SparseMatrix::Index was improperly defined as the storage index type (e.g., int),
|
||||
* whereas it is now (starting from %Eigen 3.3) deprecated and always defined as Eigen::Index.
|
||||
* Codes making use of \c SparseMatrix::Index, might thus likely have to be changed to use \c SparseMatrix::StorageIndex instead.
|
||||
*
|
||||
* This class can be extended with the help of the plugin mechanism described on the page
|
||||
* \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_SPARSEMATRIX_PLUGIN.
|
||||
*/
|
||||
|
||||
namespace internal {
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
struct traits<SparseMatrix<_Scalar, _Options, _Index> >
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex>
|
||||
struct traits<SparseMatrix<_Scalar, _Options, _StorageIndex> >
|
||||
{
|
||||
typedef _Scalar Scalar;
|
||||
typedef _Index StorageIndex;
|
||||
typedef _StorageIndex StorageIndex;
|
||||
typedef Sparse StorageKind;
|
||||
typedef MatrixXpr XprKind;
|
||||
enum {
|
||||
@@ -56,16 +60,16 @@ struct traits<SparseMatrix<_Scalar, _Options, _Index> >
|
||||
};
|
||||
};
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index, int DiagIndex>
|
||||
struct traits<Diagonal<SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex, int DiagIndex>
|
||||
struct traits<Diagonal<SparseMatrix<_Scalar, _Options, _StorageIndex>, DiagIndex> >
|
||||
{
|
||||
typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType;
|
||||
typedef SparseMatrix<_Scalar, _Options, _StorageIndex> MatrixType;
|
||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
|
||||
typedef _Scalar Scalar;
|
||||
typedef Dense StorageKind;
|
||||
typedef _Index StorageIndex;
|
||||
typedef _StorageIndex StorageIndex;
|
||||
typedef MatrixXpr XprKind;
|
||||
|
||||
enum {
|
||||
@@ -77,9 +81,9 @@ struct traits<Diagonal<SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
|
||||
};
|
||||
};
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index, int DiagIndex>
|
||||
struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
|
||||
: public traits<Diagonal<SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> >
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex, int DiagIndex>
|
||||
struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _StorageIndex>, DiagIndex> >
|
||||
: public traits<Diagonal<SparseMatrix<_Scalar, _Options, _StorageIndex>, DiagIndex> >
|
||||
{
|
||||
enum {
|
||||
Flags = 0
|
||||
@@ -88,13 +92,13 @@ struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex>
|
||||
class SparseMatrix
|
||||
: public SparseCompressedBase<SparseMatrix<_Scalar, _Options, _Index> >
|
||||
: public SparseCompressedBase<SparseMatrix<_Scalar, _Options, _StorageIndex> >
|
||||
{
|
||||
typedef SparseCompressedBase<SparseMatrix> Base;
|
||||
using Base::convert_index;
|
||||
friend class SparseVector<_Scalar,0,_Index>;
|
||||
friend class SparseVector<_Scalar,0,_StorageIndex>;
|
||||
public:
|
||||
using Base::isCompressed;
|
||||
using Base::nonZeros;
|
||||
@@ -984,11 +988,11 @@ void set_from_triplets(const InputIterator& begin, const InputIterator& end, Spa
|
||||
* an abstract iterator over a complex data-structure that would be expensive to evaluate. The triplets should rather
|
||||
* be explicitely stored into a std::vector for instance.
|
||||
*/
|
||||
template<typename Scalar, int _Options, typename _Index>
|
||||
template<typename Scalar, int _Options, typename _StorageIndex>
|
||||
template<typename InputIterators>
|
||||
void SparseMatrix<Scalar,_Options,_Index>::setFromTriplets(const InputIterators& begin, const InputIterators& end)
|
||||
void SparseMatrix<Scalar,_Options,_StorageIndex>::setFromTriplets(const InputIterators& begin, const InputIterators& end)
|
||||
{
|
||||
internal::set_from_triplets<InputIterators, SparseMatrix<Scalar,_Options,_Index> >(begin, end, *this, internal::scalar_sum_op<Scalar,Scalar>());
|
||||
internal::set_from_triplets<InputIterators, SparseMatrix<Scalar,_Options,_StorageIndex> >(begin, end, *this, internal::scalar_sum_op<Scalar,Scalar>());
|
||||
}
|
||||
|
||||
/** The same as setFromTriplets but when duplicates are met the functor \a dup_func is applied:
|
||||
@@ -1000,17 +1004,17 @@ void SparseMatrix<Scalar,_Options,_Index>::setFromTriplets(const InputIterators&
|
||||
* mat.setFromTriplets(triplets.begin(), triplets.end(), [] (const Scalar&,const Scalar &b) { return b; });
|
||||
* \endcode
|
||||
*/
|
||||
template<typename Scalar, int _Options, typename _Index>
|
||||
template<typename Scalar, int _Options, typename _StorageIndex>
|
||||
template<typename InputIterators,typename DupFunctor>
|
||||
void SparseMatrix<Scalar,_Options,_Index>::setFromTriplets(const InputIterators& begin, const InputIterators& end, DupFunctor dup_func)
|
||||
void SparseMatrix<Scalar,_Options,_StorageIndex>::setFromTriplets(const InputIterators& begin, const InputIterators& end, DupFunctor dup_func)
|
||||
{
|
||||
internal::set_from_triplets<InputIterators, SparseMatrix<Scalar,_Options,_Index>, DupFunctor>(begin, end, *this, dup_func);
|
||||
internal::set_from_triplets<InputIterators, SparseMatrix<Scalar,_Options,_StorageIndex>, DupFunctor>(begin, end, *this, dup_func);
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
template<typename Scalar, int _Options, typename _Index>
|
||||
template<typename Scalar, int _Options, typename _StorageIndex>
|
||||
template<typename DupFunctor>
|
||||
void SparseMatrix<Scalar,_Options,_Index>::collapseDuplicates(DupFunctor dup_func)
|
||||
void SparseMatrix<Scalar,_Options,_StorageIndex>::collapseDuplicates(DupFunctor dup_func)
|
||||
{
|
||||
eigen_assert(!isCompressed());
|
||||
// TODO, in practice we should be able to use m_innerNonZeros for that task
|
||||
@@ -1048,9 +1052,9 @@ void SparseMatrix<Scalar,_Options,_Index>::collapseDuplicates(DupFunctor dup_fun
|
||||
m_data.resize(m_outerIndex[m_outerSize]);
|
||||
}
|
||||
|
||||
template<typename Scalar, int _Options, typename _Index>
|
||||
template<typename Scalar, int _Options, typename _StorageIndex>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other)
|
||||
EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_StorageIndex>& SparseMatrix<Scalar,_Options,_StorageIndex>::operator=(const SparseMatrixBase<OtherDerived>& other)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
@@ -1121,8 +1125,8 @@ EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Opt
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insert(Index row, Index col)
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex>
|
||||
typename SparseMatrix<_Scalar,_Options,_StorageIndex>::Scalar& SparseMatrix<_Scalar,_Options,_StorageIndex>::insert(Index row, Index col)
|
||||
{
|
||||
eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
|
||||
|
||||
@@ -1241,8 +1245,8 @@ typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Op
|
||||
return insertUncompressed(row,col);
|
||||
}
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertUncompressed(Index row, Index col)
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex>
|
||||
EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_StorageIndex>::Scalar& SparseMatrix<_Scalar,_Options,_StorageIndex>::insertUncompressed(Index row, Index col)
|
||||
{
|
||||
eigen_assert(!isCompressed());
|
||||
|
||||
@@ -1273,8 +1277,8 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& Sparse
|
||||
return (m_data.value(p) = 0);
|
||||
}
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertCompressed(Index row, Index col)
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex>
|
||||
EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_StorageIndex>::Scalar& SparseMatrix<_Scalar,_Options,_StorageIndex>::insertCompressed(Index row, Index col)
|
||||
{
|
||||
eigen_assert(isCompressed());
|
||||
|
||||
@@ -1297,11 +1301,11 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& Sparse
|
||||
// starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g.,
|
||||
// the 2nd inner vector...
|
||||
bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0))
|
||||
&& (size_t(m_outerIndex[outer+1]) == m_data.size());
|
||||
&& (std::size_t(m_outerIndex[outer+1]) == m_data.size());
|
||||
|
||||
size_t startId = m_outerIndex[outer];
|
||||
// FIXME let's make sure sizeof(long int) == sizeof(size_t)
|
||||
size_t p = m_outerIndex[outer+1];
|
||||
std::size_t startId = m_outerIndex[outer];
|
||||
// FIXME let's make sure sizeof(long int) == sizeof(std::size_t)
|
||||
std::size_t p = m_outerIndex[outer+1];
|
||||
++m_outerIndex[outer+1];
|
||||
|
||||
double reallocRatio = 1;
|
||||
@@ -1382,12 +1386,12 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& Sparse
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
struct evaluator<SparseMatrix<_Scalar,_Options,_Index> >
|
||||
: evaluator<SparseCompressedBase<SparseMatrix<_Scalar,_Options,_Index> > >
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex>
|
||||
struct evaluator<SparseMatrix<_Scalar,_Options,_StorageIndex> >
|
||||
: evaluator<SparseCompressedBase<SparseMatrix<_Scalar,_Options,_StorageIndex> > >
|
||||
{
|
||||
typedef evaluator<SparseCompressedBase<SparseMatrix<_Scalar,_Options,_Index> > > Base;
|
||||
typedef SparseMatrix<_Scalar,_Options,_Index> SparseMatrixType;
|
||||
typedef evaluator<SparseCompressedBase<SparseMatrix<_Scalar,_Options,_StorageIndex> > > Base;
|
||||
typedef SparseMatrix<_Scalar,_Options,_StorageIndex> SparseMatrixType;
|
||||
evaluator() : Base() {}
|
||||
explicit evaluator(const SparseMatrixType &mat) : Base(mat) {}
|
||||
};
|
||||
|
||||
@@ -37,7 +37,11 @@ template<typename Derived> class SparseMatrixBase
|
||||
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
|
||||
/** The integer type used to \b store indices within a SparseMatrix.
|
||||
* For a \c SparseMatrix<Scalar,Options,IndexType> it an alias of the third template parameter \c IndexType. */
|
||||
typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
|
||||
|
||||
typedef typename internal::add_const_on_value_type_if_arithmetic<
|
||||
typename internal::packet_traits<Scalar>::type
|
||||
>::type PacketReturnType;
|
||||
@@ -213,7 +217,7 @@ template<typename Derived> class SparseMatrixBase
|
||||
|
||||
if (Flags&RowMajorBit)
|
||||
{
|
||||
const Nested nm(m.derived());
|
||||
Nested nm(m.derived());
|
||||
internal::evaluator<NestedCleaned> thisEval(nm);
|
||||
for (Index row=0; row<nm.outerSize(); ++row)
|
||||
{
|
||||
@@ -232,7 +236,7 @@ template<typename Derived> class SparseMatrixBase
|
||||
}
|
||||
else
|
||||
{
|
||||
const Nested nm(m.derived());
|
||||
Nested nm(m.derived());
|
||||
internal::evaluator<NestedCleaned> thisEval(nm);
|
||||
if (m.cols() == 1) {
|
||||
Index row = 0;
|
||||
@@ -265,6 +269,11 @@ template<typename Derived> class SparseMatrixBase
|
||||
template<typename OtherDerived>
|
||||
Derived& operator-=(const DiagonalBase<OtherDerived>& other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
Derived& operator+=(const EigenBase<OtherDerived> &other);
|
||||
template<typename OtherDerived>
|
||||
Derived& operator-=(const EigenBase<OtherDerived> &other);
|
||||
|
||||
Derived& operator*=(const Scalar& other);
|
||||
Derived& operator/=(const Scalar& other);
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ template<typename MatrixType, unsigned int _Mode> class SparseSelfAdjointView
|
||||
|
||||
enum {
|
||||
Mode = _Mode,
|
||||
TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0),
|
||||
RowsAtCompileTime = internal::traits<SparseSelfAdjointView>::RowsAtCompileTime,
|
||||
ColsAtCompileTime = internal::traits<SparseSelfAdjointView>::ColsAtCompileTime
|
||||
};
|
||||
@@ -222,14 +223,43 @@ template< typename DstXprType, typename SrcXprType, typename Functor>
|
||||
struct Assignment<DstXprType, SrcXprType, Functor, SparseSelfAdjoint2Sparse>
|
||||
{
|
||||
typedef typename DstXprType::StorageIndex StorageIndex;
|
||||
typedef internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> AssignOpType;
|
||||
|
||||
template<typename DestScalar,int StorageOrder>
|
||||
static void run(SparseMatrix<DestScalar,StorageOrder,StorageIndex> &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
|
||||
static void run(SparseMatrix<DestScalar,StorageOrder,StorageIndex> &dst, const SrcXprType &src, const AssignOpType&/*func*/)
|
||||
{
|
||||
internal::permute_symm_to_fullsymm<SrcXprType::Mode>(src.matrix(), dst);
|
||||
}
|
||||
|
||||
// FIXME: the handling of += and -= in sparse matrices should be cleanup so that next two overloads could be reduced to:
|
||||
template<typename DestScalar,int StorageOrder,typename AssignFunc>
|
||||
static void run(SparseMatrix<DestScalar,StorageOrder,StorageIndex> &dst, const SrcXprType &src, const AssignFunc& func)
|
||||
{
|
||||
SparseMatrix<DestScalar,StorageOrder,StorageIndex> tmp(src.rows(),src.cols());
|
||||
run(tmp, src, AssignOpType());
|
||||
call_assignment_no_alias_no_transpose(dst, tmp, func);
|
||||
}
|
||||
|
||||
template<typename DestScalar,int StorageOrder>
|
||||
static void run(SparseMatrix<DestScalar,StorageOrder,StorageIndex> &dst, const SrcXprType &src,
|
||||
const internal::add_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>& /* func */)
|
||||
{
|
||||
SparseMatrix<DestScalar,StorageOrder,StorageIndex> tmp(src.rows(),src.cols());
|
||||
run(tmp, src, AssignOpType());
|
||||
dst += tmp;
|
||||
}
|
||||
|
||||
template<typename DestScalar,int StorageOrder>
|
||||
static void run(SparseMatrix<DestScalar,StorageOrder,StorageIndex> &dst, const SrcXprType &src,
|
||||
const internal::sub_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>& /* func */)
|
||||
{
|
||||
SparseMatrix<DestScalar,StorageOrder,StorageIndex> tmp(src.rows(),src.cols());
|
||||
run(tmp, src, AssignOpType());
|
||||
dst -= tmp;
|
||||
}
|
||||
|
||||
template<typename DestScalar>
|
||||
static void run(DynamicSparseMatrix<DestScalar,ColMajor,StorageIndex>& dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
|
||||
static void run(DynamicSparseMatrix<DestScalar,ColMajor,StorageIndex>& dst, const SrcXprType &src, const AssignOpType&/*func*/)
|
||||
{
|
||||
// TODO directly evaluate into dst;
|
||||
SparseMatrix<DestScalar,ColMajor,StorageIndex> tmp(dst.rows(),dst.cols());
|
||||
@@ -339,7 +369,7 @@ struct generic_product_impl<Lhs, RhsView, DenseShape, SparseSelfAdjointShape, Pr
|
||||
|
||||
// transpose everything
|
||||
Transpose<Dest> dstT(dst);
|
||||
internal::sparse_selfadjoint_time_dense_product<RhsView::Mode>(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha);
|
||||
internal::sparse_selfadjoint_time_dense_product<RhsView::TransposeMode>(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -55,7 +55,10 @@ template<typename MatrixType, unsigned int Mode> class TriangularViewImpl<Matrix
|
||||
this->solveInPlace(dst);
|
||||
}
|
||||
|
||||
/** Applies the inverse of \c *this to the dense vector or matrix \a other, "in-place" */
|
||||
template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
/** Applies the inverse of \c *this to the sparse vector or matrix \a other, "in-place" */
|
||||
template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const;
|
||||
|
||||
};
|
||||
|
||||
@@ -27,6 +27,20 @@ struct traits<SparseView<MatrixType> > : traits<MatrixType>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \ingroup SparseCore_Module
|
||||
* \class SparseView
|
||||
*
|
||||
* \brief Expression of a dense or sparse matrix with zero or too small values removed
|
||||
*
|
||||
* \tparam MatrixType the type of the object of which we are removing the small entries
|
||||
*
|
||||
* This class represents an expression of a given dense or sparse matrix with
|
||||
* entries smaller than \c reference * \c epsilon are removed.
|
||||
* It is the return type of MatrixBase::sparseView() and SparseMatrixBase::pruned()
|
||||
* and most of the time this is the only way it is used.
|
||||
*
|
||||
* \sa MatrixBase::sparseView(), SparseMatrixBase::pruned()
|
||||
*/
|
||||
template<typename MatrixType>
|
||||
class SparseView : public SparseMatrixBase<SparseView<MatrixType> >
|
||||
{
|
||||
@@ -190,6 +204,23 @@ struct unary_evaluator<SparseView<ArgType>, IndexBased>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \ingroup SparseCore_Module
|
||||
*
|
||||
* \returns a sparse expression of the dense expression \c *this with values smaller than
|
||||
* \a reference * \a epsilon removed.
|
||||
*
|
||||
* This method is typically used when prototyping to convert a quickly assembled dense Matrix \c D to a SparseMatrix \c S:
|
||||
* \code
|
||||
* MatrixXd D(n,m);
|
||||
* SparseMatrix<double> S;
|
||||
* S = D.sparseView(); // suppress numerical zeros (exact)
|
||||
* S = D.sparseView(reference);
|
||||
* S = D.sparseView(reference,epsilon);
|
||||
* \endcode
|
||||
* where \a reference is a meaningful non zero reference value,
|
||||
* and \a epsilon is a tolerance factor defaulting to NumTraits<Scalar>::dummy_precision().
|
||||
*
|
||||
* \sa SparseMatrixBase::pruned(), class SparseView */
|
||||
template<typename Derived>
|
||||
const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& reference,
|
||||
const typename NumTraits<Scalar>::Real& epsilon) const
|
||||
@@ -198,7 +229,7 @@ const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& referenc
|
||||
}
|
||||
|
||||
/** \returns an expression of \c *this with values smaller than
|
||||
* \a reference * \a epsilon are removed.
|
||||
* \a reference * \a epsilon removed.
|
||||
*
|
||||
* This method is typically used in conjunction with the product of two sparse matrices
|
||||
* to automatically prune the smallest values as follows:
|
||||
|
||||
@@ -171,6 +171,8 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,ColMajor>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
template<typename ExpressionType,unsigned int Mode>
|
||||
template<typename OtherDerived>
|
||||
void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(MatrixBase<OtherDerived>& other) const
|
||||
@@ -189,6 +191,7 @@ void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(MatrixBase<Oth
|
||||
if (copy)
|
||||
other = otherCopy;
|
||||
}
|
||||
#endif
|
||||
|
||||
// pure sparse path
|
||||
|
||||
@@ -286,6 +289,7 @@ struct sparse_solve_triangular_sparse_selector<Lhs,Rhs,Mode,UpLo,ColMajor>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename ExpressionType,unsigned int Mode>
|
||||
template<typename OtherDerived>
|
||||
void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(SparseMatrixBase<OtherDerived>& other) const
|
||||
@@ -304,6 +308,7 @@ void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(SparseMatrixBa
|
||||
// if (copy)
|
||||
// other = otherCopy;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
@@ -748,7 +748,7 @@ struct SparseLUMatrixUReturnType : internal::no_assignment_operator
|
||||
else
|
||||
{
|
||||
Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
Map< Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
Map< Matrix<Scalar,Dynamic,Dest::ColsAtCompileTime, ColMajor>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
U = A.template triangularView<Upper>().solve(U);
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ void MappedSuperNodalMatrix<Scalar,Index_>::solveInPlace( MatrixBase<Dest>&X) co
|
||||
Index n = int(X.rows());
|
||||
Index nrhs = Index(X.cols());
|
||||
const Scalar * Lval = valuePtr(); // Nonzero values
|
||||
Matrix<Scalar,Dynamic,Dynamic, ColMajor> work(n, nrhs); // working vector
|
||||
Matrix<Scalar,Dynamic,Dest::ColsAtCompileTime, ColMajor> work(n, nrhs); // working vector
|
||||
work.setZero();
|
||||
for (Index k = 0; k <= nsuper(); k ++)
|
||||
{
|
||||
@@ -271,12 +271,12 @@ void MappedSuperNodalMatrix<Scalar,Index_>::solveInPlace( MatrixBase<Dest>&X) co
|
||||
|
||||
// Triangular solve
|
||||
Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
Map< Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
Map< Matrix<Scalar,Dynamic,Dest::ColsAtCompileTime, ColMajor>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
U = A.template triangularView<UnitLower>().solve(U);
|
||||
|
||||
// Matrix-vector product
|
||||
new (&A) Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
|
||||
work.block(0, 0, nrow, nrhs) = A * U;
|
||||
work.topRows(nrow).noalias() = A * U;
|
||||
|
||||
//Begin Scatter
|
||||
for (Index j = 0; j < nrhs; j++)
|
||||
|
||||
@@ -22,13 +22,13 @@ namespace Eigen {
|
||||
class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR<T>
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
|
||||
@@ -967,6 +967,7 @@ void SuperILU<MatrixType>::factorize(const MatrixType& a)
|
||||
m_factorizationIsOk = true;
|
||||
}
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename MatrixType>
|
||||
template<typename Rhs,typename Dest>
|
||||
void SuperILU<MatrixType>::_solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest>& x) const
|
||||
@@ -1019,6 +1020,8 @@ void SuperILU<MatrixType>::_solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SUPERLUSUPPORT_H
|
||||
|
||||
@@ -10,19 +10,37 @@
|
||||
#ifndef EIGEN_UMFPACKSUPPORT_H
|
||||
#define EIGEN_UMFPACKSUPPORT_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace Eigen {
|
||||
|
||||
/* TODO extract L, extract U, compute det, etc... */
|
||||
|
||||
// generic double/complex<double> wrapper functions:
|
||||
|
||||
|
||||
inline void umfpack_defaults(double control[UMFPACK_CONTROL], double)
|
||||
inline void umfpack_defaults(double control[UMFPACK_CONTROL], double)
|
||||
{ umfpack_di_defaults(control); }
|
||||
|
||||
inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex<double>)
|
||||
inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex<double>)
|
||||
{ umfpack_zi_defaults(control); }
|
||||
|
||||
inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], double)
|
||||
{ umfpack_di_report_info(control, info);}
|
||||
|
||||
inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], std::complex<double>)
|
||||
{ umfpack_zi_report_info(control, info);}
|
||||
|
||||
inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, double)
|
||||
{ umfpack_di_report_status(control, status);}
|
||||
|
||||
inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, std::complex<double>)
|
||||
{ umfpack_zi_report_status(control, status);}
|
||||
|
||||
inline void umfpack_report_control(double control[UMFPACK_CONTROL], double)
|
||||
{ umfpack_di_report_control(control);}
|
||||
|
||||
inline void umfpack_report_control(double control[UMFPACK_CONTROL], std::complex<double>)
|
||||
{ umfpack_zi_report_control(control);}
|
||||
|
||||
inline void umfpack_free_numeric(void **Numeric, double)
|
||||
{ umfpack_di_free_numeric(Numeric); *Numeric = 0; }
|
||||
|
||||
@@ -156,6 +174,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
public:
|
||||
|
||||
typedef Array<double, UMFPACK_CONTROL, 1> UmfpackControl;
|
||||
typedef Array<double, UMFPACK_INFO, 1> UmfpackInfo;
|
||||
|
||||
UmfPackLU()
|
||||
: m_dummy(0,0), mp_matrix(m_dummy)
|
||||
@@ -215,7 +234,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
return m_q;
|
||||
}
|
||||
|
||||
/** Computes the sparse Cholesky decomposition of \a matrix
|
||||
/** Computes the sparse Cholesky decomposition of \a matrix
|
||||
* Note that the matrix should be column-major, and in compressed format for best performance.
|
||||
* \sa SparseMatrix::makeCompressed().
|
||||
*/
|
||||
@@ -240,7 +259,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
{
|
||||
if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar());
|
||||
if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar());
|
||||
|
||||
|
||||
grab(matrix.derived());
|
||||
|
||||
analyzePattern_impl();
|
||||
@@ -267,7 +286,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
{
|
||||
return m_control;
|
||||
}
|
||||
|
||||
|
||||
/** Provides access to the control settings array used by UmfPack.
|
||||
*
|
||||
* If this array contains NaN's, the default values are used.
|
||||
@@ -278,7 +297,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
{
|
||||
return m_control;
|
||||
}
|
||||
|
||||
|
||||
/** Performs a numeric decomposition of \a matrix
|
||||
*
|
||||
* The given matrix must has the same sparcity than the matrix on which the pattern anylysis has been performed.
|
||||
@@ -293,10 +312,38 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
umfpack_free_numeric(&m_numeric,Scalar());
|
||||
|
||||
grab(matrix.derived());
|
||||
|
||||
|
||||
factorize_impl();
|
||||
}
|
||||
|
||||
/** Prints the current UmfPack control settings.
|
||||
*
|
||||
* \sa umfpackControl()
|
||||
*/
|
||||
void umfpackReportControl()
|
||||
{
|
||||
umfpack_report_control(m_control.data(), Scalar());
|
||||
}
|
||||
|
||||
/** Prints statistics collected by UmfPack.
|
||||
*
|
||||
* \sa analyzePattern(), compute()
|
||||
*/
|
||||
void umfpackReportInfo()
|
||||
{
|
||||
eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
|
||||
umfpack_report_info(m_control.data(), m_umfpackInfo.data(), Scalar());
|
||||
}
|
||||
|
||||
/** Prints the status of the previous factorization operation performed by UmfPack (symbolic or numerical factorization).
|
||||
*
|
||||
* \sa analyzePattern(), compute()
|
||||
*/
|
||||
void umfpackReportStatus() {
|
||||
eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
|
||||
umfpack_report_status(m_control.data(), m_fact_errorCode, Scalar());
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
template<typename BDerived,typename XDerived>
|
||||
bool _solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const;
|
||||
@@ -314,41 +361,42 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
m_numeric = 0;
|
||||
m_symbolic = 0;
|
||||
m_extractedDataAreDirty = true;
|
||||
|
||||
umfpack_defaults(m_control.data(), Scalar());
|
||||
}
|
||||
|
||||
|
||||
void analyzePattern_impl()
|
||||
{
|
||||
umfpack_defaults(m_control.data(), Scalar());
|
||||
int errorCode = 0;
|
||||
errorCode = umfpack_symbolic(internal::convert_index<int>(mp_matrix.rows()),
|
||||
internal::convert_index<int>(mp_matrix.cols()),
|
||||
mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
|
||||
&m_symbolic, m_control.data(), 0);
|
||||
m_fact_errorCode = umfpack_symbolic(internal::convert_index<int>(mp_matrix.rows()),
|
||||
internal::convert_index<int>(mp_matrix.cols()),
|
||||
mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
|
||||
&m_symbolic, m_control.data(), m_umfpackInfo.data());
|
||||
|
||||
m_isInitialized = true;
|
||||
m_info = errorCode ? InvalidInput : Success;
|
||||
m_info = m_fact_errorCode ? InvalidInput : Success;
|
||||
m_analysisIsOk = true;
|
||||
m_factorizationIsOk = false;
|
||||
m_extractedDataAreDirty = true;
|
||||
}
|
||||
|
||||
|
||||
void factorize_impl()
|
||||
{
|
||||
|
||||
m_fact_errorCode = umfpack_numeric(mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
|
||||
m_symbolic, &m_numeric, m_control.data(), 0);
|
||||
m_symbolic, &m_numeric, m_control.data(), m_umfpackInfo.data());
|
||||
|
||||
m_info = m_fact_errorCode == UMFPACK_OK ? Success : NumericalIssue;
|
||||
m_factorizationIsOk = true;
|
||||
m_extractedDataAreDirty = true;
|
||||
}
|
||||
|
||||
|
||||
template<typename MatrixDerived>
|
||||
void grab(const EigenBase<MatrixDerived> &A)
|
||||
{
|
||||
mp_matrix.~UmfpackMatrixRef();
|
||||
::new (&mp_matrix) UmfpackMatrixRef(A.derived());
|
||||
}
|
||||
|
||||
|
||||
void grab(const UmfpackMatrixRef &A)
|
||||
{
|
||||
if(&(A.derived()) != &mp_matrix)
|
||||
@@ -357,19 +405,20 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
::new (&mp_matrix) UmfpackMatrixRef(A);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// cached data to reduce reallocation, etc.
|
||||
mutable LUMatrixType m_l;
|
||||
int m_fact_errorCode;
|
||||
UmfpackControl m_control;
|
||||
|
||||
mutable UmfpackInfo m_umfpackInfo;
|
||||
|
||||
mutable LUMatrixType m_u;
|
||||
mutable IntColVectorType m_p;
|
||||
mutable IntRowVectorType m_q;
|
||||
|
||||
UmfpackMatrixType m_dummy;
|
||||
UmfpackMatrixRef mp_matrix;
|
||||
|
||||
|
||||
void* m_numeric;
|
||||
void* m_symbolic;
|
||||
|
||||
@@ -377,7 +426,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
|
||||
int m_factorizationIsOk;
|
||||
int m_analysisIsOk;
|
||||
mutable bool m_extractedDataAreDirty;
|
||||
|
||||
|
||||
private:
|
||||
UmfPackLU(const UmfPackLU& ) { }
|
||||
};
|
||||
@@ -427,7 +476,7 @@ bool UmfPackLU<MatrixType>::_solve_impl(const MatrixBase<BDerived> &b, MatrixBas
|
||||
eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet");
|
||||
eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet");
|
||||
eigen_assert(b.derived().data() != x.derived().data() && " Umfpack does not support inplace solve");
|
||||
|
||||
|
||||
int errorCode;
|
||||
Scalar* x_ptr = 0;
|
||||
Matrix<Scalar,Dynamic,1> x_tmp;
|
||||
@@ -442,7 +491,7 @@ bool UmfPackLU<MatrixType>::_solve_impl(const MatrixBase<BDerived> &b, MatrixBas
|
||||
x_ptr = &x.col(j).coeffRef(0);
|
||||
errorCode = umfpack_solve(UMFPACK_A,
|
||||
mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
|
||||
x_ptr, &b.const_cast_derived().col(j).coeffRef(0), m_numeric, m_control.data(), 0);
|
||||
x_ptr, &b.const_cast_derived().col(j).coeffRef(0), m_numeric, m_control.data(), m_umfpackInfo.data());
|
||||
if(x.innerStride()!=1)
|
||||
x.col(j) = x_tmp;
|
||||
if (errorCode!=0)
|
||||
|
||||
@@ -818,7 +818,7 @@ inline typename FixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index sta
|
||||
return typename FixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol, blockRows, blockCols);
|
||||
}
|
||||
|
||||
/// This is the const version of block<>(Index, Index, Index, Index). */
|
||||
/// This is the const version of block<>(Index, Index, Index, Index).
|
||||
template<int NRows, int NCols>
|
||||
inline const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol,
|
||||
Index blockRows, Index blockCols) const
|
||||
@@ -832,15 +832,15 @@ inline const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow
|
||||
/// Output: \verbinclude MatrixBase_col.out
|
||||
///
|
||||
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
|
||||
///
|
||||
/// \sa row(), class Block */
|
||||
/**
|
||||
* \sa row(), class Block */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ColXpr col(Index i)
|
||||
{
|
||||
return ColXpr(derived(), i);
|
||||
}
|
||||
|
||||
/// This is the const version of col(). */
|
||||
/// This is the const version of col().
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ConstColXpr col(Index i) const
|
||||
{
|
||||
@@ -853,8 +853,8 @@ inline ConstColXpr col(Index i) const
|
||||
/// Output: \verbinclude MatrixBase_row.out
|
||||
///
|
||||
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
|
||||
///
|
||||
/// \sa col(), class Block */
|
||||
/**
|
||||
* \sa col(), class Block */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline RowXpr row(Index i)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
**Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.**
|
||||
|
||||
For more information go to http://eigen.tuxfamily.org/.
|
||||
**Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.**
|
||||
|
||||
For more information go to http://eigen.tuxfamily.org/.
|
||||
|
||||
@@ -38,25 +38,32 @@ if(SUPERLU_FOUND AND BLAS_FOUND)
|
||||
endif()
|
||||
|
||||
|
||||
find_package(Pastix)
|
||||
find_package(Scotch)
|
||||
find_package(Metis)
|
||||
if(PASTIX_FOUND AND BLAS_FOUND)
|
||||
find_package(PASTIX QUIET COMPONENTS METIS SCOTCH)
|
||||
# check that the PASTIX found is a version without MPI
|
||||
find_path(PASTIX_pastix_nompi.h_INCLUDE_DIRS
|
||||
NAMES pastix_nompi.h
|
||||
HINTS ${PASTIX_INCLUDE_DIRS}
|
||||
)
|
||||
if (NOT PASTIX_pastix_nompi.h_INCLUDE_DIRS)
|
||||
message(STATUS "A version of Pastix has been found but pastix_nompi.h does not exist in the include directory."
|
||||
" Because Eigen tests require a version without MPI, we disable the Pastix backend.")
|
||||
endif()
|
||||
if(PASTIX_FOUND AND PASTIX_pastix_nompi.h_INCLUDE_DIRS AND BLAS_FOUND)
|
||||
add_definitions("-DEIGEN_PASTIX_SUPPORT")
|
||||
include_directories(${PASTIX_INCLUDES})
|
||||
include_directories(${PASTIX_INCLUDE_DIRS_DEP})
|
||||
if(SCOTCH_FOUND)
|
||||
include_directories(${SCOTCH_INCLUDES})
|
||||
include_directories(${SCOTCH_INCLUDE_DIRS})
|
||||
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})
|
||||
elseif(METIS_FOUND)
|
||||
include_directories(${METIS_INCLUDES})
|
||||
include_directories(${METIS_INCLUDE_DIRS})
|
||||
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${METIS_LIBRARIES})
|
||||
endif(SCOTCH_FOUND)
|
||||
set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES} ${ORDERING_LIBRARIES} ${BLAS_LIBRARIES})
|
||||
set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES} ${BLAS_LIBRARIES})
|
||||
set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES_DEP} ${ORDERING_LIBRARIES})
|
||||
set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES_DEP})
|
||||
endif(PASTIX_FOUND AND BLAS_FOUND)
|
||||
|
||||
if(METIS_FOUND)
|
||||
include_directories(${METIS_INCLUDES})
|
||||
include_directories(${METIS_INCLUDE_DIRS})
|
||||
set (SPARSE_LIBS ${SPARSE_LIBS} ${METIS_LIBRARIES})
|
||||
add_definitions("-DEIGEN_METIS_SUPPORT")
|
||||
endif(METIS_FOUND)
|
||||
|
||||
1503
cmake/FindBLAS.cmake
1503
cmake/FindBLAS.cmake
File diff suppressed because it is too large
Load Diff
380
cmake/FindBLASEXT.cmake
Normal file
380
cmake/FindBLASEXT.cmake
Normal file
@@ -0,0 +1,380 @@
|
||||
###
|
||||
#
|
||||
# @copyright (c) 2009-2014 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation.
|
||||
# All rights reserved.
|
||||
# @copyright (c) 2012-2016 Inria. All rights reserved.
|
||||
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
|
||||
#
|
||||
###
|
||||
#
|
||||
# - Find BLAS EXTENDED for MORSE projects: find include dirs and libraries
|
||||
#
|
||||
# This module allows to find BLAS libraries by calling the official FindBLAS module
|
||||
# and handles the creation of different library lists whether the user wishes to link
|
||||
# with a sequential BLAS or a multihreaded (BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES).
|
||||
# BLAS is detected with a FindBLAS call then if the BLAS vendor is Intel10_64lp, ACML
|
||||
# or IBMESSLMT then the module attempts to find the corresponding multithreaded libraries.
|
||||
#
|
||||
# The following variables have been added to manage links with sequential or multithreaded
|
||||
# versions:
|
||||
# BLAS_INCLUDE_DIRS - BLAS include directories
|
||||
# BLAS_LIBRARY_DIRS - Link directories for BLAS libraries
|
||||
# BLAS_SEQ_LIBRARIES - BLAS component libraries to be linked (sequential)
|
||||
# BLAS_PAR_LIBRARIES - BLAS component libraries to be linked (multithreaded)
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2012-2013 Inria
|
||||
# Copyright 2012-2013 Emmanuel Agullo
|
||||
# Copyright 2012-2013 Mathieu Faverge
|
||||
# Copyright 2012 Cedric Castagnede
|
||||
# Copyright 2013-2016 Florent Pruvost
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file MORSE-Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of Morse, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# macro to factorize this call
|
||||
macro(find_package_blas)
|
||||
if(BLASEXT_FIND_REQUIRED)
|
||||
if(BLASEXT_FIND_QUIETLY)
|
||||
find_package(BLAS REQUIRED QUIET)
|
||||
else()
|
||||
find_package(BLAS REQUIRED)
|
||||
endif()
|
||||
else()
|
||||
if(BLASEXT_FIND_QUIETLY)
|
||||
find_package(BLAS QUIET)
|
||||
else()
|
||||
find_package(BLAS)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# add a cache variable to let the user specify the BLAS vendor
|
||||
set(BLA_VENDOR "" CACHE STRING "list of possible BLAS vendor:
|
||||
Open, Eigen, Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT,
|
||||
Intel10_32 (intel mkl v10 32 bit),
|
||||
Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model),
|
||||
Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),
|
||||
Intel( older versions of mkl 32 and 64 bit),
|
||||
ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")
|
||||
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "In FindBLASEXT")
|
||||
message(STATUS "If you want to force the use of one specific library, "
|
||||
"\n please specify the BLAS vendor by setting -DBLA_VENDOR=blas_vendor_name"
|
||||
"\n at cmake configure.")
|
||||
message(STATUS "List of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, "
|
||||
"\n DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT, Intel10_32 (intel mkl v10 32 bit),"
|
||||
"\n Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model),"
|
||||
"\n Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),"
|
||||
"\n Intel( older versions of mkl 32 and 64 bit),"
|
||||
"\n ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")
|
||||
endif()
|
||||
|
||||
if (NOT BLAS_FOUND)
|
||||
# First try to detect two cases:
|
||||
# 1: only SEQ libs are handled
|
||||
# 2: both SEQ and PAR libs are handled
|
||||
find_package_blas()
|
||||
endif ()
|
||||
|
||||
# detect the cases where SEQ and PAR libs are handled
|
||||
if(BLA_VENDOR STREQUAL "All" AND
|
||||
(BLAS_mkl_core_LIBRARY OR BLAS_mkl_core_dll_LIBRARY)
|
||||
)
|
||||
set(BLA_VENDOR "Intel")
|
||||
if(BLAS_mkl_intel_LIBRARY)
|
||||
set(BLA_VENDOR "Intel10_32")
|
||||
endif()
|
||||
if(BLAS_mkl_intel_lp64_LIBRARY)
|
||||
set(BLA_VENDOR "Intel10_64lp")
|
||||
endif()
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
|
||||
"\n have also potentially detected some multithreaded BLAS libraries from the MKL."
|
||||
"\n We try to find both libraries lists (Sequential/Multithreaded).")
|
||||
endif()
|
||||
set(BLAS_FOUND "")
|
||||
elseif(BLA_VENDOR STREQUAL "All" AND BLAS_acml_LIBRARY)
|
||||
set(BLA_VENDOR "ACML")
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
|
||||
"\n have also potentially detected some multithreaded BLAS libraries from the ACML."
|
||||
"\n We try to find both libraries lists (Sequential/Multithreaded).")
|
||||
endif()
|
||||
set(BLAS_FOUND "")
|
||||
elseif(BLA_VENDOR STREQUAL "All" AND BLAS_essl_LIBRARY)
|
||||
set(BLA_VENDOR "IBMESSL")
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
|
||||
"\n have also potentially detected some multithreaded BLAS libraries from the ESSL."
|
||||
"\n We try to find both libraries lists (Sequential/Multithreaded).")
|
||||
endif()
|
||||
set(BLAS_FOUND "")
|
||||
endif()
|
||||
|
||||
# Intel case
|
||||
if(BLA_VENDOR MATCHES "Intel*")
|
||||
|
||||
###
|
||||
# look for include path if the BLAS vendor is Intel
|
||||
###
|
||||
|
||||
# gather system include paths
|
||||
unset(_inc_env)
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
endif()
|
||||
list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
set(ENV_MKLROOT "$ENV{MKLROOT}")
|
||||
if (ENV_MKLROOT)
|
||||
list(APPEND _inc_env "${ENV_MKLROOT}/include")
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _inc_env)
|
||||
|
||||
# find mkl.h inside known include paths
|
||||
set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
|
||||
if(BLAS_INCDIR)
|
||||
set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
|
||||
find_path(BLAS_mkl.h_INCLUDE_DIRS
|
||||
NAMES mkl.h
|
||||
HINTS ${BLAS_INCDIR})
|
||||
else()
|
||||
if(BLAS_DIR)
|
||||
set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
|
||||
find_path(BLAS_mkl.h_INCLUDE_DIRS
|
||||
NAMES mkl.h
|
||||
HINTS ${BLAS_DIR}
|
||||
PATH_SUFFIXES include)
|
||||
else()
|
||||
set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
|
||||
find_path(BLAS_mkl.h_INCLUDE_DIRS
|
||||
NAMES mkl.h
|
||||
HINTS ${_inc_env})
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(BLAS_mkl.h_INCLUDE_DIRS)
|
||||
## Print status if not found
|
||||
## -------------------------
|
||||
#if (NOT BLAS_mkl.h_INCLUDE_DIRS AND MORSE_VERBOSE)
|
||||
# Print_Find_Header_Status(blas mkl.h)
|
||||
#endif ()
|
||||
set(BLAS_INCLUDE_DIRS "")
|
||||
if(BLAS_mkl.h_INCLUDE_DIRS)
|
||||
list(APPEND BLAS_INCLUDE_DIRS "${BLAS_mkl.h_INCLUDE_DIRS}" )
|
||||
endif()
|
||||
|
||||
###
|
||||
# look for libs
|
||||
###
|
||||
# if Intel 10 64 bit -> look for sequential and multithreaded versions
|
||||
if(BLA_VENDOR MATCHES "Intel10_64lp*")
|
||||
|
||||
## look for the sequential version
|
||||
set(BLA_VENDOR "Intel10_64lp_seq")
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "Look for the sequential version Intel10_64lp_seq")
|
||||
endif()
|
||||
find_package_blas()
|
||||
if(BLAS_FOUND)
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
|
||||
## look for the multithreaded version
|
||||
set(BLA_VENDOR "Intel10_64lp")
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "Look for the multithreaded version Intel10_64lp")
|
||||
endif()
|
||||
find_package_blas()
|
||||
if(BLAS_FOUND)
|
||||
set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
if(BLAS_FOUND)
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# ACML case
|
||||
elseif(BLA_VENDOR MATCHES "ACML*")
|
||||
|
||||
## look for the sequential version
|
||||
set(BLA_VENDOR "ACML")
|
||||
find_package_blas()
|
||||
if(BLAS_FOUND)
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
|
||||
## look for the multithreaded version
|
||||
set(BLA_VENDOR "ACML_MP")
|
||||
find_package_blas()
|
||||
if(BLAS_FOUND)
|
||||
set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
|
||||
# IBMESSL case
|
||||
elseif(BLA_VENDOR MATCHES "IBMESSL*")
|
||||
|
||||
## look for the sequential version
|
||||
set(BLA_VENDOR "IBMESSL")
|
||||
find_package_blas()
|
||||
if(BLAS_FOUND)
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
|
||||
## look for the multithreaded version
|
||||
set(BLA_VENDOR "IBMESSLMT")
|
||||
find_package_blas()
|
||||
if(BLAS_FOUND)
|
||||
set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
if(BLAS_FOUND)
|
||||
# define the SEQ libs as the BLAS_LIBRARIES
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
else()
|
||||
set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
|
||||
endif()
|
||||
set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
if(BLAS_SEQ_LIBRARIES)
|
||||
set(BLAS_LIBRARIES "${BLAS_SEQ_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
# extract libs paths
|
||||
# remark: because it is not given by find_package(BLAS)
|
||||
set(BLAS_LIBRARY_DIRS "")
|
||||
string(REPLACE " " ";" BLAS_LIBRARIES "${BLAS_LIBRARIES}")
|
||||
foreach(blas_lib ${BLAS_LIBRARIES})
|
||||
if (EXISTS "${blas_lib}")
|
||||
get_filename_component(a_blas_lib_dir "${blas_lib}" PATH)
|
||||
list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" )
|
||||
else()
|
||||
string(REPLACE "-L" "" blas_lib "${blas_lib}")
|
||||
if (EXISTS "${blas_lib}")
|
||||
list(APPEND BLAS_LIBRARY_DIRS "${blas_lib}" )
|
||||
else()
|
||||
get_filename_component(a_blas_lib_dir "${blas_lib}" PATH)
|
||||
if (EXISTS "${a_blas_lib_dir}")
|
||||
list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" )
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
if (BLAS_LIBRARY_DIRS)
|
||||
list(REMOVE_DUPLICATES BLAS_LIBRARY_DIRS)
|
||||
endif ()
|
||||
|
||||
# check that BLAS has been found
|
||||
# ---------------------------------
|
||||
include(FindPackageHandleStandardArgs)
|
||||
if(BLA_VENDOR MATCHES "Intel*")
|
||||
if(BLA_VENDOR MATCHES "Intel10_64lp*")
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS found is Intel MKL:"
|
||||
"\n we manage two lists of libs, one sequential and one parallel if found"
|
||||
"\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)")
|
||||
message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_SEQ_LIBRARIES
|
||||
BLAS_LIBRARY_DIRS
|
||||
BLAS_INCLUDE_DIRS)
|
||||
if(BLAS_PAR_LIBRARIES)
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_PAR_LIBRARIES)
|
||||
endif()
|
||||
else()
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_SEQ_LIBRARIES
|
||||
BLAS_LIBRARY_DIRS
|
||||
BLAS_INCLUDE_DIRS)
|
||||
endif()
|
||||
elseif(BLA_VENDOR MATCHES "ACML*")
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS found is ACML:"
|
||||
"\n we manage two lists of libs, one sequential and one parallel if found"
|
||||
"\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)")
|
||||
message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_SEQ_LIBRARIES
|
||||
BLAS_LIBRARY_DIRS)
|
||||
if(BLAS_PAR_LIBRARIES)
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_PAR_LIBRARIES)
|
||||
endif()
|
||||
elseif(BLA_VENDOR MATCHES "IBMESSL*")
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS found is ESSL:"
|
||||
"\n we manage two lists of libs, one sequential and one parallel if found"
|
||||
"\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)")
|
||||
message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_SEQ_LIBRARIES
|
||||
BLAS_LIBRARY_DIRS)
|
||||
if(BLAS_PAR_LIBRARIES)
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_PAR_LIBRARIES)
|
||||
endif()
|
||||
else()
|
||||
if(NOT BLASEXT_FIND_QUIETLY)
|
||||
message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
|
||||
endif()
|
||||
find_package_handle_standard_args(BLAS DEFAULT_MSG
|
||||
BLAS_SEQ_LIBRARIES
|
||||
BLAS_LIBRARY_DIRS)
|
||||
endif()
|
||||
331
cmake/FindHWLOC.cmake
Normal file
331
cmake/FindHWLOC.cmake
Normal file
@@ -0,0 +1,331 @@
|
||||
###
|
||||
#
|
||||
# @copyright (c) 2009-2014 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation.
|
||||
# All rights reserved.
|
||||
# @copyright (c) 2012-2014 Inria. All rights reserved.
|
||||
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
|
||||
#
|
||||
###
|
||||
#
|
||||
# - Find HWLOC include dirs and libraries
|
||||
# Use this module by invoking find_package with the form:
|
||||
# find_package(HWLOC
|
||||
# [REQUIRED]) # Fail with error if hwloc is not found
|
||||
#
|
||||
# This module finds headers and hwloc library.
|
||||
# Results are reported in variables:
|
||||
# HWLOC_FOUND - True if headers and requested libraries were found
|
||||
# HWLOC_INCLUDE_DIRS - hwloc include directories
|
||||
# HWLOC_LIBRARY_DIRS - Link directories for hwloc libraries
|
||||
# HWLOC_LIBRARIES - hwloc component libraries to be linked
|
||||
#
|
||||
# The user can give specific paths where to find the libraries adding cmake
|
||||
# options at configure (ex: cmake path/to/project -DHWLOC_DIR=path/to/hwloc):
|
||||
# HWLOC_DIR - Where to find the base directory of hwloc
|
||||
# HWLOC_INCDIR - Where to find the header files
|
||||
# HWLOC_LIBDIR - Where to find the library files
|
||||
# The module can also look for the following environment variables if paths
|
||||
# are not given as cmake variable: HWLOC_DIR, HWLOC_INCDIR, HWLOC_LIBDIR
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2012-2013 Inria
|
||||
# Copyright 2012-2013 Emmanuel Agullo
|
||||
# Copyright 2012-2013 Mathieu Faverge
|
||||
# Copyright 2012 Cedric Castagnede
|
||||
# Copyright 2013 Florent Pruvost
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file MORSE-Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of Morse, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
include(CheckStructHasMember)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
if (NOT HWLOC_FOUND)
|
||||
set(HWLOC_DIR "" CACHE PATH "Installation directory of HWLOC library")
|
||||
if (NOT HWLOC_FIND_QUIETLY)
|
||||
message(STATUS "A cache variable, namely HWLOC_DIR, has been set to specify the install directory of HWLOC")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(ENV_HWLOC_DIR "$ENV{HWLOC_DIR}")
|
||||
set(ENV_HWLOC_INCDIR "$ENV{HWLOC_INCDIR}")
|
||||
set(ENV_HWLOC_LIBDIR "$ENV{HWLOC_LIBDIR}")
|
||||
set(HWLOC_GIVEN_BY_USER "FALSE")
|
||||
if ( HWLOC_DIR OR ( HWLOC_INCDIR AND HWLOC_LIBDIR) OR ENV_HWLOC_DIR OR (ENV_HWLOC_INCDIR AND ENV_HWLOC_LIBDIR) )
|
||||
set(HWLOC_GIVEN_BY_USER "TRUE")
|
||||
endif()
|
||||
|
||||
# Optionally use pkg-config to detect include/library dirs (if pkg-config is available)
|
||||
# -------------------------------------------------------------------------------------
|
||||
include(FindPkgConfig)
|
||||
find_package(PkgConfig QUIET)
|
||||
if( PKG_CONFIG_EXECUTABLE AND NOT HWLOC_GIVEN_BY_USER )
|
||||
|
||||
pkg_search_module(HWLOC hwloc)
|
||||
if (NOT HWLOC_FIND_QUIETLY)
|
||||
if (HWLOC_FOUND AND HWLOC_LIBRARIES)
|
||||
message(STATUS "Looking for HWLOC - found using PkgConfig")
|
||||
#if(NOT HWLOC_INCLUDE_DIRS)
|
||||
# message("${Magenta}HWLOC_INCLUDE_DIRS is empty using PkgConfig."
|
||||
# "Perhaps the path to hwloc headers is already present in your"
|
||||
# "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}")
|
||||
#endif()
|
||||
else()
|
||||
message(STATUS "${Magenta}Looking for HWLOC - not found using PkgConfig."
|
||||
"\n Perhaps you should add the directory containing hwloc.pc to"
|
||||
"\n the PKG_CONFIG_PATH environment variable.${ColourReset}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif( PKG_CONFIG_EXECUTABLE AND NOT HWLOC_GIVEN_BY_USER )
|
||||
|
||||
if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT HWLOC_FOUND) OR (HWLOC_GIVEN_BY_USER) )
|
||||
|
||||
if (NOT HWLOC_FIND_QUIETLY)
|
||||
message(STATUS "Looking for HWLOC - PkgConfig not used")
|
||||
endif()
|
||||
|
||||
# Looking for include
|
||||
# -------------------
|
||||
|
||||
# Add system include paths to search include
|
||||
# ------------------------------------------
|
||||
unset(_inc_env)
|
||||
if(ENV_HWLOC_INCDIR)
|
||||
list(APPEND _inc_env "${ENV_HWLOC_INCDIR}")
|
||||
elseif(ENV_HWLOC_DIR)
|
||||
list(APPEND _inc_env "${ENV_HWLOC_DIR}")
|
||||
list(APPEND _inc_env "${ENV_HWLOC_DIR}/include")
|
||||
list(APPEND _inc_env "${ENV_HWLOC_DIR}/include/hwloc")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(REMOVE_DUPLICATES _inc_env)
|
||||
|
||||
# set paths where to look for
|
||||
set(PATH_TO_LOOK_FOR "${_inc_env}")
|
||||
|
||||
# Try to find the hwloc header in the given paths
|
||||
# -------------------------------------------------
|
||||
# call cmake macro to find the header path
|
||||
if(HWLOC_INCDIR)
|
||||
set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND")
|
||||
find_path(HWLOC_hwloc.h_DIRS
|
||||
NAMES hwloc.h
|
||||
HINTS ${HWLOC_INCDIR})
|
||||
else()
|
||||
if(HWLOC_DIR)
|
||||
set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND")
|
||||
find_path(HWLOC_hwloc.h_DIRS
|
||||
NAMES hwloc.h
|
||||
HINTS ${HWLOC_DIR}
|
||||
PATH_SUFFIXES "include" "include/hwloc")
|
||||
else()
|
||||
set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND")
|
||||
find_path(HWLOC_hwloc.h_DIRS
|
||||
NAMES hwloc.h
|
||||
HINTS ${PATH_TO_LOOK_FOR}
|
||||
PATH_SUFFIXES "hwloc")
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(HWLOC_hwloc.h_DIRS)
|
||||
|
||||
# Add path to cmake variable
|
||||
# ------------------------------------
|
||||
if (HWLOC_hwloc.h_DIRS)
|
||||
set(HWLOC_INCLUDE_DIRS "${HWLOC_hwloc.h_DIRS}")
|
||||
else ()
|
||||
set(HWLOC_INCLUDE_DIRS "HWLOC_INCLUDE_DIRS-NOTFOUND")
|
||||
if(NOT HWLOC_FIND_QUIETLY)
|
||||
message(STATUS "Looking for hwloc -- hwloc.h not found")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if (HWLOC_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES HWLOC_INCLUDE_DIRS)
|
||||
endif ()
|
||||
|
||||
|
||||
# Looking for lib
|
||||
# ---------------
|
||||
|
||||
# Add system library paths to search lib
|
||||
# --------------------------------------
|
||||
unset(_lib_env)
|
||||
if(ENV_HWLOC_LIBDIR)
|
||||
list(APPEND _lib_env "${ENV_HWLOC_LIBDIR}")
|
||||
elseif(ENV_HWLOC_DIR)
|
||||
list(APPEND _lib_env "${ENV_HWLOC_DIR}")
|
||||
list(APPEND _lib_env "${ENV_HWLOC_DIR}/lib")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
|
||||
else()
|
||||
if(APPLE)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
|
||||
endif()
|
||||
list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
|
||||
list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
|
||||
endif()
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _lib_env)
|
||||
|
||||
# set paths where to look for
|
||||
set(PATH_TO_LOOK_FOR "${_lib_env}")
|
||||
|
||||
# Try to find the hwloc lib in the given paths
|
||||
# ----------------------------------------------
|
||||
|
||||
# call cmake macro to find the lib path
|
||||
if(HWLOC_LIBDIR)
|
||||
set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND")
|
||||
find_library(HWLOC_hwloc_LIBRARY
|
||||
NAMES hwloc
|
||||
HINTS ${HWLOC_LIBDIR})
|
||||
else()
|
||||
if(HWLOC_DIR)
|
||||
set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND")
|
||||
find_library(HWLOC_hwloc_LIBRARY
|
||||
NAMES hwloc
|
||||
HINTS ${HWLOC_DIR}
|
||||
PATH_SUFFIXES lib lib32 lib64)
|
||||
else()
|
||||
set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND")
|
||||
find_library(HWLOC_hwloc_LIBRARY
|
||||
NAMES hwloc
|
||||
HINTS ${PATH_TO_LOOK_FOR})
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(HWLOC_hwloc_LIBRARY)
|
||||
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
if (HWLOC_hwloc_LIBRARY)
|
||||
get_filename_component(hwloc_lib_path ${HWLOC_hwloc_LIBRARY} PATH)
|
||||
# set cmake variables (respects naming convention)
|
||||
set(HWLOC_LIBRARIES "${HWLOC_hwloc_LIBRARY}")
|
||||
set(HWLOC_LIBRARY_DIRS "${hwloc_lib_path}")
|
||||
else ()
|
||||
set(HWLOC_LIBRARIES "HWLOC_LIBRARIES-NOTFOUND")
|
||||
set(HWLOC_LIBRARY_DIRS "HWLOC_LIBRARY_DIRS-NOTFOUND")
|
||||
if(NOT HWLOC_FIND_QUIETLY)
|
||||
message(STATUS "Looking for hwloc -- lib hwloc not found")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if (HWLOC_LIBRARY_DIRS)
|
||||
list(REMOVE_DUPLICATES HWLOC_LIBRARY_DIRS)
|
||||
endif ()
|
||||
|
||||
# check a function to validate the find
|
||||
if(HWLOC_LIBRARIES)
|
||||
|
||||
set(REQUIRED_INCDIRS)
|
||||
set(REQUIRED_LIBDIRS)
|
||||
set(REQUIRED_LIBS)
|
||||
|
||||
# HWLOC
|
||||
if (HWLOC_INCLUDE_DIRS)
|
||||
set(REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}")
|
||||
endif()
|
||||
if (HWLOC_LIBRARY_DIRS)
|
||||
set(REQUIRED_LIBDIRS "${HWLOC_LIBRARY_DIRS}")
|
||||
endif()
|
||||
set(REQUIRED_LIBS "${HWLOC_LIBRARIES}")
|
||||
|
||||
# set required libraries for link
|
||||
set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
foreach(lib_dir ${REQUIRED_LIBDIRS})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
|
||||
endforeach()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
|
||||
string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
|
||||
|
||||
# test link
|
||||
unset(HWLOC_WORKS CACHE)
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(hwloc_topology_init HWLOC_WORKS)
|
||||
mark_as_advanced(HWLOC_WORKS)
|
||||
|
||||
if(NOT HWLOC_WORKS)
|
||||
if(NOT HWLOC_FIND_QUIETLY)
|
||||
message(STATUS "Looking for hwloc : test of hwloc_topology_init with hwloc library fails")
|
||||
message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
|
||||
message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
|
||||
message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif(HWLOC_LIBRARIES)
|
||||
|
||||
endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT HWLOC_FOUND) OR (HWLOC_GIVEN_BY_USER) )
|
||||
|
||||
if (HWLOC_LIBRARIES)
|
||||
if (HWLOC_LIBRARY_DIRS)
|
||||
list(GET HWLOC_LIBRARY_DIRS 0 first_lib_path)
|
||||
else()
|
||||
list(GET HWLOC_LIBRARIES 0 first_lib)
|
||||
get_filename_component(first_lib_path "${first_lib}" PATH)
|
||||
endif()
|
||||
if (${first_lib_path} MATCHES "/lib(32|64)?$")
|
||||
string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
|
||||
set(HWLOC_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of HWLOC library" FORCE)
|
||||
else()
|
||||
set(HWLOC_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of HWLOC library" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(HWLOC_DIR)
|
||||
mark_as_advanced(HWLOC_DIR_FOUND)
|
||||
|
||||
# check that HWLOC has been found
|
||||
# -------------------------------
|
||||
include(FindPackageHandleStandardArgs)
|
||||
if (PKG_CONFIG_EXECUTABLE AND HWLOC_FOUND)
|
||||
find_package_handle_standard_args(HWLOC DEFAULT_MSG
|
||||
HWLOC_LIBRARIES)
|
||||
else()
|
||||
find_package_handle_standard_args(HWLOC DEFAULT_MSG
|
||||
HWLOC_LIBRARIES
|
||||
HWLOC_WORKS)
|
||||
endif()
|
||||
|
||||
if (HWLOC_FOUND)
|
||||
set(HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${HWLOC_INCLUDE_DIRS})
|
||||
|
||||
# test headers to guess the version
|
||||
check_struct_has_member( "struct hwloc_obj" parent hwloc.h HAVE_HWLOC_PARENT_MEMBER )
|
||||
check_struct_has_member( "struct hwloc_cache_attr_s" size hwloc.h HAVE_HWLOC_CACHE_ATTR )
|
||||
check_c_source_compiles( "#include <hwloc.h>
|
||||
int main(void) { hwloc_obj_t o; o->type = HWLOC_OBJ_PU; return 0;}" HAVE_HWLOC_OBJ_PU)
|
||||
include(CheckLibraryExists)
|
||||
check_library_exists(${HWLOC_LIBRARIES} hwloc_bitmap_free "" HAVE_HWLOC_BITMAP)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES})
|
||||
endif()
|
||||
@@ -1,59 +1,264 @@
|
||||
# Pastix requires METIS or METIS (partitioning and reordering tools)
|
||||
###
|
||||
#
|
||||
# @copyright (c) 2009-2014 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation.
|
||||
# All rights reserved.
|
||||
# @copyright (c) 2012-2014 Inria. All rights reserved.
|
||||
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
|
||||
#
|
||||
###
|
||||
#
|
||||
# - Find METIS include dirs and libraries
|
||||
# Use this module by invoking find_package with the form:
|
||||
# find_package(METIS
|
||||
# [REQUIRED] # Fail with error if metis is not found
|
||||
# )
|
||||
#
|
||||
# This module finds headers and metis library.
|
||||
# Results are reported in variables:
|
||||
# METIS_FOUND - True if headers and requested libraries were found
|
||||
# METIS_INCLUDE_DIRS - metis include directories
|
||||
# METIS_LIBRARY_DIRS - Link directories for metis libraries
|
||||
# METIS_LIBRARIES - metis component libraries to be linked
|
||||
#
|
||||
# The user can give specific paths where to find the libraries adding cmake
|
||||
# options at configure (ex: cmake path/to/project -DMETIS_DIR=path/to/metis):
|
||||
# METIS_DIR - Where to find the base directory of metis
|
||||
# METIS_INCDIR - Where to find the header files
|
||||
# METIS_LIBDIR - Where to find the library files
|
||||
# The module can also look for the following environment variables if paths
|
||||
# are not given as cmake variable: METIS_DIR, METIS_INCDIR, METIS_LIBDIR
|
||||
|
||||
if (METIS_INCLUDES AND METIS_LIBRARIES)
|
||||
set(METIS_FIND_QUIETLY TRUE)
|
||||
endif (METIS_INCLUDES AND METIS_LIBRARIES)
|
||||
#=============================================================================
|
||||
# Copyright 2012-2013 Inria
|
||||
# Copyright 2012-2013 Emmanuel Agullo
|
||||
# Copyright 2012-2013 Mathieu Faverge
|
||||
# Copyright 2012 Cedric Castagnede
|
||||
# Copyright 2013 Florent Pruvost
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file MORSE-Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of Morse, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
find_path(METIS_INCLUDES
|
||||
NAMES
|
||||
metis.h
|
||||
PATHS
|
||||
$ENV{METISDIR}
|
||||
${INCLUDE_INSTALL_DIR}
|
||||
PATH_SUFFIXES
|
||||
.
|
||||
metis
|
||||
include
|
||||
)
|
||||
|
||||
macro(_metis_check_version)
|
||||
file(READ "${METIS_INCLUDES}/metis.h" _metis_version_header)
|
||||
|
||||
string(REGEX MATCH "define[ \t]+METIS_VER_MAJOR[ \t]+([0-9]+)" _metis_major_version_match "${_metis_version_header}")
|
||||
set(METIS_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
||||
string(REGEX MATCH "define[ \t]+METIS_VER_MINOR[ \t]+([0-9]+)" _metis_minor_version_match "${_metis_version_header}")
|
||||
set(METIS_MINOR_VERSION "${CMAKE_MATCH_1}")
|
||||
string(REGEX MATCH "define[ \t]+METIS_VER_SUBMINOR[ \t]+([0-9]+)" _metis_subminor_version_match "${_metis_version_header}")
|
||||
set(METIS_SUBMINOR_VERSION "${CMAKE_MATCH_1}")
|
||||
if(NOT METIS_MAJOR_VERSION)
|
||||
message(STATUS "Could not determine Metis version. Assuming version 4.0.0")
|
||||
set(METIS_VERSION 4.0.0)
|
||||
else()
|
||||
set(METIS_VERSION ${METIS_MAJOR_VERSION}.${METIS_MINOR_VERSION}.${METIS_SUBMINOR_VERSION})
|
||||
if (NOT METIS_FOUND)
|
||||
set(METIS_DIR "" CACHE PATH "Installation directory of METIS library")
|
||||
if (NOT METIS_FIND_QUIETLY)
|
||||
message(STATUS "A cache variable, namely METIS_DIR, has been set to specify the install directory of METIS")
|
||||
endif()
|
||||
if(${METIS_VERSION} VERSION_LESS ${Metis_FIND_VERSION})
|
||||
set(METIS_VERSION_OK FALSE)
|
||||
endif()
|
||||
|
||||
# Looking for include
|
||||
# -------------------
|
||||
|
||||
# Add system include paths to search include
|
||||
# ------------------------------------------
|
||||
unset(_inc_env)
|
||||
set(ENV_METIS_DIR "$ENV{METIS_DIR}")
|
||||
set(ENV_METIS_INCDIR "$ENV{METIS_INCDIR}")
|
||||
if(ENV_METIS_INCDIR)
|
||||
list(APPEND _inc_env "${ENV_METIS_INCDIR}")
|
||||
elseif(ENV_METIS_DIR)
|
||||
list(APPEND _inc_env "${ENV_METIS_DIR}")
|
||||
list(APPEND _inc_env "${ENV_METIS_DIR}/include")
|
||||
list(APPEND _inc_env "${ENV_METIS_DIR}/include/metis")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
|
||||
else()
|
||||
set(METIS_VERSION_OK TRUE)
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(REMOVE_DUPLICATES _inc_env)
|
||||
|
||||
|
||||
# Try to find the metis header in the given paths
|
||||
# -------------------------------------------------
|
||||
# call cmake macro to find the header path
|
||||
if(METIS_INCDIR)
|
||||
set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND")
|
||||
find_path(METIS_metis.h_DIRS
|
||||
NAMES metis.h
|
||||
HINTS ${METIS_INCDIR})
|
||||
else()
|
||||
if(METIS_DIR)
|
||||
set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND")
|
||||
find_path(METIS_metis.h_DIRS
|
||||
NAMES metis.h
|
||||
HINTS ${METIS_DIR}
|
||||
PATH_SUFFIXES "include" "include/metis")
|
||||
else()
|
||||
set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND")
|
||||
find_path(METIS_metis.h_DIRS
|
||||
NAMES metis.h
|
||||
HINTS ${_inc_env})
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(METIS_metis.h_DIRS)
|
||||
|
||||
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
if (METIS_metis.h_DIRS)
|
||||
set(METIS_INCLUDE_DIRS "${METIS_metis.h_DIRS}")
|
||||
else ()
|
||||
set(METIS_INCLUDE_DIRS "METIS_INCLUDE_DIRS-NOTFOUND")
|
||||
if(NOT METIS_FIND_QUIETLY)
|
||||
message(STATUS "Looking for metis -- metis.h not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Looking for lib
|
||||
# ---------------
|
||||
|
||||
# Add system library paths to search lib
|
||||
# --------------------------------------
|
||||
unset(_lib_env)
|
||||
set(ENV_METIS_LIBDIR "$ENV{METIS_LIBDIR}")
|
||||
if(ENV_METIS_LIBDIR)
|
||||
list(APPEND _lib_env "${ENV_METIS_LIBDIR}")
|
||||
elseif(ENV_METIS_DIR)
|
||||
list(APPEND _lib_env "${ENV_METIS_DIR}")
|
||||
list(APPEND _lib_env "${ENV_METIS_DIR}/lib")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
|
||||
else()
|
||||
if(APPLE)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
|
||||
endif()
|
||||
list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
|
||||
list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
|
||||
endif()
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _lib_env)
|
||||
|
||||
# Try to find the metis lib in the given paths
|
||||
# ----------------------------------------------
|
||||
# call cmake macro to find the lib path
|
||||
if(METIS_LIBDIR)
|
||||
set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND")
|
||||
find_library(METIS_metis_LIBRARY
|
||||
NAMES metis
|
||||
HINTS ${METIS_LIBDIR})
|
||||
else()
|
||||
if(METIS_DIR)
|
||||
set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND")
|
||||
find_library(METIS_metis_LIBRARY
|
||||
NAMES metis
|
||||
HINTS ${METIS_DIR}
|
||||
PATH_SUFFIXES lib lib32 lib64)
|
||||
else()
|
||||
set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND")
|
||||
find_library(METIS_metis_LIBRARY
|
||||
NAMES metis
|
||||
HINTS ${_lib_env})
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(METIS_metis_LIBRARY)
|
||||
|
||||
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
if (METIS_metis_LIBRARY)
|
||||
get_filename_component(metis_lib_path "${METIS_metis_LIBRARY}" PATH)
|
||||
# set cmake variables
|
||||
set(METIS_LIBRARIES "${METIS_metis_LIBRARY}")
|
||||
set(METIS_LIBRARY_DIRS "${metis_lib_path}")
|
||||
else ()
|
||||
set(METIS_LIBRARIES "METIS_LIBRARIES-NOTFOUND")
|
||||
set(METIS_LIBRARY_DIRS "METIS_LIBRARY_DIRS-NOTFOUND")
|
||||
if(NOT METIS_FIND_QUIETLY)
|
||||
message(STATUS "Looking for metis -- lib metis not found")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
# check a function to validate the find
|
||||
if(METIS_LIBRARIES)
|
||||
|
||||
set(REQUIRED_INCDIRS)
|
||||
set(REQUIRED_LIBDIRS)
|
||||
set(REQUIRED_LIBS)
|
||||
|
||||
# METIS
|
||||
if (METIS_INCLUDE_DIRS)
|
||||
set(REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}")
|
||||
endif()
|
||||
if (METIS_LIBRARY_DIRS)
|
||||
set(REQUIRED_LIBDIRS "${METIS_LIBRARY_DIRS}")
|
||||
endif()
|
||||
set(REQUIRED_LIBS "${METIS_LIBRARIES}")
|
||||
# m
|
||||
find_library(M_LIBRARY NAMES m)
|
||||
mark_as_advanced(M_LIBRARY)
|
||||
if(M_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "-lm")
|
||||
endif()
|
||||
|
||||
if(NOT METIS_VERSION_OK)
|
||||
message(STATUS "Metis version ${METIS_VERSION} found in ${METIS_INCLUDES}, "
|
||||
"but at least version ${Metis_FIND_VERSION} is required")
|
||||
endif(NOT METIS_VERSION_OK)
|
||||
endmacro(_metis_check_version)
|
||||
# set required libraries for link
|
||||
set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
foreach(lib_dir ${REQUIRED_LIBDIRS})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
|
||||
endforeach()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
|
||||
string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
|
||||
|
||||
if(METIS_INCLUDES AND Metis_FIND_VERSION)
|
||||
_metis_check_version()
|
||||
else()
|
||||
set(METIS_VERSION_OK TRUE)
|
||||
# test link
|
||||
unset(METIS_WORKS CACHE)
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(METIS_NodeND METIS_WORKS)
|
||||
mark_as_advanced(METIS_WORKS)
|
||||
|
||||
if(NOT METIS_WORKS)
|
||||
if(NOT METIS_FIND_QUIETLY)
|
||||
message(STATUS "Looking for METIS : test of METIS_NodeND with METIS library fails")
|
||||
message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
|
||||
message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
|
||||
message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif(METIS_LIBRARIES)
|
||||
|
||||
if (METIS_LIBRARIES)
|
||||
list(GET METIS_LIBRARIES 0 first_lib)
|
||||
get_filename_component(first_lib_path "${first_lib}" PATH)
|
||||
if (${first_lib_path} MATCHES "/lib(32|64)?$")
|
||||
string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
|
||||
set(METIS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of METIS library" FORCE)
|
||||
else()
|
||||
set(METIS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of METIS library" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(METIS_DIR)
|
||||
mark_as_advanced(METIS_DIR_FOUND)
|
||||
|
||||
find_library(METIS_LIBRARIES metis PATHS $ENV{METISDIR} ${LIB_INSTALL_DIR} PATH_SUFFIXES lib)
|
||||
|
||||
# check that METIS has been found
|
||||
# ---------------------------------
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(METIS DEFAULT_MSG
|
||||
METIS_INCLUDES METIS_LIBRARIES METIS_VERSION_OK)
|
||||
|
||||
mark_as_advanced(METIS_INCLUDES METIS_LIBRARIES)
|
||||
METIS_LIBRARIES
|
||||
METIS_WORKS)
|
||||
#
|
||||
# TODO: Add possibility to check for specific functions in the library
|
||||
#
|
||||
|
||||
423
cmake/FindPTSCOTCH.cmake
Normal file
423
cmake/FindPTSCOTCH.cmake
Normal file
@@ -0,0 +1,423 @@
|
||||
###
|
||||
#
|
||||
# @copyright (c) 2009-2014 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation.
|
||||
# All rights reserved.
|
||||
# @copyright (c) 2012-2016 Inria. All rights reserved.
|
||||
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
|
||||
#
|
||||
###
|
||||
#
|
||||
# - Find PTSCOTCH include dirs and libraries
|
||||
# Use this module by invoking find_package with the form:
|
||||
# find_package(PTSCOTCH
|
||||
# [REQUIRED] # Fail with error if ptscotch is not found
|
||||
# [COMPONENTS <comp1> <comp2> ...] # dependencies
|
||||
# )
|
||||
#
|
||||
# PTSCOTCH depends on the following libraries:
|
||||
# - Threads
|
||||
# - MPI
|
||||
#
|
||||
# COMPONENTS can be some of the following:
|
||||
# - ESMUMPS: to activate detection of PT-Scotch with the esmumps interface
|
||||
#
|
||||
# This module finds headers and ptscotch library.
|
||||
# Results are reported in variables:
|
||||
# PTSCOTCH_FOUND - True if headers and requested libraries were found
|
||||
# PTSCOTCH_LINKER_FLAGS - list of required linker flags (excluding -l and -L)
|
||||
# PTSCOTCH_INCLUDE_DIRS - ptscotch include directories
|
||||
# PTSCOTCH_LIBRARY_DIRS - Link directories for ptscotch libraries
|
||||
# PTSCOTCH_LIBRARIES - ptscotch component libraries to be linked
|
||||
# PTSCOTCH_INCLUDE_DIRS_DEP - ptscotch + dependencies include directories
|
||||
# PTSCOTCH_LIBRARY_DIRS_DEP - ptscotch + dependencies link directories
|
||||
# PTSCOTCH_LIBRARIES_DEP - ptscotch libraries + dependencies
|
||||
# PTSCOTCH_INTSIZE - Number of octets occupied by a SCOTCH_Num
|
||||
#
|
||||
# The user can give specific paths where to find the libraries adding cmake
|
||||
# options at configure (ex: cmake path/to/project -DPTSCOTCH=path/to/ptscotch):
|
||||
# PTSCOTCH_DIR - Where to find the base directory of ptscotch
|
||||
# PTSCOTCH_INCDIR - Where to find the header files
|
||||
# PTSCOTCH_LIBDIR - Where to find the library files
|
||||
# The module can also look for the following environment variables if paths
|
||||
# are not given as cmake variable: PTSCOTCH_DIR, PTSCOTCH_INCDIR, PTSCOTCH_LIBDIR
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2012-2013 Inria
|
||||
# Copyright 2012-2013 Emmanuel Agullo
|
||||
# Copyright 2012-2013 Mathieu Faverge
|
||||
# Copyright 2012 Cedric Castagnede
|
||||
# Copyright 2013-2016 Florent Pruvost
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file MORSE-Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of Morse, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
if (NOT PTSCOTCH_FOUND)
|
||||
set(PTSCOTCH_DIR "" CACHE PATH "Installation directory of PTSCOTCH library")
|
||||
if (NOT PTSCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "A cache variable, namely PTSCOTCH_DIR, has been set to specify the install directory of PTSCOTCH")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set the version to find
|
||||
set(PTSCOTCH_LOOK_FOR_ESMUMPS OFF)
|
||||
|
||||
if( PTSCOTCH_FIND_COMPONENTS )
|
||||
foreach( component ${PTSCOTCH_FIND_COMPONENTS} )
|
||||
if (${component} STREQUAL "ESMUMPS")
|
||||
# means we look for esmumps library
|
||||
set(PTSCOTCH_LOOK_FOR_ESMUMPS ON)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# PTSCOTCH depends on Threads, try to find it
|
||||
if (NOT THREADS_FOUND)
|
||||
if (PTSCOTCH_FIND_REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
else()
|
||||
find_package(Threads)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# PTSCOTCH depends on MPI, try to find it
|
||||
if (NOT MPI_FOUND)
|
||||
if (PTSCOTCH_FIND_REQUIRED)
|
||||
find_package(MPI REQUIRED)
|
||||
else()
|
||||
find_package(MPI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Looking for include
|
||||
# -------------------
|
||||
|
||||
# Add system include paths to search include
|
||||
# ------------------------------------------
|
||||
unset(_inc_env)
|
||||
set(ENV_PTSCOTCH_DIR "$ENV{PTSCOTCH_DIR}")
|
||||
set(ENV_PTSCOTCH_INCDIR "$ENV{PTSCOTCH_INCDIR}")
|
||||
if(ENV_PTSCOTCH_INCDIR)
|
||||
list(APPEND _inc_env "${ENV_PTSCOTCH_INCDIR}")
|
||||
elseif(ENV_PTSCOTCH_DIR)
|
||||
list(APPEND _inc_env "${ENV_PTSCOTCH_DIR}")
|
||||
list(APPEND _inc_env "${ENV_PTSCOTCH_DIR}/include")
|
||||
list(APPEND _inc_env "${ENV_PTSCOTCH_DIR}/include/ptscotch")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(REMOVE_DUPLICATES _inc_env)
|
||||
|
||||
|
||||
# Try to find the ptscotch header in the given paths
|
||||
# -------------------------------------------------
|
||||
|
||||
set(PTSCOTCH_hdrs_to_find "ptscotch.h;scotch.h")
|
||||
|
||||
# call cmake macro to find the header path
|
||||
if(PTSCOTCH_INCDIR)
|
||||
foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
|
||||
set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND")
|
||||
find_path(PTSCOTCH_${ptscotch_hdr}_DIRS
|
||||
NAMES ${ptscotch_hdr}
|
||||
HINTS ${PTSCOTCH_INCDIR})
|
||||
mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS)
|
||||
endforeach()
|
||||
else()
|
||||
if(PTSCOTCH_DIR)
|
||||
foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
|
||||
set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND")
|
||||
find_path(PTSCOTCH_${ptscotch_hdr}_DIRS
|
||||
NAMES ${ptscotch_hdr}
|
||||
HINTS ${PTSCOTCH_DIR}
|
||||
PATH_SUFFIXES "include" "include/scotch")
|
||||
mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS)
|
||||
endforeach()
|
||||
else()
|
||||
foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
|
||||
set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND")
|
||||
find_path(PTSCOTCH_${ptscotch_hdr}_DIRS
|
||||
NAMES ${ptscotch_hdr}
|
||||
HINTS ${_inc_env}
|
||||
PATH_SUFFIXES "scotch")
|
||||
mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS)
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find})
|
||||
if (PTSCOTCH_${ptscotch_hdr}_DIRS)
|
||||
list(APPEND PTSCOTCH_INCLUDE_DIRS "${PTSCOTCH_${ptscotch_hdr}_DIRS}")
|
||||
else ()
|
||||
set(PTSCOTCH_INCLUDE_DIRS "PTSCOTCH_INCLUDE_DIRS-NOTFOUND")
|
||||
if (NOT PTSCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "Looking for ptscotch -- ${ptscotch_hdr} not found")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES PTSCOTCH_INCLUDE_DIRS)
|
||||
|
||||
# Looking for lib
|
||||
# ---------------
|
||||
|
||||
# Add system library paths to search lib
|
||||
# --------------------------------------
|
||||
unset(_lib_env)
|
||||
set(ENV_PTSCOTCH_LIBDIR "$ENV{PTSCOTCH_LIBDIR}")
|
||||
if(ENV_PTSCOTCH_LIBDIR)
|
||||
list(APPEND _lib_env "${ENV_PTSCOTCH_LIBDIR}")
|
||||
elseif(ENV_PTSCOTCH_DIR)
|
||||
list(APPEND _lib_env "${ENV_PTSCOTCH_DIR}")
|
||||
list(APPEND _lib_env "${ENV_PTSCOTCH_DIR}/lib")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
|
||||
else()
|
||||
if(APPLE)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
|
||||
endif()
|
||||
list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
|
||||
list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
|
||||
endif()
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _lib_env)
|
||||
|
||||
# Try to find the ptscotch lib in the given paths
|
||||
# ----------------------------------------------
|
||||
|
||||
set(PTSCOTCH_libs_to_find "ptscotch;ptscotcherr")
|
||||
if (PTSCOTCH_LOOK_FOR_ESMUMPS)
|
||||
list(INSERT PTSCOTCH_libs_to_find 0 "ptesmumps")
|
||||
list(APPEND PTSCOTCH_libs_to_find "esmumps" )
|
||||
endif()
|
||||
list(APPEND PTSCOTCH_libs_to_find "scotch;scotcherr")
|
||||
|
||||
# call cmake macro to find the lib path
|
||||
if(PTSCOTCH_LIBDIR)
|
||||
foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
|
||||
set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY
|
||||
NAMES ${ptscotch_lib}
|
||||
HINTS ${PTSCOTCH_LIBDIR})
|
||||
endforeach()
|
||||
else()
|
||||
if(PTSCOTCH_DIR)
|
||||
foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
|
||||
set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY
|
||||
NAMES ${ptscotch_lib}
|
||||
HINTS ${PTSCOTCH_DIR}
|
||||
PATH_SUFFIXES lib lib32 lib64)
|
||||
endforeach()
|
||||
else()
|
||||
foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
|
||||
set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY
|
||||
NAMES ${ptscotch_lib}
|
||||
HINTS ${_lib_env})
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(PTSCOTCH_LIBRARIES "")
|
||||
set(PTSCOTCH_LIBRARY_DIRS "")
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
foreach(ptscotch_lib ${PTSCOTCH_libs_to_find})
|
||||
|
||||
if (PTSCOTCH_${ptscotch_lib}_LIBRARY)
|
||||
get_filename_component(${ptscotch_lib}_lib_path "${PTSCOTCH_${ptscotch_lib}_LIBRARY}" PATH)
|
||||
# set cmake variables
|
||||
list(APPEND PTSCOTCH_LIBRARIES "${PTSCOTCH_${ptscotch_lib}_LIBRARY}")
|
||||
list(APPEND PTSCOTCH_LIBRARY_DIRS "${${ptscotch_lib}_lib_path}")
|
||||
else ()
|
||||
list(APPEND PTSCOTCH_LIBRARIES "${PTSCOTCH_${ptscotch_lib}_LIBRARY}")
|
||||
if (NOT PTSCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "Looking for ptscotch -- lib ${ptscotch_lib} not found")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(PTSCOTCH_${ptscotch_lib}_LIBRARY)
|
||||
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES PTSCOTCH_LIBRARY_DIRS)
|
||||
|
||||
# check a function to validate the find
|
||||
if(PTSCOTCH_LIBRARIES)
|
||||
|
||||
set(REQUIRED_LDFLAGS)
|
||||
set(REQUIRED_INCDIRS)
|
||||
set(REQUIRED_LIBDIRS)
|
||||
set(REQUIRED_LIBS)
|
||||
|
||||
# PTSCOTCH
|
||||
if (PTSCOTCH_INCLUDE_DIRS)
|
||||
set(REQUIRED_INCDIRS "${PTSCOTCH_INCLUDE_DIRS}")
|
||||
endif()
|
||||
if (PTSCOTCH_LIBRARY_DIRS)
|
||||
set(REQUIRED_LIBDIRS "${PTSCOTCH_LIBRARY_DIRS}")
|
||||
endif()
|
||||
set(REQUIRED_LIBS "${PTSCOTCH_LIBRARIES}")
|
||||
# MPI
|
||||
if (MPI_FOUND)
|
||||
if (MPI_C_INCLUDE_PATH)
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${MPI_C_INCLUDE_PATH}")
|
||||
endif()
|
||||
if (MPI_C_LINK_FLAGS)
|
||||
if (${MPI_C_LINK_FLAGS} MATCHES " -")
|
||||
string(REGEX REPLACE " -" "-" MPI_C_LINK_FLAGS ${MPI_C_LINK_FLAGS})
|
||||
endif()
|
||||
list(APPEND REQUIRED_LDFLAGS "${MPI_C_LINK_FLAGS}")
|
||||
endif()
|
||||
list(APPEND REQUIRED_LIBS "${MPI_C_LIBRARIES}")
|
||||
endif()
|
||||
# THREADS
|
||||
if(CMAKE_THREAD_LIBS_INIT)
|
||||
list(APPEND REQUIRED_LIBS "${CMAKE_THREAD_LIBS_INIT}")
|
||||
endif()
|
||||
set(Z_LIBRARY "Z_LIBRARY-NOTFOUND")
|
||||
find_library(Z_LIBRARY NAMES z)
|
||||
mark_as_advanced(Z_LIBRARY)
|
||||
if(Z_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "-lz")
|
||||
endif()
|
||||
set(M_LIBRARY "M_LIBRARY-NOTFOUND")
|
||||
find_library(M_LIBRARY NAMES m)
|
||||
mark_as_advanced(M_LIBRARY)
|
||||
if(M_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "-lm")
|
||||
endif()
|
||||
set(RT_LIBRARY "RT_LIBRARY-NOTFOUND")
|
||||
find_library(RT_LIBRARY NAMES rt)
|
||||
mark_as_advanced(RT_LIBRARY)
|
||||
if(RT_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "-lrt")
|
||||
endif()
|
||||
|
||||
# set required libraries for link
|
||||
set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}")
|
||||
foreach(lib_dir ${REQUIRED_LIBDIRS})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
|
||||
endforeach()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS "${REQUIRED_FLAGS}")
|
||||
string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
|
||||
|
||||
# test link
|
||||
unset(PTSCOTCH_WORKS CACHE)
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(SCOTCH_dgraphInit PTSCOTCH_WORKS)
|
||||
mark_as_advanced(PTSCOTCH_WORKS)
|
||||
|
||||
if(PTSCOTCH_WORKS)
|
||||
# save link with dependencies
|
||||
set(PTSCOTCH_LIBRARIES_DEP "${REQUIRED_LIBS}")
|
||||
set(PTSCOTCH_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}")
|
||||
set(PTSCOTCH_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}")
|
||||
set(PTSCOTCH_LINKER_FLAGS "${REQUIRED_LDFLAGS}")
|
||||
list(REMOVE_DUPLICATES PTSCOTCH_LIBRARY_DIRS_DEP)
|
||||
list(REMOVE_DUPLICATES PTSCOTCH_INCLUDE_DIRS_DEP)
|
||||
list(REMOVE_DUPLICATES PTSCOTCH_LINKER_FLAGS)
|
||||
else()
|
||||
if(NOT PTSCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PTSCOTCH : test of SCOTCH_dgraphInit with PTSCOTCH library fails")
|
||||
message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
|
||||
message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
|
||||
message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif(PTSCOTCH_LIBRARIES)
|
||||
|
||||
if (PTSCOTCH_LIBRARIES)
|
||||
list(GET PTSCOTCH_LIBRARIES 0 first_lib)
|
||||
get_filename_component(first_lib_path "${first_lib}" PATH)
|
||||
if (${first_lib_path} MATCHES "/lib(32|64)?$")
|
||||
string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
|
||||
set(PTSCOTCH_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of PTSCOTCH library" FORCE)
|
||||
else()
|
||||
set(PTSCOTCH_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of PTSCOTCH library" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(PTSCOTCH_DIR)
|
||||
mark_as_advanced(PTSCOTCH_DIR_FOUND)
|
||||
|
||||
# Check the size of SCOTCH_Num
|
||||
# ---------------------------------
|
||||
set(CMAKE_REQUIRED_INCLUDES ${PTSCOTCH_INCLUDE_DIRS})
|
||||
|
||||
include(CheckCSourceRuns)
|
||||
#stdio.h and stdint.h should be included by scotch.h directly
|
||||
set(PTSCOTCH_C_TEST_SCOTCH_Num_4 "
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <ptscotch.h>
|
||||
int main(int argc, char **argv) {
|
||||
if (sizeof(SCOTCH_Num) == 4)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
")
|
||||
|
||||
set(PTSCOTCH_C_TEST_SCOTCH_Num_8 "
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <ptscotch.h>
|
||||
int main(int argc, char **argv) {
|
||||
if (sizeof(SCOTCH_Num) == 8)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
")
|
||||
check_c_source_runs("${PTSCOTCH_C_TEST_SCOTCH_Num_4}" PTSCOTCH_Num_4)
|
||||
if(NOT PTSCOTCH_Num_4)
|
||||
check_c_source_runs("${PTSCOTCH_C_TEST_SCOTCH_Num_8}" PTSCOTCH_Num_8)
|
||||
if(NOT PTSCOTCH_Num_8)
|
||||
set(PTSCOTCH_INTSIZE -1)
|
||||
else()
|
||||
set(PTSCOTCH_INTSIZE 8)
|
||||
endif()
|
||||
else()
|
||||
set(PTSCOTCH_INTSIZE 4)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES "")
|
||||
|
||||
# check that PTSCOTCH has been found
|
||||
# ---------------------------------
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PTSCOTCH DEFAULT_MSG
|
||||
PTSCOTCH_LIBRARIES
|
||||
PTSCOTCH_WORKS)
|
||||
#
|
||||
# TODO: Add possibility to check for specific functions in the library
|
||||
#
|
||||
@@ -1,25 +1,704 @@
|
||||
# Pastix lib requires linking to a blas library.
|
||||
# It is up to the user of this module to find a BLAS and link to it.
|
||||
# Pastix requires SCOTCH or METIS (partitioning and reordering tools) as well
|
||||
###
|
||||
#
|
||||
# @copyright (c) 2009-2014 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation.
|
||||
# All rights reserved.
|
||||
# @copyright (c) 2012-2014 Inria. All rights reserved.
|
||||
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
|
||||
#
|
||||
###
|
||||
#
|
||||
# - Find PASTIX include dirs and libraries
|
||||
# Use this module by invoking find_package with the form:
|
||||
# find_package(PASTIX
|
||||
# [REQUIRED] # Fail with error if pastix is not found
|
||||
# [COMPONENTS <comp1> <comp2> ...] # dependencies
|
||||
# )
|
||||
#
|
||||
# PASTIX depends on the following libraries:
|
||||
# - Threads, m, rt
|
||||
# - MPI
|
||||
# - HWLOC
|
||||
# - BLAS
|
||||
#
|
||||
# COMPONENTS are optional libraries PASTIX could be linked with,
|
||||
# Use it to drive detection of a specific compilation chain
|
||||
# COMPONENTS can be some of the following:
|
||||
# - MPI: to activate detection of the parallel MPI version (default)
|
||||
# it looks for Threads, HWLOC, BLAS, MPI and ScaLAPACK libraries
|
||||
# - SEQ: to activate detection of the sequential version (exclude MPI version)
|
||||
# - STARPU: to activate detection of StarPU version
|
||||
# it looks for MPI version of StarPU (default behaviour)
|
||||
# if SEQ and STARPU are given, it looks for a StarPU without MPI
|
||||
# - STARPU_CUDA: to activate detection of StarPU with CUDA
|
||||
# - STARPU_FXT: to activate detection of StarPU with FxT
|
||||
# - SCOTCH: to activate detection of PASTIX linked with SCOTCH
|
||||
# - PTSCOTCH: to activate detection of PASTIX linked with SCOTCH
|
||||
# - METIS: to activate detection of PASTIX linked with SCOTCH
|
||||
#
|
||||
# This module finds headers and pastix library.
|
||||
# Results are reported in variables:
|
||||
# PASTIX_FOUND - True if headers and requested libraries were found
|
||||
# PASTIX_LINKER_FLAGS - list of required linker flags (excluding -l and -L)
|
||||
# PASTIX_INCLUDE_DIRS - pastix include directories
|
||||
# PASTIX_LIBRARY_DIRS - Link directories for pastix libraries
|
||||
# PASTIX_LIBRARIES - pastix libraries
|
||||
# PASTIX_INCLUDE_DIRS_DEP - pastix + dependencies include directories
|
||||
# PASTIX_LIBRARY_DIRS_DEP - pastix + dependencies link directories
|
||||
# PASTIX_LIBRARIES_DEP - pastix libraries + dependencies
|
||||
#
|
||||
# The user can give specific paths where to find the libraries adding cmake
|
||||
# options at configure (ex: cmake path/to/project -DPASTIX_DIR=path/to/pastix):
|
||||
# PASTIX_DIR - Where to find the base directory of pastix
|
||||
# PASTIX_INCDIR - Where to find the header files
|
||||
# PASTIX_LIBDIR - Where to find the library files
|
||||
# The module can also look for the following environment variables if paths
|
||||
# are not given as cmake variable: PASTIX_DIR, PASTIX_INCDIR, PASTIX_LIBDIR
|
||||
|
||||
if (PASTIX_INCLUDES AND PASTIX_LIBRARIES)
|
||||
set(PASTIX_FIND_QUIETLY TRUE)
|
||||
endif (PASTIX_INCLUDES AND PASTIX_LIBRARIES)
|
||||
|
||||
find_path(PASTIX_INCLUDES
|
||||
NAMES
|
||||
pastix_nompi.h
|
||||
PATHS
|
||||
$ENV{PASTIXDIR}
|
||||
${INCLUDE_INSTALL_DIR}
|
||||
)
|
||||
|
||||
find_library(PASTIX_LIBRARIES pastix PATHS $ENV{PASTIXDIR} ${LIB_INSTALL_DIR})
|
||||
#=============================================================================
|
||||
# Copyright 2012-2013 Inria
|
||||
# Copyright 2012-2013 Emmanuel Agullo
|
||||
# Copyright 2012-2013 Mathieu Faverge
|
||||
# Copyright 2012 Cedric Castagnede
|
||||
# Copyright 2013 Florent Pruvost
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file MORSE-Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of Morse, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
|
||||
if (NOT PASTIX_FOUND)
|
||||
set(PASTIX_DIR "" CACHE PATH "Installation directory of PASTIX library")
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "A cache variable, namely PASTIX_DIR, has been set to specify the install directory of PASTIX")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set the version to find
|
||||
set(PASTIX_LOOK_FOR_MPI ON)
|
||||
set(PASTIX_LOOK_FOR_SEQ OFF)
|
||||
set(PASTIX_LOOK_FOR_STARPU OFF)
|
||||
set(PASTIX_LOOK_FOR_STARPU_CUDA OFF)
|
||||
set(PASTIX_LOOK_FOR_STARPU_FXT OFF)
|
||||
set(PASTIX_LOOK_FOR_SCOTCH ON)
|
||||
set(PASTIX_LOOK_FOR_PTSCOTCH OFF)
|
||||
set(PASTIX_LOOK_FOR_METIS OFF)
|
||||
|
||||
if( PASTIX_FIND_COMPONENTS )
|
||||
foreach( component ${PASTIX_FIND_COMPONENTS} )
|
||||
if (${component} STREQUAL "SEQ")
|
||||
# means we look for the sequential version of PaStiX (without MPI)
|
||||
set(PASTIX_LOOK_FOR_SEQ ON)
|
||||
set(PASTIX_LOOK_FOR_MPI OFF)
|
||||
endif()
|
||||
if (${component} STREQUAL "MPI")
|
||||
# means we look for the MPI version of PaStiX (default)
|
||||
set(PASTIX_LOOK_FOR_SEQ OFF)
|
||||
set(PASTIX_LOOK_FOR_MPI ON)
|
||||
endif()
|
||||
if (${component} STREQUAL "STARPU")
|
||||
# means we look for PaStiX with StarPU
|
||||
set(PASTIX_LOOK_FOR_STARPU ON)
|
||||
endif()
|
||||
if (${component} STREQUAL "STARPU_CUDA")
|
||||
# means we look for PaStiX with StarPU + CUDA
|
||||
set(PASTIX_LOOK_FOR_STARPU ON)
|
||||
set(PASTIX_LOOK_FOR_STARPU_CUDA ON)
|
||||
endif()
|
||||
if (${component} STREQUAL "STARPU_FXT")
|
||||
# means we look for PaStiX with StarPU + FxT
|
||||
set(PASTIX_LOOK_FOR_STARPU_FXT ON)
|
||||
endif()
|
||||
if (${component} STREQUAL "SCOTCH")
|
||||
set(PASTIX_LOOK_FOR_SCOTCH ON)
|
||||
endif()
|
||||
if (${component} STREQUAL "SCOTCH")
|
||||
set(PASTIX_LOOK_FOR_PTSCOTCH ON)
|
||||
endif()
|
||||
if (${component} STREQUAL "METIS")
|
||||
set(PASTIX_LOOK_FOR_METIS ON)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Dependencies detection
|
||||
# ----------------------
|
||||
|
||||
|
||||
# Required dependencies
|
||||
# ---------------------
|
||||
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect pthread")
|
||||
endif()
|
||||
if (PASTIX_FIND_REQUIRED)
|
||||
find_package(Threads REQUIRED QUIET)
|
||||
else()
|
||||
find_package(Threads QUIET)
|
||||
endif()
|
||||
set(PASTIX_EXTRA_LIBRARIES "")
|
||||
if( THREADS_FOUND )
|
||||
list(APPEND PASTIX_EXTRA_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif ()
|
||||
|
||||
# Add math library to the list of extra
|
||||
# it normally exists on all common systems provided with a C compiler
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect libm")
|
||||
endif()
|
||||
set(PASTIX_M_LIBRARIES "")
|
||||
if(UNIX OR WIN32)
|
||||
find_library(
|
||||
PASTIX_M_m_LIBRARY
|
||||
NAMES m
|
||||
)
|
||||
mark_as_advanced(PASTIX_M_m_LIBRARY)
|
||||
if (PASTIX_M_m_LIBRARY)
|
||||
list(APPEND PASTIX_M_LIBRARIES "${PASTIX_M_m_LIBRARY}")
|
||||
list(APPEND PASTIX_EXTRA_LIBRARIES "${PASTIX_M_m_LIBRARY}")
|
||||
else()
|
||||
if (PASTIX_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could NOT find libm on your system."
|
||||
"Are you sure to a have a C compiler installed?")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Try to find librt (libposix4 - POSIX.1b Realtime Extensions library)
|
||||
# on Unix systems except Apple ones because it does not exist on it
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect librt")
|
||||
endif()
|
||||
set(PASTIX_RT_LIBRARIES "")
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_library(
|
||||
PASTIX_RT_rt_LIBRARY
|
||||
NAMES rt
|
||||
)
|
||||
mark_as_advanced(PASTIX_RT_rt_LIBRARY)
|
||||
if (PASTIX_RT_rt_LIBRARY)
|
||||
list(APPEND PASTIX_RT_LIBRARIES "${PASTIX_RT_rt_LIBRARY}")
|
||||
list(APPEND PASTIX_EXTRA_LIBRARIES "${PASTIX_RT_rt_LIBRARY}")
|
||||
else()
|
||||
if (PASTIX_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could NOT find librt on your system")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# PASTIX depends on HWLOC
|
||||
#------------------------
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect HWLOC")
|
||||
endif()
|
||||
if (PASTIX_FIND_REQUIRED)
|
||||
find_package(HWLOC REQUIRED QUIET)
|
||||
else()
|
||||
find_package(HWLOC QUIET)
|
||||
endif()
|
||||
|
||||
# PASTIX depends on BLAS
|
||||
#-----------------------
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect BLAS")
|
||||
endif()
|
||||
if (PASTIX_FIND_REQUIRED)
|
||||
find_package(BLASEXT REQUIRED QUIET)
|
||||
else()
|
||||
find_package(BLASEXT QUIET)
|
||||
endif()
|
||||
|
||||
# Optional dependencies
|
||||
# ---------------------
|
||||
|
||||
# PASTIX may depend on MPI
|
||||
#-------------------------
|
||||
if (NOT MPI_FOUND AND PASTIX_LOOK_FOR_MPI)
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect MPI")
|
||||
endif()
|
||||
# allows to use an external mpi compilation by setting compilers with
|
||||
# -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90
|
||||
# at cmake configure
|
||||
if(NOT MPI_C_COMPILER)
|
||||
set(MPI_C_COMPILER mpicc)
|
||||
endif()
|
||||
if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_MPI)
|
||||
find_package(MPI REQUIRED QUIET)
|
||||
else()
|
||||
find_package(MPI QUIET)
|
||||
endif()
|
||||
if (MPI_FOUND)
|
||||
mark_as_advanced(MPI_LIBRARY)
|
||||
mark_as_advanced(MPI_EXTRA_LIBRARY)
|
||||
endif()
|
||||
endif (NOT MPI_FOUND AND PASTIX_LOOK_FOR_MPI)
|
||||
|
||||
# PASTIX may depend on STARPU
|
||||
#----------------------------
|
||||
if( NOT STARPU_FOUND AND PASTIX_LOOK_FOR_STARPU)
|
||||
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect StarPU")
|
||||
endif()
|
||||
|
||||
set(PASTIX_STARPU_VERSION "1.1" CACHE STRING "oldest STARPU version desired")
|
||||
|
||||
# create list of components in order to make a single call to find_package(starpu...)
|
||||
# we explicitly need a StarPU version built with hwloc
|
||||
set(STARPU_COMPONENT_LIST "HWLOC")
|
||||
|
||||
# StarPU may depend on MPI
|
||||
# allows to use an external mpi compilation by setting compilers with
|
||||
# -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90
|
||||
# at cmake configure
|
||||
if (PASTIX_LOOK_FOR_MPI)
|
||||
if(NOT MPI_C_COMPILER)
|
||||
set(MPI_C_COMPILER mpicc)
|
||||
endif()
|
||||
list(APPEND STARPU_COMPONENT_LIST "MPI")
|
||||
endif()
|
||||
if (PASTIX_LOOK_FOR_STARPU_CUDA)
|
||||
list(APPEND STARPU_COMPONENT_LIST "CUDA")
|
||||
endif()
|
||||
if (PASTIX_LOOK_FOR_STARPU_FXT)
|
||||
list(APPEND STARPU_COMPONENT_LIST "FXT")
|
||||
endif()
|
||||
# set the list of optional dependencies we may discover
|
||||
if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_STARPU)
|
||||
find_package(STARPU ${PASTIX_STARPU_VERSION} REQUIRED
|
||||
COMPONENTS ${STARPU_COMPONENT_LIST})
|
||||
else()
|
||||
find_package(STARPU ${PASTIX_STARPU_VERSION}
|
||||
COMPONENTS ${STARPU_COMPONENT_LIST})
|
||||
endif()
|
||||
|
||||
endif( NOT STARPU_FOUND AND PASTIX_LOOK_FOR_STARPU)
|
||||
|
||||
# PASTIX may depends on SCOTCH
|
||||
#-----------------------------
|
||||
if (NOT SCOTCH_FOUND AND PASTIX_LOOK_FOR_SCOTCH)
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect SCOTCH")
|
||||
endif()
|
||||
if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_SCOTCH)
|
||||
find_package(SCOTCH REQUIRED QUIET)
|
||||
else()
|
||||
find_package(SCOTCH QUIET)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# PASTIX may depends on PTSCOTCH
|
||||
#-------------------------------
|
||||
if (NOT PTSCOTCH_FOUND AND PASTIX_LOOK_FOR_PTSCOTCH)
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect PTSCOTCH")
|
||||
endif()
|
||||
if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_PTSCOTCH)
|
||||
find_package(PTSCOTCH REQUIRED QUIET)
|
||||
else()
|
||||
find_package(PTSCOTCH QUIET)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# PASTIX may depends on METIS
|
||||
#----------------------------
|
||||
if (NOT METIS_FOUND AND PASTIX_LOOK_FOR_METIS)
|
||||
if (NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX - Try to detect METIS")
|
||||
endif()
|
||||
if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_METIS)
|
||||
find_package(METIS REQUIRED QUIET)
|
||||
else()
|
||||
find_package(METIS QUIET)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Error if pastix required and no partitioning lib found
|
||||
if (PASTIX_FIND_REQUIRED AND NOT SCOTCH_FOUND AND NOT PTSCOTCH_FOUND AND NOT METIS_FOUND)
|
||||
message(FATAL_ERROR "Could NOT find any partitioning library on your system"
|
||||
" (install scotch, ptscotch or metis)")
|
||||
endif()
|
||||
|
||||
|
||||
# Looking for PaStiX
|
||||
# ------------------
|
||||
|
||||
# Looking for include
|
||||
# -------------------
|
||||
|
||||
# Add system include paths to search include
|
||||
# ------------------------------------------
|
||||
unset(_inc_env)
|
||||
set(ENV_PASTIX_DIR "$ENV{PASTIX_DIR}")
|
||||
set(ENV_PASTIX_INCDIR "$ENV{PASTIX_INCDIR}")
|
||||
if(ENV_PASTIX_INCDIR)
|
||||
list(APPEND _inc_env "${ENV_PASTIX_INCDIR}")
|
||||
elseif(ENV_PASTIX_DIR)
|
||||
list(APPEND _inc_env "${ENV_PASTIX_DIR}")
|
||||
list(APPEND _inc_env "${ENV_PASTIX_DIR}/include")
|
||||
list(APPEND _inc_env "${ENV_PASTIX_DIR}/include/pastix")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(REMOVE_DUPLICATES _inc_env)
|
||||
|
||||
|
||||
# Try to find the pastix header in the given paths
|
||||
# ---------------------------------------------------
|
||||
# call cmake macro to find the header path
|
||||
if(PASTIX_INCDIR)
|
||||
set(PASTIX_pastix.h_DIRS "PASTIX_pastix.h_DIRS-NOTFOUND")
|
||||
find_path(PASTIX_pastix.h_DIRS
|
||||
NAMES pastix.h
|
||||
HINTS ${PASTIX_INCDIR})
|
||||
else()
|
||||
if(PASTIX_DIR)
|
||||
set(PASTIX_pastix.h_DIRS "PASTIX_pastix.h_DIRS-NOTFOUND")
|
||||
find_path(PASTIX_pastix.h_DIRS
|
||||
NAMES pastix.h
|
||||
HINTS ${PASTIX_DIR}
|
||||
PATH_SUFFIXES "include" "include/pastix")
|
||||
else()
|
||||
set(PASTIX_pastix.h_DIRS "PASTIX_pastix.h_DIRS-NOTFOUND")
|
||||
find_path(PASTIX_pastix.h_DIRS
|
||||
NAMES pastix.h
|
||||
HINTS ${_inc_env}
|
||||
PATH_SUFFIXES "pastix")
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(PASTIX_pastix.h_DIRS)
|
||||
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
if (PASTIX_pastix.h_DIRS)
|
||||
set(PASTIX_INCLUDE_DIRS "${PASTIX_pastix.h_DIRS}")
|
||||
else ()
|
||||
set(PASTIX_INCLUDE_DIRS "PASTIX_INCLUDE_DIRS-NOTFOUND")
|
||||
if(NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for pastix -- pastix.h not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Looking for lib
|
||||
# ---------------
|
||||
|
||||
# Add system library paths to search lib
|
||||
# --------------------------------------
|
||||
unset(_lib_env)
|
||||
set(ENV_PASTIX_LIBDIR "$ENV{PASTIX_LIBDIR}")
|
||||
if(ENV_PASTIX_LIBDIR)
|
||||
list(APPEND _lib_env "${ENV_PASTIX_LIBDIR}")
|
||||
elseif(ENV_PASTIX_DIR)
|
||||
list(APPEND _lib_env "${ENV_PASTIX_DIR}")
|
||||
list(APPEND _lib_env "${ENV_PASTIX_DIR}/lib")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
|
||||
else()
|
||||
if(APPLE)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
|
||||
endif()
|
||||
list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
|
||||
list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
|
||||
endif()
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _lib_env)
|
||||
|
||||
# Try to find the pastix lib in the given paths
|
||||
# ------------------------------------------------
|
||||
|
||||
# create list of libs to find
|
||||
set(PASTIX_libs_to_find "pastix_murge;pastix")
|
||||
|
||||
# call cmake macro to find the lib path
|
||||
if(PASTIX_LIBDIR)
|
||||
foreach(pastix_lib ${PASTIX_libs_to_find})
|
||||
set(PASTIX_${pastix_lib}_LIBRARY "PASTIX_${pastix_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(PASTIX_${pastix_lib}_LIBRARY
|
||||
NAMES ${pastix_lib}
|
||||
HINTS ${PASTIX_LIBDIR})
|
||||
endforeach()
|
||||
else()
|
||||
if(PASTIX_DIR)
|
||||
foreach(pastix_lib ${PASTIX_libs_to_find})
|
||||
set(PASTIX_${pastix_lib}_LIBRARY "PASTIX_${pastix_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(PASTIX_${pastix_lib}_LIBRARY
|
||||
NAMES ${pastix_lib}
|
||||
HINTS ${PASTIX_DIR}
|
||||
PATH_SUFFIXES lib lib32 lib64)
|
||||
endforeach()
|
||||
else()
|
||||
foreach(pastix_lib ${PASTIX_libs_to_find})
|
||||
set(PASTIX_${pastix_lib}_LIBRARY "PASTIX_${pastix_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(PASTIX_${pastix_lib}_LIBRARY
|
||||
NAMES ${pastix_lib}
|
||||
HINTS ${_lib_env})
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
foreach(pastix_lib ${PASTIX_libs_to_find})
|
||||
|
||||
get_filename_component(${pastix_lib}_lib_path ${PASTIX_${pastix_lib}_LIBRARY} PATH)
|
||||
# set cmake variables (respects naming convention)
|
||||
if (PASTIX_LIBRARIES)
|
||||
list(APPEND PASTIX_LIBRARIES "${PASTIX_${pastix_lib}_LIBRARY}")
|
||||
else()
|
||||
set(PASTIX_LIBRARIES "${PASTIX_${pastix_lib}_LIBRARY}")
|
||||
endif()
|
||||
if (PASTIX_LIBRARY_DIRS)
|
||||
list(APPEND PASTIX_LIBRARY_DIRS "${${pastix_lib}_lib_path}")
|
||||
else()
|
||||
set(PASTIX_LIBRARY_DIRS "${${pastix_lib}_lib_path}")
|
||||
endif()
|
||||
mark_as_advanced(PASTIX_${pastix_lib}_LIBRARY)
|
||||
|
||||
endforeach(pastix_lib ${PASTIX_libs_to_find})
|
||||
|
||||
# check a function to validate the find
|
||||
if(PASTIX_LIBRARIES)
|
||||
|
||||
set(REQUIRED_LDFLAGS)
|
||||
set(REQUIRED_INCDIRS)
|
||||
set(REQUIRED_LIBDIRS)
|
||||
set(REQUIRED_LIBS)
|
||||
|
||||
# PASTIX
|
||||
if (PASTIX_INCLUDE_DIRS)
|
||||
set(REQUIRED_INCDIRS "${PASTIX_INCLUDE_DIRS}")
|
||||
endif()
|
||||
foreach(libdir ${PASTIX_LIBRARY_DIRS})
|
||||
if (libdir)
|
||||
list(APPEND REQUIRED_LIBDIRS "${libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(REQUIRED_LIBS "${PASTIX_LIBRARIES}")
|
||||
# STARPU
|
||||
if (PASTIX_LOOK_FOR_STARPU AND STARPU_FOUND)
|
||||
if (STARPU_INCLUDE_DIRS_DEP)
|
||||
list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS_DEP}")
|
||||
elseif (STARPU_INCLUDE_DIRS)
|
||||
list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS}")
|
||||
endif()
|
||||
if(STARPU_LIBRARY_DIRS_DEP)
|
||||
list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS_DEP}")
|
||||
elseif(STARPU_LIBRARY_DIRS)
|
||||
list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS}")
|
||||
endif()
|
||||
if (STARPU_LIBRARIES_DEP)
|
||||
list(APPEND REQUIRED_LIBS "${STARPU_LIBRARIES_DEP}")
|
||||
elseif (STARPU_LIBRARIES)
|
||||
foreach(lib ${STARPU_LIBRARIES})
|
||||
if (EXISTS ${lib} OR ${lib} MATCHES "^-")
|
||||
list(APPEND REQUIRED_LIBS "${lib}")
|
||||
else()
|
||||
list(APPEND REQUIRED_LIBS "-l${lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
# CUDA
|
||||
if (PASTIX_LOOK_FOR_STARPU_CUDA AND CUDA_FOUND)
|
||||
if (CUDA_INCLUDE_DIRS)
|
||||
list(APPEND REQUIRED_INCDIRS "${CUDA_INCLUDE_DIRS}")
|
||||
endif()
|
||||
foreach(libdir ${CUDA_LIBRARY_DIRS})
|
||||
if (libdir)
|
||||
list(APPEND REQUIRED_LIBDIRS "${libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND REQUIRED_LIBS "${CUDA_CUBLAS_LIBRARIES};${CUDA_LIBRARIES}")
|
||||
endif()
|
||||
# MPI
|
||||
if (PASTIX_LOOK_FOR_MPI AND MPI_FOUND)
|
||||
if (MPI_C_INCLUDE_PATH)
|
||||
list(APPEND REQUIRED_INCDIRS "${MPI_C_INCLUDE_PATH}")
|
||||
endif()
|
||||
if (MPI_C_LINK_FLAGS)
|
||||
if (${MPI_C_LINK_FLAGS} MATCHES " -")
|
||||
string(REGEX REPLACE " -" "-" MPI_C_LINK_FLAGS ${MPI_C_LINK_FLAGS})
|
||||
endif()
|
||||
list(APPEND REQUIRED_LDFLAGS "${MPI_C_LINK_FLAGS}")
|
||||
endif()
|
||||
list(APPEND REQUIRED_LIBS "${MPI_C_LIBRARIES}")
|
||||
endif()
|
||||
# HWLOC
|
||||
if (HWLOC_FOUND)
|
||||
if (HWLOC_INCLUDE_DIRS)
|
||||
list(APPEND REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}")
|
||||
endif()
|
||||
foreach(libdir ${HWLOC_LIBRARY_DIRS})
|
||||
if (libdir)
|
||||
list(APPEND REQUIRED_LIBDIRS "${libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(lib ${HWLOC_LIBRARIES})
|
||||
if (EXISTS ${lib} OR ${lib} MATCHES "^-")
|
||||
list(APPEND REQUIRED_LIBS "${lib}")
|
||||
else()
|
||||
list(APPEND REQUIRED_LIBS "-l${lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
# BLAS
|
||||
if (BLAS_FOUND)
|
||||
if (BLAS_INCLUDE_DIRS)
|
||||
list(APPEND REQUIRED_INCDIRS "${BLAS_INCLUDE_DIRS}")
|
||||
endif()
|
||||
foreach(libdir ${BLAS_LIBRARY_DIRS})
|
||||
if (libdir)
|
||||
list(APPEND REQUIRED_LIBDIRS "${libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND REQUIRED_LIBS "${BLAS_LIBRARIES}")
|
||||
if (BLAS_LINKER_FLAGS)
|
||||
list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
# SCOTCH
|
||||
if (PASTIX_LOOK_FOR_SCOTCH AND SCOTCH_FOUND)
|
||||
if (SCOTCH_INCLUDE_DIRS)
|
||||
list(APPEND REQUIRED_INCDIRS "${SCOTCH_INCLUDE_DIRS}")
|
||||
endif()
|
||||
foreach(libdir ${SCOTCH_LIBRARY_DIRS})
|
||||
if (libdir)
|
||||
list(APPEND REQUIRED_LIBDIRS "${libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND REQUIRED_LIBS "${SCOTCH_LIBRARIES}")
|
||||
endif()
|
||||
# PTSCOTCH
|
||||
if (PASTIX_LOOK_FOR_PTSCOTCH AND PTSCOTCH_FOUND)
|
||||
if (PTSCOTCH_INCLUDE_DIRS)
|
||||
list(APPEND REQUIRED_INCDIRS "${PTSCOTCH_INCLUDE_DIRS}")
|
||||
endif()
|
||||
foreach(libdir ${PTSCOTCH_LIBRARY_DIRS})
|
||||
if (libdir)
|
||||
list(APPEND REQUIRED_LIBDIRS "${libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND REQUIRED_LIBS "${PTSCOTCH_LIBRARIES}")
|
||||
endif()
|
||||
# METIS
|
||||
if (PASTIX_LOOK_FOR_METIS AND METIS_FOUND)
|
||||
if (METIS_INCLUDE_DIRS)
|
||||
list(APPEND REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}")
|
||||
endif()
|
||||
foreach(libdir ${METIS_LIBRARY_DIRS})
|
||||
if (libdir)
|
||||
list(APPEND REQUIRED_LIBDIRS "${libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND REQUIRED_LIBS "${METIS_LIBRARIES}")
|
||||
endif()
|
||||
# Fortran
|
||||
if (CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
find_library(
|
||||
FORTRAN_gfortran_LIBRARY
|
||||
NAMES gfortran
|
||||
HINTS ${_lib_env}
|
||||
)
|
||||
mark_as_advanced(FORTRAN_gfortran_LIBRARY)
|
||||
if (FORTRAN_gfortran_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "${FORTRAN_gfortran_LIBRARY}")
|
||||
endif()
|
||||
elseif (CMAKE_C_COMPILER_ID MATCHES "Intel")
|
||||
find_library(
|
||||
FORTRAN_ifcore_LIBRARY
|
||||
NAMES ifcore
|
||||
HINTS ${_lib_env}
|
||||
)
|
||||
mark_as_advanced(FORTRAN_ifcore_LIBRARY)
|
||||
if (FORTRAN_ifcore_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "${FORTRAN_ifcore_LIBRARY}")
|
||||
endif()
|
||||
endif()
|
||||
# EXTRA LIBS such that pthread, m, rt
|
||||
list(APPEND REQUIRED_LIBS ${PASTIX_EXTRA_LIBRARIES})
|
||||
|
||||
# set required libraries for link
|
||||
set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}")
|
||||
foreach(lib_dir ${REQUIRED_LIBDIRS})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
|
||||
endforeach()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS "${REQUIRED_FLAGS}")
|
||||
string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
|
||||
|
||||
# test link
|
||||
unset(PASTIX_WORKS CACHE)
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(pastix PASTIX_WORKS)
|
||||
mark_as_advanced(PASTIX_WORKS)
|
||||
|
||||
if(PASTIX_WORKS)
|
||||
# save link with dependencies
|
||||
set(PASTIX_LIBRARIES_DEP "${REQUIRED_LIBS}")
|
||||
set(PASTIX_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}")
|
||||
set(PASTIX_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}")
|
||||
set(PASTIX_LINKER_FLAGS "${REQUIRED_LDFLAGS}")
|
||||
list(REMOVE_DUPLICATES PASTIX_LIBRARY_DIRS_DEP)
|
||||
list(REMOVE_DUPLICATES PASTIX_INCLUDE_DIRS_DEP)
|
||||
list(REMOVE_DUPLICATES PASTIX_LINKER_FLAGS)
|
||||
else()
|
||||
if(NOT PASTIX_FIND_QUIETLY)
|
||||
message(STATUS "Looking for PASTIX : test of pastix() fails")
|
||||
message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
|
||||
message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
|
||||
message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
|
||||
message(STATUS "Maybe PASTIX is linked with specific libraries. "
|
||||
"Have you tried with COMPONENTS (MPI/SEQ, STARPU, STARPU_CUDA, SCOTCH, PTSCOTCH, METIS)? "
|
||||
"See the explanation in FindPASTIX.cmake.")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif(PASTIX_LIBRARIES)
|
||||
|
||||
if (PASTIX_LIBRARIES)
|
||||
list(GET PASTIX_LIBRARIES 0 first_lib)
|
||||
get_filename_component(first_lib_path "${first_lib}" PATH)
|
||||
if (${first_lib_path} MATCHES "/lib(32|64)?$")
|
||||
string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
|
||||
set(PASTIX_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of PASTIX library" FORCE)
|
||||
else()
|
||||
set(PASTIX_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of PASTIX library" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(PASTIX_DIR)
|
||||
mark_as_advanced(PASTIX_DIR_FOUND)
|
||||
|
||||
# check that PASTIX has been found
|
||||
# ---------------------------------
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PASTIX DEFAULT_MSG
|
||||
PASTIX_INCLUDES PASTIX_LIBRARIES)
|
||||
|
||||
mark_as_advanced(PASTIX_INCLUDES PASTIX_LIBRARIES)
|
||||
PASTIX_LIBRARIES
|
||||
PASTIX_WORKS)
|
||||
|
||||
@@ -1,24 +1,369 @@
|
||||
# Pastix requires SCOTCH or METIS (partitioning and reordering tools)
|
||||
###
|
||||
#
|
||||
# @copyright (c) 2009-2014 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation.
|
||||
# All rights reserved.
|
||||
# @copyright (c) 2012-2014 Inria. All rights reserved.
|
||||
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
|
||||
#
|
||||
###
|
||||
#
|
||||
# - Find SCOTCH include dirs and libraries
|
||||
# Use this module by invoking find_package with the form:
|
||||
# find_package(SCOTCH
|
||||
# [REQUIRED] # Fail with error if scotch is not found
|
||||
# [COMPONENTS <comp1> <comp2> ...] # dependencies
|
||||
# )
|
||||
#
|
||||
# COMPONENTS can be some of the following:
|
||||
# - ESMUMPS: to activate detection of Scotch with the esmumps interface
|
||||
#
|
||||
# This module finds headers and scotch library.
|
||||
# Results are reported in variables:
|
||||
# SCOTCH_FOUND - True if headers and requested libraries were found
|
||||
# SCOTCH_INCLUDE_DIRS - scotch include directories
|
||||
# SCOTCH_LIBRARY_DIRS - Link directories for scotch libraries
|
||||
# SCOTCH_LIBRARIES - scotch component libraries to be linked
|
||||
# SCOTCH_INTSIZE - Number of octets occupied by a SCOTCH_Num
|
||||
#
|
||||
# The user can give specific paths where to find the libraries adding cmake
|
||||
# options at configure (ex: cmake path/to/project -DSCOTCH=path/to/scotch):
|
||||
# SCOTCH_DIR - Where to find the base directory of scotch
|
||||
# SCOTCH_INCDIR - Where to find the header files
|
||||
# SCOTCH_LIBDIR - Where to find the library files
|
||||
# The module can also look for the following environment variables if paths
|
||||
# are not given as cmake variable: SCOTCH_DIR, SCOTCH_INCDIR, SCOTCH_LIBDIR
|
||||
|
||||
if (SCOTCH_INCLUDES AND SCOTCH_LIBRARIES)
|
||||
set(SCOTCH_FIND_QUIETLY TRUE)
|
||||
endif (SCOTCH_INCLUDES AND SCOTCH_LIBRARIES)
|
||||
#=============================================================================
|
||||
# Copyright 2012-2013 Inria
|
||||
# Copyright 2012-2013 Emmanuel Agullo
|
||||
# Copyright 2012-2013 Mathieu Faverge
|
||||
# Copyright 2012 Cedric Castagnede
|
||||
# Copyright 2013 Florent Pruvost
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file MORSE-Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of Morse, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
find_path(SCOTCH_INCLUDES
|
||||
NAMES
|
||||
scotch.h
|
||||
PATHS
|
||||
$ENV{SCOTCHDIR}
|
||||
${INCLUDE_INSTALL_DIR}
|
||||
PATH_SUFFIXES
|
||||
scotch
|
||||
)
|
||||
if (NOT SCOTCH_FOUND)
|
||||
set(SCOTCH_DIR "" CACHE PATH "Installation directory of SCOTCH library")
|
||||
if (NOT SCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "A cache variable, namely SCOTCH_DIR, has been set to specify the install directory of SCOTCH")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set the version to find
|
||||
set(SCOTCH_LOOK_FOR_ESMUMPS OFF)
|
||||
|
||||
if( SCOTCH_FIND_COMPONENTS )
|
||||
foreach( component ${SCOTCH_FIND_COMPONENTS} )
|
||||
if (${component} STREQUAL "ESMUMPS")
|
||||
# means we look for esmumps library
|
||||
set(SCOTCH_LOOK_FOR_ESMUMPS ON)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# SCOTCH may depend on Threads, try to find it
|
||||
if (NOT THREADS_FOUND)
|
||||
if (SCOTCH_FIND_REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
else()
|
||||
find_package(Threads)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Looking for include
|
||||
# -------------------
|
||||
|
||||
# Add system include paths to search include
|
||||
# ------------------------------------------
|
||||
unset(_inc_env)
|
||||
set(ENV_SCOTCH_DIR "$ENV{SCOTCH_DIR}")
|
||||
set(ENV_SCOTCH_INCDIR "$ENV{SCOTCH_INCDIR}")
|
||||
if(ENV_SCOTCH_INCDIR)
|
||||
list(APPEND _inc_env "${ENV_SCOTCH_INCDIR}")
|
||||
elseif(ENV_SCOTCH_DIR)
|
||||
list(APPEND _inc_env "${ENV_SCOTCH_DIR}")
|
||||
list(APPEND _inc_env "${ENV_SCOTCH_DIR}/include")
|
||||
list(APPEND _inc_env "${ENV_SCOTCH_DIR}/include/scotch")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
|
||||
list(APPEND _inc_env "${_path_env}")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
list(REMOVE_DUPLICATES _inc_env)
|
||||
|
||||
|
||||
find_library(SCOTCH_LIBRARIES scotch PATHS $ENV{SCOTCHDIR} ${LIB_INSTALL_DIR})
|
||||
# Try to find the scotch header in the given paths
|
||||
# -------------------------------------------------
|
||||
# call cmake macro to find the header path
|
||||
if(SCOTCH_INCDIR)
|
||||
set(SCOTCH_scotch.h_DIRS "SCOTCH_scotch.h_DIRS-NOTFOUND")
|
||||
find_path(SCOTCH_scotch.h_DIRS
|
||||
NAMES scotch.h
|
||||
HINTS ${SCOTCH_INCDIR})
|
||||
else()
|
||||
if(SCOTCH_DIR)
|
||||
set(SCOTCH_scotch.h_DIRS "SCOTCH_scotch.h_DIRS-NOTFOUND")
|
||||
find_path(SCOTCH_scotch.h_DIRS
|
||||
NAMES scotch.h
|
||||
HINTS ${SCOTCH_DIR}
|
||||
PATH_SUFFIXES "include" "include/scotch")
|
||||
else()
|
||||
set(SCOTCH_scotch.h_DIRS "SCOTCH_scotch.h_DIRS-NOTFOUND")
|
||||
find_path(SCOTCH_scotch.h_DIRS
|
||||
NAMES scotch.h
|
||||
HINTS ${_inc_env}
|
||||
PATH_SUFFIXES "scotch")
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(SCOTCH_scotch.h_DIRS)
|
||||
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
if (SCOTCH_scotch.h_DIRS)
|
||||
set(SCOTCH_INCLUDE_DIRS "${SCOTCH_scotch.h_DIRS}")
|
||||
else ()
|
||||
set(SCOTCH_INCLUDE_DIRS "SCOTCH_INCLUDE_DIRS-NOTFOUND")
|
||||
if (NOT SCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "Looking for scotch -- scotch.h not found")
|
||||
endif()
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES SCOTCH_INCLUDE_DIRS)
|
||||
|
||||
# Looking for lib
|
||||
# ---------------
|
||||
|
||||
# Add system library paths to search lib
|
||||
# --------------------------------------
|
||||
unset(_lib_env)
|
||||
set(ENV_SCOTCH_LIBDIR "$ENV{SCOTCH_LIBDIR}")
|
||||
if(ENV_SCOTCH_LIBDIR)
|
||||
list(APPEND _lib_env "${ENV_SCOTCH_LIBDIR}")
|
||||
elseif(ENV_SCOTCH_DIR)
|
||||
list(APPEND _lib_env "${ENV_SCOTCH_DIR}")
|
||||
list(APPEND _lib_env "${ENV_SCOTCH_DIR}/lib")
|
||||
else()
|
||||
if(WIN32)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LIB}")
|
||||
else()
|
||||
if(APPLE)
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}")
|
||||
else()
|
||||
string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}")
|
||||
endif()
|
||||
list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
|
||||
list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
|
||||
endif()
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _lib_env)
|
||||
|
||||
# Try to find the scotch lib in the given paths
|
||||
# ----------------------------------------------
|
||||
|
||||
set(SCOTCH_libs_to_find "scotch;scotcherrexit")
|
||||
if (SCOTCH_LOOK_FOR_ESMUMPS)
|
||||
list(INSERT SCOTCH_libs_to_find 0 "esmumps")
|
||||
endif()
|
||||
|
||||
# call cmake macro to find the lib path
|
||||
if(SCOTCH_LIBDIR)
|
||||
foreach(scotch_lib ${SCOTCH_libs_to_find})
|
||||
set(SCOTCH_${scotch_lib}_LIBRARY "SCOTCH_${scotch_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(SCOTCH_${scotch_lib}_LIBRARY
|
||||
NAMES ${scotch_lib}
|
||||
HINTS ${SCOTCH_LIBDIR})
|
||||
endforeach()
|
||||
else()
|
||||
if(SCOTCH_DIR)
|
||||
foreach(scotch_lib ${SCOTCH_libs_to_find})
|
||||
set(SCOTCH_${scotch_lib}_LIBRARY "SCOTCH_${scotch_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(SCOTCH_${scotch_lib}_LIBRARY
|
||||
NAMES ${scotch_lib}
|
||||
HINTS ${SCOTCH_DIR}
|
||||
PATH_SUFFIXES lib lib32 lib64)
|
||||
endforeach()
|
||||
else()
|
||||
foreach(scotch_lib ${SCOTCH_libs_to_find})
|
||||
set(SCOTCH_${scotch_lib}_LIBRARY "SCOTCH_${scotch_lib}_LIBRARY-NOTFOUND")
|
||||
find_library(SCOTCH_${scotch_lib}_LIBRARY
|
||||
NAMES ${scotch_lib}
|
||||
HINTS ${_lib_env})
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(SCOTCH_LIBRARIES "")
|
||||
set(SCOTCH_LIBRARY_DIRS "")
|
||||
# If found, add path to cmake variable
|
||||
# ------------------------------------
|
||||
foreach(scotch_lib ${SCOTCH_libs_to_find})
|
||||
|
||||
if (SCOTCH_${scotch_lib}_LIBRARY)
|
||||
get_filename_component(${scotch_lib}_lib_path "${SCOTCH_${scotch_lib}_LIBRARY}" PATH)
|
||||
# set cmake variables
|
||||
list(APPEND SCOTCH_LIBRARIES "${SCOTCH_${scotch_lib}_LIBRARY}")
|
||||
list(APPEND SCOTCH_LIBRARY_DIRS "${${scotch_lib}_lib_path}")
|
||||
else ()
|
||||
list(APPEND SCOTCH_LIBRARIES "${SCOTCH_${scotch_lib}_LIBRARY}")
|
||||
if (NOT SCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "Looking for scotch -- lib ${scotch_lib} not found")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(SCOTCH_${scotch_lib}_LIBRARY)
|
||||
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES SCOTCH_LIBRARY_DIRS)
|
||||
|
||||
# check a function to validate the find
|
||||
if(SCOTCH_LIBRARIES)
|
||||
|
||||
set(REQUIRED_INCDIRS)
|
||||
set(REQUIRED_LIBDIRS)
|
||||
set(REQUIRED_LIBS)
|
||||
|
||||
# SCOTCH
|
||||
if (SCOTCH_INCLUDE_DIRS)
|
||||
set(REQUIRED_INCDIRS "${SCOTCH_INCLUDE_DIRS}")
|
||||
endif()
|
||||
if (SCOTCH_LIBRARY_DIRS)
|
||||
set(REQUIRED_LIBDIRS "${SCOTCH_LIBRARY_DIRS}")
|
||||
endif()
|
||||
set(REQUIRED_LIBS "${SCOTCH_LIBRARIES}")
|
||||
# THREADS
|
||||
if(CMAKE_THREAD_LIBS_INIT)
|
||||
list(APPEND REQUIRED_LIBS "${CMAKE_THREAD_LIBS_INIT}")
|
||||
endif()
|
||||
set(Z_LIBRARY "Z_LIBRARY-NOTFOUND")
|
||||
find_library(Z_LIBRARY NAMES z)
|
||||
mark_as_advanced(Z_LIBRARY)
|
||||
if(Z_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "-lz")
|
||||
endif()
|
||||
set(M_LIBRARY "M_LIBRARY-NOTFOUND")
|
||||
find_library(M_LIBRARY NAMES m)
|
||||
mark_as_advanced(M_LIBRARY)
|
||||
if(M_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "-lm")
|
||||
endif()
|
||||
set(RT_LIBRARY "RT_LIBRARY-NOTFOUND")
|
||||
find_library(RT_LIBRARY NAMES rt)
|
||||
mark_as_advanced(RT_LIBRARY)
|
||||
if(RT_LIBRARY)
|
||||
list(APPEND REQUIRED_LIBS "-lrt")
|
||||
endif()
|
||||
|
||||
# set required libraries for link
|
||||
set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
foreach(lib_dir ${REQUIRED_LIBDIRS})
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}")
|
||||
endforeach()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}")
|
||||
string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
|
||||
|
||||
# test link
|
||||
unset(SCOTCH_WORKS CACHE)
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(SCOTCH_graphInit SCOTCH_WORKS)
|
||||
mark_as_advanced(SCOTCH_WORKS)
|
||||
|
||||
if(SCOTCH_WORKS)
|
||||
# save link with dependencies
|
||||
set(SCOTCH_LIBRARIES "${REQUIRED_LIBS}")
|
||||
else()
|
||||
if(NOT SCOTCH_FIND_QUIETLY)
|
||||
message(STATUS "Looking for SCOTCH : test of SCOTCH_graphInit with SCOTCH library fails")
|
||||
message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}")
|
||||
message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}")
|
||||
message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails")
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif(SCOTCH_LIBRARIES)
|
||||
|
||||
if (SCOTCH_LIBRARIES)
|
||||
list(GET SCOTCH_LIBRARIES 0 first_lib)
|
||||
get_filename_component(first_lib_path "${first_lib}" PATH)
|
||||
if (${first_lib_path} MATCHES "/lib(32|64)?$")
|
||||
string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}")
|
||||
set(SCOTCH_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of SCOTCH library" FORCE)
|
||||
else()
|
||||
set(SCOTCH_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of SCOTCH library" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
mark_as_advanced(SCOTCH_DIR)
|
||||
mark_as_advanced(SCOTCH_DIR_FOUND)
|
||||
|
||||
# Check the size of SCOTCH_Num
|
||||
# ---------------------------------
|
||||
set(CMAKE_REQUIRED_INCLUDES ${SCOTCH_INCLUDE_DIRS})
|
||||
|
||||
include(CheckCSourceRuns)
|
||||
#stdio.h and stdint.h should be included by scotch.h directly
|
||||
set(SCOTCH_C_TEST_SCOTCH_Num_4 "
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <scotch.h>
|
||||
int main(int argc, char **argv) {
|
||||
if (sizeof(SCOTCH_Num) == 4)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
")
|
||||
|
||||
set(SCOTCH_C_TEST_SCOTCH_Num_8 "
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <scotch.h>
|
||||
int main(int argc, char **argv) {
|
||||
if (sizeof(SCOTCH_Num) == 8)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
")
|
||||
check_c_source_runs("${SCOTCH_C_TEST_SCOTCH_Num_4}" SCOTCH_Num_4)
|
||||
if(NOT SCOTCH_Num_4)
|
||||
check_c_source_runs("${SCOTCH_C_TEST_SCOTCH_Num_8}" SCOTCH_Num_8)
|
||||
if(NOT SCOTCH_Num_8)
|
||||
set(SCOTCH_INTSIZE -1)
|
||||
else()
|
||||
set(SCOTCH_INTSIZE 8)
|
||||
endif()
|
||||
else()
|
||||
set(SCOTCH_INTSIZE 4)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES "")
|
||||
|
||||
# check that SCOTCH has been found
|
||||
# ---------------------------------
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(SCOTCH DEFAULT_MSG
|
||||
SCOTCH_INCLUDES SCOTCH_LIBRARIES)
|
||||
|
||||
mark_as_advanced(SCOTCH_INCLUDES SCOTCH_LIBRARIES)
|
||||
SCOTCH_LIBRARIES
|
||||
SCOTCH_WORKS)
|
||||
#
|
||||
# TODO: Add possibility to check for specific functions in the library
|
||||
#
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user