Search code examples
c++clangeigen

Getting clang error when setting large Eigen VectorXd


I have a function that all it does is

Eigen::VectorXd x(%s);
x << %s;

where the first %s is the size and the second is the input (to dynamically set my vector). When I run this on "small" inputs ( > 4000 parameters) everything works great. But when I do it on larger ones I can't compile and I get

clang: error: unable to execute command: Illegal instruction: 4
clang: error: clang frontend command failed due to signal (use -v to see invocation)
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
clang: note: diagnostic msg: PLEASE submit a bug report to http://developer.apple.com/bugreporter/ and include the crash backtrace, preprocessed source, and associated run script.
clang: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /var/folders/jc/nh9bfd2j5_q4w0x2mbq02svc0000gq/T/wenzel-f181fc.cpp
clang: note: diagnostic msg: /var/folders/jc/nh9bfd2j5_q4w0x2mbq02svc0000gq/T/wenzel-f181fc.sh
clang: note: diagnostic msg: Crash backtrace is located in
clang: note: diagnostic msg: /Users/ipq500/Library/Logs/DiagnosticReports/clang_<YYYY-MM-DD-HHMMSS>_<hostname>.crash
clang: note: diagnostic msg: (choose the .crash file that corresponds to your crash)
clang: note: diagnostic msg:

********************

I've seen that this might be an XCode issue, but was wondering what could possibly be going on. I'm at a complete loss here.


Solution

  • I assume what you try to do is something like

    Eigen::VectorXd x(4000);
    x << 0, 1, 2, 3, /* many more values */ 3999;
    

    This is implemented by overloading the << and the , operators, i.e., the syntax is equivalent to something like:

    operator,( /* many more calls ... */
      operator,(operator,(operator,(operator<<(x,0), 1), 2), 3)
               /* ... */, 3999 );
    

    This could indeed be very hard for a compiler to translate, as you are having a 4000-depth call-stack (even though this will get inlined, during compile-time this could trigger some limits).

    With C++11 and the development branch you could try this (not sure about compiler limits for that syntax):

    Eigen::VectorXd x{ {0, 1, 2, 3, /* ... */ 3999} };
    

    If that does not work try this alternative (C++03 compatible):

    static const x_data[4000] = {0,1,2, /* ... */, 3999}; // ideally this should be aligned
    Eigen::Map<Eigen::VectorXd> x(x_data, 4000);
    

    Alternatively, if you have the data in binary form (e.g., in a separate file) then mmap the file at runtime and create an Eigen::Map on that data.