Registered Member
|
Hello
I can't get my program to work. It always crashes with those "Assertion failed" messages. I've tried the three workarounds and placed EIGEN_MAKE_ALIGNED_OPERATOR_NEW in every class. Obviously the fourth reason also applies, as I compile with WinXP and MinGW. They suggest to use __attribute__((force_align_arg_pointer)) before functions or -mincoming-stack-boundary=2 / -mstackrealign. But neither are recognized by the compiler. Before that, I used another vector class but I'd like to switch to Eigen, because it's elegant and powerful. However, if I have to spend days to get it running, it isn't worth the effort. And all that because of the vectorisation, isn't that the reason? I want to use Eigen, but I don't want to struggle with all these GCC workarounds. Is there a way I can do that? Thanks for any suggestions, regards, Johannes |
Moderator
|
I guess you are using gcc 3.x ? So I see two solutions for you:
1 - use gcc 4.x with -mincoming-stack-boundary=2 or -mstackrealign 2 - completely disable the alignment. To this end, you unfortunately have to manually edit the Eigen/src/Core/util/Macro.h file around line 45 so that EIGEN_ARCH_WANTS_ALIGNMENT is defined to 0. In the next release (2.0.4) I'll make sure this is doable by simply defining a preprocessor token. |
Registered Member
|
#define EIGEN_ARCH_WANTS_ALIGNMENT 0 didn't work for me. Program crashes at once. Do I have to remove the new-overloading from every class? I must admit, I didn't do a detailled analysis of the problem because:
Both solutions suggested wouldn't be best. Global disabling of alignment isn't too smart. There are 2 parts of my program: - algorithm engine, performance-critical, running stable with Eigen 2.0.2 and alignment enabled. - visualization, not performance critical, can't get it running with Eigen (I think the error is "Cause 4"), runs with some **** vector class. So I think I will use 'typedef' to switch quickly between vector classes and just postpone the problem 'till later. Some more questions about the assertion workarounds: - I guess, I have to use #include <Eigen/StdVector> *only* for std::vector's which contain Eigen objects? - Return values *may* be value-passed Eigen objects, e.g. return Eigen::Vector4f(...); ? - The EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro needs to be used *only* in classes that contain Eigen objects as member variables? So pointers wouldn't be affected? Thanx for helping, Johannes |
Moderator
|
To answer your questions, let me first say that each class which contains fixed-size Eigen objects requires a correct alignment. This include fixed-size Eigen objects themselves. This definition is recursive, so any class which itself contains or inherits a class requiring alignment also requires a correct alignment.
So for all such classes, you have to: - use the <Eigen/StdVector> workaround, - use the EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro, - and do not pass them by value. However, returning them by value should be fine. For further help, please give us more information. Which gcc version ? Is your program multi-threaded ? Also please, run your program under a debugger and analyze the backtrace. If you feel lost, feel free to post the backtrace with the accompanying relevant piece of code. You might also try to declare the Eigen matrices with the DontAlign option:
|
Registered Member
|
The Eigen::DontAlign switch does seem to be helping. Could get my program run further than before. It still crashes at the following code:
------------------- [class member variables: Eigen::Quaternionf mQuat, mTemp;] SaveVector3f axis = ... float phi = ... Eigen::AngleAxisf aaf(phi, axis); mTemp = aaf; mQuat *= mTemp; // <== this crashes -------------------- any direct call mQuat *= Quaternion(AngleAxisf(phi, axis)) crashes too The above function is a member of a class 'Trackball', which has the overloaded new macro. Is there some Aligning in Quaterions, or does it use aligned matrices? What makes my Visualization (which doesn't run with Eigen) different from the rest of the software (which runs perfectly with Eigen) is, that I have some static callback functions from the graphics engine. Maybe this could be the difference. And I include lots of header and dll, e.g. <windows.h>, "gl/glut.h", opengl32.dll, glu32.dll (for OpenGL), gdi32 (some Windows stuff) BTW, I use: WinXP SP2, MinGW gcc 3.4.5, Eigen 2.0.2 |
Moderator
|
Indeed, Quaternion stores a Vector4 which have to be aligned. Your crash means that your Trackball instance is not aligned. So now the question is how this instance has been created ? Dynamic alloc ? member of another class ? local variable of a function ? If it is a member of another object then we also have to investigate how this later object has been created and so on...
I see you are using gcc 3.4.5, so for performance reasons (and many others) I'd recommend you to switch to with gcc 4.4 (see http://www.tdragon.net/recentgcc/). This will also allow you to try the global options -mincoming-stack-boundary=2 / -mstackrealign. If one these options work then we'll know that the issue come from an "unaligned function call" which can occur if the function is called from another thread (I don't know if the stack is kept aligned with function callbacks). |
Registered Member
|
Originally, my Trackball object was a global static object. After your suggestion, I tried it as a member of the Visualizer "main" class, where all the graphic stuff is inside. Of course the classes have the new overloader macro. It still crashed.
- Maybe the aligning gets lost, when OpenGL calls the static handleMouseClick() callback from where dvis->mouseClicked() is called, which calls move() where the crash occurs. dvis is a pointer to the new Visualizer() object. I create it using the "Singleton pattern". - It could also be that this "new" makes Visualizer unaligned... the makro shouldn't have been executed by then. I will try gcc 4 soon, I think. But those global changes are often a problem to my other existing projects. Thanx for your continued help! |
Moderator
|
hm I tried mingw with gcc 3.4.4 and I cannot reproduce your issue. I tried to nest various classes, create them statically inside functions called from a pointer function, I tried to create the objects with operator new, etc.
Also, there is something I don't understand: you said it crashes at this line: mQuat *= Quaternion(AngleAxisf(phi, axis)); with the "blabla READ THIS WEB PAGE" assertion, right ? However if it would be mQuat which was not correctly aligned then the assertion would be raise at the construction time (when the Trackball is created). So if you confirm you still get this assertion then we know that the issue the stack which is not correctly aligned in that function call (because this product yield a temporary Vector4 created on the stack). In this case I suggest you to add __attribute__((force_align_arg_pointer)) to the first functions which can be called from the outside, i.e., handleMouseClick(), so that the stack is explicitly realigned. |
Registered Member
|
- When I say "Eigen crashes" I always speak about the alignment assertion
- Creation of Quaternion mQuat and any mTemp as class members works fine. Splitting the line up reveals that any Quaternion() call in that function crashes. And as you say, the multiplication call seems to try an aligned Matrix() call. - the force_align_arg_pointer attribute is ignored by my compiler, otherwise I would have tried: warning: `force_align_arg_pointer' attribute directive ignored I think I will try again this afternoon. |
Registered Member
|
Okay, now my project runs with gcc 4.4 and the attribute ((force_align_arg_pointer)) before every critical function. Eigen works this way.
Unfortunately now I'd have to convert all my older projects from gcc 3.4 to 4.4. gcc 4.4 seems to be much more rigid about some sloppy declarations, there are lots of warnings and even some errors (printf not declared). I'll have to find a way to get both installed parallel. |
Registered users: Bing [Bot], Google [Bot], Sogou [Bot]