How to use ezARPACK in your project¶
Depending on what build system your C++ project is based on, there are two ways to use ezARPACK. Either way, you would need
A compiler supporting C++11 or newer;
a working ARPACK-NG installation (version 3.6.0 or newer).
One of supported linear algebra libraries (unless you are going to add support for a new one).
A working implementation of MPI-3.0 or newer, such as OpenMPI or MPICH, if you plan to use the Parallel ARPACK solvers.
Warning
The Parallel ARPACK eigensolvers for general complex matrices are
known to be unstable
and can yield wrong results in ARPACK-NG versions prior to 3.8.0.
Be sure to link your code to ARPACK-NG 3.8.0 or newer if you use the
complex variant of ezarpack::mpi::arpack_solver
.
Makefiles/no build system¶
Assume that <EZARPACK_ROOT>
is either a directory with unpacked
ezARPACK sources or its installation
directory. A compiler command line for your program can be as simple as
g++ -O3 -o myprog myprog.cpp \
-I<EZARPACK_ROOT>/include -L<ARPACK_NG_ROOT>/lib -larpack
# For executables using the Parallel ARPACK (MPI) solvers
mpic++ -O3 -o myprog_mpi myprog_mpi.cpp -I<EZARPACK_ROOT>/include \
-L<ARPACK_NG_ROOT>/lib -larpack -lparpack
(similar for clang++
and other compilers). More -I
flags may be needed
if the linear algebra framework you choose is not visible to the compiler by
default. Similarly, adding -I<MPI_ROOT>/include -L<MPI_ROOT>/lib
may be
necessary if you are using an MPI implementation installed in a non-system
location.
Note
When linking to the static version of ARPACK-NG library
(libarpack.a
), you might also need to explicitly link your executable to
a BLAS/LAPACK implementation. A common symptom of this problem is
undefined references to dgemv_
and other LAPACK subroutines.
CMake¶
Here is a minimal example of a root CMakeLists.txt
script for your
project.
cmake_minimum_required(VERSION 3.13.0 FATAL_ERROR)
project(myproject LANGUAGES CXX)
# ezARPACK_ROOT is the installation prefix of ezARPACK.
set(ezARPACK_DIR ${ezARPACK_ROOT}/lib/cmake)
# Import ezARPACK target.
find_package(ezARPACK 1.0 CONFIG REQUIRED)
# Import Eigen (Blaze, Armadillo, etc) targets.
find_package(Eigen3 CONFIG REQUIRED)
# Build an executable called `myprog`.
add_executable(myprog myprog.cpp)
target_link_libraries(myprog ezarpack Eigen3::Eigen)
# Find a usable version of ARPACK-NG.
find_arpackng(3.6.0 REQUIRED)
# Link the executable to the ARPACK library.
target_link_libraries(myprog ${ARPACK_LIBRARIES})
Linking your targets to ARPACK-NG libraries can be a bit of a hassle, as CMake
interface of ARPACK-NG changed a few times since version 3.6.0. In particular,
CMake scripts of the versions prior to 3.8.0 do not export any targets. Instead,
they expose library information via a variable arpack_ng_LIBRARIES
.
In order to make linking more user-friendly, ezARPACK exports a macro called
find_arpackng()
. It finds an ARPACK-NG installation while taking care of
said CMake interface differences. Upon successful detection of ARPACK-NG,
find_arpackng()
sets two variables that can be later passed to
target_link_libraries()
,
ARPACK_LIBRARIES
- list of ARPACK libraries and linker flags
PARPACK_LIBRARIES
- list of Parallel ARPACK libraries and linker flags
Setting CMake variable ARPACK_NG_ROOT
will instruct find_arpackng()
to look for ARPACK-NG at a specific installation prefix before proceeding
to system locations.
Making the Parallel ARPACK solvers work requires additional linking to MPI and PARPACK.
# Parallel ARPACK (MPI)
# Build another executable `myprog_mpi`.
add_executable(myprog_mpi myprog_mpi.cpp)
target_link_libraries(myprog_mpi ezarpack Eigen3::Eigen)
# Detect an MPI-3.0 implementation.
find_package(MPI 3.0 REQUIRED)
# Link the executable to the Parallel ARPACK library and to the MPI.
target_include_directories(myprog_mpi PRIVATE ${MPI_CXX_INCLUDE_PATH})
target_link_libraries(myprog_mpi ${PARPACK_LIBRARIES} ${MPI_CXX_LIBRARIES})