---
title: 生成完整的LAPACK
description: "KML_LAPACK依赖于开源的Netlib LAPACK以提供完整的LAPACK接口功能。因此安装KML_LAPACK后需自行获取开源的Netlib LAPACK v3.10.1的源代码包，具体安装步骤如下所述："
url: https://www.hikunpeng.com/document/detail/zh/kunpengboostkithistory/2200/accel/kunpengaccel_kml_16_0218.html
sourcePath: /source/zh/kunpengboostkithistory/2200/accel/kunpengaccel_kml_16_0218.html
indexId: 236fad86596d01fcaf509a0a622786521565c3e1203b8208afe529607b5274d274
---
# 生成完整的LAPACK

#### 操作步骤

KML_LAPACK依赖于开源的Netlib LAPACK以提供完整的LAPACK接口功能。因此安装KML_LAPACK后需自行获取开源的Netlib LAPACK v3.10.1的源代码包，具体安装步骤如下所述：

1. 下载Netlib LAPACK v3.10.1的源代码包。保存在编译机器可访问的路径中，假设位于“/data/lapack-3.10.1.tar.gz”。
  可从此处下载：https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.10.1.tar.gz(https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.10.1.tar.gz)

2. 假设libklapack.a位于“/usr/local/kml/lib/libklapack.a”，使用以下脚本编译原始的Netlib LAPACK库，并在当前目录的lapack_adapt子目录下生成适配的liblapack_adapt.a。

```
netlib=/data/lapack-3.10.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.10.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
```


3. （可选）生成完整功能的单一KML_LAPACK动态库。
  某些应用场景可能只允许链接单个LAPACK动态链接库，此时可采用以下方法将上一节生成的libklapack_xxx.a和liblapack_adapt.a合成单一的libklapack_full.so。

  假设KML_LAPACK库为“/usr/local/kml/lib/libklapack.a”
  和“/usr/local/kml/lib/libkservice.a”
  ，适配后的Netlib LAPACK库为当前目录下的liblapack_adapt.a。

```
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_BLAS场景（高性能）
假设KML_BLAS已构建的库（libkblas.a和libkblas.so）位于KML_BLAS_ROOT中，为获得最高性能请使用KML_BLAS单线程版本。当使用KML_BLAS时，仍然需要上一节最后获得Netlib LAPACK适配的liblapack_adapt.a，但不再需要Netlib LAPACK中的libblas.a。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：

```
if [ ! -n "$LD_LIBRARY_PATH" ]
then
export LD_LIBRARY_PATH=/usr/local/kml/lib:$KML_BLAS_ROOT
else
export LD_LIBRARY_PATH=/usr/local/kml/lib:$KML_BLAS_ROOT:$LD_LIBRARY_PATH
fi
```


  - 使用静态链接库
    此场景不再需要链接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
```


- 场景二：无KML_BLAS场景（依赖Netlib LAPACK中自带的BLAS，性能较低）

  - 使用动态链接库

```
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：

```
if [ ! -n "$LD_LIBRARY_PATH" ]
then
export LD_LIBRARY_PATH=/usr/local/kml/lib:$ADAPT_ROOT
else
export LD_LIBRARY_PATH=/usr/local/kml/lib:$ADAPT_ROOT:$LD_LIBRARY_PATH
fi
```


  - 使用静态链接库

```
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
```
