1. 介绍

mcSolverIT库是建立在沐曦 MXMACA® 运行时环境(MXMACA工具包的一部分)和沐曦软件库之上实现的稀疏线性系统迭代求解器和预条件子。 该库设计成可从C++代码中调用。它使用沐曦的MXMACA运行时环境在GPU设备上运行。

mcSolverIT库支持以下求解器或预条件子:

  • 代数多网格(AMG):提供经典的AMG和聚合AMG,其中包含AMG求解过程的不同选项。例如,循环可以是CG,CGF,F,V或W。

  • 简单的松弛迭代求解器:例如,高斯-赛戴尔(Gauss-Seidel)、雅可比(Jacobi)及其变体。

  • 多项式迭代求解器:例如,切比雪夫多项式(Chebyshev Polynomial)方法。

  • 克雷洛夫求解器:例如,共轭梯度(Conjugate Gradient,CG)、广义最小残差(Generalized Minimum Residual,GMRES)及其变体。

  • 不完全直接求解器:例如,不完全LU分解。

  • 预条件求解器:例如,预条件共轭梯度(Preconditioned Conjugate Gradient,PCG)、预条件广义最小残差(Preconditioned Generalized Minimum Residual,PGMRES)等。

mcSolverIT的功能分为以下几类:

  • 实用程序参考:描述用于内存管理、文件输入/输出以及链接库实用程序的可用实用程序函数。

  • 配置参考:描述配置句柄的操作,该句柄将包含内存信息和求解器设置。

  • 资源参考:描述资源句柄的操作,该句柄指示求解器将使用的内存资源。

  • 矩阵参考:描述矩阵句柄的操作。

  • 向量参考:描述向量句柄的操作。

  • 求解器参考:描述求解器句柄的操作。

1.1. 安装mcSolverIT

mcSolverIT是一个与MXMACA工具包一起发布和安装的库。 MXMACA工具包的安装,参见《曦云系列通用计算GPU 快速上手指南》。 安装MXMACA工具包后,请确保设置了环境变量MACA_PATH。

export MACA_PATH=/opt/maca

mcSolverIT API相关文件如下所示。

#header location:
${MACA_PATH}/include/mcSolverIt

#lib location:
${MACA_PATH}/lib/libmcSolverIt.so

在使用mcSolverIT库编译代码之前,请确保环境变量ISU_FASTMODEL设置为1。

export ISU_FASTMODEL=1

1.2. 示例

请参考使用mcSolverIT编写代码的示例。 它们展示了使用mcSolverIT库应用程序编程接口(Application Programing Interface,API)编写的一些C++应用程序。 一个单节点示例如下所示。

#include <vector>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "amgx_c.h"
#include "mc_runtime.h"

int main() {
   // 步骤1:输入索引基数为0的Csr矩阵
   int n = 12;
   int nnz = 61;
   int block_dimx = 1;
   int block_dimy = 1;
   std::vector<int> A_rows = {0, 4, 8, 13, 21, 25, 32, 36, 41, 46, 50, 57, 61};
   std::vector<int> A_cols = {0, 1, 3, 8,
                              0, 1, 2, 3,
                              1, 2, 3, 4, 5,
                              0, 1, 2, 3, 4, 5, 8, 10,
                              2, 4, 5, 6,
                              2, 3, 4, 5, 6, 7, 10,
                              4, 5, 6, 7,
                              5, 6, 7, 9, 10,
                              0, 3, 8, 10, 11,
                              7, 9, 10, 11,
                              3, 5, 7, 8, 9, 10, 11,
                              8, 9, 10, 11};
   std::vector<double> A_vals = {1, 2, 3, 4,
                                 5, 6, 7, 8,
                                 9, 10, 11, 12, 13,
                                 14, 15, 16, 17, 18, 19, 20, 21,
                                 22, 23, 24, 25,
                                 26, 27, 28, 29, 30, 31, 32,
                                 33, 34, 35, 36,
                                 37, 38, 39, 40, 41,
                                 42, 43, 44, 45, 46,
                                 47, 48, 49, 50,
                                 51, 52, 53, 54, 55, 56, 57,
                                 58, 59, 60, 61};
   std::vector<double> h_x(n, 0);
   std::vector<double> h_b(n, 1);
   void *d_A_rows, *d_A_cols, *d_A_vals, *d_x, *d_b;
   mcMalloc((void **)&d_A_rows, (n + 1) * sizeof(int));
   mcMalloc((void **)&d_A_cols, nnz * sizeof(int));
   mcMalloc((void **)&d_A_vals, nnz * sizeof(double));
   mcMalloc((void **)&d_x, n * sizeof(double));
   mcMalloc((void **)&d_b, n * sizeof(double));
   mcMemcpy(d_A_rows, A_rows.data(), (n + 1) * sizeof(int),
            mcMemcpyHostToDevice);
   mcMemcpy(d_A_cols, A_cols.data(), nnz * sizeof(int),
            mcMemcpyHostToDevice);
   mcMemcpy(d_A_vals, A_vals.data(), nnz * sizeof(double),
            mcMemcpyHostToDevice);
   mcMemcpy(d_x, h_x.data(), n * sizeof(double),
            mcMemcpyHostToDevice);
   mcMemcpy(d_b, h_b.data(), n * sizeof(double),
            mcMemcpyHostToDevice);

   // 步骤 2:声明库句柄并初始化
   // 库句柄
   MCSOLVERIT_Mode mode = MCSOLVERIT_mode_dDDI;
   MCSOLVERIT_config_handle config_handle;
   MCSOLVERIT_resources_handle resources_handle;
   MCSOLVERIT_matrix_handle mtx_handle;
   MCSOLVERIT_vector_handle rhs_handle, sol_handle;
   MCSOLVERIT_solver_handle solver_handle;
   // 状态处理
   MCSOLVERIT_SOLVE_STATUS status;
   void *lib_handle = NULL;
   // 初始化
   MCSOLVERIT_initialize();
   MCSOLVERIT_initialize_plugins();

   // 步骤 3:创建句柄
   MCSOLVERIT_config_create(&config_handle, "solver=AMG, cycle=V, \
                            monitor_residual=1, store_res_history=1, \
                            max_iters=10, tolerance=1e-6");
   MCSOLVERIT_resources_create_simple(&resources_handle, config_handle);
   MCSOLVERIT_solver_create(&solver_handle, resources_handle, mode, config_handle);
   MCSOLVERIT_matrix_create(&mtx_handle, resources_handle, mode);
   MCSOLVERIT_vector_create(&rhs_handle, resources_handle, mode);
   MCSOLVERIT_vector_create(&sol_handle, resources_handle, mode);
   // 如果对角线包含在矩阵本身中,则diag_data 必须设置为 NULL
   MCSOLVERIT_matrix_upload_all(mtx_handle, n, nnz, block_dimx, block_dimy,
                                (int*)d_A_rows, (int*)d_A_cols, d_A_vals,
                                NULL);
   MCSOLVERIT_vector_upload(rhs_handle, n, block_dimy, d_b);
   MCSOLVERIT_vector_upload(sol_handle, n, block_dimx, d_x);

   // 步骤 4:求解器设置
   MCSOLVERIT_solver_setup(solver_handle, mtx_handle);

   // 步骤 5:求解器求解
   MCSOLVERIT_solver_solve(solver_handle, rhs_handle, sol_handle);

   // 步骤 6:获取求解器状态、迭代和残差
   MCSOLVERIT_solver_get_status(solver_handle, &status);
   int iterations = 0;
   double initial_residual;
   double final_residual;
   MCSOLVERIT_solver_get_iterations_number(solver_handle, &iterations);
   MCSOLVERIT_solver_get_iteration_residual(solver_handle, 0, 0,
                                            &initial_residual);
   MCSOLVERIT_solver_get_iteration_residual(solver_handle, iterations, 0,
                                            &final_residual);
   final_residual = final_residual / initial_residual;
   printf("iterations = %d, relative residual = %le\n", iterations,
          final_residual);

   // 步骤 7:检查结果
   double test_tolerance = 1e-04;
   if (status == MCSOLVERIT_SOLVE_FAILED) {
      printf("Error: Solver err\n");
   }
   if (test_tolerance < final_residual) {
      printf("Error: Solver not convergence\n");
   }

   // 步骤 8:释放资源并退出
   // 销毁资源、矩阵、向量和求解器
   MCSOLVERIT_solver_destroy(solver_handle);
   MCSOLVERIT_vector_destroy(sol_handle);
   MCSOLVERIT_vector_destroy(rhs_handle);
   MCSOLVERIT_matrix_destroy(mtx_handle);
   MCSOLVERIT_resources_destroy(resources_handle);
   // 销毁配置
   MCSOLVERIT_config_destroy(config_handle);
   // 关机和退出
   MCSOLVERIT_finalize_plugins();
   MCSOLVERIT_finalize();
   // 释放资源
   mcFree(d_x);
   mcFree(d_b);
   mcFree(d_A_rows);
   mcFree(d_A_cols);
   mcFree(d_A_vals);

   return 0;
}

如果要使用其他求解器,可以在MCSOLVERIT_config_create中更改传递给配置句柄的设置,也可以将MCSOLVERIT_config_create_from_file与配置文件一起使用来设置求解器操作。