New user self-registration is currently disabled. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Bug 1161 - Crash while evaluating product of AutoDiffScalar matrices
Crash while evaluating product of AutoDiffScalar matrices
Status: RESOLVED FIXED
Product: Eigen
Classification: Unclassified
Component: Core - matrix products
3.3 (current stable)
x86 - 64-bit All
: Normal Crash
Assigned To: Nobody
:
Depends on:
Blocks: 3.3
  Show dependency treegraph
 
Reported: 2016-02-01 21:40 UTC by twan_koolen
Modified: 2016-02-03 20:47 UTC (History)
2 users (show)



Attachments
Example demonstrating crash (646 bytes, text/plain)
2016-02-01 21:40 UTC, twan_koolen
no flags Details
Trace (9.61 KB, text/plain)
2016-02-01 21:41 UTC, twan_koolen
no flags Details

Description twan_koolen 2016-02-01 21:40:46 UTC
Created attachment 649 [details]
Example demonstrating crash

See attached example. Seems pretty low level and not specific to AutoDiffScalar matrices.

Looks like in evaluateProductBlockingSizesHeuristic, evaluating
      k = (k%max_kc)==0 ? max_kc
                        : max_kc - k_peeling * ((max_kc-1-(k%max_kc))/(k_peeling*(k/max_kc+1)));
results in taking an undefined remainder by zero (max_kc happens to evaluate to 0), triggering
Exception: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0))

This is on OSX, but we get a crash on Linux too, so I filled in All. This used to work fine with Eigen 3.2.7, but causes a crash with 3.3 beta 1 and with the default branch. I will attach a stack trace to a follow up comment.
Comment 1 twan_koolen 2016-02-01 21:41:46 UTC
Created attachment 650 [details]
Trace
Comment 2 Gael Guennebaud 2016-02-03 17:29:23 UTC
Fixed: https://bitbucket.org/eigen/eigen/commits/7b1fb73c5346/

however, a cleaner solution would be to to fallback to another product implementation for heavy scalar types.

Using R.lazyProduct(....) instead of R*... is very likely to be much faster.
Comment 3 Gael Guennebaud 2016-02-03 17:32:49 UTC
(In reply to Gael Guennebaud from comment #2)
> Using R.lazyProduct(....) instead of R*... is very likely to be much faster.

Indeed, a quick bench tell me 1.11ms versus 0.17ms for lazyProduct.
Comment 4 twan_koolen 2016-02-03 19:45:23 UTC
Thank you for the fix!

> Indeed, a quick bench tell me 1.11ms versus 0.17ms for lazyProduct.

Hmm, that's very interesting. Sorry, I wasn't quite clear on this: did you mean that as a recommendation for us or as a possible future improvement on your end?

A lot of our code is templated on the scalar type and supposed to work for (at least) both double and AutoDiffScalar<...> types, with a heavier performance requirement on the double template instantiations. This means that switching everything to lazyProduct outright is not the best option for us. I suppose we could select which product implementation to use based on the scalar type. But having that done automatically by Eigen would be incredible for us given the potential huge speedup and would mean we could keep our code more readable.
Comment 5 Gael Guennebaud 2016-02-03 20:47:58 UTC
This comment was mostly for Eigen, but actually, if R is always as small as 3x3, then better use lazyProduct even for double.

Note You need to log in before you can comment on or make changes to this bug.