KML_LAPACK依赖于开源的Netlib LAPACK以提供完整的LAPACK接口功能。因此安装KML_LAPACK后需自行获取开源的Netlib LAPACK v3.9.1的源代码包,具体安装步骤如下所述:
可从此处下载:https://github.com/Reference-LAPACK/lapack/archive/v3.9.1.tar.gz
netlib=/data/lapack-3.9.1.tar.gz klapack=/usr/local/kml/lib/libklapack.a mkdir lapack_adapt cd lapack_adapt # build netlib lapack mkdir netlib cd netlib tar zxvf $netlib mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON ../lapack-3.9.1 make -j cd ../.. cp netlib/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 $klapack | 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; \ ar d liblapack_adapt.a ${sym}.f.o; \ ar ru liblapack_adapt.a ${sym}_netlib.f.o; \ rm ${sym}_netlib.f.o; \ done < comm.sym
某些应用场景可能只允许链接单个LAPACK动态链接库,此时可采用以下方法将上一节生成的libklapack_xxx.a和liblapack_adapt.a合成单一的libklapack_full.so。
gcc -o libklapack_full.so -shared -fPIC -Wl,--whole-archive /usr/local/kml/lib/libklapack.a liblapack_adapt.a -Wl,--no-whole-archive /usr/local/kml/lib/libkservice.a -fopenmp -lpthread -lgfortran -lm
执行完成后当前目录下会生成libklapack_full.so,可以单独链接此so得到LAPACK-3.9.1的全部接口功能。
此时仍然需要单独链接KML_BLAS库以及libgfortran等系统库。
使用时,假设环境变量KML_LAPACK_ROOT为libklapack.*所在目录,ADAPT_ROOT为适配后Netlib LAPACK库所在目录。用户应用可以选择使用动态链接库或静态链接库。编译应用源代码时需要链接到KML_LAPACK、Netlib LAPACK、Netlib BLAS和gfortran库并开启OpenMP支持。
KML_LAPACK多线程调用KML_BLAS,因此不可以使用nolocking版本的KML_BLAS,推荐使用omp版本,即/usr/local/kml/lib/kblas/omp/libkblas.so。
此场景下由于适配的Netlib LAPACK只有静态库liblapack_adapt.a,因此总是静态链接到此库。不再需要链接Netlib LAPACK的libblas.a。
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
运行时需能找到KML_LAPACK所需的这些动态链接库,或者将/usr/local/kml/lib和$KML_BLAS_ROOT加入LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/usr/local/kml/lib:$KML_BLAS_ROOT:$LD_LIBRARY_PATH
此场景不再需要链接Netlib LAPACK的libblas.a。
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
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
运行时需能找到KML_LAPACK所需的这些动态链接库,或者将/usr/local/kml/lib和$ADAPT_ROOT加入LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/usr/local/kml/lib:$ADAPT_ROOT:$LD_LIBRARY_PATH
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