EN
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助
鲲鹏小智

生成完整的SCALAPACK

操作步骤

KML_SCALAPACK只包含了部分自研SCALAPACK接口,还需要SCALAPACK的其他接口才能运行。因此请自行获取开源的Netlib SCALAPACK v2.2.0的源代码包,并与KML_SCALAPACK适配,以得到全量的SCALAPACK接口。具体安装步骤如下所述:

  1. 下载Netlib SCALAPACK v2.2.0的源代码包。保存在编译机器可访问的路径中,假设位于“/openlib/scalapack-2.2.0.tar.gz”
  2. 假设libkscalapack.a位于“/usr/local/kml/lib/”,使用以下脚本编译原始的Netlib ScaLAPACK库,编译Netlib ScaLAPCK库需要Netlib LAPACK库,Netlib LAPACK库安装请参见生成完整的LAPACK,假设Netlib LAPACK库位于“/openlib/lapack-3.11/”,并在当前目录的scalapack_adapt子目录下生成适配的libscalapack_adapt.a。
    netlib=/openlib/scalapack-2.2.0.tar.gz
    kscalapack=/usr/local/kml/lib/libkscalapack.a
    libLapackPath=/openlib/lapack_adapt/libklapack_full.so
    libRefBlasPath=/usr/local/kml/lib/kblas/omp/libkblas.so
    
    mkdir scalapack_adapt
    cd scalapack_adapt
    
    # build netlib scalapack
    mkdir netlib
    cd netlib
    tar zxvf $netlib
    mkdir build
    cd build
    cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_CXX_COMPILER=mpicxx -DCMAKE_C_COMPILER=mpicc -DCMAKE_Fortran_COMPILER=mpifort \
    -DLAPACK_LIBRARIES=/$libLapackPath -DBLAS_LIBRARIES=/$libRefBlasPath ../scalapack-2.2.0
    make -j
    cd ../..
    
    cp netlib/build/lib/libscalapack.a libscalapack_adapt.a
    
    # get symbols defined both in kscalapack and netlib scalapack
    nm -g libscalapack_adapt.a | grep 'T ' | grep -oP '\K\w+(?=_$)' | sort | uniq > netlib.sym
    nm -g $kscalapack | grep 'T ' | grep -oP '\K\w+(?=_$)' | sort | uniq > kscalapack.sym
    comm -12 kscalapack.sym netlib.sym > comm.sym 
    
    # update symbols name of libscalapack_adapt.a
    while read sym; do \
        if ! nm libscalapack_adapt.a | grep -qe " T ${sym}_\$"; then \
            continue; \
        fi; \
        ar x libscalapack_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 libscalapack_adapt.a ${sym}.f.o; \
        ar ru libscalapack_adapt.a ${sym}_netlib.f.o; \
        rm ${sym}_netlib.f.o; \
    done < comm.sym
  3. (可选)生成完整功能的单一KML_SCALAPACK动态库。

    某些应用场景可能只允许链接单个SCALAPACK动态链接库,此时可采用以下方法将上一节生成的libkscalapack_xxx.a和libscalapack_adapt.a合成单一的libkscalapack_full.so。

    假设KML_SCALAPACK库为“/usr/local/kml/lib/libkscalapack.a”,适配后的Netlib ScaLAPACK库为当前目录下的libscalapack_adapt.a。
    gcc -o libkscalapack_full.so -shared -fPIC -Wl,--whole-archive /usr/local/kml/lib/libkscalapack.a libscalapack_adapt.a -Wl,--no-whole-archive /usr/local/kml/lib/libkservice.a -fopenmp -lpthread -lgfortran -lm

    执行完成后当前目录下会生成libkscalapack_full.so,可以单独链接此so文件得到SCALAPACK v2.2.0的全部接口功能。

    此时仍然需要单独链接KML_BLAS库、KML_LAPACK库、KML_SERVICE库以及libgfortran、libm等系统库。

安装后验证

假设KML_BLAS已构建的库(libkblas.a和libkblas.so)位于KML_BLAS_ROOT中,KML_LAPACK位于KML_LAPACK_ROOT中。当使用KML_BLAS时,仍然需要上一节最后获得Netlib SCALAPACK适配的libscalapack_adapt.a,但不再需要Netlib SCALAPACK中的libblas.a。

使用时,假设环境变量KML_SCALAPACK_ROOT为libkscalapack.*所在目录,ADAPT_ROOT为适配后Netlib SCALAPACK库所在目录。用户应用可以选择使用动态链接库或静态链接库。

编译应用源代码时需要链接到KML_SCALAPACK、Netlib SCALAPACK、KML_LAPACK、Netlib LAPACK、Netlib BLAS和gfortran库并开启OpenMP支持。

选项一、协同KML_BLAS和KML_LAPACK场景(高性能)

  • 使用动态链接库

    此场景下由于适配的Netlib SCALAPACK只有静态库libscalapack_adapt.a,因此总是静态链接到此库。

    gcc app.c -o app -fopenmp -I $KML_LAPACK_ROOT/include/kml-0.3.0 -L /usr/local/kml/lib/ -lkscalapack -L $ADAPT_ROOT -l:libscalapack_adapt.a -L $KML_BLAS_ROOT -lkblas $KML_LAPACK_ROOT -lklapack -lgfortran -lm -lkservice

    运行时需能找到KML_SCALAPACK所需的这些动态链接库,或者将“/usr/local/kml/lib”和$KML_BLAS_ROOT、$KML_LAPACK_ROOT加入LD_LIBRARY_PATH:

    export LD_LIBRARY_PATH=/usr/local/kml/lib:$KML_BLAS_ROOT:$KML_LAPACK_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/lib -l:libkscalapack.a -L $ADAPT_ROOT -l:libscalapack_adapt.a -L $KML_BLAS_ROOT -l:libkblas.a $KML_LAPACK_ROOT -l:klapack.a -l:libkservice.a -l:libgfortran.a -lm

选项二、无KML_BLAS和KML_LAPACK场景(依赖Netlib LAPACK以及自带的BLAS,性能较低)

  • 使用动态链接库
    gcc app.c -o app -fopenmp -I $KML_LAPACK_ROOT/include/kml-0.3.0 -L /usr/local/kml/lib -lkscalapack -L $ADAPT_ROOT -l:libscalapack_adapt.a -lblas -llapack -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:libkscalapack.a -L $ADAPT_ROOT -l:libscalapack_adapt.a -l:libblas.a -l:liblapack.a -l:libkservice.a -l:libgfortran.a -lm