Installing the KML_LAPACK
Procedure
KML_LAPACK depends on the open-source Netlib LAPACK to provide complete LAPACK interface functions. Therefore, you need to obtain the open-source Netlib LAPACK v3.9.0 source package and adapt it to KML_LAPACK. The installation procedure is as follows:
- Go to the root directory of the KML_LAPACK source code and perform compilation.
./build.sh
After the compilation is complete, the following path is generated in KML_LAPACK/output:- include
- include/kml-a.b.c: Stores the header file of the C language. a.b.c indicates the version number.
- lib64
- lib64/libklapack_xxx.a: static library file of KML_LAPACK.
- lib64/libklapack_xxx.so: dynamic library file of KML_LAPACK.
- include
- Download the Netlib LAPACK v3.9.0 source package. Save the file in a path that can be accessed by the compiler, for example, /data/lapack-3.9.0.tar.gz.
You can download it from https://github.com/Reference-LAPACK/lapack/archive/v3.9.0.tar.gz.
- Compile the original Netlib LAPACK library.
- Decompress the source package.
For example, decompress the package to /data/lapack-3.9.0.
cd /data tar zxvf lapack-3.9.0.tar.gz
- Go to the /data/lapack-3.9.0 directory and create the build directory. Perform build in the build directory.
cd /data/lapack-3.9.0
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON ..
make -j
After the preceding commands are executed, the liblapack.a file is generated in /data/lapack-3.9.0/build/lib.
- Decompress the source package.
- Adapt liblapack.a of Netlib to KML_LAPACK.
In this step, the symbol of the original Netlib liblapack.a is renamed to adapt to KML_LAPACK to obtain the complete LAPACK interface function. Assume that the original liblapack.a file is in the current directory and the libklapack.a file is in $KML_LAPACK_ROOT/lib64.
- Obtain the list of symbols to be renamed based on the symbol table in the KML_LAPACK library.Run the following commands to generate the internal.sym and replaced.sym files. These two files are the list of the Netlib LAPACK interfaces to be replaced by KML_LAPACK and the list of Netlib LAPACK interfaces for which symbol aliases need to be added.
nm -g $KML_LAPACK_ROOT/lib64/libklapack.a | grep -oP '\K\w+(?=_netlib_)' | sort | uniq > netlib.sym while read sym; do \ if nm -g $KML_LAPACK_ROOT/lib64/libklapack.a | grep -q "T $sym"; then \ echo $sym; \ fi; \ done < netlib.sym > replaced.sym comm -3 netlib.sym replaced.sym > internal.sym - Copy the original LAPACK library as the modification target.
cp liblapack.a liblapack_adapt.a
- Rename the symbols provided by KML_LAPACK.
while read sym; do \ ar x liblapack_adapt.a $sym.f.o; \ objcopy --redefine-sym ${sym}_=${sym}_netlib_ $sym.f.o; \ ar ru liblapack_adapt.a $sym.f.o; \ rm $sym.f.o; \ done < replaced.sym - Add the alias of the original symbol required by KML_LAPACK.
- Create the alias.c file in the current directory. Enter the following content, save the file, and exit.
#define STRINGIFY(x) STRINGIFy(x) #define STRINGIFy(x) #x #define NEW STRINGIFY(ALIAS) #define OLD STRINGIFY(ORIG) asm( ".section .text." NEW ",\"ax\",%progbits\n" ".align 2\n" ".global " NEW "\n" ".type " NEW ", %function\n" NEW ":\n" "b " OLD "\n" ".size " NEW ", . - " NEW "\n" ); - Add a symbol alias.
while read sym; do \ gcc -c alias.c -DORIG=${sym}_ -DALIAS=${sym}_netlib_ -o ${sym}_netlib_.o; \ ar ru liblapack_adapt.a ${sym}_netlib_.o; \ rm ${sym}_netlib_.o; \ done < internal.sym
After the preceding steps are complete, the liblapack_adapt.a file in the current directory is the Netlib LAPACK library that adapts to KML_LAPACK.
- Create the alias.c file in the current directory. Enter the following content, save the file, and exit.
- Obtain the list of symbols to be renamed based on the symbol table in the KML_LAPACK library.
- (Optional) Generate a single KML_LAPACK dynamic library with complete functions.
In some application scenarios, only a single LAPACK dynamic link library can be linked. For this case, you can use the following method to combine the libklapack_xxx.a and liblapack_adapt.a files generated in the previous section into a single libklapack_full.so file.
Assume that the KML_LAPACK library is $KML_LAPACK_ROOT/lib64/libklapack.a, then the adapted Netlib LAPACK library is liblapack_adapt.a in the current directory.gcc -o libklapack_full.so -shared -fPIC -Wl,--whole-archive $KML_LAPACK_ROOT/lib64/libklapack.a liblapack_adapt.a -Wl,--no-whole-archive -fopenmp -lpthread -lgfortran -lm
After 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 full interfaces of LAPACK-3.9.0.
In this case, the KML_BLAS library and system libraries such as libgfortran need to be linked separately.
Verifying the Installation
- Log out of the current terminal and log in again.
- Check whether the environment variable LD_LIBRARY_PATH contains the KML_LAPACK installation path /usr/local/kml/lib.
env | grep LD_LIBRARY_PATH
If the variable contains the installation path, the installation is successful.
After the installation is successful, the corresponding files are generated in the installation path (/usr/local/kml by default). The include folder contains the header files, and the lib folder contains the KML_LAPACK dynamic library files.
- Assume that the environment variable KML_LAPACK_ROOT is the directory of libklapack.*, then ADAPT_ROOT is the directory of the Netlib LAPACK library after adaptation. User applications can use dynamic link libraries (DLLs) or static link libraries (DLLs).
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.
Option 1: Collaborative KML_BLAS scenario (high performance)
Assume that the libraries (libkblas.a and libkblas.so) constructed by KML_BLAS are located in KML_BLAS_ROOT. To achieve the highest performance, use the KML_BLAS single-thread version. When KML_BLAS is used, liblapack.a obtained in the previous section needs to adapt to Netlib LAPACK, but libblas.a in Netlib LAPACK is not required.
KML_BLAS with a single thread lock must be used. The KML_LAPACK installation package provides the KML_BLAS version with a single thread lock, that is, /usr/local/kml/lib/kblas/locking/libkblas.so.
To build the KML_BLAS version with a single thread and lock, add the -DUSE_LOCKING=1 compilation option to the 23rd line of the KML_BLAS/build/function.sh build script.
- Using the Dynamic Link Library
In this scenario, the Netlib LAPACK has only the static library liblapack.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 $KML_LAPACK_ROOT/lib64 -lklapack -L $ADAPT_ROOT -l:liblapack.a -L $KML_BLAS_ROOT -lkblas -lgfortran -lm
The dynamic link libraries required by KML_LAPACK must be found, or $KML_LAPACK_ROOT/lib64 and $KML_BLAS_ROOT must be added to LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=$KML_LAPACK_ROOT/lib64:$KML_BLAS_ROOT:$LD_LIBRARY_PATH
- Using a 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 $KML_LAPACK_ROOT/lib64 -l:libklapack.a -L $ADAPT_ROOT -l:liblapack.a -L $KML_BLAS_ROOT -l:libkblas.a -l:libgfortran.a -lm
Option 2: Scenario with no 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 $KML_LAPACK_ROOT/lib64 -lklapack -L $ADAPT_ROOT -llapack -lblas -lgfortran -lm
The dynamic link libraries required by KML_LAPACK must be found, or $KML_LAPACK_ROOT/lib64 and $ADAPT_ROOT must be added to LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=$KML_LAPACK_ROOT/lib64:$ADAPT_ROOT:$LD_LIBRARY_PATH
- Using a Static Link Library
gcc app.c -o app -fopenmp -I $KML_LAPACK_ROOT/include/kml-0.3.0 -L $KML_LAPACK_ROOT/lib64 -l:libklapack.a -L $ADAPT_ROOT -l:liblapack.a -l:libblas.a -l:libgfortran.a -lm
- Using the Dynamic Link Library