Cross-Compiling Armadillo Linear Algebra Library

后端 未结 2 1484
情歌与酒
情歌与酒 2020-12-31 23:08

I enjoy using the Armadillo Linear Algebra Library. It becomes extremely nice when porting octave .m files over to C++, especially when you have to use the eigen methods.

2条回答
  •  抹茶落季
    2020-12-31 23:23

    My specific setup is OSX (IDE Eclipse) cross compiled to a Beaglebone Black. However, these instructions should work for similar setups.

    Optional:

    For compiling I used the Mac OS X ARM GNU Linux G++ Lite 2013.11-33 Toolchain. Specifically, the ARM GNU/Linux G++ Lite 2013.11-33 Advanced Binary.

    1. Download:

    Just as Matt posted, the GCC cross compiler doesn't support Fortran, so if you want to compile LAPACK and BLAS, use a modified version found here. I'm using is clapack-3.2.1-CMAKE.tgz

    2. Make a cross compile cmake file:

    You can use a toolchain builder or just write one. I wrote one.

    Example:

    # http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
    
    # REQUIRED
    SET(CMAKE_SYSTEM_NAME Linux)
    SET(CMAKE_SYSTEM_VERSION 1)
    SET(CMAKE_SYSTEM_PROCESSOR arm)
    
    # Added for the beaglebone
    SET(FLOAT_ABI_SUFFIX "")
    
    # specify the cross compiler
    SET(CMAKE_C_COMPILER   /usr/local/arm-2013.11/bin/arm-none-linux-gnueabi-gcc)
    SET(CMAKE_CXX_COMPILER /usr/local/arm-2013.11/bin/arm-none-linux-gnueabi-c++)
    
    # where is the target environment 
    SET(CMAKE_FIND_ROOT_PATH  /usr/local/arm-2013.11)
    
    # search for programs in the build host directories
    SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    # for libraries and headers in the target directories
    SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    

    Note: This is my first time making a cmake file. It isn't guaranteed to be correct.

    You'll want to replace /usr/local/arm-2013.11/bin/arm-none-linux-gnueabi-gcc with the path to your selected compiler, as well as /usr/local/arm-2013.11/bin/arm-none-linux-gnueabi-c++ and /usr/local/arm-2013.11

    I chose to save this cmake file as beaglebone.cmake

    3. Compile:

    Extract clapack-3.2.1-CMAKE.tgz and cd

    compile: cmake -DCMAKE_TOOLCHAIN_FILE=~/Dropbox/workspaces/beaglebone/beaglebone.cmake
    where ~/Dropbox/workspaces/beaglebone/beaglebone.cmake is the path to your cmake file.

    make

    For some sort of reason I get:

    ds-mac-pro:clapack-3.2.1-CMAKE bunny$ make
    Scanning dependencies of target arithchk
    [  0%] Building C object F2CLIBS/libf2c/CMakeFiles/arithchk.dir/arithchk.c.o
    Linking C executable arithchk
    [  0%] Built target arithchk
    [  0%] Generating arith.h
    /bin/sh: arithchk: command not found
    make[2]: *** [F2CLIBS/libf2c/arith.h] Error 127
    make[1]: *** [F2CLIBS/libf2c/CMakeFiles/f2c.dir/all] Error 2
    make: *** [all] Error 2
    

    Oddly, running make again compiles fine:

    ds-mac-pro:clapack-3.2.1-CMAKE bunny$ make
    [  0%] Built target arithchk
    Scanning dependencies of target f2c
    [  0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/f77vers.c.o
    [  0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/i77vers.c.o
    [  0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/main.c.o
    [  0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/s_rnge.c.o
    

    ...

    [100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/xerbla.c.o
    [100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/xlaenv.c.o
    [100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/chkxer.c.o
    [100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/__/__/INSTALL/dsecnd.c.o
    Linking C executable xeigtstz
    [100%] Built target xeigtstz
    

    4. Copy (Install):

    find . | grep \.a$
    

    returns

    ./BLAS/SRC/libblas.a
    ./F2CLIBS/libf2c/libf2c.a
    ./SRC/liblapack.a
    ./TESTING/MATGEN/libtmglib.a
    

    cp libblas.a libf2c.a and liblapack.a to your favorite library folder. I made /usr/local/armadillo-4.300.3/lib

    Required:

    1. Copy Includes:

    Armadillo doesn't need to be compiled. I haven't ran any benchmarks to verify, but it appears that using LAPACK and BLAS works fine with an uncompiled copy of Armadillo by using #define in code. Code examples later.

    extract armadillo-4.300.3.tar.gz

    (optional) cp armadillo-4.300.3/include/ /usr/local/armadillo-4.300.3/include
    and of course, replace /usr/local/armadillo-4.300.3/include with your path of choice

    2. Setup GCC to use Armadillo:

    I'm using Eclipse with the C/C++ Cross Compiler Support addon (Help Menu -> Install New Software...), but the instructions are easy to convert to cli or other IDEs.

    In the project properties window: C/C++ Build -> Settings

    Cross G++ Compiler -> Includes -> Include paths (-I)

    Click the + to add an include. My include path is: /usr/local/armadillo-4.300.3/include

    3. OPTIONAL - Setup GCC to use the compiled libraries:

    Cross G++ Linker -> Libraries ->

    Libraries (-l)

    lapack
    f2c
    blas

    Library Search Path (-L)

    Click the + to add a path. My path is: /usr/local/armadillo-4.300.3/lib

    3. Code Example:

    In a cpp file try:

    #include 
    using namespace arma;
    
    mat A = randu(4,5);
    mat B = randu(4,5);
    
    std::cout << A*B.t() << std::endl;
    

    Success! :D

    Some functionality Armadillo does not directly support and will only work with compiled libraries. You can test that the libraries are compiled and working correctly by running a simple test like:

    #define ARMA_DONT_USE_WRAPPER
    #define ARMA_USE_LAPACK
    #define ARMA_USE_BLAS
    #include 
    using namespace arma;
    
    mat    A = randu(5,5);
    double x = det(A);
    
    std::cout << x << std::endl;
    

提交回复
热议问题