美文网首页我爱编程
Hypre与Petsc安装文档及性能测试

Hypre与Petsc安装文档及性能测试

作者: 冘若烦 | 来源:发表于2018-04-27 02:31 被阅读0次

    1. 前言

    本文介绍了并行计算库的Hypre和Petsc的安装方法以及在线性系统求解中不同算法的性能测试,用于日后在不同系统上的Hypre和Petsc的安装需要和新型算法性能测试基准。程序安装运行环境为NVIDIA-dgx1,详细参数请见dgx1参数。本文将分为Hypre和Petsc两个部分,分别以总体介绍,安装,程序运行关键代码和在IEEE不同节点数据下性能测试的顺序介绍两款软件的使用。

    2. Hypre介绍,安装及使用

    2.1 Hypre介绍

    2.1.1 性能介绍

    Hypre是运行在多核处理器上,借助目前性能较好的预处理矩阵(preconditioner)对于大型稀疏线性方程组使用迭代法求解的一个c语言库。其基本目标是让用户可以借助于多核处理器的并行性能,并行存储矩阵不同范围的信息,并行地进行迭代法求解,从而达到事半功倍的效果。Hypre具有扩展性极强的预处理矩阵算法,对于大型系统的预处理矩阵生成也有着不错的性能,并且迭代法所用算法选择空间较大,从后续的测试结果也可以看到,在选择了合适的算法的情况下,对于实际的电力系统线性方程组求解也可以有较快的计算速度。

    另一方面,从用户的使用角度来讲,用户无需预先学习复杂的稀疏矩阵存储,而只需分配对应行列坐标给矩阵类,之后的空间压缩操作都可以由Hypre完成,这对于新手来说,可以在最短时间内搭好自己的第一个求解线性方程组程序,是很好的入门函数库。

    2.1.2 程序框架介绍

    Hypre使用了“原型”的概念,这个概念对于程序来说,是一种储存信息的统一格式,可以更为高效地分配存储空间。在编程之前,用户需要决定对于自己的问题,使用哪一种原型来存储信息。其包括:

    • Structured-Grid System Interface

      这是应用于矩阵中非零元素十分规则,可以用Stencil类型来统一表示非0元素分布的系统。其中Stencil类型使用的相对坐标位置的方法,在确定中心点的情况下(0,0),使用对应坐标来确定非零元素的位置和值,并且在矩阵的赋值过程得以使用。

    • Linear-Algebraic System Interface (IJ)

      IJ适用于一般的线性系统,这类系统非零元素的分布没有规律可循,我们可以通过按行赋值的方式存储矩阵中非零元素的信息。而在赋值完毕后,程序将使用CSR的格式存储非零元素的信息。

    在线程的资源分配上,Hypre也采用了相对坐标的方式决定一个线程拥有的矩阵信息范围。使用左下角的坐标点和右上角的坐标点,Hypre可以通过他们的差值来得出其拥有的矩阵范围。另一方面,Hypre也可以通过行坐标的范围,来决定各线程所分配到矩阵范围。用户可以通过自身系统的特点,来判断到底采取哪一种分配方式。

    2.1.3 用户使用的Hypre的总体步骤

    综上,在使用Hypre计算线性系统方程时,需要包括以下步骤:

    • 根据系统特点,选择不同的原型结构
    • 根据该结构,对系统生成的矩阵进行赋值
    • 为系统不同的线程分配属于该线程的系统信息
    • 选用合适的方法与preconditioner进行求解
    • 获取结果

    2.2 Hypre安装

    2.2.1 检查openmpi安装

    • 首先检查系统中是否存在openmpi:

      $ mpirun --version
      
      • 如果存在则直接去安装Hypre,否则先安装openmpi(本文档选用的版本是openmpi v1.10)。

    2.2.2 安装openmpi

    • 进入openmpi官网(https://www.open-mpi.org/software/ompi/v1.10/),下载.tar.gz文件到本地。

    • 在下载路径下,解压该tar.gz文件

      $ tar -zxvf openmpi-1.10.7.tar.gz
      
    • 进入解压后生成的文件夹

      $ cd openmpi-1.10.7
      
    • configure路径下的文件,注意"--prefix="指定的是安装路径,用户可以自己指定,在后面找得到就行。

      $ ./configure --prefix="/usr/local/openmpi"
      
    • 编译并安装

      $ make 
      $ sudo make install
      
    • 为openmpi设置环境变量,进入~/.bashrc加入如下内容后保存并source

      $ vim ~/.bashrc
      /* 以下内容在.bashrc中更改 */
      export PATH="$PATH:/usr/local/openmpi/bin"
      export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/openmpi/lib/"
      /****************************************************************/
      $ source ~/.bashrc
      
    • 测试是否安装成功:进入openmpi解压的文件夹中有一个examples,运行如下例程将为出现两行"hello",则表示安装成功

      $ mpirun -np 2 ./hello_c
      

    2.2.3 安装Hypre

    • 进入Hypre的github中clone源代码

      $ git clone https://github.com/LLNL/hypre.git
      // 进入source code文件夹
      $ cd hypre/src
      
    • 注意在configure的时候要让hypre知道Openmpi在哪

      $ ./configure -prefix=/usr/local/hypre \
          -with-MPI-include=/usr/local/openmpi/include \
          -with-MPI-libs="mpi_cxx mpi" \
          -with-MPI-lib-dirs=/usr/local/openmpi/lib
      
    • 编译安装

      $ sudo make install
      

      需要一段时间。。。

    • 在src文件夹中有一个examples文件夹,里面有测试是否安装成功的例程。在使用Makefile编译后,生成的可执行文件需要mpirun运行。

      $ make
      $ mpirun -np 2 ex1(ex2)
      

      如果正常输出,则表示安装成功。

    2.3 Hypre计算代码详解

    2.3.1 Hypre线程分配空间方式

    在将矩阵不同行分给hypre不同线程时,需要告知该线程矩阵的起始行终止行,在已知矩阵总行数(N)和处理器个数(线程个数 num_procs)的情况下,考虑N无法被num_procs整除的情况,可以得到如下的计算公式。其中,myid表示这是第几个线程。

    local_size = N / num_procs;         // size per processor
    extra = N - local_size * num_procs; // consider rows cannot be fully divided by procs
    ilower = local_size * myid;
    ilower += hypre_min(myid, extra);
    iupper = local_size * (myid + 1);
    iupper += hypre_min(myid + 1, extra);
    iupper = iupper - 1;
    // update num of rows
    local_size = iupper - ilower + 1;
    

    2.3.2 Hypre矩阵,向量储存形式和赋值

    目前Hypre支持的存储形式为HYPRE_PARCSR,矩阵类为HYPRE_IJMatrix,和HYPRE_IJVector,经过print打出之后为“行,列,值”的坐标对。矩阵赋值支持按行赋值

    HYPRE_IJMatrixSetValues(ij_matrix, nrows, ncols, rows, cols, values);
    // 其中,ij_matrix为矩阵地址,nrows是赋值的行数,ncols为该行非0元素个数,rows为行坐标,cols为列作标,values为所赋的非0值
    

    Vector的赋值与上述矩阵赋值相似。

    另一方面,需要注意在每次赋值前都需要initialize矩阵,赋值完毕后都需要assemble矩阵,并且获取控制该矩阵的句柄。

    HYPRE_IJMatrixInitialize(A);
    /* ... 赋值操作 ... */
    HYPRE_IJMatrixAssemble(A);
    HYPRE_IJMatrixGetObject(A, (void **)&parcsr_A);
    

    2.4 Hypre求解线性系统性能测试

    <table>
    <thead>
    <td>计算题目</td>
    <td>计算方法</td>
    <td>迭代次数</td>
    <td>计算时间</td>
    </thead>

    <tr>
        <td rowspan="4"> 14节点<br/>
    </tr>
    <tr>
        <td> PCG </td>
        <td> 13 </td>
        <td> 0.000860s </td>
    </tr>
    <tr>
        <td> AMG </td>
        <td> 5 </td>
        <td> 0.000328s </td>
    </tr>
    <tr>
        <td> PCG with AMG preconditioner </td>
        <td> 4 </td>
        <td> 0.000310s </td>
    </tr>
    
    <tr>
        <td rowspan="4"> 118节点<br/>
    </tr>
    <tr>
        <td> PCG </td>
        <td> 117 </td>
        <td> 0.001329s </td>
    </tr>
    <tr>
        <td> AMG </td>
        <td> 10 </td>
        <td> 0.000752s </td>
    </tr>
    <tr>
        <td> PCG with AMG preconditioner </td>
        <td> 6 </td>
        <td> 0.000787s </td>
    </tr>   
    
    <tr>
        <td rowspan="4"> 10790节点<br/>
    </tr>
    <tr>
        <td> PCG </td>
        <td> 6207 </td>
        <td> 0.9464s </td>
    </tr>
    <tr>
        <td> AMG </td>
        <td> 12 </td>
        <td> 0.0337s </td>
    </tr>
    <tr>
        <td> PCG with AMG preconditioner </td>
        <td> 7 </td>
        <td> 0.0284s </td>
    </tr>
    
    <tr>
        <td rowspan="4"> 
            福建1425节点
        <br/>
    </tr>
    <tr>
        <td> PCG </td>
        <td> 21246 </td>
        <td> 0.388728s </td>
    </tr>
    <tr>
        <td> AMG </td>
        <td> 迭代发散 </td>
        <td> NA </td>
    </tr>
    <tr>
        <td> PCG with AMG preconditioner </td>
        <td> 375 </td>
        <td> 0.061298s </td>
    </tr>
    
    <tr>
        <td rowspan="4"> 四川2433节点 <br/>
    </tr>
    <tr>
        <td> PCG </td>
        <td> 16705 </td>
        <td> 0.496167s </td>
    </tr>
    <tr>
        <td> AMG </td>
        <td> 迭代发散 </td>
        <td> NA </td>
    </tr>
    <tr>
        <td> PCG with AMG preconditioner </td>
        <td> 10000(迭代未结束但结果误差在0.01级别) </td>
        <td> 2.464774s </td>
    </tr>
    

    </table>

    3. PETSC的安装及使用

    3.1 PETSC安装

    3.1.1 下载PETSC安装包

    说明:本部分基于机器上已经安装有openmpi,如果没有,请移步“安装openmpi”部分。

    • 使用git clone下载petsc源码
    $ git clone -b maint https://bitbucket.org/petsc/petsc petsc
    

    3.1.2 安装PETSC

    • 在源代码根目录下,编译源码,假设你的openmpi装在了“/usr/local/openmpi”里面,你想把petsc装在“$HOME/petsc”下:
    $ ./configure --with-mpi-dir=/usr/local/openmpi/ --download-fblaslapack --prefix=$HOME/petsc
    
    • 测试安装是否成功
    $ make all test
    

    3.1.3 运行PETSC程序

    • 源代码中有一些example的文件,假定你已经在petsc根目录下面,examples的文件在 “./src/snes/examples/tutorials/”中。注意在make的时候需要指定PETSC_DIR和PETSC_ARCH中的路径。PETSC_DIR就是petsc的根目录,PETSC_ARCH是名字带“ARCH”的文件夹。假设你要编译ex12.c的文件夹
    # 编译
    $ make PETSC_DIR=$HOME/iterative/petsc PETSC_ARCH=arch-linux2-c-debug ex12
    # mpi运行, -n 为指定processor数量
    $ mpiexec -n 4 ./ex12
    

    3.2 PETSC计算代码详解

    3.2.1 PETSC线程分配空间方式

    与Hypre不同的是,PETSC无需显式地表达分配给该线程的矩阵/向量行坐标范围,而只需告诉PETSC矩阵的行数和列数,使用PETSC_DECIDE让PETSC自行决定分配给该线程的行坐标范围,并且可以通过内置的函数来获得属于该线程的起始坐标和结束坐标。以下为示例代码:

    // A为matrix
    ierr = MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, numRow, numCol);
    /*...矩阵操作...*/
    ierr = MatGetOwnershipRange(A, &Istart, &Iend);
    

    值得一提的是,PETSC中大部分的函数操作均会返回该操作的状态码,可以通过

    CHKERRQ(ierr)
    

    来检查程序是否出错。推荐每做一次操作都要检查一次状态码。

    3.2.2 PETSC矩阵,向量储存形式和赋值

    PETSC存储矩阵的类型为Mat,存储向量的类型为Vec,在矩阵赋值时,需要告知行坐标,赋值个数,和所赋的值。

    ierr = MatSetValues(A, 1, &Ii, 1, &J, &v, INSERT_VALUES);
    

    其中INSERT_VALUES表示赋值类型,代表将该坐标上的参数设为v。而在每次赋值完毕后,都需要Assemble矩阵来告知系统矩阵赋值已完成。

    // assemble matrix A
    ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    

    3.3 PETSC求解线性系统性能测试

    目前PETSC只能支持PCG的求解,如若要使用AMG的求解需要自行编写相关的代码,因此,本文只在PETSC测试中,使用了PCG的求解方法进行性能测试。

    计算题目 迭代次数 计算时间
    14节点 13 0.001009s
    118节点 78 0.004705s
    10790节点 2257 0.911253s
    福建1425节点 发散 NA
    四川2433节点 发散 NA

    4 结论

    本测试报告详细总结了并行计算库Hypre,PETSC的安装和求解线性方程组的过程,并且在不同的线性系统问题上进行了性能测试。测试结果表明,Hypre对于实际系统的适应度较高,在算法选择上多样,并且在合适的preconditioner的帮助下,对于实际系统方程的求解也会有比较好的性能。而PETSC在一些算法的开发的上仍然存在不足,如AMG的算法需要自行编写。并且在实际系统环境下的线性方程组求解上,无法获得比较好的结果。

    相关文章

      网友评论

        本文标题:Hypre与Petsc安装文档及性能测试

        本文链接:https://www.haomeiwen.com/subject/kzzulftx.html