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与配置文件一起使用来设置求解器操作。