Cling inline assembly support

Hi,
I am experimenting the fantastic tool of cling by loading several libraries. From some simple stuffs, it works beautifully. It fails for the libraries using inline assembly.
From this page,
github.com/cptG/qling

At the moment, llvm’s JIT does not support inline assembler, which is needed for Qt’s atomic stuff. For this reason there is a folder qt-hack, which includes modified qatomic-headers that #ifdef the inline asm away and cause the compiler to use the non-inline functions provided by qatomic_sun.s instead. These inline-asm issues likely cause other libraries that you might want to use from within cling to make the app crash, as well. An example is Eigen3 - I do have a patched version of Eigen3, too but there is a more elegant way to go: Recently the “MC framework” has been included in llvm and MC’s JIT does support inline assembly. Unfortunately cling needs to be patched to make use of that and I have not yet been successful in making this work correctly - it segfaults atm which seems to be some JIT-memory-manager issue that I have yet to figure out. I have only spent ~1hour on this and then given up due to lack of time.

My question is whether you have a plan to support this feature. I am not sure how difficult this will be. But it will be great if we have it :smiley: . Thanks.

regards,

gma

Hi,

We do plan to switch to MCJIT at some point. I am going to investigate still this week whether this will happen in November or only next year.

Cheers, Axel.

Many thanks, Axel. It will be awesome to have this feature. :smiley: Look forwards to seeing your progress on this.

cheers,

gma

When testing following boost asio code in cling:

    #include <iostream>
    .L libboost_system.so
    #include <boost/asio.hpp>
    #include <boost/date_time/posix_time/posix_time.hpp>

    boost::asio::io_service io;
    boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));

cling aborts giving following error message:

Cannot allocate thread local storage on this arch!
UNREACHABLE executed at /mnt/vdb/lsf/cling-1459fc6235a3-full-890866/cling-src-1459fc6235a30707fa2b9817d62e6a115b3ec7fa/lib/Target/X86/X86JITInfo.cpp:579!
Stack dump:
0.	Running pass 'X86 Machine Code Emitter' on function '@_ZNK5boost4asio6detail15keyword_tss_ptrINS1_10call_stackINS1_15task_io_serviceENS4_11thread_infoEE7contextEEcvPS7_Ev'
Aborted

http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-September/053742.html says mcjit will support thread local variables.

Hope cling will support it soon.

Dear all,

Can we keep this post up-to-date :

  • plans to migrate to MCJIT and usability of inline asm code
  • usability of Eigen3 in Cling :
//test.C
#include <iostream>
#include <Eigen/Dense>
void test()
{
    using Eigen::MatrixXd ;
    using namespace std ;

    MatrixXd m(2,2);
    m(0,0) = 3;
    m(1,0) = 2.5;
    m(0,1) = -1;
    m(1,1) = m(1,0) + m(0,1);
    std::cout << m << std::endl;
}

this code is working after .I /path/to/eigen3 in ROOT6beta2 and in Cling but the

#include <Eigen/Dense> takes 7 seconds for me in Cling and 1 second in ROOT6beta2 …

I dont know what’s already loaded in ROOT that makes it faster than cling…

More elaborate examples are not working for the moment in ROOT6/Cling :

//test2.C
#include <iostream>
#include <Eigen/Dense>

void test2()
{
    using namespace std;
    using namespace Eigen;

    Matrix3f A;
    Vector3f b;
    A << 1,2,3, 4,5,6, 7,8,10;
    b << 3, 3, 4;
    cout << "Here is the matrix A:\n" << A << endl;
    cout << "Here is the vector b:\n" << b << endl;
    Vector3f x = A.colPivHouseholderQr().solve(b);
    cout << "The solution is:\n" << x << endl;
}

gives me some errors :

root [0] .I /path/to/eigen3
root [1] .x test2.C
input_line_131:1:6: error: variable has incomplete type 'void'
void __cling_Un1Qu30() {
     ^
-:1:1: error: expected expression
^
input_line_131:1:22: error: expected ';' after top level declarator
void __cling_Un1Qu30() {
                     ^
                     ;
input_line_131:1:22: error: expected unqualified-id

It could be awesome to have this Eigen3 working with ROOT6/Cling … A fantastic way to learn modern C++ for all the applied mathematics students…

:slight_smile:

Hi,
The MCJIT is on our plans right after the release of ROOT6.
I believe Eigen can be still usable with some patches (#ifdef-s) in the header files, avoiding the inline asm.
Cheers,
Vassil

I have tried with this 2 years-old patched version of Eigen :

github.com/cptG/qling/tree/mast … ched/Eigen

it works for test.C as before ( plus some warnings) :

root [0] .I /home/kulam/data/paquets/qling/eigen-patched
root [1] .L test.C
In file included from input_line_22:1:
In file included from /home/kulam/travail/root/eigen/test.C:21:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Dense:1:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Core:255:
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:494:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux0 = aux[0]<aux[1] ? aux[0] : aux[1];
  ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:495:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux2 = aux[2]<aux[3] ? aux[2] : aux[3];
  ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:515:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux0 = aux[0]>aux[1] ? aux[0] : aux[1];
  ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:516:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux2 = aux[2]>aux[3] ? aux[2] : aux[3];
  ^~~~~~~~~
In file included from input_line_22:1:
In file included from /home/kulam/travail/root/eigen/test.C:21:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Dense:1:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Core:324:
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/products/SelfadjointMatrixVector.h:74:5: warning: 
      'register' storage class specifier is deprecated [-Wdeprecated-register]
    register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
    ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/products/SelfadjointMatrixVector.h:75:5: warning: 
      'register' storage class specifier is deprecated [-Wdeprecated-register]
    register const Scalar* EIGEN_RESTRICT A1 = lhs + (j+1)*lhsStride;
    ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/products/SelfadjointMatrixVector.h:142:5: warning: 
      'register' storage class specifier is deprecated [-Wdeprecated-register]
    register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
    ^~~~~~~~~
root [2] test()
  3  -1
2.5 1.5

and does not work for test2.C as before (plus some warnings) :

root [0] .I /home/kulam/data/paquets/qling/eigen-patched
root [1] .L test2.C
In file included from input_line_22:1:
In file included from /home/kulam/travail/root/eigen/test2.C:20:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Dense:1:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Core:255:
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:494:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux0 = aux[0]<aux[1] ? aux[0] : aux[1];
  ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:495:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux2 = aux[2]<aux[3] ? aux[2] : aux[3];
  ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:515:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux0 = aux[0]>aux[1] ? aux[0] : aux[1];
  ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/arch/SSE/PacketMath.h:516:3: warning: 'register' storage
      class specifier is deprecated [-Wdeprecated-register]
  register int aux2 = aux[2]>aux[3] ? aux[2] : aux[3];
  ^~~~~~~~~
In file included from input_line_22:1:
In file included from /home/kulam/travail/root/eigen/test2.C:20:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Dense:1:
In file included from /home/kulam/data/paquets/qling/eigen-patched/Eigen/Core:324:
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/products/SelfadjointMatrixVector.h:74:5: warning: 
      'register' storage class specifier is deprecated [-Wdeprecated-register]
    register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
    ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/products/SelfadjointMatrixVector.h:75:5: warning: 
      'register' storage class specifier is deprecated [-Wdeprecated-register]
    register const Scalar* EIGEN_RESTRICT A1 = lhs + (j+1)*lhsStride;
    ^~~~~~~~~
/home/kulam/data/paquets/qling/eigen-patched/Eigen/src/Core/products/SelfadjointMatrixVector.h:142:5: warning: 
      'register' storage class specifier is deprecated [-Wdeprecated-register]
    register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
    ^~~~~~~~~
root [2] test2()
input_line_23:1:6: error: variable has incomplete type 'void'
void __cling_Un1Qu31(void* vpClingValue) {
     ^
-:1:1: error: expected expression
^
input_line_23:1:22: error: expected ';' after top level declarator
void __cling_Un1Qu31(void* vpClingValue) {
                     ^
                     ;
input_line_23:1:40: error: expected ';' after top level declarator
void __cling_Un1Qu31(void* vpClingValue) {
                                       ^
                                       ;

Does someone know how to patch Eigen3 in order to use it with Cling ?

Thanks in advance…