Re: [eigen] ei_redux_impl & ei_alignmentOffset |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] ei_redux_impl & ei_alignmentOffset
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Wed, 16 Dec 2009 08:05:00 -0500
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=dQjYx6jvCZnMAzIKs47z9nsBRc+jni27S87UWAKqLo0=; b=tmy00osDurB+/h1UBcwttYMmRSxzUyHFrqswTOD6vuzMnvLBKq2st1lyo3wiF00OGf miVos4OoZrvAKLKkBHCe9qgJF592k0UzxKdfXIJP1u+AofnEKUpJc0ui95Ax28TI3weW JsFcDGn2UIeDDCZxyB49pD47c5qIOeILc7bHU=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=OKmN5BDObpR/OY8JTeDyC6U5+eBmReFJotu1thFgZomF2TC+hNNe6UNHE8rRrksxux bryqpamUGruKUc2cxfnRgVwkmN6bxdpsJ9HQ/tAeVjtZV4Vpu/YqOnEg0MDVkYRxGzKo c1zEfZV0rKrUtp5eswD1L1nHgIuAa8DZiP3OM=
*oh*
I know where you can very plausibly get an infinite recursion. It is
in the call to coeffRef() itself!!!
Indeed we define it only for lvalue expressions!
Here your cwise().abs2() produces a rvalue expression, hence it
doesn't have coeffRef() defined, hence matrixBase::coeffRef() calls
derived().coeffRef() which is itself!
Solution: in the line,
&mat.const_cast_derived().coeffRef(0)
replace coeffRef by coeff.
Indeed, coeff returns a const reference too when there is direct
access (or else it's a bug).
The naming coeff/coeffRef dates back to very old days when coeff() was
always returning by value. Now it returns by reference if there is
DirectAccess.
I was actually wondering, recently. Is the name difference coeffRef
vs. coeff needed? Couldn't we call them both coeff, letting them
differ only by const-qualification?
Benoit
2009/12/16 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
> 2009/12/16 Hauke Heibel <hauke.heibel@xxxxxxxxxxxxxx>:
>> Hi,
>>
>> I am still every now and then looking at the inlining warnings created by
>> MSVC (+1500). Here are some findings regarding a whole bunch of those
>> warnings.
>>
>> Many many warnings we observe on MSVC (W4) are caused by this call here
>> (taken from ei_redux_impl<Func, Derived, LinearVectorizedTraversal,
>> NoUnrolling>::run)
>>
>> &mat.const_cast_derived().coeffRef(0)
>>
>> My most simple example to trigger this warning is
>>
>> #include <Eigen/Core>
>> #include <Eigen/Array>
>>
>> using namespace Eigen;
>>
>> void main ()
>> {
>> typedef Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::AutoAlign>
>> MatrixType;
>> MatrixType a = MatrixType::Random(50,50);
>> a.cwise().abs2().sum();
>> }
>>
>> This call brings us to
>>
>> ei_redux_impl<Func, Derived, LinearVectorizedTraversal,
>> NoUnrolling>::run(...)
>>
>> triggering the warning while the variable alignedStart is zero. I am
>> wondering how I can create an example that actually causes alignedStart != 0
>> ?? When I set the DontAlign option, I am ending up in a completely different
>> branch.
>
> To produce alignedStart!=0, you could do:
>
> VectorXf v(1000);
> v.end(999).sum();
>
>>
>> For testing purposes I added this code at the very beginning of the function
>>
>> const Scalar& s = mat.const_cast_derived().coeffRef(0);
>>
>> resulting in warning telling me that everything beyond this line is
>> unreachable code. That is the case since derived() will end up in an
>> infinite loop.
>
> Do you mean const_cast_derived() ?
>
>> Here is why:
>>
>> - mat is a CwiseUnaryOp< ei_scalar_abs2_op<float>, MatrixXf >
>
> yes,
>
>> - mat.const_cast_derived() calls MatrixBase< CwiseUnaryOp<
>> ei_scalar_abs2_op<float>, MatrixXf > >
>
> Yes, it calls MatrixBase::const_cast_derived(),
>
>> and returns a CwiseUnaryOp<
>> ei_scalar_abs2_op<float>, MatrixXf >
>>
>> and here we go - infinite loop.
>
> Why ? Here, MatrixBase::const_cast_derived() is implemented like this:
>
> inline Derived& const_cast_derived() const
> { return *static_cast<Derived*>(const_cast<MatrixBase*>(this)); }
>
> So this call doesn't call anything itself, so where is the infinite recursion?
>
> If you have an infinite recursion, you get a stack overflow. Is that
> happening? Can you get a backtrace then? If the stack is damaged by
> the overflow, try doing an assert() on the call depth using a static
> int variable, then you'll get a good stack...
>
> Benoit
>
>
>> So there is something odd going on and I can
>> understand that MSVC complains about inlining. Infinite inlining is rather
>> tricky.
>>
>> Any ideas?
>>
>> - Hauke
>>
>