c++cmakeeigenintel-mklpardiso

Trouble compiling PardisoSupport with Eigen?


Below is a minimum working example of the problem I ran into recently:

My source code:

// main.cc
#define EIGEN_USE_MKL_ALL
#include <Eigen/Sparse>
#include <Eigen/PardisoSupport>

int main() {
    Eigen::SparseMatrix<double> sp;
    Eigen::PardisoLDLT<Eigen::SparseMatrix<double>> ldlt_solver;
    ldlt_solver.compute(sp);

}

and the cmake file is straight from the official website:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(test)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

find_package(Eigen3 3.4.0 REQUIRED)
find_package(MKL CONFIG REQUIRED)

add_executable(main main.cc)
target_link_libraries(main PUBLIC Eigen3::Eigen)
target_compile_options(main PUBLIC $<TARGET_PROPERTY:MKL::MKL,INTERFACE_COMPILE_OPTIONS>)
target_include_directories(main PUBLIC $<TARGET_PROPERTY:MKL::MKL,INTERFACE_INCLUDE_DIRECTORIES>)
target_link_libraries(main PUBLIC $<LINK_ONLY:MKL::MKL>)

And I compile using the following code:

mkdir build
cd build
cmake ..
make

Then I got the following compile error:

/usr/include/eigen3/Eigen/src/PardisoSupport/PardisoSupport.h:50:22: error: cannot convert ‘int*’ to ‘const long long int*’
   50 |       ::pardiso(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error);
      |                      ^~~~~~
      |                      |
      |                      int*

I noticed this from the official website of Eigen:

  1. on a 64bits system, you must use the LP64 interface (not the ILP64 one)

and thought that this could be the problem causing the compile error. However, I do not know where that leads to. Do I need to change the link or compile options to make it work?

Also I have read about this post of stackoverflow and I have tried adding #define EIGEN_DEFAULT_DENSE_INDEX_TYPE long long int before including Eigen. But I still got the same error.


Solution

  • After carefully reading the output of the cmake configuring process, I realize the problem could be solved by setting MKL_INTERFACE to lp64 as indicated by MKLConfig.cmake

    Here is the final CMakeLists.txt:

    # CMakeLists.txt
    cmake_minimum_required(VERSION 3.22)
    project(test)
    
    set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
    
    # for 64 bit system
    set(MKL_INTERFACE lp64)
    find_package(MKL CONFIG REQUIRED)
    find_package(Eigen3 3.4.0 REQUIRED)
    
    add_executable(main main.cc)
    target_link_libraries(main PUBLIC Eigen3::Eigen)
    target_compile_options(main PUBLIC $<TARGET_PROPERTY:MKL::MKL,INTERFACE_COMPILE_OPTIONS>)
    target_include_directories(main PUBLIC $<TARGET_PROPERTY:MKL::MKL,INTERFACE_INCLUDE_DIRECTORIES>)
    target_link_libraries(main PUBLIC $<LINK_ONLY:MKL::MKL>)