[Note/suggestions] Got Arpack, etc sort of working with MKL [tested on macos]

Update: With fflags from here and borrowing from the Arpack builder script, here’s a way to potentially get Arpack and packages that depend on it working with MKL( Pkg.test("Arpack") , Pkg.test("LightGraphs") or Pkg.test("Distributions") all pass) [basically, use the suggestions here to provide a arpack binary compiled with mkl to the julia package]:

  1. Clone arpack-ng, checkout "b095052372aa95d4281a645ee1e367c28255c947" according to the script used by Arpack.jl’s builder
  2. Build arpack library binary with mkl: mkdir build, cd to build folder and use the script (64 bit):
#!/usr/bin/env bash
source /opt/intel/mkl/bin/mklvars.sh intel64 ilp64

# cmake -DINTERFACE64=1 -DBUILD_SHARED_LIBS=ON -DLAPACK_FOUND=true -DLAPACK_INCLUDE_DIRS=${MKLROOT}/include -DLAPACK_LIBRARIES=mkl_rt -DBLAS_FOUND=true -DBLAS_INCLUDE_DIRS=${MKLROOT}/include -DBLAS_LIBRARIES=mkl_rt ..
CMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,$MKLROOT/lib"



# Symbols that have float32, float64, complexf32, and complexf64 support
SDCZ_SYMBOLS="axpy copy gemv geqr2 lacpy lahqr lanhs larnv lartg \
              lascl laset scal trevc trmm trsen gbmv gbtrf gbtrs \
              gttrf gttrs pttrf pttrs"
# All symbols that have float32/float64 support (including the SDCZ_SYMBOLS above)
SD_SYMBOLS="${SDCZ_SYMBOLS} dot ger labad laev2 lamch lanst lanv2 \
            lapy2 larf larfg lasr nrm2 orm2r rot steqr swap"
# All symbols that have complexf32/complexf64 support (including the SDCZ_SYMBOLS above)
CZ_SYMBOLS="${SDCZ_SYMBOLS} dotc geru unm2r"
# Add in (s|d)*_64 symbol remappings:
for sym in ${SD_SYMBOLS}; do
    SYMBOL_DEFS="${SYMBOL_DEFS} -Ds${sym}=s${sym}_64 -Dd${sym}=d${sym}_64"
done
# Add in (c|z)*_64 symbol remappings:
for sym in ${CZ_SYMBOLS}; do
    SYMBOL_DEFS="${SYMBOL_DEFS} -Dc${sym}=c${sym}_64 -Dz${sym}=z${sym}_64"
done
# Add one-off symbol mappings; things that don't fit into any other bucket:
for sym in scnrm2 dznrm2 csscal zdscal dgetrf dgetrs; do
    SYMBOL_DEFS="${SYMBOL_DEFS} -D${sym}=${sym}_64"
done
# Set up not only lowercase symbol remappings, but uppercase as well:
SYMBOL_DEFS="${SYMBOL_DEFS} ${SYMBOL_DEFS^^}"

FFLAGS="${FFLAGS} -fdefault-integer-8 ${SYMBOL_DEFS} -ff2c"

cmake ..  -DINTERFACE64=1 -DBUILD_SHARED_LIBS=ON -DBLAS_LIBRARIES="-L$MKLROOT/lib -lmkl_rt" -DLAPACK_LIBRARIES="-L$MKLROOT/lib -lmkl_rt" -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS}" -DCMAKE_Fortran_FLAGS="${FFLAGS}"

Followed by make clean all; The built library libarpack.2.0.0.dylib is in the build/lib folder. Then, copy and overwrite the libarpack.2.0.0.dylib in the arpack’s folder in .julia, e.g. current version lives in:

~/.julia/packages/Arpack/UiiMc/deps/usr/lib/libarpack.2.0.0.dylib

Build it in julia:

]
(v1.1) pkg> build Arpack

then, e.g.

using Pkg, Arpack, LinearAlgebra
A = Diagonal(1:4)
eigs(A, nev=3)

works, and all Pkg.test("Arpack") , Pkg.test("LightGraphs") , Pkg.test("Distributions") pass.

Now the tests are working with mkl, this whole process may be cleaned up a bit. May be working on other platforms? Do not have access to linux/windows to test. If the tests pass maybe it’s relatively safe to use? Out of caution, test your own code with official binary without mkl and compare. Note that to use Arpack in the official binary may need removing the self-build arpack binary in e.g. ~/.julia/packages/Arpack/UiiMc/deps/usr/lib/libarpack.2.0.0.dylib (official non-mil binary should download the missing binary automatically), and rebuild build Arpack in pkg.

6 Likes

Edit: Can replicate on Mac, and on Linux as well, when I install MKL in the official way.

On Ubuntu, I needed to edit the script a bit to point to the new mklvars.sh (i.e., the default installation is ~/intel/mkl/....)

Will try on Windows next, and then work on bundling this into a standalone thing.

1 Like

I would add into:

cmake ..  -DINTERFACE64=1 -DBUILD_SHARED_LIBS=ON -DBLAS_LIBRARIES="-L$MKLROOT/lib -lmkl_rt" -DLAPACK_LIBRARIES="-L$MKLROOT/lib -lmkl_rt" -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS}" -DCMAKE_Fortran_FLAGS="${FFLAGS}"

The MKL_DIRECT_CALL Macro.

So it would be something like:

cmake ..  -DINTERFACE64=1 -DBUILD_SHARED_LIBS=ON -DMKL_DIRECT_CALL -DBLAS_LIBRARIES="-L$MKLROOT/lib -lmkl_rt" -DLAPACK_LIBRARIES="-L$MKLROOT/lib -lmkl_rt" -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS}" -DCMAKE_Fortran_FLAGS="${FFLAGS}"

This will decrease the over head of calling MKL functions.

FYI: https://github.com/arnavs/ArpackMKLBuilder. To feed into https://github.com/arnavs/ArpackMKL.jl (not populated yet.)

Currently I’ve got it only spitting out Linux out of BinaryBuilder, but am working on Windows/macOS.

Edit: I’m running into this (well-known) soname not found error for ld when compiling on Mac. I think you get around this by running install_name_tool? But I’m not sure exactly how.

Windows is a nightmare.

2 Likes

Yes, thanks for your efforts! For mac I think I put the source /opt/intel/mkl/bin/mklvars.sh intel64 ilp64 in my bash_profile or .zshrc, and used

install_name_tool -add_rpath $MKLROOT/lib /path/to/libarpack.2.0.0.dylib
1 Like

Thanks, I’ll add this to a mac-specific branch in the execution script and see if it works.

Edit: I played around and couldn’t get it to work. I inserted this logic at the end, like in the main ArpackBuilder repository here, but no dice. Also, running this inside of BinaryBuilder is tricky, because the MKL.jl build script just gives us the binaries (i.e., no mklvars.sh). But, we’re still able to use environment variables like MKLROOT inside the build script, so I dunno…

If someone would like to submit Mac/Windows support as a PR, I’d be much obliged. We’re working on plugging this into Arpack.jl so it would be great to have that support.