Various compilation fixes for MSVC 9. All tests compile but some

still fail at runtime in ei_aligned_free() (even without vectorization).
This commit is contained in:
Gael Guennebaud 2008-08-19 11:06:40 +00:00
parent 9466e5f94e
commit a6d387a359
14 changed files with 50 additions and 49 deletions

View File

@ -3,6 +3,10 @@
#include "Core"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
namespace Eigen {
/** \defgroup Geometry Geometry module

View File

@ -34,8 +34,8 @@ static void ei_cache_friendly_product(
bool _rhsRowMajor, const Scalar* _rhs, int _rhsStride,
bool resRowMajor, Scalar* res, int resStride)
{
const Scalar* __restrict__ lhs;
const Scalar* __restrict__ rhs;
const Scalar* EIGEN_RESTRICT lhs;
const Scalar* EIGEN_RESTRICT rhs;
int lhsStride, rhsStride, rows, cols;
bool lhsRowMajor;
@ -88,11 +88,11 @@ static void ei_cache_friendly_product(
const int l2BlockSize = MaxL2BlockSize > size ? size : MaxL2BlockSize;
const int l2BlockSizeAligned = (1 + std::max(l2BlockSize,l2BlockCols)/PacketSize)*PacketSize;
const bool needRhsCopy = (PacketSize>1) && ((rhsStride%PacketSize!=0) || (size_t(rhs)%16!=0));
Scalar* __restrict__ block = 0;
Scalar* EIGEN_RESTRICT block = 0;
const int allocBlockSize = sizeof(Scalar)*l2BlockRows*size;
const bool allocBlockUsingAlloca = EIGEN_USE_ALLOCA && allocBlockSize<=16000000;
block = (Scalar*)ei_alloca_or_malloc(allocBlockUsingAlloca, allocBlockSize);
Scalar* __restrict__ rhsCopy
Scalar* EIGEN_RESTRICT rhsCopy
= (Scalar*)ei_alloca_or_malloc(true, sizeof(Scalar)*l2BlockSizeAligned*l2BlockSizeAligned);
// loops on each L2 cache friendly blocks of the result
@ -107,7 +107,6 @@ static void ei_cache_friendly_product(
int count = 0;
// copy l2blocksize rows of m_lhs to blocks of ps x bw
asm("#eigen begin buildblocks");
for(int l2k=0; l2k<size; l2k+=l2BlockSize)
{
const int l2blockSizeEnd = std::min(l2k+l2BlockSize, size);
@ -154,7 +153,6 @@ static void ei_cache_friendly_product(
}
}
}
asm("#eigen end buildblocks");
for(int l2j=0; l2j<cols; l2j+=l2BlockCols)
{
@ -177,11 +175,11 @@ static void ei_cache_friendly_product(
for(int l1i=l2i; l1i<l2blockRowEndBW; l1i+=MaxBlockRows)
{
int offsetblock = l2k * (l2blockRowEnd-l2i) + (l1i-l2i)*(l2blockSizeEnd-l2k) - l2k*MaxBlockRows;
const Scalar* __restrict__ localB = &block[offsetblock];
const Scalar* EIGEN_RESTRICT localB = &block[offsetblock];
for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
{
const Scalar* __restrict__ rhsColumn;
const Scalar* EIGEN_RESTRICT rhsColumn;
if (needRhsCopy)
rhsColumn = &(rhsCopy[l2BlockSizeAligned*(l1j-l2j)-l2k]);
else
@ -194,7 +192,6 @@ static void ei_cache_friendly_product(
PacketType tmp;
asm("#eigen begincore");
for(int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
{
tmp = ei_ploadu(&rhsColumn[k]);
@ -220,7 +217,7 @@ static void ei_cache_friendly_product(
}
}
Scalar* __restrict__ localRes = &(res[l1i + l1j*resStride]);
Scalar* EIGEN_RESTRICT localRes = &(res[l1i + l1j*resStride]);
if (PacketSize>1 && resIsAligned)
{
@ -250,7 +247,6 @@ static void ei_cache_friendly_product(
localRes[7] += ei_predux(dst[7]);
}
}
asm("#eigen endcore");
}
}
if (l2blockRemainingRows>0)
@ -258,10 +254,9 @@ static void ei_cache_friendly_product(
int offsetblock = l2k * (l2blockRowEnd-l2i) + (l2blockRowEndBW-l2i)*(l2blockSizeEnd-l2k) - l2k*l2blockRemainingRows;
const Scalar* localB = &block[offsetblock];
asm("#eigen begin dynkernel");
for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
{
const Scalar* __restrict__ rhsColumn;
const Scalar* EIGEN_RESTRICT rhsColumn;
if (needRhsCopy)
rhsColumn = &(rhsCopy[l2BlockSizeAligned*(l1j-l2j)-l2k]);
else
@ -292,7 +287,7 @@ static void ei_cache_friendly_product(
}
}
Scalar* __restrict__ localRes = &(res[l2blockRowEndBW + l1j*resStride]);
Scalar* EIGEN_RESTRICT localRes = &(res[l2blockRowEndBW + l1j*resStride]);
// process the remaining rows once at a time
localRes[0] += ei_predux(dst[0]);
@ -307,7 +302,6 @@ static void ei_cache_friendly_product(
if (l2blockRemainingRows>=8) localRes[7] += ei_predux(dst[7]);
}
asm("#eigen end dynkernel");
}
}
}
@ -373,7 +367,6 @@ EIGEN_DONT_INLINE static void ei_cache_friendly_product_colmajor_times_vector(
ei_padd(ei_pmul(ptmp0,ei_pload ## A0(&lhs0[j OFFSET])),ei_pmul(ptmp1,ei_pload ## A13(&lhs1[j OFFSET]))), \
ei_padd(ei_pmul(ptmp2,ei_pload ## A2(&lhs2[j OFFSET])),ei_pmul(ptmp3,ei_pload ## A13(&lhs3[j OFFSET]))) )))
asm("#begin matrix_vector_product");
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
@ -541,7 +534,6 @@ EIGEN_DONT_INLINE static void ei_cache_friendly_product_colmajor_times_vector(
else
break;
} while(PacketSize>1);
asm("#end matrix_vector_product");
#undef _EIGEN_ACCUMULATE_PACKETS
}
@ -563,7 +555,6 @@ EIGEN_DONT_INLINE static void ei_cache_friendly_product_rowmajor_times_vector(
ptmp2 = ei_pmadd(b, ei_pload##A2 (&lhs2[j]), ptmp2); \
ptmp3 = ei_pmadd(b, ei_pload##A13(&lhs3[j]), ptmp3); }
asm("#begin matrix_vector_product");
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
@ -752,7 +743,6 @@ EIGEN_DONT_INLINE static void ei_cache_friendly_product_rowmajor_times_vector(
else
break;
} while(PacketSize>1);
asm("#end matrix_vector_product");
#undef _EIGEN_ACCUMULATE_PACKETS
}

View File

@ -166,7 +166,7 @@ Cwise<ExpressionType>::abs2() const
*
* \sa adjoint() */
template<typename Derived>
inline const typename MatrixBase<Derived>::ConjugateReturnType
inline typename MatrixBase<Derived>::ConjugateReturnType
MatrixBase<Derived>::conjugate() const
{
return ConjugateReturnType(derived());

View File

@ -166,7 +166,7 @@ template<typename Derived> class MapBase
{ return derived() = forceAligned() / other; }
protected:
const Scalar* __restrict__ m_data;
const Scalar* EIGEN_RESTRICT m_data;
const ei_int_if_dynamic<RowsAtCompileTime> m_rows;
const ei_int_if_dynamic<ColsAtCompileTime> m_cols;
};

View File

@ -286,8 +286,8 @@ class Matrix : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _MaxRows, _MaxCol
if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2)
|| (RowsAtCompileTime == 2 && ColsAtCompileTime == 1))
{
m_storage.data()[0] = x;
m_storage.data()[1] = y;
m_storage.data()[0] = Scalar(x);
m_storage.data()[1] = Scalar(y);
}
else
{

View File

@ -185,13 +185,13 @@ template<typename Derived> class MatrixBase
typedef CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> ScalarQuotient1ReturnType;
/** \internal the return type of MatrixBase::conjugate() */
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
Derived&
const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
const Derived&
>::ret ConjugateReturnType;
/** \internal the return type of MatrixBase::real() */
typedef CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType;
/** \internal the return type of MatrixBase::adjoint() */
typedef Transpose<NestByValue<typename ei_unref<ConjugateReturnType>::type> >
typedef Transpose<NestByValue<typename ei_cleantype<ConjugateReturnType>::type> >
AdjointReturnType;
/** \internal the return type of MatrixBase::eigenvalues() */
typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
@ -489,7 +489,7 @@ template<typename Derived> class MatrixBase
inline const NestByValue<Derived> nestByValue() const;
const ConjugateReturnType conjugate() const;
ConjugateReturnType conjugate() const;
const RealReturnType real() const;
template<typename CustomUnaryOp>

View File

@ -545,7 +545,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirect
enum {
EvalToRes = (ei_packet_traits<Scalar>::size==1)
||((DestDerived::Flags&ActualPacketAccessBit) && (!(DestDerived::Flags & RowMajorBit))) };
Scalar* __restrict__ _res;
Scalar* EIGEN_RESTRICT _res;
if (EvalToRes)
_res = &res.coeffRef(0);
else
@ -590,7 +590,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
enum {
EvalToRes = (ei_packet_traits<Scalar>::size==1)
||((DestDerived::Flags & ActualPacketAccessBit) && (DestDerived::Flags & RowMajorBit)) };
Scalar* __restrict__ _res;
Scalar* EIGEN_RESTRICT _res;
if (EvalToRes)
_res = &res.coeffRef(0);
else
@ -622,7 +622,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,RowMajor,HasDirect
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
Scalar* __restrict__ _rhs;
Scalar* EIGEN_RESTRICT _rhs;
if (UseRhsDirectly)
_rhs = &product.rhs().const_cast_derived().coeffRef(0);
else
@ -650,7 +650,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
Scalar* __restrict__ _lhs;
Scalar* EIGEN_RESTRICT _lhs;
if (UseLhsDirectly)
_lhs = &product.lhs().const_cast_derived().coeffRef(0);
else

View File

@ -99,6 +99,8 @@ using Eigen::MatrixBase;
#define EIGEN_ALIGN_128
#endif
#define EIGEN_RESTRICT __restrict
#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \
template<typename OtherDerived> \
Derived& operator Op(const MatrixBase<OtherDerived>& other) \

View File

@ -224,12 +224,16 @@ template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret
template<typename T, int n=1, typename EvalType = typename ei_eval<T>::type> struct ei_nested
{
enum {
CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost)
};
typedef typename ei_meta_if<
ei_must_nest_by_value<T>::ret,
T,
typename ei_meta_if<
(int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
|| ((n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost) <= (n-1) * int(T::CoeffReadCost)),
|| ( int(CostEval) <= int(CostNoEval) ),
EvalType,
const T&
>::ret

View File

@ -71,6 +71,9 @@ template<typename MatrixType> class LU
MatrixType::MaxRowsAtCompileTime)
};
typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, Dynamic,
MatrixType::MaxColsAtCompileTime, MaxSmallDimAtCompileTime> KernelReturnType;
/** Constructor.
*
* \param matrix the matrix of which to compute the LU decomposition.
@ -165,9 +168,8 @@ template<typename MatrixType> class LU
* Output: \verbinclude LU_kernel.out
*
* \sa computeKernel()
*/ const Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, Dynamic,
MatrixType::MaxColsAtCompileTime,
LU<MatrixType>::MaxSmallDimAtCompileTime> kernel() const;
*/
const KernelReturnType kernel() const;
/** This method finds a solution x to the equation Ax=b, where A is the matrix of which
* *this is the LU decomposition, if any exists.
@ -408,9 +410,7 @@ void LU<MatrixType>::computeKernel(Matrix<typename MatrixType::Scalar,
}
template<typename MatrixType>
const Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, Dynamic,
MatrixType::MaxColsAtCompileTime,
LU<MatrixType>::MaxSmallDimAtCompileTime>
const typename LU<MatrixType>::KernelReturnType
LU<MatrixType>::kernel() const
{
Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, Dynamic,

View File

@ -285,8 +285,8 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
hCoeffs.end(n-i-1) += (h * Scalar(-0.5) * matA.col(i).end(n-i-1).dot(hCoeffs.end(n-i-1)))
* matA.col(i).end(n-i-1);
const Scalar* __restrict__ pb = &matA.coeffRef(0,i);
const Scalar* __restrict__ pa = (&hCoeffs.coeffRef(0)) - 1;
const Scalar* EIGEN_RESTRICT pb = &matA.coeffRef(0,i);
const Scalar* EIGEN_RESTRICT pa = (&hCoeffs.coeffRef(0)) - 1;
for (int j1=i+1; j1<n; ++j1)
{
int starti = i+1;

View File

@ -79,7 +79,7 @@ template<typename Real> void MandelbrotThread::render(int img_width, int img_hei
// in which case we can stop iterating.
int j = 0;
typedef Eigen::Matrix<int, packetSize, 1> Packeti;
Packeti pix_iter = Packeti::zero(), // number of iteration per pixel in the packet
Packeti pix_iter = Packeti::Zero(), // number of iteration per pixel in the packet
pix_dont_diverge; // whether or not each pixel has already diverged
do
{
@ -93,7 +93,7 @@ template<typename Real> void MandelbrotThread::render(int img_width, int img_hei
}
pix_dont_diverge = ((pzr.cwise().square() + pzi.cwise().square())
.eval() // temporary fix as what follows is not yet vectorized by Eigen
.cwise() <= Packet::constant(4))
.cwise() <= Packet::Constant(4))
// the 4 here is not a magic value, it's a math fact that if
// the square modulus is >4 then divergence is inevitable.
.template cast<int>();

View File

@ -1,5 +1,6 @@
IF(BUILD_TESTS)
IF(CMAKE_COMPILER_IS_GNUCXX)
IF(CMAKE_SYSTEM_NAME MATCHES Linux)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g2")
@ -7,6 +8,9 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-inline-functions")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g2")
ENDIF(CMAKE_SYSTEM_NAME MATCHES Linux)
SET(EI_OFLAG "-O2")
ELSE(CMAKE_COMPILER_IS_GNUCXX)
SET(EI_OFLAG "")
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
OPTION(EIGEN_NO_ASSERTION_CHECKING "Disable checking of assertions" OFF)
@ -38,11 +42,7 @@ MACRO(EI_ADD_TEST testname)
SET(targetname test_${testname})
# IF(${ARGC} EQUAL 2)
# SET(filename ${ARGV1})
# ELSE(${ARGC} EQUAL 2)
SET(filename ${testname}.cpp)
# ENDIF(${ARGC} EQUAL 2)
SET(filename ${testname}.cpp)
ADD_EXECUTABLE(${targetname} ${filename})
IF(NOT EIGEN_NO_ASSERTION_CHECKING)
@ -90,7 +90,7 @@ EI_ADD_TEST(basicstuff)
EI_ADD_TEST(linearstructure)
EI_ADD_TEST(cwiseop)
EI_ADD_TEST(product_small)
EI_ADD_TEST(product_large "-O2")
EI_ADD_TEST(product_large ${EI_OFLAG})
EI_ADD_TEST(adjoint)
EI_ADD_TEST(submatrices)
EI_ADD_TEST(miscmatrices)
@ -99,7 +99,7 @@ EI_ADD_TEST(map)
EI_ADD_TEST(array)
EI_ADD_TEST(triangular)
EI_ADD_TEST(cholesky)
EI_ADD_TEST(lu "-O2")
EI_ADD_TEST(lu ${EI_OFLAG})
EI_ADD_TEST(determinant)
EI_ADD_TEST(inverse)
EI_ADD_TEST(qr)

View File

@ -72,6 +72,7 @@ template<typename MatrixType> void adjoint(const MatrixType& m)
VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1));
// check compatibility of dot and adjoint
// FIXME this line failed with MSVC and complex<double> in the ei_aligned_free()
VERIFY_IS_APPROX(v1.dot(square * v2), (square.adjoint() * v1).dot(v2));
// like in testBasicStuff, test operator() to check const-qualification