Generating a Complete LAPACK Library
Procedure
- Download the Netlib LAPACK v3.12.0 source package. Save the package in a path that can be accessed by the compilation device, for example, /data/Download/lapack-3.12.0.tar.gz.
- Assume that libklapack.a is in the /usr/local/kml/lib/libklapack.a directory. Run the following script to compile the original Netlib LAPACK library. Then the adapted file liblapack_adapt.a will be generated in the lapack_adapt subdirectory of the current directory.
set -eE echo "LAPACK_SRC_DIR ${LAPACK_SRC_DIR:-<undefined>}" echo "LAPACK_TGZ ${LAPACK_TGZ:=/data/Download/lapack-3.12.0.tar.gz}" echo "LIBKLAPACK_A ${LIBKLAPACK_A:=/usr/local/kml/lib/libklapack.a}" echo "LIBKSERVICE_A ${LIBKSERVICE_A:=${LIBKLAPACK_A/klapack/kservice}}" echo "ADAPT_DIR ${ADAPT_DIR:=./lapack_adapt}" echo "CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE:=Release}" echo "LIBLAPACK_ADAPT_A ${LIBLAPACK_ADAPT_A:=liblapack_adapt.a}" echo "LIBKLAPACK_FULL_SO ${LIBKLAPACK_FULL_SO:=libklapack_full.so}" echo "CC ${CC:=gcc}" echo "FC ${FC:=gfortran}" mkdir -p ${ADAPT_DIR} cd ${ADAPT_DIR} # build netlib lapack if [ ! -r "${LAPACK_SRC_DIR}/CMakeLists.txt" ]; then mkdir -p netlib ( cd netlib ; tar xzpf ${LAPACK_TGZ} ) LAPACK_SRC_DIR=$(cd netlib/l* ; pwd) fi mkdir -p build cmake_flags=( -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_C_COMPILER=${CC} -DCMAKE_Fortran_COMPILER=${FC} -DCMAKE_RULE_MESSAGES=off -DBUILD_DEPRECATED=on -DBUILD_TESTING=off ) ( cd build ; cmake ${cmake_flags[*]} ${LAPACK_SRC_DIR} ) ( cd build ; make -j ) cp build/lib/liblapack.a ${LIBLAPACK_ADAPT_A} # get symbols defined both in klapack and netlib lapack nm -g ${LIBLAPACK_ADAPT_A} | grep 'T ' | grep -oP '\K\w+(?=_$)' | sort | uniq > netlib.sym nm -g ${LIBKLAPACK_A} | grep 'T ' | grep -oP '\K\w+(?=_$)' | sort | uniq > klapack.sym comm -12 klapack.sym netlib.sym > comm.sym # update symbols name of ${LIBLAPACK_ADAPT_A} while read sym; do ( if ! nm ${LIBLAPACK_ADAPT_A} | grep -qe " T ${sym}_\$"; then continue fi ar x ${LIBLAPACK_ADAPT_A} ${sym}.f.o mv ${sym}.f.o ${sym}_netlib.f.o objcopy --redefine-sym ${sym}_=${sym}_netlib_ ${sym}_netlib.f.o ) & done < comm.sym wait ar d ${LIBLAPACK_ADAPT_A} $(sed -ne 's/$/.f.o/p' comm.sym) ar d ${LIBLAPACK_ADAPT_A} xerbla.f.o ar ru ${LIBLAPACK_ADAPT_A} *_netlib.f.o rm *_netlib.f.o - (Optional) Generate a standalone KML_LAPACK dynamic library with complete functions.
In some application scenarios, only a single LAPACK dynamic link library can be linked. In this case, you can use the following method to combine libklapack_xxx.a and liblapack_adapt.a generated previously into a single libklapack_full.so.
For example, if KML_LAPACK is /usr/local/kml/lib/libklapack.a and /usr/local/kml/lib/libkservice.a, then the adapted Netlib LAPACK library is liblapack_adapt.a in the current directory.${FC} -o ${LIBKLAPACK_FULL_SO} -shared -fPIC -Wl,--whole-archive ${LIBKLAPACK_A} ${LIBLAPACK_ADAPT_A} -Wl,--no-whole-archive ${LIBKSERVICE_A} -fopenmp -lpthread -lmAfter the execution is complete, the libklapack_full.so file is generated in the current directory. You can link the libklapack_full.so file to obtain all interface functions of LAPACK-3.12.0.
The KML_BLAS library and system libraries such as libgfortran need to be linked separately.
Verifying the Installation
Assume that the environment variable KML_LAPACK_ROOT is the directory of libklapack.*. Then ADAPT_ROOT is the directory of the adapted Netlib LAPACK library. User applications can use dynamic link libraries or static link libraries. When compiling the application source code, you need to link to the KML_LAPACK, Netlib LAPACK, Netlib BLAS, and GFortran libraries and enable OpenMP support.
- Scenario 1 with KML_BLAS (high performance)Assume that the libraries (libkblas.a and libkblas.so) constructed by KML_BLAS are located in KML_BLAS_ROOT. To achieve optimal performance, use the KML_BLAS single-thread version. Using KML_BLAS requires the adapted file liblapack_adapt.a but does not require libblas.a in Netlib LAPACK.
KML_LAPACK uses multiple threads to call KML_BLAS. Therefore, KML_BLAS of the nolocking version cannot be used. You are advised to use the omp version, that is, /usr/local/kml/lib/kblas/omp/libkblas.so.
- Using the dynamic link library
In this scenario, the Netlib LAPACK has only the static library liblapack_adapt.a. Therefore, the library is always statically linked. The libblas.a file of the Netlib LAPACK does not need to be linked.
gcc app.c -o app -fopenmp -I $KML_LAPACK_ROOT/include/kml-0.3.0 -L /usr/local/kml/lib -lklapack -L $ADAPT_ROOT -l:liblapack_adapt.a -L $KML_BLAS_ROOT -lkblas -lgfortran -lm -lkservice
The dynamic link libraries required by KML_LAPACK must be found, or /usr/local/kml/lib and $KML_BLAS_ROOT must be added to LD_LIBRARY_PATH.
export LD_LIBRARY_PATH=/usr/local/kml/lib:$KML_BLAS_ROOT:$LD_LIBRARY_PATH
- Using the static link library
In this scenario, libblas.a of Netlib LAPACK does not need to be linked.
gcc app.c -o app -fopenmp -I $KML_LAPACK_ROOT/include/kml-0.3.0 -L /usr/local/kml/lib -l:libklapack.a -L $ADAPT_ROOT -l:liblapack_adapt.a -L $KML_BLAS_ROOT -l:libkblas.a -l:libkservice.a -l:libgfortran.a -lm
- Using the dynamic link library
- Scenario 2 without KML_BLAS (depending on BLAS in Netlib LAPACK, low performance)
- Using the dynamic link library
gcc app.c -o app -fopenmp -I $KML_LAPACK_ROOT/include/kml-0.3.0 -L /usr/local/kml/lib -lklapack -L $ADAPT_ROOT -l:liblapack_adapt.a -lblas -lgfortran -lm -lkservice
The dynamic link libraries required by KML_LAPACK must be found, or /usr/local/kml/lib and $ADAPT_ROOT must be added to LD_LIBRARY_PATH.
export LD_LIBRARY_PATH=/usr/local/kml/lib:$ADAPT_ROOT:$LD_LIBRARY_PATH
- Using the static link library
gcc app.c -o app -fopenmp -I $KML_LAPACK_ROOT/include/kml-0.3.0 -L /usr/local/kml/lib -l:libklapack.a -L $ADAPT_ROOT -l:liblapack_adapt.a -l:libblas.a -l:libkservice.a -l:libgfortran.a -lm
- Using the dynamic link library