This forum has been archived. All content is frozen. Please use KDE Discuss instead.

How does solve() work?

Tags: None
(comma "," separated)
noether
Registered Member
Posts
10
Karma
0
OS

How does solve() work?

Sun Jun 10, 2012 1:42 pm
Hello,

time ago I posted a problem about a link issue using Eigen in a embedded system:
viewtopic.php?f=74&t=98611

The other day I could isolate a little bit more the problem. If I use operations between matrices, or matrix decomposition, everything
is ok. But if I use solve method (or inverse for "large" matrices) I can not link the program because I have the error posted in the before topic.
However, if I do not link with stdc++ , I have realized that I only have the error when the operator new is called.
By the way, depending on 'the complexity' of the operation, the call to 'new' can be avoided just increasing the -Ox compiler option (related
with the before link), but if you use solve method, even with -O3, the call to 'new' can not be avoided.

This is the error from the linker:
Code: Select all
Linking build/ch.elf
build/obj/main.o: In function `throw_std_bad_alloc':
/usr/include/eigen3/Eigen/src/Core/util/Memory.h:91: undefined reference to `operator new[](unsigned int)'


Does it mean that solve() method require always dynamic memory for working? (because it should not be allowed in my system).
So, even with fixed matrices, I can still have creation of new aux matrices?
I have compiled the code with -DNDEBUG -DEIGEN_NO_MALLOC -DEIGEN_RUNTIME_NO_MALLOC (I do not know if it helps in some way),
and I still have the same link error.

Herewith is a test code, if I comment the last two lines, everything goes fine.
Code: Select all
   Matrix2f A, B, C;
   A << 3, 0, 0, 3;
   B << 1, 2, 3, 1;

   Matrix3f AA;
   AA << 1, 2, 3,  4, 5, 6, 55, 6, 8;
   Vector3f xx, b;
   b << 3, 3, 4;

   Matrix<float, 6, 6> U, X;
   U << 1, 1, 0, 0, 0, 0,  0, 1, 0, 0, 0, 0,  0, 0, 1, 0, 0, 0,
        0, 0, 0, 1, 0, 0,  0, 0, 0, 0, 3, 0,  0, 0, 0, 0, 0, 6;

   
  while (TRUE) {
   A = A + B;
   C = A.llt().matrixL();
   A = C.colPivHouseholderQr().matrixQR();
   X = U.llt().matrixL();
   X = U + X;
   xx = AA.colPivHouseholderQr().solve(b);
   X = U.inverse();
}


By the way, looking at the Memory.h

Code: Select all
namespace internal {

inline void throw_std_bad_alloc()
{
  #ifdef EIGEN_EXCEPTIONS
    throw std::bad_alloc();
  #else
    std::size_t huge = -1;
    new int[huge];
  #endif
}


I guess this is not related with the creation of any aux matrix? Can I get around my problem?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: How does solve() work?

Mon Jun 11, 2012 6:28 am
To be sure you could try to compile with -DEIGEN_EXCEPTIONS?
noether
Registered Member
Posts
10
Karma
0
OS

Re: How does solve() work?

Tue Jun 12, 2012 12:40 pm
ggael wrote:To be sure you could try to compile with -DEIGEN_EXCEPTIONS?


Hello ggael, thanks for the response. Unfortunately, I am compiling with -fno-exceptions (I do not allow throws neither).

Finally, I have worked the problem out just writing a minimal implementation of the syscalls. Now I can compile Eigen stuff without problems,
even with -O0. Probably I will rewrite _kill and _exit just in case the microcontroller goes in for doing easy a possible debug tracking.

Code: Select all
int _getpid()
{
   return 1;
}

int _kill(int pid, int sig){
   errno=EINVAL;
   return(-1);
}

void _exit (int  rc)
{
  while (1)
    {
    }
}


I do not have my hardware available in the next two weeks. However, I would like to knoe if Eigen needs in whatever way this syscalls working properly (not just with this minimal implementation). I mean, all my matrices in the system are static, should I be afraid of some dynamic allocation (or calls to the system such as abort etc) using solve, householder, etc? (I am only using Dense stuff).

Thanks in advance for the help.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: How does solve() work?

Tue Jun 12, 2012 5:10 pm
hi,

I wanted to suggested you to overload operator new, but your solution is fine too. Today I fixed an issue where solving for a fixed size matrix as the right hand side triggered a dynamic allocation when alloca was not available.

Except for memory allocation, Eigen does not rely on any particular behavior of syscalls. Another exception is to handle runtime assertion when EIGEN_NO_DEBUG (or NDEBUG) is not defined. With fixed sizes objects most assertion should be resolved at compile time, but who knows...


Bookmarks



Who is online

Registered users: Baidu [Spider], Bing [Bot], Google [Bot], rblackwell