cuSOLVER API参考文档

cuSOLVER API参考指南,这是一个用于稠密和稀疏矩阵分解及线性系统求解的GPU加速库。

1. 简介

cuSolver库是基于cuBLAS和cuSPARSE库的高级软件包。它包含两个模块,分别对应两组API:

  1. 单GPU上的cuSolver API

  2. 单节点多GPU上的cuSolverMG API

这些功能可以独立使用,也可以与其他工具库配合使用。为简化表述,cuSolver表示单GPU接口,cuSolverMg表示多GPU接口。

cuSolver 旨在提供类似 LAPACK 的有用功能,例如针对稠密矩阵的常见矩阵分解和三角求解例程、稀疏最小二乘求解器以及特征值求解器。此外,cuSolver 还提供了一个新的重构库,可用于求解具有共享稀疏模式的一系列矩阵。

cuSolver将三个独立组件整合在一个统一的框架下。cuSolver的第一部分称为cuSolverDN,负责处理稠密矩阵分解和求解例程,如LU、QR、SVD和LDLT,以及实用的工具函数,如矩阵和向量置换。

接下来,cuSolverSP提供了一套基于稀疏QR分解的新稀疏例程。并非所有矩阵在分解过程中都具有良好的并行稀疏模式,因此cuSolverSP库还提供了CPU路径来处理这些类似串行的矩阵。对于那些具有丰富并行性的矩阵,GPU路径将提供更高的性能。该库设计用于从C和C++调用。

最后一部分是cuSolverRF,这是一个稀疏重分解包,在求解一系列仅系数改变但稀疏模式保持不变的矩阵时,能够提供非常出色的性能。

cuSolver库的GPU路径假定数据已在设备内存中。开发者需负责使用标准CUDA运行时API例程(如cudaMalloc()cudaFree()cudaMemcpy()cudaMemcpyAsync())在GPU内存与CPU内存之间分配内存并复制数据。

cuSolverMg是GPU加速的ScaLAPACK。目前,cuSolverMg支持一维列块循环布局,并提供对称特征值求解器。

注意

cuSolver库需要硬件支持CUDA计算能力(CC)5.0或更高版本。有关所有NVIDIA GPU对应的计算能力列表,请参阅CUDA C++编程指南

1.1. cuSolverDN: 密集线性代数包

cuSolverDN库旨在求解以下形式的稠密线性系统

\[Ax = b\]

其中系数矩阵 \(A\in R^{nxn}\),右侧向量 \(b\in R^{n}\) 和解向量 \(x\in R^{n}\)

cuSolverDN库提供QR分解和带部分主元消去的LU分解,用于处理一般的非对称矩阵A。同时为对称/厄米特矩阵提供Cholesky分解。对于对称不定矩阵,我们提供Bunch-Kaufman(LDL)分解。

cuSolverDN库还提供了一个有用的双对角化例程和奇异值分解(SVD)功能。

cuSolverDN库专注于LAPACK中计算密集且常用的例程,并提供与LAPACK兼容的API接口。用户可以通过cuSolverDN加速这些耗时的例程,同时无需大幅修改现有代码即可保留LAPACK中的其他功能。

1.2. cuSolverSP: 稀疏线性代数包

cuSolverSP库主要设计用于求解稀疏线性系统

\[Ax = b\]

以及最小二乘问题

\[x = {argmin}{||}A*z - b{||}\]

其中稀疏矩阵 \(A\in R^{mxn}\),右侧向量 \(b\in R^{m}\) 和解向量 \(x\in R^{n}\)。对于线性系统,我们要求 m=n

核心算法基于稀疏QR分解。矩阵A采用CSR格式接收。如果矩阵A是对称/厄米特矩阵,用户需要提供完整矩阵,即补全缺失的下三角或上三角部分。

如果矩阵 A 是对称正定的,且用户只需要求解 \(Ax = b\),则可以使用 Cholesky 分解,此时用户只需提供 A 的下三角部分。

除了线性和最小二乘求解器外,cuSolverSP库还提供了一个基于移位逆幂法的简易特征值求解器,以及一个用于计算复平面区域内特征值数量的函数。

1.3. cuSolverRF: 重因子化

cuSolverRF库旨在通过快速重新因子化来加速求解具有相同稀疏模式但给定新系数的线性方程组。

\[A_{i}x_{i} = f_{i}\]

其中给定了一系列系数矩阵 \(A_{i}\in R^{nxn}\)、右侧项 \(f_{i}\in R^{n}\) 和解向量 \(x_{i}\in R^{n}\),对应 i=1,...,k 的情况。

cuSolverRF库适用于当系数矩阵\(A_{i}\)的稀疏模式、用于最小化填充的重新排序以及LU分解过程中使用的枢轴选择在这些线性系统中保持不变的情况。在这种情况下,第一个线性系统(i=1)需要完整的LU分解,而后续的线性系统(i=2,...,k)仅需要LU重新分解。后者可以使用cuSolverRF库来执行。

请注意,由于系数矩阵的稀疏模式保持不变,重新排序和主元选择也保持不变,因此生成的三角因子\(L_{i}\)\(U_{i}\)的稀疏模式也保持不变。因此,完整LU分解与LU重新分解之间的真正区别在于所需内存可以提前预知。

1.4. 命名规范

cuSolverDN库提供两种不同的API接口:legacy(传统)和generic(通用)。

传统API中的函数支持以下数据类型:floatdoublecuComplexcuDoubleComplex。传统API的命名规范如下:

cusolverDn<t><operation>

其中 <t> 可以是 SDCZX,分别对应数据类型 floatdoublecuComplexcuDoubleComplex 以及通用类型。<operation> 可以是 Cholesky 分解 (potrf)、带部分主元的 LU 分解 (getrf)、QR 分解 (geqrf) 以及 Bunch-Kaufman 分解 (sytrf)。

通用API中的函数为每个例程提供单一入口点,并支持使用64位整数定义矩阵和向量维度。通用API的命名规范与数据类型无关,具体如下:

cusolverDn<operation>

其中 <operation> 可以是 Cholesky 分解 (potrf)、带部分主元的 LU 分解 (getrf) 和 QR 分解 (geqrf)。

cuSolverSP库函数支持以下数据类型:floatdoublecuComplexcuDoubleComplex。其命名规则如下:

cusolverSp[Host]<t>[<matrix data format>]<operation>[<output matrix data format>]<based on>

其中cuSolverSp是GPU路径,cusolverSpHost是对应的CPU路径。<t>可以是SDCZX,分别对应数据类型floatdoublecuComplexcuDoubleComplex以及通用类型。

matrix data formatcsr,即压缩稀疏行格式。

<operation> 可以是 lslsqeigeigs,分别对应线性求解器、最小二乘求解器、特征值求解器以及计算指定区间内的特征值数量。

output matrix data format可以是vm,分别对应向量或矩阵。

<based on> 描述了所使用的算法。例如,在线性求解器和最小二乘求解器中使用了qr(稀疏QR分解)。

所有函数的返回类型均为cusolverStatus_t,具体说明将在后续章节中详细展开。

cuSolverSP API

例程

数据格式

操作

输出格式

基于

csrlsvlu

csr

linear solver (ls)

vector (v)

LU (lu) with partial pivoting

csrlsvqr

csr

linear solver (ls)

vector (v)

QR 分解 (qr)

csrlsvchol

csr

linear solver (ls)

vector (v)

Cholesky factorization (chol)

csrlsqvqr

csr

最小二乘 求解器 (lsq)

vector (v)

QR 分解 (qr)

csreigvsi

csr

eigenvalue solver (eig)

vector (v)

shift-inverse

csreigs

csr

number of eigenvalues in a box (eigs)

csrsymrcm

csr

Symmetric Reverse Cuthill-McKee (symrcm)

cuSolverRF库例程支持数据类型double。大多数例程遵循以下命名规范:

cusolverRf_<operation>_[[Host]](…)

其中可选的尾部Host限定符表示数据是在主机上访问的,而不是在设备上访问的,后者是默认情况。<operation>可以是SetupAnalyzeRefactorSolveResetValuesAccessBundledFactorsExtractSplitFactors

最后,cuSolverRF库例程的返回类型是cusolverStatus_t

1.5. 异步执行

cuSolver库函数倾向于尽可能保持异步执行。开发者始终可以使用cudaDeviceSynchronize()函数来确保特定cuSolver库例程的执行已完成。

开发者也可以使用cudaMemcpy()例程,通过分别指定cudaMemcpyDeviceToHostcudaMemcpyHostToDevice参数,将数据从设备复制到主机或反之。在这种情况下,无需额外调用cudaDeviceSynchronize(),因为使用上述参数的cudaMemcpy()调用是阻塞式的,只有当结果在主机端准备就绪时才会完成。

1.6. 库属性

libraryPropertyType 数据类型是一个库属性类型的枚举(例如,CUDA 版本 X.Y.Z 将生成 MAJOR_VERSION=XMINOR_VERSION=YPATCH_LEVEL=Z)。

typedef enum libraryPropertyType_t
{
        MAJOR_VERSION,
        MINOR_VERSION,
        PATCH_LEVEL
} libraryPropertyType;

以下代码可以显示cusolver库的版本。

int major=-1,minor=-1,patch=-1;
cusolverGetProperty(MAJOR_VERSION, &major);
cusolverGetProperty(MINOR_VERSION, &minor);
cusolverGetProperty(PATCH_LEVEL, &patch);
printf("CUSOLVER Version (Major,Minor,PatchLevel): %d.%d.%d\n", major,minor,patch);

1.7. 高精度包

cusolver 库在必要时会使用高精度进行迭代优化。

2. 使用CUSOLVER API

2.1. 概述

本章介绍如何使用cuSolver库API。它并非cuSolver API数据类型和函数的参考文档,这些内容将在后续章节中提供。

2.1.1. 线程安全

该库是线程安全的,其函数可以从多个主机线程调用。

2.1.2. 标量参数

在cuSolver API中,标量参数可以通过主机上的引用传递。

2.1.3. 使用流实现并行化

如果应用程序执行多个小型独立计算,或者它在计算过程中并行传输数据,那么可以使用CUDA流来重叠这些任务。

应用程序可以在概念上将每个任务与一个流关联起来。为了实现任务之间的计算重叠,开发者应该:

  1. 使用函数 cudaStreamCreate() 创建 CUDA 流,并且

  2. 在调用实际的cuSolverDN例程之前,通过调用例如cusolverDnSetStream()来设置每个单独的cuSolver库例程要使用的流。

The computations performed in separate streams would then be overlapped automatically on the GPU, when possible. This approach is especially useful when the computation performed by a single task is relatively small, and is not enough to fill the GPU with work, or when there is a data transfer that can be performed in parallel with the computation.

2.1.6. 信息规范

每个LAPACK例程都会返回一个info值,用于指示无效参数的位置。如果info = -i,则表示第i个参数无效。为了与LAPACK的基1索引保持一致,cusolver不会将无效的handle报告到info中。相反,对于无效的handlecusolver会返回CUSOLVER_STATUS_NOT_INITIALIZED状态码。

2.1.7. _bufferSize参数的使用

cuSolver库内部没有cudaMalloc功能,用户必须显式分配设备工作空间。例程xyz_bufferSize用于查询例程xyz所需工作空间的大小,例如xyz = potrf。为了简化API设计,xyz_bufferSize几乎完全遵循xyz的函数签名,尽管它仅依赖部分参数(例如设备指针并不用于决定工作空间大小)。在大多数情况下,xyz_bufferSize会在实际设备数据(由设备指针指向)准备就绪前或分配设备指针前被调用。这种情况下,用户可以向xyz_bufferSize传递空指针而不会影响功能。

2.1.8. cuSOLVERDn 日志记录

可以通过在启动目标应用程序之前设置以下环境变量来启用cuSOLVERDn日志记录机制:

  • CUSOLVERDN_LOG_LEVEL= - 其中 为以下级别之一:

    • 0 - 关闭 - 日志记录已禁用(默认)

    • 1 - 错误 - 仅记录错误日志

    • 2 - 跟踪 - 调用启动CUDA内核的API将记录其参数和重要信息

    • 3 - 提示 - 可能提升应用性能的提示

    • 4 - 信息 - 提供关于库执行的一般信息,可能包含启发式算法状态的详细信息

    • 5 - API跟踪 - API调用将记录其参数和重要信息

  • CUSOLVERDN_LOG_MASK= - 其中mask是以下掩码的组合:

    • 0 - 关闭

    • 1 - 错误

    • 2 - 追踪

    • 4 - 提示

    • 8 - 信息

    • 16 - API跟踪

  • CUSOLVERDN_LOG_FILE= - 其中file_name是日志文件的路径。文件名可以包含%i,这将被替换为进程ID,例如_%i.log。如果未定义CUSOLVERDN_LOG_FILE,日志消息将打印到标准输出。

另一个选项是使用实验性的cusolverDn日志记录API。参见: cusolverDnLoggerSetCallback(), cusolverDnLoggerSetFile(), cusolverDnLoggerOpenFile(), cusolverDnLoggerSetLevel(), cusolverDnLoggerSetMask(), cusolverDnLoggerForceDisable().

2.1.9. 确定性结果

在本文档中,如果一个函数在相同的输入参数、硬件和软件环境下每次执行都能计算出完全相同的二进制结果,则该函数被声明为确定性的。相反,非确定性函数可能由于浮点运算顺序的变化而计算出不同的二进制结果,例如四个值abcd的和s可以通过不同的顺序计算:

  1. s = (a + b) + (c + d)

  2. s = (a + (b + c)) + d

  3. s = a + (b + (c + d))

由于浮点运算的非结合性,所有结果可能在位级别上存在差异。

默认情况下,cuSolverDN会计算确定性结果。为了提高某些函数的性能,可以通过cusolverDnSetDeterministicMode()允许非确定性结果。

2.2. cuSolver 类型参考

2.2.1. cuSolverDN 类型

支持floatdoublecuComplexcuDoubleComplex数据类型。前两种是标准C语言数据类型,后两种是从cuComplex.h导出的。此外,cuSolverDN还使用了cuBLAS中一些常见的数据类型。

2.2.1.1. cusolverDnHandle_t

这是一个指向不透明cuSolverDN上下文的指针类型,用户必须在调用任何其他库函数之前通过调用cusolverDnCreate()来初始化它。未初始化的Handle对象将导致意外行为,包括cuSolverDN崩溃。由cusolverDnCreate()创建并返回的句柄必须传递给每个cuSolverDN函数。

2.2.1.2. cublasFillMode_t

该类型指示密集矩阵的哪一部分(下三角或上三角)已被填充,因此应由函数使用。

含义

CUBLAS_FILL_MODE_LOWER

矩阵的下半部分已填充。

CUBLAS_FILL_MODE_UPPER

矩阵的上半部分已填充。

CUBLAS_FILL_MODE_FULL

完整矩阵已填充。

请注意,BLAS实现通常使用Fortran字符‘L’‘l’(下三角)以及‘U’‘u’(上三角)来描述矩阵的哪一部分被填充。

2.2.1.3. cublasOperation_t

cublasOperation_t 类型表示需要对密集矩阵执行哪种操作。

含义

CUBLAS_OP_N

选择非转置操作。

CUBLAS_OP_T

已选择转置操作。

CUBLAS_OP_C

选择了共轭转置操作。

请注意,BLAS实现通常使用Fortran字符‘N’‘n’(非转置)、‘T’‘t’(转置)以及‘C’‘c’(共轭转置)来描述需要对密集矩阵执行的操作。

2.2.1.4. cusolverEigType_t

cusolverEigType_t 类型表示求解器处理的是哪种特征值类型。

含义

CUSOLVER_EIG_TYPE_1

A*x = lambda*B*x

CUSOLVER_EIG_TYPE_2

A*B*x = lambda*x

CUSOLVER_EIG_TYPE_3

B*A*x = lambda*x

请注意,LAPACK实现通常使用Fortran整数1(A*x = lambda*B*x)、2(A*B*x = lambda*x)、3(B*A*x = lambda*x)来表示求解器处理的是哪种类型的特征值问题。

2.2.1.5. cusolverEigMode_t

cusolverEigMode_t 类型指示是否计算特征向量。

含义

CUSOLVER_EIG_MODE_NOVECTOR

仅计算特征值。

CUSOLVER_EIG_MODE_VECTOR

计算特征值和特征向量。

请注意,LAPACK实现通常使用Fortran字符'N'(仅计算特征值)、'V'(同时计算特征值和特征向量)来表示是否计算特征向量。

2.2.1.6. cusolverIRSRefinement_t

cusolverIRSRefinement_t 类型表示将用于特定 cuda 函数的求解器类型。我们的大多数实验表明,CUSOLVER_IRS_REFINE_GMRES 是最佳选择。

有关优化过程的更多详细信息,请参阅Azzam Haidar、Stanimire Tomov、Jack Dongarra和Nicholas J. Higham于2018年发表的论文《利用GPU张量核心实现快速FP16算术运算以加速混合精度迭代优化求解器》。该论文收录于《国际高性能计算、网络、存储与分析会议论文集》(SC '18)。IEEE出版社,美国新泽西州皮斯卡塔韦,第47篇文章,共11页。

CUSOLVER_IRS_REFINE_NOT_SET

求解器未设置;该值是在创建params结构时设置的。IRS求解器将返回错误。

CUSOLVER_IRS_REFINE_NONE

无精化求解器,IRS求解器执行因式分解后直接求解,不进行任何精化步骤。例如,如果IRS求解器是cusolverDnIRSXgesv(),这相当于不带精化步骤的Xgesv例程,且因式分解以最低精度执行。举例来说,若主精度为CUSOLVER_R_64F且最低精度同样为CUSOLVER_R_64F,则等效于调用cusolverDnDgesv()

CUSOLVER_IRS_REFINE_CLASSICAL

经典迭代精化求解器。类似于LAPACK例程中使用的方法。

CUSOLVER_IRS_REFINE_GMRES

基于GMRES(广义最小残差)的迭代精化求解器。在最近的研究中,GMRES方法因其作为精化求解器的优异性能超越了经典迭代精化方法,引起了科学界的广泛关注。根据我们的实验验证,我们推荐采用此设置。

CUSOLVER_IRS_REFINE_CLASSICAL_GMRES

经典迭代精化求解器,内部使用GMRES(广义最小残差法)在每次迭代中求解修正方程。我们将经典精化迭代称为外部迭代,而GMRES称为内部迭代。请注意,如果将内部GMRES的容差设置得非常低(例如达到机器精度),那么外部的经典精化迭代将仅执行一次迭代,因此该选项的行为将类似于CUSOLVER_IRS_REFINE_GMRES

CUSOLVER_IRS_REFINE_GMRES_GMRES

类似于CUSOLVER_IRS_REFINE_CLASSICAL_GMRES,它包含使用GMRES求解内部校正系统的经典精化过程;这里是一个基于GMRES(广义最小残差)的迭代精化求解器,它在内部使用另一个GMRES来求解预处理系统。

2.2.1.7. cusolverDnIRSParams_t

这是一个指向不透明结构体cusolverDnIRSParams_t的指针类型,该结构体保存了迭代精化线性求解器(如cusolverDnXgesv())的参数。请使用下文描述的相应辅助函数来创建/销毁此结构体或设置/获取求解器参数。

2.2.1.8. cusolverDnIRSInfos_t

这是一个指向不透明结构体cusolverDnIRSInfos_t的指针类型,该结构体保存了关于迭代精化线性求解器(如cusolverDnXgesv())调用执行的相关信息。请使用下文描述的对应辅助函数来创建/销毁该结构体或获取求解信息。

2.2.1.9. cusolverDnFunction_t

cusolverDnFunction_t 类型表示需要通过 cusolverDnSetAdvOptions() 配置的例程。值 CUSOLVERDN_GETRF 对应例程 Getrf

含义

CUSOLVERDN_GETRF

对应 Getrf

2.2.1.10. cusolverAlgMode_t

cusolverAlgMode_t类型表示通过cusolverDnSetAdvOptions()选择的算法。每个例程支持的算法集将在该例程的文档中详细说明。

默认算法是CUSOLVER_ALG_0。用户也可以提供NULL来使用默认算法。

2.2.1.11. cusolverStatus_t

这与稀疏LAPACK部分中的cusolverStatus_t相同。

2.2.1.12. cusolverDnLoggerCallback_t

cusolverDnLoggerCallback_t 是一个回调函数指针类型。

参数

参数

内存

输入/输出

描述

logLevel

输出

参见 cuSOLVERDn 日志记录

functionName

输出

记录此消息的API名称。

message

输出

日志消息。

使用以下函数设置回调函数:cusolverDnLoggerSetCallback()

2.2.1.13. cusolverDeterministicMode_t

cusolverDeterministicMode_t 类型用于指示多次执行相同输入的 cuSolver 函数是否会得到完全相同的位级结果(确定性模式),还是可能产生位级差异的结果(非确定性模式)。与仅涉及原子函数使用的 cublasAtomicsMode_t 不同,cusolverDeterministicMode_t 涵盖了所有非确定性的编程模式。可以通过 cusolverDnSetDeterministicMode()cusolverDnGetDeterministicMode() 函数分别设置和查询确定性模式。

含义

CUSOLVER_DETERMINISTIC_RESULTS

计算确定性结果。

CUSOLVER_ALLOW_NON_DETERMINISTIC_RESULTS

允许非确定性结果。

2.2.1.14. cusolverStorevMode_t

指定定义基本反射器的向量如何存储。

含义

CUBLAS_STOREV_COLUMNWISE

按列。

CUBLAS_STOREV_ROWWISE

按行处理。

2.2.1.15. cusolverDirectMode_t

指定基本反射器相乘形成块反射器的顺序。

含义

CUBLAS_DIRECT_FORWARD

前进。

CUBLAS_DIRECT_BACKWARD

反向传播。

2.2.2. cuSolverSP 类型

支持floatdoublecuComplexcuDoubleComplex数据类型。前两种是标准C语言数据类型,后两种是从cuComplex.h导出的。

2.2.2.1. cusolverSpHandle_t

这是一个指向不透明cuSolverSP上下文的指针类型,用户必须在调用任何其他库函数之前通过调用cusolverSpCreate()来初始化它。未初始化的Handle对象将导致意外行为,包括cuSolverSP崩溃。由cusolverSpCreate()创建并返回的句柄必须传递给每个cuSolverSP函数。

2.2.2.2. cusparseMatDescr_t

我们决定保留与cuSPARSE相同的矩阵形状和属性描述结构。这样可以使用相同的矩阵描述来调用cuSPARSE或cuSOLVER。

typedef struct {
    cusparseMatrixType_t MatrixType;
    cusparseFillMode_t FillMode;
    cusparseDiagType_t DiagType;
    cusparseIndexBase_t IndexBase;
} cusparseMatDescr_t;

请阅读cuSPARSE库的文档以理解cusparseMatDescr_t的每个字段。

2.2.2.3. cusolverStatus_t

这是库函数返回的状态类型,它可以有以下取值。

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

cuSolver库未被初始化。这通常是由于缺少先前的调用、cuSolver例程调用的CUDA Runtime API出现错误,或硬件设置存在问题所导致的。

需要修正:在调用该函数前先调用cusolverDnCreate();并检查硬件、适当版本的驱动程序以及cuSolver库是否正确安装。

CUSOLVER_STATUS_ALLOC_FAILED

cuSolver库内部资源分配失败。这通常是由cudaMalloc()失败引起的。

需要修正:在函数调用之前,尽可能释放之前分配的内存。

CUSOLVER_STATUS_INVALID_VALUE

向函数传递了不支持的值或参数(例如负向量大小)。

需要修正:确保所有传递的参数都具有有效值。

CUSOLVER_STATUS_ARCH_MISMATCH

该函数需要的功能在当前设备架构中缺失;通常是由于缺乏对原子操作或双精度运算的支持所致。

需要修正:在计算能力5.0或更高的设备上编译并运行该应用程序。

CUSOLVER_STATUS_EXECUTION_FAILED

GPU程序执行失败。这通常是由于内核在GPU上启动失败导致的,可能由多种原因引起。

需要修正: 检查硬件、适当版本的驱动程序以及cuSolver库是否正确安装。

CUSOLVER_STATUS_INTERNAL_ERROR

内部cuSolver操作失败。此错误通常由cudaMemcpyAsync()故障引起。

需要修正: 检查硬件、适当版本的驱动程序以及cuSolver库是否正确安装。同时,确保作为参数传递给例程的内存在例程完成前未被释放。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

该函数不支持此矩阵类型。这通常是由于向函数传递了无效的矩阵描述符所致。

需要修正: 检查descrA中的字段是否设置正确。

CUSOLVER_STATUS_NOT_SUPPORTED

不支持该参数组合,例如不支持批处理版本或M < N的情况。

需要修正:查阅文档,并使用受支持的配置。

2.2.3. cuSolverRF 类型

cuSolverRF 仅支持 double

2.2.3.1. cusolverRfHandle_t

cusolverRfHandle_t 是一个指向不透明数据结构的指针,该结构包含 cuSolverRF 库的句柄。用户必须先调用 cusolverRfCreate() 来初始化该句柄,然后才能进行其他 cuSolverRF 库调用。该句柄会被传递给所有其他 cuSolverRF 库调用。

2.2.3.2. cusolverRfMatrixFormat_t

cusolverRfMatrixFormat_t 是一个枚举类型,用于指定 cusolverRfSetupDevice()cusolverRfSetupHost()cusolverRfResetValues()cusolveRfExtractBundledFactorsHost()cusolverRfExtractSplitFactorsHost() 例程所采用的输入/输出矩阵格式。

含义

CUSOLVER_MATRIX_FORMAT_CSR

假设矩阵格式为CSR。(默认)

CUSOLVER_MATRIX_FORMAT_CSC

假设矩阵格式为CSC。

2.2.3.3. cusolverRfNumericBoostReport_t

cusolverRfNumericBoostReport_t 是一个枚举类型,用于指示在 cusolverRfRefactor()cusolverRfSolve() 例程期间是否使用了(主元的)数值增强功能。数值增强功能默认是禁用的。

含义

CUSOLVER_NUMERIC_BOOST_NOT_USED

未使用数值提升。(默认)

CUSOLVER_NUMERIC_BOOST_USED

使用了数值提升。

2.2.3.4. cusolverRfResetValuesFastMode_t

cusolverRfResetValuesFastMode_t 是一个枚举类型,用于指示 cusolverRfResetValues() 例程使用的模式。快速模式需要额外的内存,仅当需要非常快速地调用 cusolverRfResetValues() 时才推荐使用。

含义

CUSOLVER_RESET_VALUES_FAST_MODE_OFF

快速模式已禁用。(默认)

CUSOLVER_RESET_VALUES_FAST_MODE_ON

快速模式已启用。

2.2.3.5. cusolverRfFactorization_t

cusolverRfFactorization_t 是一个枚举类型,用于指示在 cusolverRfRefactor() 例程中使用哪种(内部)算法进行重新分解。

含义

CUSOLVER_FACTORIZATION_ALG0

算法 0. (默认)

CUSOLVER_FACTORIZATION_ALG1

算法1.

CUSOLVER_FACTORIZATION_ALG2

算法2. 基于Domino的方案。

2.2.3.6. cusolverRfTriangularSolve_t

cusolverRfTriangularSolve_t 是一个枚举类型,用于指示在 cusolverRfSolve() 例程中使用哪种(内部)算法进行三角求解。

含义

CUSOLVER_TRIANGULAR_SOLVE_ALG1

算法1. (默认)

CUSOLVER_TRIANGULAR_SOLVE_ALG2

算法2. 基于Domino的方案。

CUSOLVER_TRIANGULAR_SOLVE_ALG3

算法3. 基于Domino的方案。

2.2.3.7. cusolverRfUnitDiagonal_t

cusolverRfUnitDiagonal_t 是一个枚举类型,用于指示在cusolverRfSetupDevice()cusolverRfSetupHost()cusolverRfExtractSplitFactorsHost()例程中,输入/输出三角因子是否以及何处存储了单位对角线。

含义

CUSOLVER_UNIT_DIAGONAL_STORED_L

单位对角线存储在下三角因子中(默认)。

CUSOLVER_UNIT_DIAGONAL_STORED_U

单位对角线存储在上三角因子中。

CUSOLVER_UNIT_DIAGONAL_ASSUMED_L

假设下三角因子具有单位对角线。

CUSOLVER_UNIT_DIAGONAL_ASSUMED_U

假设上三角因子具有单位对角线。

2.2.3.8. cusolverStatus_t

cusolverStatus_t 是一个枚举类型,用于指示 cuSolverRF 库调用成功或失败。所有 cuSolver 库例程都会返回此状态值,它使用与稀疏和密集 Lapack 例程相同的枚举值。

2.3. cuSolver格式参考

2.3.1. 索引基础格式

cuSolver 支持基于1和基于0的索引方式。

2.3.2. 向量(稠密)格式

假设向量在内存中是线性存储的。例如,向量

\[\begin{split}x = \begin{pmatrix} x_1 \\ x_1 \\ \vdots \\ x_n \end{pmatrix}\end{split}\]

表示为

\[\begin{split}\begin{pmatrix} x_1 & x_2 & \ldots & x_n \\ \end{pmatrix}\end{split}\]

2.3.3. 矩阵(密集)格式

假设密集矩阵在内存中以列优先顺序存储。可以使用原始矩阵的主维来访问子矩阵。例如,m*n(子)矩阵

\[\begin{split}\begin{pmatrix} a_{1,1} & \cdots & a_{1,n} \\ a_{2,1} & \cdots & a_{2,n} \\ \vdots \\ a_{m,1} & \cdots & a_{m,n} \\ \end{pmatrix}\end{split}\]

表示为

\[\begin{split}\begin{pmatrix} a_{1,1} & \ldots & a_{1,n} \\ a_{2,1} & \ldots & a_{2,n} \\ \vdots & \ddots & \vdots \\ a_{m,1} & \ldots & a_{m,n} \\ \vdots & \ddots & \vdots \\ a_{{lda},1} & \ldots & a_{{lda},n} \\ \end{pmatrix}\end{split}\]

其元素在内存中线性排列为

\[\begin{split}\begin{pmatrix} a_{1,1} \quad a_{2,1} \quad \ldots \quad a_{m,1} \quad \ldots \quad a_{lda,1} \quad \ldots \quad a_{1,n} \quad a_{2,n} \quad \ldots \quad a_{m,n} \quad \ldots \quad a_{lda,n} \\ \end{pmatrix}\end{split}\]

其中 lda \(\geq\) mA 的主维度。

2.3.4. 矩阵 (CSR) 格式

在CSR格式中,矩阵由以下参数表示:

参数

类型

大小

含义

n

(int)

矩阵中的行数(和列数)。

nnz

(int)

矩阵中非零元素的数量。

csrRowPtr

(int *)

n+1

对应于数组csrColIndcsrVal中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵中非零元素的数量。

csrColInd

(int *)

nnz

对应矩阵中非零元素的列索引数组。假设该数组按行排序,且每行内按列排序。

csrVal

(S|D|C|Z)*

nnz

对应矩阵中非零元素的数值数组。假设该数组已按行排序,且每行内按列排序。

请注意,在我们的CSR格式中,稀疏矩阵默认按行优先顺序存储。换句话说,索引数组首先按行索引排序,然后在每行内按列索引排序。此外,假定每对行和列索引仅出现一次。

例如,4x4矩阵

\[\begin{split}A = \begin{pmatrix} {1.0} & {3.0} & {0.0} & {0.0} \\ {0.0} & {4.0} & {6.0} & {0.0} \\ {2.0} & {5.0} & {7.0} & {8.0} \\ {0.0} & {0.0} & {0.0} & {9.0} \\ \end{pmatrix}\end{split}\]

表示为

\[\begin{split}{csrRowPtr} = \begin{pmatrix} 0 & 2 & 4 & 8 & 9 \\ \end{pmatrix}\end{split}\]
\[\begin{split}{csrColInd} = \begin{pmatrix} 0 & 1 & 1 & 2 & 0 & 1 & 2 & 3 & 3 \\ \end{pmatrix}\end{split}\]
\[\begin{split}{csrVal} = \begin{pmatrix} 1.0 & 3.0 & 4.0 & 6.0 & 2.0 & 5.0 & 7.0 & 8.0 & 9.0 \\ \end{pmatrix}\end{split}\]

2.3.5. 矩阵 (CSC) 格式

在CSC格式中,矩阵由以下参数表示:

参数

类型

大小

含义

n

(int)

矩阵中的行数(和列数)。

nnz

(int)

矩阵中非零元素的数量。

cscColPtr

(int *)

n+1

对应于数组cscRowIndcscVal中每列起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵中非零元素的数量。

cscRowInd

(int *)

nnz

对应矩阵中非零元素的行索引数组。假设该数组按列排序,且每列内按行排序。

cscVal

(S|D|C|Z)*

nnz

与矩阵中非零元素对应的值数组。假设该数组按列排序,并且每列内按行排序。

请注意,在我们的CSC格式中,稀疏矩阵默认按列主序存储,换句话说,索引数组首先按列索引排序,然后在每列内按行索引排序。此外,假定每对行和列索引仅出现一次。

例如,4x4矩阵

\[\begin{split}A = \begin{pmatrix} {1.0} & {3.0} & {0.0} & {0.0} \\ {0.0} & {4.0} & {6.0} & {0.0} \\ {2.0} & {5.0} & {7.0} & {8.0} \\ {0.0} & {0.0} & {0.0} & {9.0} \\ \end{pmatrix}\end{split}\]

表示为

\[\begin{split}{cscColPtr} = \begin{pmatrix} 0 & 2 & 5 & 7 & 9 \\ \end{pmatrix}\end{split}\]
\[\begin{split}{cscRowInd} = \begin{pmatrix} 0 & 2 & 0 & 1 & 2 & 1 & 2 & 2 & 3 \\ \end{pmatrix}\end{split}\]
\[\begin{split}{cscVal} = \begin{pmatrix} 1.0 & 2.0 & 3.0 & 4.0 & 5.0 & 6.0 & 7.0 & 8.0 & 9.0 \\ \end{pmatrix}\end{split}\]

2.4. cuSolverDN: 稠密矩阵LAPACK函数参考

本节介绍cuSolverDN的API,它提供了密集LAPACK函数的一个子集。

2.4.1. cuSolverDN 辅助函数参考

本节介绍cuSolverDN辅助函数。

2.4.1.1. cusolverDnCreate()

cusolverStatus_t
cusolverDnCreate(cusolverDnHandle_t *handle);

该函数用于初始化cuSolverDN库并创建cuSolverDN上下文的句柄。在调用任何其他cuSolverDN API函数之前必须先调用此函数。它会分配访问GPU所需的硬件资源。 此函数会分配4MB或32MB内存(针对计算能力9.0及以上的GPU),这些内存将用作首个用户自定义流上的cuBLAS工作区,在该流上会调用cusolverDnSetStream()。 对于默认流和所有其他情况,cuBLAS将管理自己的工作区。

参数

内存

输入/输出

含义

handle

host

output

指向cuSolverDN上下文句柄的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

初始化成功。

CUSOLVER_STATUS_NOT_INITIALIZED

CUDA运行时初始化失败。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

2.4.1.2. cusolverDnDestroy()

cusolverStatus_t
cusolverDnDestroy(cusolverDnHandle_t handle);

该函数释放由cuSolverDN库使用的CPU端资源。

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

关闭成功。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.4.1.3. cusolverDnSetStream()

cusolverStatus_t
cusolverDnSetStream(cusolverDnHandle_t handle, cudaStream_t streamId)

此函数设置cuSolverDN库用于执行其例程的流。

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

streamId

host

input

该库要使用的流。

返回状态

CUSOLVER_STATUS_SUCCESS

流设置成功。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.4.1.4. cusolverDnGetStream()

cusolverStatus_t
cusolverDnGetStream(cusolverDnHandle_t handle, cudaStream_t *streamId)

此函数查询将由cuSolverDN库用于执行其例程的流。

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

streamId

host

output

该流由handle使用。

返回状态

CUSOLVER_STATUS_SUCCESS

流设置成功。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.4.1.5. cusolverDnLoggerSetCallback()

cusolverStatus_t cusolverDnLoggerSetCallback(cusolverDnLoggerCallback_t callback);

此函数用于设置日志回调函数。

参数

参数

内存

输入/输出

含义

callback

input

指向回调函数的指针。参见 cusolverDnLoggerCallback_t

返回状态

CUSOLVER_STATUS_SUCCESS

如果回调函数设置成功。

查看cusolverStatus_t获取完整的有效返回代码列表。

2.4.1.6. cusolverDnLoggerSetFile()

cusolverStatus_t cusolverDnLoggerSetFile(FILE* file);

此函数用于设置日志输出文件。注意:一旦通过此函数调用注册后,除非再次调用该函数切换到不同的文件句柄,否则不得关闭提供的文件句柄。

参数

参数

内存

输入/输出

含义

file

input

指向一个已打开文件的指针。该文件应具有写入权限。

返回状态

CUSOLVER_STATUS_SUCCESS

如果日志文件设置成功。

查看cusolverStatus_t获取完整的有效返回代码列表。

2.4.1.7. cusolverDnLoggerOpenFile()

cusolverStatus_t cusolverDnLoggerOpenFile(const char* logFile);

此函数在给定路径下打开一个日志输出文件。

参数

参数

内存

输入/输出

含义

logFile

input

日志输出文件的路径。

返回状态

CUSOLVER_STATUS_SUCCESS

如果日志文件成功打开。

查看cusolverStatus_t获取完整的状态返回码列表。

2.4.1.8. cusolverDnLoggerSetLevel()

cusolverStatus_t cusolverDnLoggerSetLevel(int level);

此函数用于设置日志记录级别的值。

参数

参数

内存

输入/输出

含义

level

input

日志记录级别的值。请参阅cuSOLVERDn 日志记录

返回状态

CUSOLVER_STATUS_INVALID_VALUE

如果该值不是有效的日志级别。请参阅cuSOLVERDn Logging

CUSOLVER_STATUS_SUCCESS

如果日志级别设置成功。

查看cusolverStatus_t获取完整的有效返回代码列表。

2.4.1.9. cusolverDnLoggerSetMask()

cusolverStatus_t cusolverDnLoggerSetMask(int mask);

此函数设置日志掩码的值。

参数

参数

内存

输入/输出

含义

mask

input

日志掩码的值。请参阅cuSOLVERDn Logging

返回状态

CUSOLVER_STATUS_SUCCESS

如果日志掩码设置成功。

查看cusolverStatus_t获取完整的有效返回代码列表。

2.4.1.10. cusolverDnLoggerForceDisable()

cusolverStatus_t cusolverDnLoggerForceDisable();

此函数禁用整个运行的日志记录。

返回状态

CUSOLVER_STATUS_SUCCESS

如果日志记录已成功禁用。

查看cusolverStatus_t获取完整的有效返回代码列表。

2.4.1.11. cusolverDnSetDeterministicMode()

cusolverStatus_t
cusolverDnSetDeterministicMode(cusolverDnHandle_t handle, cusolverDeterministicMode_t mode)

此函数为handle设置所有cuSolverDN函数的确定性模式。为了提高性能,可以允许非确定性结果。受影响的函数包括cusolverDngeqrf()cusolverDnsyevd()cusolverDnsyevdx()cusolverDngesvd()(当m > n时)、cusolverDngesvdj()cusolverDnXgeqrf()cusolverDnXsyevd()cusolverDnXsyevdx()cusolverDnXgesvd()(当m > n时)、cusolverDnXgesvdr()以及cusolverDnXgesvdp()

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

mode

host

input

handle一起使用的确定性模式。

返回状态

CUSOLVER_STATUS_SUCCESS

模式设置成功。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INTERNAL_ERROR

发生了一个内部错误。

2.4.1.12. cusolverDnGetDeterministicMode()

cusolverStatus_t
cusolverDnGetDeterministicMode(cusolverDnHandle_t handle, cusolverDeterministicMode_t* mode)

此函数查询为handle设置的确定性模式。

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

mode

host

output

handle的确定性模式。

返回状态

CUSOLVER_STATUS_SUCCESS

模式设置成功。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

mode 是一个 NULL 指针。

2.4.1.13. cusolverDnCreateSyevjInfo()

cusolverStatus_t
cusolverDnCreateSyevjInfo(
    syevjInfo_t *info);

该函数创建并初始化syevjsyevjBatchedsygvj的结构为默认值。

参数

内存

输入/输出

含义

信息

host

output

指向syevj结构的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

结构初始化成功。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

2.4.1.14. cusolverDnDestroySyevjInfo()

cusolverStatus_t
cusolverDnDestroySyevjInfo(
    syevjInfo_t info);

该函数销毁并释放该结构所需的任何内存。

参数

内存

输入/输出

含义

信息

host

input

syevj的结构。

返回状态

CUSOLVER_STATUS_SUCCESS

资源已成功释放。

2.4.1.15. cusolverDnXsyevjSetTolerance()

cusolverStatus_t
cusolverDnXsyevjSetTolerance(
    syevjInfo_t info,
    double tolerance)

此函数用于配置syevj的容差。

参数

内存

输入/输出

含义

信息

host

输入/输出

指向syevj结构的指针。

tolerance

host

input

数值特征值的准确性。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

2.4.1.16. cusolverDnXsyevjSetMaxSweeps()

cusolverStatus_t
cusolverDnXsyevjSetMaxSweeps(
    syevjInfo_t info,
    int max_sweeps)

此函数用于配置syevj中的最大扫描次数。默认值为100。

参数

内存

输入/输出

含义

信息

host

输入/输出

指向syevj结构的指针。

max_sweeps

host

input

最大扫描次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

2.4.1.17. cusolverDnXsyevjSetSortEig()

cusolverStatus_t
cusolverDnXsyevjSetSortEig(
    syevjInfo_t info,
    int sort_eig)

如果sort_eig为零,则不对特征值进行排序。此函数仅适用于syevjBatchedsyevjsygvj始终按升序对特征值进行排序。默认情况下,特征值始终按升序排序。

参数

内存

输入/输出

含义

信息

host

输入/输出

指向syevj结构的指针。

sort_eig

host

input

如果 sort_eig 为零,则不排序特征值。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

2.4.1.18. cusolverDnXsyevjGetResidual()

cusolverStatus_t
cusolverDnXsyevjGetResidual(
    cusolverDnHandle_t handle,
    syevjInfo_t info,
    double *residual)

此函数报告syevjsygvj的残差。它不支持syevjBatched。如果用户在调用syevjBatched后调用此函数,将返回错误CUSOLVER_STATUS_NOT_SUPPORTED

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

信息

host

input

指向syevj结构的指针。

residual

host

output

syevj的残差。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_SUPPORTED

不支持批量版本。

2.4.1.19. cusolverDnXsyevjGetSweeps()

cusolverStatus_t
cusolverDnXsyevjGetSweeps(
    cusolverDnHandle_t handle,
    syevjInfo_t info,
    int *executed_sweeps)

此函数报告syevjsygvj已执行的扫描次数。它不支持syevjBatched。如果用户在调用syevjBatched后调用此函数,将返回错误CUSOLVER_STATUS_NOT_SUPPORTED

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

信息

host

input

指向syevj结构的指针。

executed_sweeps

host

output

已执行的扫描次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_SUPPORTED

不支持批量版本。

2.4.1.20. cusolverDnCreateGesvdjInfo()

cusolverStatus_t
cusolverDnCreateGesvdjInfo(
    gesvdjInfo_t *info);

该函数创建并初始化gesvdjgesvdjBatched的结构为默认值。

参数

内存

输入/输出

含义

信息

host

output

指向gesvdj结构的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

结构初始化成功。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

2.4.1.21. cusolverDnDestroyGesvdjInfo()

cusolverStatus_t
cusolverDnDestroyGesvdjInfo(
    gesvdjInfo_t info);

该函数销毁并释放该结构所需的任何内存。

参数

内存

输入/输出

含义

信息

host

input

gesvdj的结构。

返回状态

CUSOLVER_STATUS_SUCCESS

资源已成功释放。

2.4.1.22. cusolverDnXgesvdjSetTolerance()

cusolverStatus_t
cusolverDnXgesvdjSetTolerance(
    gesvdjInfo_t info,
    double tolerance)

此函数用于配置gesvdj的容差。

参数

内存

输入/输出

含义

信息

host

输入/输出

指向gesvdj结构的指针。

tolerance

host

input

数值奇异值的准确性。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

2.4.1.23. cusolverDnXgesvdjSetMaxSweeps()

cusolverStatus_t
cusolverDnXgesvdjSetMaxSweeps(
    gesvdjInfo_t info,
    int max_sweeps)

此函数用于配置gesvdj中的最大扫描次数。默认值为100。

参数

内存

输入/输出

含义

信息

host

输入/输出

指向gesvdj结构的指针。

max_sweeps

host

input

最大扫描次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

2.4.1.24. cusolverDnXgesvdjSetSortEig()

cusolverStatus_t
cusolverDnXgesvdjSetSortEig(
    gesvdjInfo_t info,
    int sort_svd)

如果sort_svd为零,则不对奇异值进行排序。此函数仅适用于gesvdjBatchedgesvdj始终按降序对奇异值进行排序。默认情况下,奇异值始终按降序排序。

参数

内存

输入/输出

含义

信息

host

输入/输出

指向gesvdj结构的指针。

sort_svd

host

input

如果sort_svd为零,则不对奇异值进行排序。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

2.4.1.25. cusolverDnXgesvdjGetResidual()

cusolverStatus_t
cusolverDnXgesvdjGetResidual(
    cusolverDnHandle_t handle,
    gesvdjInfo_t info,
    double *residual)

此函数报告由gesvdj返回的内部残差的Frobenius范数。请注意,这并非通过以下公式计算的精确残差的Frobenius范数:

\[{\|{S} - {U}^{H}*{A}*{V}\|}_{F}\]

此函数不支持gesvdjBatched。如果用户在调用gesvdjBatched后调用此函数,将返回错误CUSOLVER_STATUS_NOT_SUPPORTED

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

信息

host

input

指向gesvdj结构的指针。

residual

host

output

gesvdj的残差。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_SUPPORTED

不支持批量版本

2.4.1.26. cusolverDnXgesvdjGetSweeps()

cusolverStatus_t
cusolverDnXgesvdjGetSweeps(
    cusolverDnHandle_t handle,
    gesvdjInfo_t info,
    int *executed_sweeps)

此函数报告gesvdj已执行的扫描次数。它不支持gesvdjBatched。如果用户在调用gesvdjBatched后调用此函数,将返回错误CUSOLVER_STATUS_NOT_SUPPORTED

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

信息

host

input

指向gesvdj结构的指针。

executed_sweeps

host

output

已执行的扫描次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_SUPPORTED

不支持批量版本

2.4.1.27. cusolverDnIRSParamsCreate()

cusolverStatus_t
cusolverDnIRSParamsCreate(cusolverDnIRSParams_t *params);

该函数创建并初始化IRS求解器(如cusolverDnIRSXgesv()cusolverDnIRSXgels()函数)的参数结构为默认值。通过此函数创建的params结构可被同一或不同IRS求解器多次调用使用。请注意在CUDA 10.2版本中行为有所不同,每次调用IRS求解器都需要新建params结构。另请注意用户也可修改params配置后调用新的IRS实例,但需确保前次调用已完成,因为在未完成前次调用时修改配置可能会影响其执行。

参数

内存

输入/输出

含义

params

host

output

指向cusolverDnIRSParams_t Params结构的指针

返回状态

CUSOLVER_STATUS_SUCCESS

结构已成功创建并初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

2.4.1.28. cusolverDnIRSParamsDestroy()

cusolverStatus_t
cusolverDnIRSParamsDestroy(cusolverDnIRSParams_t params);

该函数销毁并释放Params结构所需的任何内存。

参数

内存

输入/输出

含义

params

host

input

cusolverDnIRSParams_t Params 结构体。

返回状态

CUSOLVER_STATUS_SUCCESS

资源已成功释放。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

CUSOLVER_STATUS_IRS_INFOS_NOT_DESTROYED

与此Params结构关联的所有Infos结构尚未全部销毁。

2.4.1.29. cusolverDnIRSParamsSetSolverPrecisions()

cusolverStatus_t
    cusolverDnIRSParamsSetSolverPrecisions(
            cusolverDnIRSParams_t params,
            cusolverPrecType_t solver_main_precision,
            cusolverPrecType_t solver_lowest_precision );

此函数为迭代精化求解器(IRS)同时设置主精度和最低精度。主精度指的是输入输出数据类型所使用的精度。最低精度则指在LU分解过程中求解器允许使用的最低计算精度。请注意,用户必须在首次调用IRS求解器前设置主精度和最低精度,因为它们不会随params结构体的创建而默认设置,这取决于输入输出数据类型和用户需求。该函数是cusolverDnIRSParamsSetSolverMainPrecision()cusolverDnIRSParamsSetSolverLowestPrecision()的封装函数。主精度/最低精度所有可能的组合如下表所示。通常最低精度决定了可实现的加速比。最低精度与主精度(即输入/输出数据类型)的性能比定义了可获取加速比的上限。更准确地说,虽然这取决于诸多因素,但对于大规模矩阵而言,矩阵-矩阵秩k积(例如当K=256且M=N=矩阵大小时的GEMM运算)的性能比决定了可能的加速比。例如,若输入输出精度为双精度实数CUSOLVER_R_64F而最低精度为CUSOLVER_R_32F,则对于大规模问题我们最多可预期2倍加速。若最低精度为CUSOLVER_R_16F,则可预期3-4倍加速。合理的策略应同时考虑右端项数量、矩阵规模以及收敛速率等因素。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体。

solver_main_precision

host

input

允许的输入/输出数据类型(例如CUSOLVER_R_FP64表示双精度实数数据)。支持的精度类型请参阅下表。

solver_lowest_precision

host

input

允许的最低计算类型(例如CUSOLVER_R_16F用于半精度计算)。支持的精度请参阅下表。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

IRS求解器支持的数据输入/输出类型及低精度选项

输入/输出数据类型(例如主精度)

最低精度支持的值

CUSOLVER_C_64F

CUSOLVER_C_64F, CUSOLVER_C_32F, CUSOLVER_C_16F, CUSOLVER_C_16BF, CUSOLVER_C_TF32

CUSOLVER_C_32F

CUSOLVER_C_32F, CUSOLVER_C_16F, CUSOLVER_C_16BF, CUSOLVER_C_TF32

CUSOLVER_R_64F

CUSOLVER_R_64F, CUSOLVER_R_32F, CUSOLVER_R_16F, CUSOLVER_R_16BF, CUSOLVER_R_TF32

CUSOLVER_R_32F

CUSOLVER_R_32F, CUSOLVER_R_16F, CUSOLVER_R_16BF, CUSOLVER_R_TF32

2.4.1.30. cusolverDnIRSParamsSetSolverMainPrecision()

cusolverStatus_t
cusolverDnIRSParamsSetSolverMainPrecision(
    cusolverDnIRSParams_t params,
    cusolverPrecType_t solver_main_precision);

此函数用于设置迭代精化求解器(IRS)的主精度。所谓主精度,指的是输入和输出数据的类型。需要注意的是,用户必须在首次调用IRS求解器之前同时设置主精度和最低精度,因为它们不会随params结构体的创建而默认设置,这取决于输入输出数据类型和用户需求。用户可以通过调用本函数或调用cusolverDnIRSParamsSetSolverPrecisions()来设置这两种精度(该函数会同时设置主精度和最低精度)。所有可能的主/最低精度组合方案都记录在上文cusolverDnIRSParamsSetSolverPrecisions()章节中的表格里。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体。

solver_main_precision

host

input

允许的输入/输出数据类型(例如CUSOLVER_R_FP64表示双精度实数数据)。支持的精度请参阅上文cusolverDnIRSParamsSetSolverPrecisions()章节中的表格。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

2.4.1.31. cusolverDnIRSParamsSetSolverLowestPrecision()

cusolverStatus_t
cusolverDnIRSParamsSetSolverLowestPrecision(
    cusolverDnIRSParams_t params,
    cusolverPrecType_t lowest_precision_type);

此函数设置迭代求精求解器将使用的最低精度。所谓最低精度,是指求解器在LU分解过程中允许采用的最低计算精度。请注意,用户必须在首次调用IRS求解器前同时设置主精度和最低精度,因为它们不会随params结构体的创建而默认设置,这取决于输入输出数据类型和用户需求。通常最低精度决定了可实现的加速比。最低精度与主精度(如输入/输出数据类型)的性能比值在某种程度上定义了可获取加速比的上限。更准确地说,这取决于诸多因素,但对于大规模矩阵而言,决定潜在加速比的关键是矩阵-矩阵秩k积(例如当K=256且M=N=矩阵大小时GEMM运算)的性能比值。举例说明,若输入输出精度为双精度实数CUSOLVER_R_64F而最低精度为CUSOLVER_R_32F,则对于大规模问题我们最多可预期2倍加速;若最低精度为CUSOLVER_R_16F,则可预期3-4倍加速。合理的策略应综合考虑右端项数量、矩阵规模以及收敛速率等因素。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体。

lowest_precision_type

host

input

允许的最低计算类型(例如CUSOLVER_R_16F用于半精度计算)。支持的精度请参阅上文cusolverDnIRSParamsSetSolverPrecisions()章节中的表格。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

参数结构未被创建。

2.4.1.32. cusolverDnIRSParamsSetRefinementSolver()

cusolverStatus_t
cusolverDnIRSParamsSetRefinementSolver(
    cusolverDnIRSParams_t params,
    cusolverIRSRefinement_t solver);

此函数设置用于迭代精化求解器函数(如cusolverDnIRSXgesv()cusolverDnIRSXgels())中的精化求解器。请注意,用户必须在首次调用IRS求解器之前设置精化算法,因为在创建参数时默认不会设置该算法。下表详细描述了可以设置的值及其含义。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_tParams 结构体

solver

host

input

IRS求解器使用的细化求解器类型,例如cusolverDnIRSXgesv()cusolverDnIRSXgels()

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

CUSOLVER_IRS_REFINE_NOT_SET

未设置求解器,该值是在创建参数结构时设置的。IRS求解器将返回错误。

CUSOLVER_IRS_REFINE_NONE

无精化求解器;IRS求解器执行因式分解后直接求解,不进行任何精化步骤。例如,如果IRS求解器是cusolverDnIRSXgesv(),这相当于不带精化步骤的Xgesv例程,且因式分解以最低精度执行。若主精度为CUSOLVER_R_64F且最低精度同样为CUSOLVER_R_64F,则等效于调用cusolverDnDgesv()

CUSOLVER_IRS_REFINE_CLASSICAL

经典迭代精化求解器。类似于LAPACK例程中使用的方法。

CUSOLVER_IRS_REFINE_GMRES

基于GMRES(广义最小残差)的迭代精化求解器。在最近的研究中,GMRES方法因其作为精化求解器的优异性能超越了经典迭代精化方法,引起了科学界的广泛关注。根据我们的实验验证,我们推荐采用此设置。

CUSOLVER_IRS_REFINE_CLASSICAL_GMRES

经典迭代精化求解器,内部使用GMRES(广义最小残差法)在每次迭代中求解修正方程。我们将经典精化迭代称为外部迭代,而将GMRES称为内部迭代。请注意,如果将内部GMRES的容差设置得非常低(例如达到机器精度),那么外部的经典精化迭代将仅执行一次迭代,因此该选项的行为将类似于CUSOLVER_IRS_REFINE_GMRES

CUSOLVER_IRS_REFINE_GMRES_GMRES

类似于CUSOLVER_IRS_REFINE_CLASSICAL_GMRES,它包含使用GMRES求解内部校正系统的经典精化过程,这里是一个基于GMRES(广义最小残差)的迭代精化求解器,它在内部使用另一个GMRES来求解预处理系统。

2.4.1.33. cusolverDnIRSParamsSetTol()

cusolverStatus_t
cusolverDnIRSParamsSetTol(
            cusolverDnIRSParams_t params,
            double val );

此函数设置细化求解器的容差。默认情况下,所有右侧项(RHS)均满足:

    RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX 其中

  • RNRM是残差的无穷范数

  • XNRM 是解的无穷范数

  • ANRM是矩阵A的无穷算子范数

  • EPS是与LAPACK LAMCH('Epsilon')匹配的输入/输出数据类型的机器精度值

  • BWDMAX,该值BWDMAX固定为1.0

用户可以使用此函数将容差调整为更低或更高的值。我们的目标是让用户拥有更多控制权,使其能够研究和控制IRS求解器的每个细节。请注意,无论输入/输出数据类型如何,容差值始终以双精度实数表示。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体。

val

host

input

设置优化容差的双精度实数值。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

2.4.1.34. cusolverDnIRSParamsSetTolInner()

cusolverStatus_t
    cusolverDnIRSParamsSetTolInner(
            cusolverDnIRSParams_t params,
            double val );

该函数用于设置当精化求解器采用两级求解器(例如CUSOLVER_IRS_REFINE_CLASSICAL_GMRES或CUSOLVER_IRS_REFINE_GMRES_GMRES情况)时内部精化求解器的容差。对于单级精化求解器(如CUSOLVER_IRS_REFINE_CLASSICAL或CUSOLVER_IRS_REFINE_GMRES)则不适用此参数。默认值设为1e-4。此函数专门设置内部求解器(例如内部GMRES)的容差。举例来说,若精化求解器设置为CUSOLVER_IRS_REFINE_CLASSICAL_GMRES,设置此容差意味着内部GMRES求解器将在经典精化求解器的每次外部迭代中收敛至该容差值。我们的目标是让用户获得更精细的控制能力,从而能够研究和调控IRS求解器的每个细节。请注意,无论输入/输出数据类型如何,容差值始终以双精度实数表示。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体。

val

host

input

双精度实数值,用于设置内部精化求解器的容差。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

2.4.1.35. cusolverDnIRSParamsSetMaxIters()

cusolverStatus_t
cusolverDnIRSParamsSetMaxIters(
    cusolverDnIRSParams_t params,
    int max_iters);

此函数设置允许的细化迭代总次数,达到该次数后求解器将停止运行。"总次数"指所有迭代之和,包括外层和内层迭代(当设置为两级细化求解器时,内层迭代才有意义)。默认值设为50次。我们的目标是让用户能够以更精细的方式掌控求解过程,从而可以研究和控制IRS求解器的每个细节。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体。

max_iters

host

input

允许优化求解器运行的最大总迭代次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

2.4.1.36. cusolverDnIRSParamsSetMaxItersInner()

cusolverStatus_t
    cusolverDnIRSParamsSetMaxItersInner(
            cusolverDnIRSParams_t params,
            cusolver_int_t maxiters_inner );

此函数用于设置内部精化求解器允许的最大迭代次数。对于单层精化求解器(如CUSOLVER_IRS_REFINE_CLASSICAL或CUSOLVER_IRS_REFINE_GMRES)则不适用该参数。内部精化求解器将在达到内部容差或MaxItersInner值后停止。默认设置为50。请注意该值不能大于MaxIters,因为MaxIters是允许的总迭代次数。注意如果用户在调用此函数后又调用了cusolverDnIRSParamsSetMaxIters,则SetMaxIters具有优先级,并将把MaxItersInner覆盖为(MaxIters, MaxItersInner)中的较小值。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体

maxiters_inner

host

input

内部精化求解器允许的最大内部迭代次数。当精化求解器为双层求解器(如CUSOLVER_IRS_REFINE_CLASSICAL_GMRES或CUSOLVER_IRS_REFINE_GMRES_GMRES)时此参数有效。该值应小于或等于MaxIters

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

CUSOLVER_STATUS_IRS_PARAMS_INVALID

如果该值大于 MaxIters

2.4.1.37. cusolverDnIRSParamsEnableFallback()

cusolverStatus_t
    cusolverDnIRSParamsEnableFallback(
            cusolverDnIRSParams_t params );

该函数在迭代精化求解器(IRS)无法收敛时启用回退到主精度的功能。换句话说,如果IRS求解器未能收敛,求解器将返回一个非收敛代码(例如niter < 0),但可以选择直接返回非收敛解(即禁用回退),或者回退(即启用回退)到主精度(即输入/输出数据的精度)并从头开始求解问题以返回正确解。这是默认行为,它将确保IRS求解器始终提供正确解。提供此函数是因为我们提供了cusolverDnIRSParamsDisableFallback允许用户禁用回退功能,而这个函数则允许用户重新启用它。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

2.4.1.38. cusolverDnIRSParamsDisableFallback()

cusolverStatus_t
    cusolverDnIRSParamsDisableFallback(
            cusolverDnIRSParams_t params );

此函数用于在迭代精化求解器(IRS)无法收敛时禁用回退到主精度的功能。换句话说,如果IRS求解器未能收敛,求解器将返回不收敛代码(例如niter < 0),但可以选择直接返回非收敛解(即禁用回退),或者回退(即启用回退)到主精度(即输入/输出数据的精度)并从头开始求解问题以返回正确解。本函数禁用回退功能,返回的解将是精化求解器在返回前所能达到的任何结果。禁用回退并不保证解是正确的。然而,如果用户希望在IRS经过一定次数的迭代后仍未收敛时继续获取较低精度的解,则需要禁用回退功能。用户可以通过调用cusolverDnIRSParamsEnableFallback重新启用该功能。

参数

内存

输入/输出

含义

params

host

输入/输出

cusolverDnIRSParams_t Params 结构体

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

2.4.1.39. cusolverDnIRSParamsGetMaxIters()

cusolverStatus_t
    cusolverDnIRSParamsGetMaxIters(
            cusolverDnIRSParams_t params,
            cusolver_int_t *maxiters );

此函数返回params结构中当前设置的最大允许迭代次数(例如,默认的MaxIters,或用户通过cusolverDnIRSParamsSetMaxIters设置的数值)。请注意,此函数返回的是params配置中的当前设置,不要与cusolverDnIRSInfosGetMaxIters混淆,后者返回的是对IRS求解器特定调用时允许的最大迭代次数。更明确地说,params结构可以用于多次调用IRS求解器。用户可以在不同调用之间更改允许的MaxIters值,而cusolverDnIRSInfosGetMaxIters中的Infos结构包含特定调用的信息,不能重复用于不同调用,因此cusolverDnIRSInfosGetMaxIters返回的是该次调用允许的MaxIters值。

参数

内存

输入/输出

含义

params

host

in

cusolverDnIRSParams_t Params 结构体。

maxiters

host

output

当前设置的最大迭代次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

Params 结构未被创建。

2.4.1.40. cusolverDnIRSInfosCreate()

cusolverStatus_t
cusolverDnIRSInfosCreate(
    cusolverDnIRSInfos_t* infos )

该函数创建并初始化Infos结构体,用于保存迭代精化求解器(IRS)调用的精化信息。这些信息包括收敛所需的总迭代次数(Niters)、外部迭代次数(当使用两级预处理器如CUSOLVER_IRS_REFINE_CLASSICAL_GMRES时有意义)、该调用允许的最大迭代次数,以及指向收敛历史残差范数矩阵的指针。Infos结构体需要在调用IRS求解器之前创建。由于Infos结构体保存的是特定求解过程的信息,因此它仅对一次IRS求解器调用有效,每次求解都需要自己的Infos结构体。

参数

内存

输入/输出

含义

信息

host

output

指向 cusolverDnIRSInfos_t Infos 结构的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

结构初始化成功。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

2.4.1.41. cusolverDnIRSInfosDestroy()

cusolverStatus_t
cusolverDnIRSInfosDestroy(
    cusolverDnIRSInfos_t infos );

该函数销毁并释放Infos结构所需的任何内存。此函数会清除求解器调用的所有信息(例如已执行的Niters次数、已执行的OuterNiters次数、残差历史记录等);因此,仅当用户完成信息使用后才应调用此函数。

参数

内存

输入/输出

含义

信息

host

输入/输出

cusolverDnIRSInfos_t Infos 结构体。

返回状态

CUSOLVER_STATUS_SUCCESS

资源已成功释放。

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

Infos 结构未被创建。

2.4.1.42. cusolverDnIRSInfosGetMaxIters()

cusolverStatus_t
    cusolverDnIRSInfosGetMaxIters(
            cusolverDnIRSInfos_t infos,
            cusolver_int_t *maxiters );

此函数返回为对应IRS求解器调用设置的最大允许迭代次数。请注意,该函数返回的是调用发生时设置的参数,不要与cusolverDnIRSParamsGetMaxIters混淆,后者返回的是params配置结构中的当前设置。更明确地说,params结构体可用于多次IRS求解器调用。用户可以在不同调用之间更改允许的MaxIters值,而cusolverDnIRSInfosGetMaxIters中的Infos结构体包含特定调用的信息且不能重复用于不同调用,因此cusolverDnIRSInfosGetMaxIters返回的是该次调用允许的MaxIters值。

参数

内存

输入/输出

含义

infos

host

in

cusolverDnIRSInfos_t Infos 结构体。

maxiters

host

output

当前设置的最大迭代次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

Infos 结构未被创建。

2.4.1.43. cusolverDnIRSInfosGetNiters()

cusolverStatus_t cusolverDnIRSInfosGetNiters(
            cusolverDnIRSInfos_t infos,
            cusolver_int_t *niters );

此函数返回IRS求解器执行的总迭代次数。如果返回值为负,表示IRS求解器未收敛,若用户未禁用回退到全精度模式,则会回退到全精度解且该解有效。有关负值niters的详细说明,请参阅相应IRS线性求解器函数如cusolverDnXgesv()cusolverDnXgels()中的描述。

参数

内存

输入/输出

含义

infos

host

in

cusolverDnIRSInfos_t Infos 结构体。

niters

host

output

IRS求解器执行的总迭代次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

Infos 结构未被创建。

2.4.1.44. cusolverDnIRSInfosGetOuterNiters()

cusolverStatus_t
    cusolverDnIRSInfosGetOuterNiters(
            cusolverDnIRSInfos_t infos,
            cusolver_int_t *outer_niters );

该函数返回IRS求解器外部精化循环执行的迭代次数。当精化解算器由单层解算器(如CUSOLVER_IRS_REFINE_CLASSICALCUSOLVER_IRS_REFINE_GMRES)组成时,其值与Niters相同。当精化解算器由双层解算器(如CUSOLVER_IRS_REFINE_CLASSICAL_GMRESCUSOLVER_IRS_REFINE_GMRES_GMRES)组成时,它表示外部循环的迭代次数。更多详情请参阅cusolverIRSRefinement_t的描述。

参数

内存

输入/输出

含义

infos

host

in

cusolverDnIRSInfos_t Infos 结构体。

outer_niters

host

output

IRS求解器外部细化循环的迭代次数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

Infos 结构未被创建。

2.4.1.45. cusolverDnIRSInfosRequestResidual()

cusolverStatus_t cusolverDnIRSInfosRequestResidual(
        cusolverDnIRSInfos_t infos );

此函数指示IRS求解器将细化阶段的收敛历史(残差范数)存储在一个矩阵中,该矩阵可通过cusolverDnIRSInfosGetResidualHistory()函数返回的指针访问。

参数

内存

输入/输出

含义

infos

host

in

cusolverDnIRSInfos_t Infos 结构体

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

Infos 结构未被创建。

2.4.1.46. cusolverDnIRSInfosGetResidualHistory()

cusolverStatus_t
cusolverDnIRSInfosGetResidualHistory(
    cusolverDnIRSInfos_t infos,
    void **residual_history );

如果用户在调用IRS函数之前调用了cusolverDnIRSInfosRequestResidual(),那么IRS求解器会将细化阶段的收敛历史(残差范数)存储在一个矩阵中,该矩阵可通过本函数返回的指针访问。残差范数的数据类型取决于输入和输出的数据类型。如果输入/输出数据类型是双精度实数或复数(CUSOLVER_R_FP64或CUSOLVER_C_FP64),则此残差将为实双精度(FP64)double类型;否则,如果输入/输出数据类型是单精度实数或复数(CUSOLVER_R_FP32或CUSOLVER_C_FP32),则此残差将为实单精度FP32float类型。

残差历史矩阵由两列组成(即使对于多右侧项情况NRHS),共有MaxIters+1行,因此矩阵尺寸为(MaxIters+1,2)。只有前OuterNiters+1行包含残差范数,其余行(例如OuterNiters+2:Maxiters+1)为无效数据。第一列中,每行"i"表示截至此外部迭代"i"发生的总迭代次数,第二列则是对应此外部迭代"i"的残差范数。因此,首行(即外部迭代"0")包含初始残差(即在精化循环开始前的残差),后续各行记录精化循环每次外部迭代获得的残差。需注意,该矩阵仅记录外部循环的历史数据。

如果优化求解器是CUSOLVER_IRS_REFINE_CLASSICALCUSOLVER_IRS_REFINE_GMRES,那么OuterNiters=Niters(Niters是执行的总迭代次数)并且有Niters+1行的范数对应于Niters次外部迭代。

如果精化求解器是CUSOLVER_IRS_REFINE_CLASSICAL_GMRESCUSOLVER_IRS_REFINE_GMRES_GMRES,那么OuterNiters <= Niters对应于外部精化循环执行的外部迭代次数。因此,会有OuterNiters+1个残差范数,其中行"i"对应于外部迭代"i",第一列指定到该步骤为止执行的总迭代次数(外部和内部),第二列对应于该步骤的残差范数。

例如,假设用户指定CUSOLVER_IRS_REFINE_CLASSICAL_GMRES作为细化求解器,并且需要3次外部迭代才能收敛,每次外部迭代分别进行4、3、3次内部迭代。这总共包含10次迭代。第0行对应细化开始前的初始残差,因此其第一列为0。第1行对应第一次外部迭代,此时总迭代次数为4(4是截至目前已执行的迭代总数),第2行为7次,第3行为10次。

总结一下,我们定义ldh=Maxiters+1作为残差矩阵的前导维度。那么residual_history[i]表示在第"i"次外部迭代时执行的总迭代次数,而residual_history[i+ldh]则对应此次外部迭代的残差范数。

参数

内存

输入/输出

含义

infos

host

in

cusolverDnIRSInfos_t Infos 结构体。

residual_history

host

output

返回一个指向收敛历史残差范数矩阵的void指针。关于残差范数数据类型与输入输出数据类型之间的关系,请参阅上述描述。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

Infos 结构未被创建

CUSOLVER_STATUS_INVALID_VALUE

调用此函数前未预先调用cusolverDnIRSInfosRequestResidual()

2.4.1.47. cusolverDnCreateParams()

cusolverStatus_t
cusolverDnCreateParams(
    cusolverDnParams_t *params);

该函数创建并初始化64-bit API的结构,将其设置为默认值。

参数

内存

输入/输出

含义

params

host

output

指向64-bit API结构的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

结构初始化成功。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

2.4.1.48. cusolverDnDestroyParams()

cusolverStatus_t
cusolverDnDestroyParams(
    cusolverDnParams_t params);

该函数销毁并释放该结构所需的任何内存。

参数

内存

输入/输出

含义

params

host

input

64-bit API的结构。

返回状态

CUSOLVER_STATUS_SUCCESS

资源已成功释放。

2.4.1.49. cusolverDnSetAdvOptions()

cusolverStatus_t
cusolverDnSetAdvOptions (
    cusolverDnParams_t params,
    cusolverDnFunction_t function,
    cusolverAlgMode_t algo   );

此函数用于配置function的算法algo,这是一个64-bit API例程。

参数

内存

输入/输出

含义

params

host

输入/输出

指向64-bit API结构的指针。

function

host

input

需要配置的例程。

algo

host

input

需要配置的算法。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_INVALID_VALUE

functionalgo 的组合错误。

2.4.2. 稠密线性求解器参考(旧版)

本节介绍cuSolverDN的线性求解器API,包括Cholesky分解、带部分主元的LU分解、QR分解以及Bunch-Kaufman(LDLT)分解。

2.4.2.1. cusolverDnpotrf()

这些辅助函数用于计算工作缓冲区的必要大小。

cusolverStatus_t
cusolverDnSpotrf_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 float *A,
                 int lda,
                 int *Lwork );

cusolverStatus_t
cusolverDnDpotrf_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 double *A,
                 int lda,
                 int *Lwork );

cusolverStatus_t
cusolverDnCpotrf_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 cuComplex *A,
                 int lda,
                 int *Lwork );

cusolverStatus_t
cusolverDnZpotrf_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 cuDoubleComplex *A,
                 int lda,
                 int *Lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSpotrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           float *A,
           int lda,
           float *Workspace,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnDpotrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           double *A,
           int lda,
           double *Workspace,
           int Lwork,
           int *devInfo );

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCpotrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           cuComplex *A,
           int lda,
           cuComplex *Workspace,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnZpotrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           cuDoubleComplex *A,
           int lda,
           cuDoubleComplex *Workspace,
           int Lwork,
           int *devInfo );

该函数计算一个埃尔米特正定矩阵的Cholesky分解。

A 是一个 \(n \times n\) 埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数 uplo 指示使用矩阵的哪一部分。该函数不会修改其他部分。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L

\[A = L*L^{H}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U

\[A = U^{H}*U\]

用户需要提供由输入参数Workspace指向的工作空间。输入参数Lwork表示工作空间的大小,该值由potrf_bufferSize()函数返回。

如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说LU的某些对角线元素不是实数。输出参数devInfo将指示A中不是正定的最小前导子矩阵。

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

potrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示矩阵A的下三角或上三角部分是否被存储;另一部分未被引用。

n

host

input

矩阵A的行数和列数。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

工作区

device

输入/输出

工作空间,大小为Lwork数组。

Lwork

host

input

Workspace的大小,由potrf_bufferSize返回。

devInfo

device

output

如果 devInfo = 0,表示Cholesky分解成功。如果 devInfo = -i,表示第 i-th 个参数有误(不包含handle)。如果 devInfo = i,表示第i阶前导子矩阵不是正定的。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n<0lda)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.2. cusolverDnPotrf() [已弃用]

[[已弃用]] 请改用cusolverDnXpotrf()。该例程将在下一个主要版本中移除。

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnPotrf_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType computeType,
    size_t *workspaceInBytes )

以下例程

cusolverStatus_t
cusolverDnPotrf(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType computeType,
    void *pBuffer,
    size_t workspaceInBytes,
    int *info )

使用通用API接口计算埃尔米特正定矩阵的Cholesky分解。

A 是一个 \(n \times n\) 埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数 uplo 指示使用矩阵的哪一部分。该函数将保持其他部分不变。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L

\[A = L*L^{H}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U

\[A = U^{H}*U\]

用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnPotrf_bufferSize()函数返回。

如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说LU的某些对角线元素不是实数。输出参数info将指示A中不是正定的最小前导子矩阵。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnPotrf仅支持默认算法。

cusolverDnPotrf支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnPotrf_bufferSizecusolverDnPotrf 的输入参数列表:

potrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

computeType

host

in

计算的数据类型。

pBuffer

device

输入/输出

工作空间。类型为void的数组,大小为workspaceInBytes字节。

workspaceInBytes

host

input

pBuffer的字节大小,由cusolverDnPotrf_bufferSize返回。

信息

device

output

如果info = 0,表示Cholesky分解成功。如果info = -i,表示第i-th个参数有误(不包含handle)。如果info = i,表示第i阶前导子矩阵不是正定的。

通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型。cusolverDnPotrf仅支持以下四种组合。

数据类型与计算类型的有效组合

DataTypeA

ComputeType

含义

CUDA_R_32F

CUDA_R_32F

SPOTRF

CUDA_R_64F

CUDA_R_64F

DPOTRF

CUDA_C_32F

CUDA_C_32F

CPOTRF

CUDA_C_64F

CUDA_C_64F

ZPOTRF

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n<0lda<max(1,n))。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.3. cusolverDnpotrs()

cusolverStatus_t
cusolverDnSpotrs(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           int nrhs,
           const float *A,
           int lda,
           float *B,
           int ldb,
           int *devInfo);

cusolverStatus_t
cusolverDnDpotrs(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           int nrhs,
           const double *A,
           int lda,
           double *B,
           int ldb,
           int *devInfo);

cusolverStatus_t
cusolverDnCpotrs(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           int nrhs,
           const cuComplex *A,
           int lda,
           cuComplex *B,
           int ldb,
           int *devInfo);

cusolverStatus_t
cusolverDnZpotrs(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           int nrhs,
           const cuDoubleComplex *A,
           int lda,
           cuDoubleComplex *B,
           int ldb,
           int *devInfo);

该函数用于求解线性方程组

\[A*X = B\]

其中 A 是一个 \(n \times n\) 的埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数 uplo 表示使用矩阵的哪一部分。该函数将保持其他部分不变。

用户需要先调用potrf来分解矩阵A。如果输入参数uploCUBLAS_FILL_MODE_LOWER,则A是下三角Cholesky因子L,对应\(A = L*L^H\)。如果输入参数uploCUBLAS_FILL_MODE_UPPER,则A是上三角Cholesky因子U,对应\(A = U^{H}*U\)

该操作是原地进行的,即矩阵 X 会覆盖矩阵 B,两者具有相同的前导维度 ldb

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

potrs的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

矩阵 XB 的列数。

A

device

input

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)A 可以是下Cholesky因子 L 或上Cholesky因子 U

lda

host

input

用于存储矩阵A的二维数组的主维度。

B

device

输入/输出

维度为 ldb * nrhs 的数组。ldb 不小于 max(1,n)。作为输入时,B 是右侧矩阵;作为输出时,B 是解矩阵。

devInfo

device

output

如果 devInfo = 0,表示Cholesky分解成功。如果 devInfo = -i,表示第 i-th 个参数有误(不包含handle参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0nrhs<0ldaldb)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.4. cusolverDnPotrs() [已弃用]

[[已弃用]] 请改用 cusolverDnXpotrs()。该例程将在下一个主要版本中移除。

cusolverStatus_t
cusolverDnPotrs(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasFillMode_t uplo,
    int64_t n,
    int64_t nrhs,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeB,
    void *B,
    int64_t ldb,
    int *info)

该函数用于求解线性方程组

\[A*X = B\]

其中 A 是一个 \(n \times n\) 埃尔米特矩阵,使用通用API接口时仅需提供下三角或上三角部分。输入参数 uplo 用于指定使用矩阵的哪一部分。函数将保持另一部分不变。

用户需要先调用cusolverDnPotrf来分解矩阵A。如果输入参数uploCUBLAS_FILL_MODE_LOWER,则A是对应\(A = L*L^H\)的下三角Cholesky因子L。如果输入参数uploCUBLAS_FILL_MODE_UPPER,则A是对应\(A = U^{H}*U\)的上三角Cholesky因子U

该操作是原地进行的,即矩阵 X 会覆盖具有相同主维度 ldb 的矩阵 B

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnPotrs仅支持默认算法。

cusolverDnPotrs支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnPotrs的输入参数列表:

potrs API(已弃用)

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

矩阵 XB 的列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

input

维度为lda * n的数组,其中lda不小于max(1,n)A可以是下Cholesky因子L或上Cholesky因子U

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeB

host

in

数组 B 的数据类型。

B

device

输入/输出

维度为ldb * nrhs的数组。ldb不小于max(1,n)。作为输入时,B是右侧矩阵;作为输出时,B是解矩阵。

信息

device

output

如果info = 0,表示Cholesky分解成功。如果info = -i,表示第i-th个参数有误(不包含handle参数)。

通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeB表示矩阵B的数据类型。cusolverDnPotrs仅支持以下四种组合。

数据类型与计算类型的有效组合

dataTypeA

dataTypeB

含义

CUDA_R_32F

CUDA_R_32F

SPOTRS

CUDA_R_64F

CUDA_R_64F

DPOTRS

CUDA_C_32F

CUDA_C_32F

CPOTRS

CUDA_C_64F

CUDA_C_64F

ZPOTRS

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0nrhs<0ldaldb)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.5. cusolverDnpotri()

这些辅助函数用于计算工作缓冲区的必要大小。

cusolverStatus_t
cusolverDnSpotri_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 float *A,
                 int lda,
                 int *Lwork );

cusolverStatus_t
cusolverDnDpotri_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 double *A,
                 int lda,
                 int *Lwork );

cusolverStatus_t
cusolverDnCpotri_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 cuComplex *A,
                 int lda,
                 int *Lwork );

cusolverStatus_t
cusolverDnZpotri_bufferSize(cusolverDnHandle_t handle,
                 cublasFillMode_t uplo,
                 int n,
                 cuDoubleComplex *A,
                 int lda,
                 int *Lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSpotri(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           float *A,
           int lda,
           float *Workspace,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnDpotri(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           double *A,
           int lda,
           double *Workspace,
           int Lwork,
           int *devInfo );

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCpotri(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           cuComplex *A,
           int lda,
           cuComplex *Workspace,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnZpotri(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           cuDoubleComplex *A,
           int lda,
           cuDoubleComplex *Workspace,
           int Lwork,
           int *devInfo );

该函数使用Cholesky分解计算正定矩阵A的逆矩阵

\[A = L*L^H = U^{H}*U\]

potrf()计算得出。

A 是一个 \(n \times n\) 矩阵,包含由 Cholesky 分解计算得到的三角因子 LU。仅下三角或上三角部分有意义,输入参数 uplo 指示矩阵的哪一部分被使用。该函数将保持另一部分不变。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并将其替换为 A 逆矩阵的下三角部分。

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并将其替换为 A 逆矩阵的上三角部分。

用户需要提供由输入参数Workspace指向的工作空间。输入参数Lwork表示工作空间的大小,由potri_bufferSize()返回。

如果逆矩阵计算失败,即LU的某个前导子矩阵为空,输出参数devInfo将指示LU中不是正定的最小前导子矩阵。

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

potri的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

工作区

device

输入/输出

工作空间,大小为Lwork的<type>数组。

Lwork

host

input

Workspace的大小,由potri_bufferSize返回。

devInfo

device

output

如果 devInfo = 0,表示逆矩阵计算成功。如果 devInfo = -i,表示第 i-th 个参数有误(不包含句柄)。如果 devInfo = i,表示第 i 阶前导子式为零。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n<0lda<max(1,n))。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.6. cusolverDngetrf()

这些辅助函数用于计算所需工作缓冲区的大小。

请访问cuSOLVER库示例 - getrf查看代码示例。

cusolverStatus_t
cusolverDnSgetrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      float *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnDgetrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      double *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnCgetrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      cuComplex *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnZgetrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      cuDoubleComplex *A,
                      int lda,
                      int *Lwork );

S和D数据类型分别表示单精度和双精度实数。

cusolverStatus_t
cusolverDnSgetrf(cusolverDnHandle_t handle,
           int m,
           int n,
           float *A,
           int lda,
           float *Workspace,
           int *devIpiv,
           int *devInfo );

cusolverStatus_t
cusolverDnDgetrf(cusolverDnHandle_t handle,
           int m,
           int n,
           double *A,
           int lda,
           double *Workspace,
           int *devIpiv,
           int *devInfo );

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCgetrf(cusolverDnHandle_t handle,
           int m,
           int n,
           cuComplex *A,
           int lda,
           cuComplex *Workspace,
           int *devIpiv,
           int *devInfo );

cusolverStatus_t
cusolverDnZgetrf(cusolverDnHandle_t handle,
           int m,
           int n,
           cuDoubleComplex *A,
           int lda,
           cuDoubleComplex *Workspace,
           int *devIpiv,
           int *devInfo );

该函数计算一个\(m \times n\)矩阵的LU分解

\[P*A = L*U\]

其中 A 是一个 \(m \times n\) 矩阵,P 是置换矩阵,L 是单位下三角矩阵,U 是上三角矩阵。

用户需要提供由输入参数Workspace指向的工作空间。输入参数Lwork表示工作空间的大小,该值由getrf_bufferSize()函数返回。

如果LU分解失败,即矩阵AU)是奇异矩阵,输出参数devInfo=i表示U(i,i) = 0

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

如果 devIpiv 为空,则不执行主元选择。因式分解形式为 A=L*U,这种形式在数值上不稳定。

无论LU分解是否成功,输出参数devIpiv都包含主元置换序列,第i行将与第devIpiv(i)行进行交换。

用户可以结合getrfgetrs来完成线性求解器。

备注:getrf 使用具有大型工作空间(大小为 m*n)的最快实现。用户可以通过 GetrfcusolverDnSetAdvOptions(params, CUSOLVERDN_GETRF, CUSOLVER_ALG_1) 选择具有最小工作空间的传统实现。

getrf API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,m)

lda

host

input

用于存储矩阵A的二维数组的主维度。

工作区

device

输入/输出

工作空间,大小为Lwork的<type>数组。

devIpiv

device

output

大小至少为min(m,n)的数组,包含主元索引。

devInfo

device

output

如果devInfo = 0,表示LU分解成功。如果devInfo = -i,表示第i-th个参数错误(不包含handle)。如果devInfo = i,表示U(i,i) = 0

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (m,n<0lda)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.7. cusolverDnGetrf() [已弃用]

[[已弃用]] 请改用cusolverDnXgetrf()。该例程将在下一个主要版本中移除。

下面的辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnGetrf_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType computeType,
    size_t *workspaceInBytes )

以下函数:

cusolverStatus_t
cusolverDnGetrf(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    int64_t *ipiv,
    cudaDataType computeType,
    void *pBuffer,
    size_t workspaceInBytes,
    int *info )

计算一个\(m \times n\)矩阵的LU分解

\[P*A = L*U\]

其中 A 是一个 \(m \times n\) 矩阵,P 是置换矩阵,L 是单位下三角矩阵,U 是上三角矩阵,通过通用API接口实现。

如果LU分解失败,即矩阵A (U)是奇异的,输出参数info=i表示U(i,i) = 0

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

如果 ipiv 为空,则不进行主元选择。因式分解结果为 A=L*U,这种分解在数值上不稳定。

无论LU分解是否成功,输出参数ipiv都包含主元交换序列,第i行会与第ipiv(i)行进行交换。

用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnGetrf_bufferSize()函数返回。

用户可以结合cusolverDnGetrfcusolverDnGetrs来完成线性求解器。

目前,cusolverDnGetrf支持两种算法。要选择旧版实现,用户需要调用cusolverDnSetAdvOptions

cusolverDnGetrf 支持的算法

CUSOLVER_ALG_0NULL

默认算法。速度最快,需要一个包含m*n元素的大型工作空间。

CUSOLVER_ALG_1

旧版实现

cusolverDnGetrf_bufferSizecusolverDnGetrf 的输入参数列表:

cusolverDnGetrf的API

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,m)

lda

host

input

用于存储矩阵A的二维数组的主维度。

ipiv

device

output

大小至少为min(m,n)的数组,包含主元索引。

computeType

host

in

计算的数据类型。

pBuffer

device

输入/输出

工作空间。类型为void的数组,大小为workspaceInBytes字节。

workspaceInBytes

host

input

pBuffer的字节大小,由cusolverDnGetrf_bufferSize返回。

信息

device

output

如果 info = 0,表示LU分解成功。如果 info = -i,表示第 i 个参数有误(不包含句柄)。如果 info = i,表示 U(i,i) = 0

通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型。cusolverDnGetrf仅支持以下四种组合。

数据类型与计算类型的有效组合

DataTypeA

ComputeType

含义

CUDA_R_32F

CUDA_R_32F

SGETRF

CUDA_R_64F

CUDA_R_64F

DGETRF

CUDA_C_32F

CUDA_C_32F

CGETRF

CUDA_C_64F

CUDA_C_64F

ZGETRF

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (m,n<0lda<max(1,m))。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.8. cusolverDngetrs()

请访问cuSOLVER库示例 - getrf查看代码示例。

cusolverStatus_t
cusolverDnSgetrs(cusolverDnHandle_t handle,
           cublasOperation_t trans,
           int n,
           int nrhs,
           const float *A,
           int lda,
           const int *devIpiv,
           float *B,
           int ldb,
           int *devInfo );

cusolverStatus_t
cusolverDnDgetrs(cusolverDnHandle_t handle,
           cublasOperation_t trans,
           int n,
           int nrhs,
           const double *A,
           int lda,
           const int *devIpiv,
           double *B,
           int ldb,
           int *devInfo );

cusolverStatus_t
cusolverDnCgetrs(cusolverDnHandle_t handle,
           cublasOperation_t trans,
           int n,
           int nrhs,
           const cuComplex *A,
           int lda,
           const int *devIpiv,
           cuComplex *B,
           int ldb,
           int *devInfo );

cusolverStatus_t
cusolverDnZgetrs(cusolverDnHandle_t handle,
           cublasOperation_t trans,
           int n,
           int nrhs,
           const cuDoubleComplex *A,
           int lda,
           const int *devIpiv,
           cuDoubleComplex *B,
           int ldb,
           int *devInfo );

该函数用于求解具有多个右侧项的线性方程组

\[op(A)*X = B\]

其中 A 是一个 \(n \times n\) 矩阵,并且已通过 getrf 进行LU分解,即A的下三角部分是 L,而 A 的上三角部分(包括对角元素)是 UB 是一个 \(n\times {nrhs}\) 的右侧矩阵。

输入参数 trans 的定义如下

image1

输入参数 devIpivgetrf 的输出结果。它包含主元索引,用于置换右侧项。

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

用户可以结合getrfgetrs来完成线性求解器。

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

trans

host

input

操作 op(A) 表示非转置或共轭转置。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

右侧的数量。

A

device

input

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

devIpiv

device

input

大小至少为n的数组,包含主元索引。

B

device

output

维度为 ldb * nrhs 的数组,其中 ldb 不小于 max(1,n)

ldb

host

input

用于存储矩阵B的二维数组的主维度。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i-th个参数错误(不包含handle)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0ldaldb)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.9. cusolverDnGetrs() [已弃用]

[[已弃用]] 请改用cusolverDnXgetrs()。该例程将在下一个主要版本中移除。

cusolverStatus_t
cusolverDnGetrs(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasOperation_t trans,
    int64_t n,
    int64_t nrhs,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    const int64_t *ipiv,
    cudaDataType dataTypeB,
    void *B,
    int64_t ldb,
    int *info )

该函数用于求解具有多个右端项的线性方程组

\[op(A)*X = B\]

其中A是一个\(n \times n\)矩阵,并且已经通过cusolverDnGetrf进行了LU分解,即A的下三角部分是L,而A的上三角部分(包括对角元素)是UB是一个n×nrhs :math:` times nrhs`的右侧矩阵,使用通用API接口。

输入参数 trans 的定义如下

image1

输入参数 ipivcusolverDnGetrf 的输出结果。它包含用于置换右侧项的枢轴索引。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

用户可以结合cusolverDnGetrfcusolverDnGetrs来完成线性求解器。

目前,cusolverDnGetrs仅支持默认算法。

cusolverDnGetrs 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnGetrs的输入参数列表:

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

trans

host

input

操作 op(A) 表示非转置或共轭转置。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

右侧的数量。

dataTypeA

host

in

数组 A 的数据类型。

A

device

input

维度为lda * n的数组,其中lda不小于max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

ipiv

device

input

大小至少为n的数组,包含主元索引。

dataTypeB

host

in

数组 B 的数据类型。

B

device

output

维度为 ldb * nrhs 的数组,其中 ldb 不小于 max(1,n)

ldb

host

input

用于存储矩阵B的二维数组的主维度。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle参数)。

通用API有两种不同类型,dataTypeA是矩阵A的数据类型,dataTypeB是矩阵B的数据类型。cusolverDnGetrs仅支持以下四种组合。

数据类型与计算类型的有效组合

DataTypeA

dataTypeB

含义

CUDA_R_32F

CUDA_R_32F

SGETRS

CUDA_R_64F

CUDA_R_64F

DGETRS

CUDA_C_32F

CUDA_C_32F

CGETRS

CUDA_C_64F

CUDA_C_64F

ZGETRS

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0ldaldb)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.10. cusolverDngesv()

这些函数模仿了LAPACK中的DSGESV和ZCGESV函数。它们通过基于LU分解Xgesv的混合精度迭代优化技术,计算具有一个或多个右侧的线性方程组的解。这些函数在功能上与全精度LU求解器(Xgesv,其中X表示Z、C、D、S)类似,但它在内部使用较低精度以提供更快的求解时间,因此得名混合精度。混合精度迭代优化技术意味着求解器以较低精度计算LU分解,然后迭代优化解以达到输入/输出数据类型的精度。对应于输入/输出数据类型的精度,而表示执行分解时内部使用的较低精度。

\[A \times X = B\]

其中 An-by-n 矩阵,XBn-by-nrhs 矩阵。

函数API的设计尽可能接近LAPACK API,以便作为快速简便的直接替代方案。参数和行为大多与LAPACK对应函数相同。以下描述这些函数及其与LAPACK的区别。gesv()函数由两种浮点精度指定,其中对应主精度(例如输入/输出数据类型精度),表示进行因式分解的内部较低精度。cusolvergesv()首先尝试以较低精度对矩阵进行因式分解,并在迭代细化过程中使用此因式分解,以获得与主精度具有相同范数后向误差的解。如果该方法未能收敛,则回退到主精度因式分解和求解(Xgesv),确保这些函数的输出始终有良好的解。如果等于,则不是混合精度过程,而是在同一主精度下进行的完整单精度因式分解、求解和细化。

迭代优化过程在以下情况下停止

ITER > ITERMAX

或者对于所有的右侧表达式我们有:

RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX

其中

  • ITER是迭代优化过程中的当前迭代次数

  • RNRM是残差的无穷范数

  • XNRM 是解的无穷范数

  • ANRM是矩阵A的无穷算子范数

  • EPS是匹配LAPACK LAMCH('Epsilon')的机器精度值

参数ITERMAX和BWDMAX分别固定为50和1.0。

该函数返回值描述了求解过程的结果。CUSOLVER_STATUS_SUCCESS表示函数成功完成,否则表示API参数存在错误或函数未成功完成。更多错误详情可通过nitersdinfoAPI参数获取。具体说明请参阅下文描述。用户需提供预先在设备内存中分配的所需工作空间,可通过调用相应的gesv_bufferSize()函数查询所需字节数。

请注意,除了LAPACK中提供的两种混合精度函数(例如dsgesvzcgesv),我们还提供了一组广泛的混合精度函数,其中包括半精度(half)、bfloat和tensorfloat作为较低精度,以及相同精度函数(主精度和最低精度相等,即等于)。下表详细说明了各接口函数将使用哪些精度。

张量浮点(TF32)是NVIDIA安培架构GPU引入的运算模式,它是迭代精化求解器中最强大的张量核心加速计算模式。该模式能够解决高性能计算(HPC)中由不同应用产生的最广泛问题,并为实数和复数系统分别提供高达4倍和5倍的加速效果。对于Volta和图灵架构GPU,建议采用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,输入输出数据精度)时,建议将主精度作为内部最低精度使用(例如FP64情况下使用cusolverDn[DD,ZZ]gesv)。

cusolver gesv() 函数支持的浮点精度组合

接口函数

主要精度

(矩阵、右侧项和解的数据类型)

允许的最低内部使用精度

cusolverDnZZgesv

cuDoubleComplex

double complex

cusolverDnZCgesv*

cuDoubleComplex

single complex

cusolverDnZKgesv

cuDoubleComplex

half complex

cusolverDnZEgesv

cuDoubleComplex

bfloat complex

cusolverDnZYgesv

cuDoubleComplex

tensorfloat complex

cusolverDnCCgesv

cuComplex

single complex

cusolverDnCKgesv

cuComplex

half complex

cusolverDnCEgesv

cuComplex

bfloat complex

cusolverDnCYgesv

cuComplex

tensorfloat complex

cusolverDnDDgesv

double

double

cusolverDnDSgesv*

double

single

cusolverDnDHgesv

double

half

cusolverDnDBgesv

double

bfloat

cusolverDnDXgesv

double

tensorfloat

cusolverDnSSgesv

float

single

cusolverDnSHgesv

float

half

cusolverDnSBgesv

float

bfloat

cusolverDnSXgesv

float

tensorfloat

* 具有LAPACK对应功能

cusolverDngesv_bufferSize() 函数将返回对应 cusolverDngesv() 函数所需的工作缓冲区大小(以字节为单位)。

cusolverStatus_t
cusolverDnZZgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZCgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZKgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZEgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZYgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCCgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCKgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCEgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCYgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    int                         *   dipiv,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDDgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    int                         *   dipiv,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDSgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    int                         *   dipiv,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDHgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    int                         *   dipiv,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDBgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    int                         *   dipiv,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDXgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    int                         *   dipiv,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSSgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    int                         *   dipiv,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSHgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    int                         *   dipiv,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSBgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    int                         *   dipiv,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSXgesv_bufferSize(
    cusolverHandle_t                handle,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    int                         *   dipiv,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);
cusolverDngesv_bufferSize()函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDN库上下文的句柄。

n

host

input

方阵A的行数和列数。应为非负数。

nrhs

host

input

需要求解的右侧项数量。应为非负数。

dA

device

None

矩阵 A 的大小为 n-by-n。可以是 NULL

ldda

host

input

用于存储矩阵A的二维数组的主维度。lda >= n

dipiv

device

None

枢轴序列。未使用,可以为NULL

dB

device

None

右侧项集合 B 的大小为 n-by-nrhs。可以是 NULL

lddb

host

input

用于存储右侧矩阵的二维数组的主维度 Bldb >= n

dX

device

None

大小为n-by-nrhs的解向量集X。可以是NULL

lddx

host

input

用于存储解向量矩阵的二维数组的主维度 Xldx >= n

dwork

device

none

指向设备工作区的指针。未使用,可以为NULL

lwork_bytes

host

output

指向一个变量的指针,该变量将存储临时工作空间所需的字节大小。不能为NULL。

cusolverStatus_t cusolverDnZZgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZCgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZKgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZEgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZYgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCCgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCKgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCEgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCYgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        int                 *   dipiv,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDDgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        int                 *   dipiv,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDSgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        int                 *   dipiv,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDHgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        int                 *   dipiv,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDBgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        int                 *   dipiv,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDXgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        int                 *   dipiv,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSSgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        int                 *   dipiv,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSHgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        int                 *   dipiv,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSBgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        int                 *   dipiv,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSXgesv(
        cusolverDnHandle_t      handle,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        int                 *   dipiv,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);
cusolverDngesv()函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDN库上下文的句柄。

n

host

input

方阵A的行数和列数。应为非负数。

nrhs

host

input

需要求解的右侧项数量。应为非负数。

dA

device

输入/输出

矩阵 A 的大小为 n-by-n。不能为 NULL。返回时 - 如果迭代精化过程收敛则保持不变。如果未收敛 - 将包含主精度 下的矩阵A的分解结果 (A = P * L * U,其中P - 由向量ipiv定义的置换矩阵,L和U - 下三角和上三角矩阵)。

ldda

host

input

用于存储矩阵A的二维数组的主维度。lda >= n

dipiv

device

output

定义因式分解置换的向量 - 行i与行ipiv[i]进行了交换

dB

device

input

右侧项集合 B 的大小为 n-by-nrhs。不能为 NULL

lddb

host

input

用于存储右侧矩阵的二维数组的主维度 Bldb >= n

dX

device

output

大小为n-by-nrhs的解向量集X。不能为NULL

lddx

host

input

用于存储解向量矩阵的二维数组的主维度Xldx >= n

dWorkspace

device

input

指向设备内存中已分配工作空间的指针,大小为 lwork_bytes

lwork_bytes

host

input

分配的设备工作空间大小。至少应为cusolverDngesv_bufferSize()函数返回的值。

niters

host

output

如果 iter

  • <0 : 迭代优化失败,已执行主精度(输入/输出精度)分解

  • -1 : 考虑到机器参数、n、nrhs,先验判断不值得使用较低精度进行计算

  • -2 : 从主精度移动到较低精度时条目溢出

  • -3 : 分解过程中失败

  • -5 : 计算过程中发生溢出

  • -50: 求解器在达到最大允许迭代次数后停止了迭代优化

  • >0 : iter 是求解器为达到收敛标准所执行的迭代次数

dinfo

device

output

IRS求解器在返回时的状态。如果为0 - 求解成功。如果dinfo = -i,则第i个参数无效。如果dinfo = i,则表示在主精度下计算的U(i,i)恰好为零。分解已完成,但因子U恰好是奇异的,因此无法计算解。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数,例如:

  • n<0

  • lda

  • ldb

  • ldx

CUSOLVER_STATUS_ARCH_MISMATCH

IRS求解器支持计算能力7.0及以上版本。最低精度选项CUSOLVER_[CR]_16BF和CUSOLVER_[CR]_TF32仅在计算能力8.0及以上版本中可用。

CUSOLVER_STATUS_INVALID_WORKSPACE

lwork_bytes 小于所需的工作空间。

CUSOLVER_STATUS_IRS_OUT_OF_RANGE

与迭代次数 niters 小于0相关的数值错误,详情请参阅 niters 描述。

CUSOLVER_STATUS_INTERNAL_ERROR

发生内部错误,请检查dinfoniters参数以获取更多详细信息。

2.4.2.11. cusolverDnIRSXgesv()

该函数旨在实现与cusolverDngesv()相同的功能,但封装在一个更通用和专业的接口中,使用户能够更好地控制参数设置,并提供更详细的输出信息。cusolverDnIRSXgesv()允许对求解器参数进行额外控制,例如设置:

  • 求解器的主要精度(输入/输出精度)

  • 求解器内部使用的最低精度

  • 优化求解器类型

  • 精炼阶段允许的最大迭代次数

  • 优化求解器的容差

  • 回退到主精度

  • 以及更多

通过配置参数结构体gesv_irs_params及其辅助函数。关于可设置配置项及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSParamsxxxx()开头的函数。此外,cusolverDnIRSXgesv()还提供了诸如每次迭代的收敛历史(例如残差范数)和收敛所需迭代次数等额外输出信息。关于可获取信息及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSInfosxxxx()开头的函数。

该函数返回值描述了求解过程的结果。CUSOLVER_STATUS_SUCCESS表示函数成功完成,否则表示API参数有误、params/infos结构配置不正确或函数未成功完成。通过检查nitersdinfoAPI参数可获取更多错误详情(详见下文描述)。用户需为cusolverDnIRSXgesv()函数提供设备上分配的所需工作空间,可通过调用对应的cusolverDnIRSXgesv_bufferSize()函数查询所需字节数。请注意,若用户希望通过params结构设置特定配置,应在调用cusolverDnIRSXgesv_bufferSize()获取所需工作空间大小之前完成设置。

张量浮点(TF32)是NVIDIA安培架构GPU引入的,它是迭代精化求解器中最强大的张量核心加速计算模式。该技术能够解决高性能计算(HPC)中来自不同应用的最广泛问题,对实数和复数系统分别提供高达4倍和5倍的加速。对于Volta和图灵架构GPU,建议使用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,输入输出数据精度)时,建议使用主精度作为内部最低精度。

下表提供了输入/输出数据类型对应的最低精度所有可能组合值。请注意,如果最低精度与输入/输出数据类型匹配,则将使用主精度分解。

IRS求解器支持的数据输入/输出类型及低精度选项

输入/输出数据类型(例如主精度)

最低精度支持的值

CUSOLVER_C_64F

CUSOLVER_C_64F, CUSOLVER_C_32F, CUSOLVER_C_16F, CUSOLVER_C_16BF, CUSOLVER_C_TF32

CUSOLVER_C_32F

CUSOLVER_C_32F, CUSOLVER_C_16F, CUSOLVER_C_16BF, CUSOLVER_C_TF32

CUSOLVER_R_64F

CUSOLVER_R_64F, CUSOLVER_R_32F, CUSOLVER_R_16F, CUSOLVER_R_16BF, CUSOLVER_R_TF32

CUSOLVER_R_32F

CUSOLVER_R_32F, CUSOLVER_R_16F, CUSOLVER_R_16BF, CUSOLVER_R_TF32

cusolverDnIRSXgesv_bufferSize() 函数返回在给定 gesv_irs_params 配置下,对应 cusolverDnXgesv() 调用所需的工作缓冲区大小(以字节为单位)。

cusolverStatus_t
cusolverDnIRSXgesv_bufferSize(
        cusolverDnHandle_t          handle,
        cusolverDnIRSParams_t       gesv_irs_params,
        cusolver_int_t              n,
        cusolver_int_t              nrhs,
        size_t                  *   lwork_bytes);
cusolverDnIRSXgesv_bufferSize() 函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDn库上下文的句柄。

params

host

input

Xgesv 配置参数

n

host

input

方阵A的行数和列数。应为非负数。

nrhs

host

input

需要求解的右侧向量数量。应为非负数。请注意,如果选择的IRS细化求解器为CUSOLVER_IRS_REFINE_GMRES、CUSOLVER_IRS_REFINE_GMRES_GMRES或CUSOLVER_IRS_REFINE_CLASSICAL_GMRES时,nrhs限制为1。

lwork_bytes

host

out

指向一个变量的指针,在调用cusolverDnIRSXgesv_bufferSize后,将在此存储所需工作空间的大小(以字节为单位)。不能为NULL。

cusolverStatus_t cusolverDnIRSXgesv(
        cusolverDnHandle_t          handle,
        cusolverDnIRSParams_t       gesv_irs_params,
        cusolverDnIRSInfos_t        gesv_irs_infos,
        int                         n,
        int                         nrhs,
        void                    *   dA,
        int                         ldda,
        void                    *   dB,
        int                         lddb,
        void                    *   dX,
        int                         lddx,
        void                    *   dWorkspace,
        size_t                      lwork_bytes,
        int                     *   dinfo);
cusolverDnIRSXgesv() 函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDn库上下文的句柄。

gesv_irs_params

host

input

配置参数结构体,可用于对任何IRS求解器的一次或多次调用

gesv_irs_infos

host

输入/输出

信息结构,用于存储特定求解的相关信息。gesv_irs_infos结构对应特定的调用。因此不同的调用需要不同的gesv_irs_infos结构,否则会被覆盖。

n

host

input

方阵A的行数和列数。应为非负数。

nrhs

host

input

需要求解的右端项数量。应为非负数。请注意,如果选择的IRS细化求解器为CUSOLVER_IRS_REFINE_GMRES、CUSOLVER_IRS_REFINE_GMRES_GMRES或CUSOLVER_IRS_REFINE_CLASSICAL_GMRES,则nrhs限制为1。

dA

device

输入/输出

矩阵 A 的大小为 n-by-n。不能为 NULL。返回时 - 如果迭代精化求解器设置为 CUSOLVER_IRS_REFINE_NONE 且最低精度等于主精度(输入/输出数据类型),或者迭代精化求解器未收敛且启用了回退到主精度(默认启用回退),则将在主精度中包含矩阵 A 的分解(A = P * L * U,其中 P 是由向量 ipiv 定义的置换矩阵,L 和 U 是下三角和上三角矩阵);否则保持不变。

ldda

host

input

用于存储矩阵A的二维数组的主维度。lda >= n

dB

device

input

右侧项集合 B 的大小为 n-by-nrhs。不能为 NULL

lddb

host

input

用于存储右侧矩阵的二维数组的主维度 Bldb >= n

dX

device

output

大小为n-by-nrhs的解向量集X。不能为NULL

lddx

host

input

用于存储解向量矩阵的二维数组的主维度 Xldx >= n

dWorkspace

device

input

指向设备内存中已分配工作空间的指针,大小为lwork_bytes。

lwork_bytes

host

input

分配的设备工作空间大小。应至少为cusolverDnIRSXgesv_bufferSize()函数返回的值

niters

host

output

如果迭代是

  • <0 : 迭代优化失败,如果启用了回退机制,则已执行主精度(输入/输出精度)分解。

  • -1 : 考虑到机器参数、n、nrhs,先验判断不值得使用较低精度进行计算

  • -2 : 从主精度移动到较低精度时条目溢出

  • -3 : 分解过程中失败

  • -5 : 计算过程中发生溢出

  • -maxiter: 求解器在达到最大允许迭代次数后停止迭代优化。

  • >0 : iter 是求解器为达到收敛标准所执行的迭代次数

dinfo

device

output

IRS求解器在返回时的状态。如果为0 - 求解成功。如果dinfo = -i,则第i个参数无效。如果dinfo = i,则表示在主精度下计算的U(i,i)恰好为零。分解已完成,但因子U恰好是奇异的,因此无法计算解。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数,例如:

  • n<0

  • lda

  • ldb

  • ldx

CUSOLVER_STATUS_ARCH_MISMATCH

IRS求解器支持计算能力7.0及以上版本。最低精度选项CUSOLVER_[CR]_16BF和CUSOLVER_[CR]_TF32仅在计算能力8.0及以上版本中可用。

CUSOLVER_STATUS_INVALID_WORKSPACE

lwork_bytes 小于所需的工作空间。如果用户调用了 cusolverDnIRSXgesv_bufferSize() 函数后更改了某些配置设置(例如最低精度),则可能发生这种情况。

CUSOLVER_STATUS_IRS_OUT_OF_RANGE

与 niters <0 相关的数值错误,更多详情请参阅 niters 描述。

CUSOLVER_STATUS_INTERNAL_ERROR

发生内部错误,请检查dinfoniters参数以获取更多详细信息。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

配置参数 gesv_irs_params 结构未被创建。

CUSOLVER_STATUS_IRS_PARAMS_INVALID

gesv_irs_params 结构体中的一个配置参数无效。

CUSOLVER_STATUS_IRS_PARAMS_INVALID_PREC

gesv_irs_params 结构体中的主要和/或最低精度配置参数无效,请检查上表以获取支持的组合。

CUSOLVER_STATUS_IRS_PARAMS_INVALID_MAXITER

gesv_irs_params 结构中的 maxiter 配置参数无效。

CUSOLVER_STATUS_IRS_PARAMS_INVALID_REFINE

gesv_irs_params 结构体中的 refinement solver 配置参数无效。

CUSOLVER_STATUS_IRS_NOT_SUPPORTED

gesv_irs_params 结构中有一个配置参数不受支持。例如,如果 nrhs >1,并且将精化求解器设置为 CUSOLVER_IRS_REFINE_GMRES

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

信息结构 gesv_irs_infos 未被创建。

CUSOLVER_STATUS_ALLOC_FAILED

CPU内存分配失败,很可能是在存储残差范数的残差数组分配期间发生的。

2.4.2.12. cusolverDngeqrf()

这些辅助函数用于计算所需工作缓冲区的大小。

cusolverStatus_t
cusolverDnSgeqrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      float *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnDgeqrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      double *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnCgeqrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      cuComplex *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnZgeqrf_bufferSize(cusolverDnHandle_t handle,
                      int m,
                      int n,
                      cuDoubleComplex *A,
                      int lda,
                      int *Lwork );

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSgeqrf(cusolverDnHandle_t handle,
           int m,
           int n,
           float *A,
           int lda,
           float *TAU,
           float *Workspace,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnDgeqrf(cusolverDnHandle_t handle,
           int m,
           int n,
           double *A,
           int lda,
           double *TAU,
           double *Workspace,
           int Lwork,
           int *devInfo );

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCgeqrf(cusolverDnHandle_t handle,
           int m,
           int n,
           cuComplex *A,
           int lda,
           cuComplex *TAU,
           cuComplex *Workspace,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnZgeqrf(cusolverDnHandle_t handle,
           int m,
           int n,
           cuDoubleComplex *A,
           int lda,
           cuDoubleComplex *TAU,
           cuDoubleComplex *Workspace,
           int Lwork,
           int *devInfo );

该函数计算一个\(m \times n\)矩阵的QR分解

\[A = Q*R\]

其中 A 是一个 \(m \times n\) 矩阵,Q 是一个 \(m \times n\) 矩阵,而 R 是一个 \(n \times n\) 上三角矩阵。

用户需要提供一个工作空间,该空间由输入参数Workspace指定。输入参数Lwork表示工作空间的大小,该值由geqrf_bufferSize()函数返回。

矩阵 R 会被覆盖写入 A 的上三角部分,包括对角线元素。

矩阵 Q 不会显式生成,而是将一系列豪斯霍尔德向量存储在 A 的下三角部分。假设豪斯霍尔德向量的前导非零元素为1,因此输出参数 TAU 包含缩放因子 τ。如果 v 是原始豪斯霍尔德向量,q 是对应于 τ 的新豪斯霍尔德向量,满足以下关系

\[I - 2*v*v^{H} = I - \tau*q*q^{H}\]

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

geqrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

A

device

输入/输出

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,m)

lda

host

input

用于存储矩阵A的二维数组的主维度。

TAU

device

output

至少为 min(m,n) 维的数组。

工作区

device

输入/输出

工作空间,大小为Lwork的<type>数组。

Lwork

host

input

工作数组 Workspace 的大小。

devInfo

device

output

如果 devInfo = 0,表示LU分解成功。如果 devInfo = -i,表示第 i-th 个参数有误(不包含handle参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (m,n<0lda<max(1,m))。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.13. cusolverDnGeqrf() [已弃用]

[[已弃用]] 请改用cusolverDnXgeqrf()。该例程将在下一个主要版本中移除。

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnGeqrf_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeTau,
    const void *tau,
    cudaDataType computeType,
    size_t *workspaceInBytes )

以下例程:

cusolverStatus_t
cusolverDnGeqrf(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeTau,
    void *tau,
    cudaDataType computeType,
    void *pBuffer,
    size_t workspaceInBytes,
    int *info )

计算一个\(m \times n\)矩阵的QR分解

\[A = Q*R\]

其中 A 是一个 \(m \times n\) 矩阵,Q 是一个 \(m \times n\) 矩阵,而 R 是一个 \(n \times n\) 上三角矩阵,使用的是通用API接口。

用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnGeqrf_bufferSize()返回。

矩阵 R 会被覆盖写入 A 的上三角部分,包括对角线元素。

矩阵 Q 不会显式生成,而是将一系列豪斯霍尔德向量存储在 A 的下三角部分。假设豪斯霍尔德向量的首非零元素为1,因此输出参数 TAU 包含缩放因子 τ。如果 v 是原始豪斯霍尔德向量,q 是对应于 τ 的新豪斯霍尔德向量,满足以下关系:

\[I - 2*v*v^{H} = I - \tau*q*q^{H}\]

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnGeqrf仅支持默认算法。

cusolverDnGeqrf 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnGeqrf_bufferSizecusolverDnGeqrf 的输入参数列表:

geqrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,m)

lda

host

input

用于存储矩阵A的二维数组的主维度。

TAU

device

output

维度至少为min(m,n)的数组。

computeType

host

in

计算的数据类型。

pBuffer

device

输入/输出

工作空间。类型为void的数组,大小为workspaceInBytes字节。

workspaceInBytes

host

input

工作数组 pBuffer 的字节大小。

信息

device

output

如果 info = 0,表示LU分解成功。如果 info = -i,表示第 i-th 个参数有误(不包含handle)。

通用API有两种不同类型,dataTypeA表示矩阵A和数组tau的数据类型,而computeType表示运算的计算类型。cusolverDnGeqrf仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

计算类型

含义

CUDA_R_32F

CUDA_R_32F

SGEQRF

CUDA_R_64F

CUDA_R_64F

DGEQRF

CUDA_C_32F

CUDA_C_32F

CGEQRF

CUDA_C_64F

CUDA_C_64F

ZGEQRF

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (m,n<0lda<max(1,m))。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.14. cusolverDngels()

这些函数使用基于QR分解Xgels的混合精度迭代优化技术,计算具有单个或多个右侧的线性方程组的解。这些函数在功能上与全精度LAPACK QR(最小二乘)求解器(Xgels,其中X表示Z、C、D、S)类似,但其内部使用较低精度以提供更快的求解时间,因此得名混合精度。混合精度迭代优化技术意味着求解器以较低精度计算QR分解,然后通过迭代优化解以达到输入/输出数据类型的精度要求。对应输入/输出数据类型的精度,而表示执行分解时内部使用的较低精度。

\[A \times X = B\]

其中 Am-by-n 矩阵,Xn-by-nrhs 矩阵,Bm-by-nrhs 矩阵。

函数API的设计尽可能接近LAPACK API,以便作为快速简便的直接替代方案。以下是对这些函数的描述。gels()函数由两种浮点精度指定,对应主精度(例如输入/输出数据类型精度),表示进行因子分解的内部较低精度。cusolvergels()首先尝试以较低精度对矩阵进行因子分解,并在迭代细化过程中使用此因子分解,以获得与主精度具有相同范数后向误差的解。如果该方法未能收敛,则回退到主精度因子分解和求解(Xgels),从而确保这些函数的输出始终有良好的解。如果等于,则这不是混合精度过程,而是在同一主精度下的完整单精度因子分解、求解和细化。

迭代优化过程在以下情况下停止:

ITER > ITERMAX

或者对于所有的右侧表达式我们有:

RNRM < SQRT(N)*XNRM*ANRM*EPS*BWDMAX

其中

  • ITER是迭代优化过程中的当前迭代次数

  • RNRM是残差的无穷范数

  • XNRM 是解的无穷范数

  • ANRM是矩阵A的无穷算子范数

  • EPS是匹配LAPACKLAMCH('Epsilon')的机器精度

ITERMAX和BWDMAX的值分别固定为50和1.0。

该函数返回值描述了求解过程的结果。CUSOLVER_STATUS_SUCCESS表示函数成功完成,否则表示API参数存在错误或函数未能成功完成。更多错误详情可通过nitersdinfo这两个API参数获取,具体说明请参阅下文描述。用户需要提供预先在设备内存中分配的所需工作空间,可通过调用相应的gels_bufferSize()函数查询所需字节数。

我们提供了大量混合精度函数,其中包含半精度(half)、bfloat和tensorfloat作为较低精度,以及相同精度函数(例如主精度和最低精度相等时,等于)。下表指定了各接口函数将使用的精度:

张量浮点(TF32)是NVIDIA安培架构GPU引入的运算模式,它是迭代精化求解器中最强大的张量核心加速计算模式。该模式能够解决高性能计算(HPC)中由不同应用产生的最广泛问题,对实数和复数系统分别提供高达4倍和5倍的加速效果。对于Volta和图灵架构GPU,建议采用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,即输入输出数据精度)时,建议将主精度作为内部最低精度使用(例如FP64情况下使用cusolverDn[DD,ZZ]gels)。

cusolver gels() 函数支持的浮点精度组合

接口函数

主要精度(矩阵、右侧项和解的数据类型)

内部允许使用的最低精度

cusolverDnZZgels

cuDoubleComplex

double complex

cusolverDnZCgels

cuDoubleComplex

single complex

cusolverDnZKgels

cuDoubleComplex

half complex

cusolverDnZEgels

cuDoubleComplex

bfloat complex

cusolverDnZYgels

cuDoubleComplex

tensorfloat complex

cusolverDnCCgels

cuComplex

single complex

cusolverDnCKgels

cuComplex

half complex

cusolverDnCEgels

cuComplex

bfloat complex

cusolverDnCYgels

cuComplex

tensorfloat complex

cusolverDnDDgels

double

double

cusolverDnDSgels

double

single

cusolverDnDHgels

double

half

cusolverDnDBgels

double

bfloat

cusolverDnDXgels

double

tensorfloat

cusolverDnSSgels

float

single

cusolverDnSHgels

float

half

cusolverDnSBgels

float

bfloat

cusolverDnSXgels

float

tensorfloat

cusolverDngels_bufferSize() 函数将返回对应 cusolverDngels() 函数所需的以字节为单位的工作缓冲区大小。

cusolverStatus_t
cusolverDnZZgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZCgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZKgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZEgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnZYgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuDoubleComplex             *   dA,
    int                             ldda,
    cuDoubleComplex             *   dB,
    int                             lddb,
    cuDoubleComplex             *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCCgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCKgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCEgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnCYgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    cuComplex                   *   dA,
    int                             ldda,
    cuComplex                   *   dB,
    int                             lddb,
    cuComplex                   *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDDgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDSgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDHgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDBgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnDXgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    double                      *   dA,
    int                             ldda,
    double                      *   dB,
    int                             lddb,
    double                      *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSSgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSHgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSBgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);

cusolverStatus_t
cusolverDnSXgels_bufferSize(
    cusolverHandle_t                handle,
    int                             m,
    int                             n,
    int                             nrhs,
    float                       *   dA,
    int                             ldda,
    float                       *   dB,
    int                             lddb,
    float                       *   dX,
    int                             lddx,
    void                        *   dwork,
    size_t                      *   lwork_bytes);
cusolverDngels_bufferSize()函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDN库上下文的句柄。

m

host

input

矩阵 A 的行数。应为非负数且 n<=m

n

host

input

矩阵 A 的列数。应为非负数且 n<=m。

nrhs

host

input

需要求解的右侧项数量。应为非负数。

dA

device

None

矩阵 A 的大小为 m-by-n。可以是 NULL

ldda

host

input

用于存储矩阵A的二维数组的主维度。ldda >= m

dB

device

None

右侧项集合 B 的大小为 m-by-nrhs。可以是 NULL

lddb

host

input

用于存储右侧矩阵的二维数组的主维度 Blddb >= max(1,m)

dX

device

None

大小为n-by-nrhs的解向量集X。可以是NULL

lddx

host

input

用于存储解向量矩阵的二维数组的主维度 Xlddx >= max(1,n)

dwork

device

none

指向设备工作区的指针。未使用,可以为NULL

lwork_bytes

host

output

指向一个变量的指针,该变量将存储临时工作空间所需的字节大小。不能为NULL。

cusolverStatus_t cusolverDnZZgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZCgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZKgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZEgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnZYgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuDoubleComplex     *   dA,
        int                     ldda,
        cuDoubleComplex     *   dB,
        int                     lddb,
        cuDoubleComplex     *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCCgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCKgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCEgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnCYgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        cuComplex           *   dA,
        int                     ldda,
        cuComplex           *   dB,
        int                     lddb,
        cuComplex           *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDDgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDSgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDHgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDBgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnDXgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        double              *   dA,
        int                     ldda,
        double              *   dB,
        int                     lddb,
        double              *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSSgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSHgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSBgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);

cusolverStatus_t cusolverDnSXgels(
        cusolverDnHandle_t      handle,
        int                     m,
        int                     n,
        int                     nrhs,
        float               *   dA,
        int                     ldda,
        float               *   dB,
        int                     lddb,
        float               *   dX,
        int                     lddx,
        void                *   dWorkspace,
        size_t                  lwork_bytes,
        int                 *   niter,
        int                 *   dinfo);
cusolverDngels()函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDN库上下文的句柄。

m

host

input

矩阵 A 的行数。应为非负数且 n<=m

n

host

input

矩阵A的列数。应为非负数且n<=m。

nrhs

host

input

需要求解的右侧项数量。应为非负数。

dA

device

输入/输出

矩阵 A 的大小为 m-by-n。不能为 NULL。返回时:若最低精度不等于主精度且迭代精化求解器收敛,则保持不变;否则返回无效数据。

ldda

host

input

用于存储矩阵A的二维数组的主维度。ldda >= m

dB

device

input

右侧矩阵集合 B,大小为 m-by-nrhs。不能为 NULL

lddb

host

input

用于存储右侧矩阵的二维数组的主维度 Blddb >= max(1,m)

dX

device

output

大小为n-by-nrhs的解向量集X。不能为NULL

lddx

host

input

用于存储解向量矩阵的二维数组的主维度 Xlddx >= max(1,n)

dWorkspace

device

input

指向设备内存中已分配工作空间的指针,大小为lwork_bytes。

lwork_bytes

host

input

分配的设备工作空间大小。应至少为cusolverDngels_bufferSize()函数返回的值

niters

host

output

如果迭代是

  • <0 : 迭代优化失败,已执行主精度(输入/输出精度)分解。

  • -1 : 考虑到机器参数、n、nrhs,先验上不值得使用较低精度进行计算

  • -2 : 从主精度移动到较低精度时条目溢出

  • -3 : 分解过程中失败

  • -5 : 计算过程中发生溢出

  • -50: 求解器在达到最大允许迭代次数后停止了迭代优化。

  • >0 : iter 是求解器为达到收敛标准所执行的迭代次数

dinfo

device

output

IRS求解器在返回时的状态。如果为0 - 求解成功。如果dinfo = -i则表示第i个参数无效。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数,例如:

  • n<0

  • ldda小于max(1,m)

  • lddb

  • lddx

CUSOLVER_STATUS_ARCH_MISMATCH

IRS求解器支持计算能力7.0及以上版本。最低精度选项CUSOLVER_[CR]_16BF和CUSOLVER_[CR]_TF32仅在计算能力8.0及以上版本中可用。

CUSOLVER_STATUS_INVALID_WORKSPACE

lwork_bytes 小于所需的工作空间。

CUSOLVER_STATUS_IRS_OUT_OF_RANGE

与 niters <0 相关的数值错误,更多详情请参阅 niters 描述。

CUSOLVER_STATUS_INTERNAL_ERROR

发生内部错误;请检查dinfoniters参数以获取更多详细信息。

2.4.2.15. cusolverDnIRSXgels()

此函数旨在实现与cusolverDngels()相同的功能,但封装在一个更通用和专业的接口中,使用户能够更好地控制参数设置,并提供更详细的输出信息。cusolverDnIRSXgels()允许对求解器参数进行额外控制,例如设置:

  • 求解器的主要精度(输入/输出精度),

  • 求解器内部使用的最低精度,

  • 优化求解器类型

  • 精炼阶段允许的最大迭代次数

  • 优化求解器的容差

  • 回退到主精度

  • 以及其他

通过配置参数结构体gels_irs_params及其辅助函数。关于可设置配置项及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSParamsxxxx()开头的函数。此外,cusolverDnIRSXgels()还提供了额外的输出信息,例如每次迭代的收敛历史(如残差范数)和收敛所需的迭代次数。关于可获取信息及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSInfosxxxx()开头的函数。

该函数返回值描述了求解过程的结果。CUSOLVER_STATUS_SUCCESS表示函数成功完成,否则表示API参数不正确、params/infos结构配置错误或函数未成功完成。通过检查nitersdinfoAPI参数可以获取更多错误详情。具体描述请参阅下文。用户需要为cusolverDnIRSXgels()函数提供设备上分配的所需工作空间。可通过调用相应的cusolverDnIRSXgels_bufferSize()函数查询所需字节数。请注意,如果用户希望通过params结构设置特定配置,应在调用cusolverDnIRSXgels_bufferSize()获取所需工作空间大小之前进行设置。

下表提供了输入/输出数据类型对应的最低精度所有可能的组合值。请注意,如果最低精度与输入/输出数据类型匹配,则将使用主精度分解方法。

张量浮点(TF32)是NVIDIA安培架构GPU引入的运算模式,它是迭代精化求解器中最强大的张量核心加速计算模式。它能够解决高性能计算(HPC)中由不同应用产生的最广泛问题,并为实数和复数系统分别提供高达4倍和5倍的加速。对于Volta和图灵架构GPU,建议使用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,输入输出数据精度)时,建议使用主精度作为内部最低精度。

IRS求解器支持的数据输入/输出类型及低精度选项

输入/输出数据类型(例如主精度)

最低精度支持的值

CUSOLVER_C_64F

CUSOLVER_C_64F, CUSOLVER_C_32F, CUSOLVER_C_16F, CUSOLVER_C_16BF, CUSOLVER_C_TF32

CUSOLVER_C_32F

CUSOLVER_C_32F, CUSOLVER_C_16F, CUSOLVER_C_16BF, CUSOLVER_C_TF32

CUSOLVER_R_64F

CUSOLVER_R_64F, CUSOLVER_R_32F, CUSOLVER_R_16F, CUSOLVER_R_16BF, CUSOLVER_R_TF32

CUSOLVER_R_32F

CUSOLVER_R_32F, CUSOLVER_R_16F, CUSOLVER_R_16BF, CUSOLVER_R_TF32

cusolverDnIRSXgels_bufferSize() 函数返回对应 cusolverDnXgels() 调用所需的以字节为单位的工作缓冲区大小,该调用使用给定的 gels_irs_params 配置。

cusolverStatus_t
cusolverDnIRSXgels_bufferSize(
        cusolverDnHandle_t          handle,
        cusolverDnIRSParams_t       gels_irs_params,
        cusolver_int_t              m,
        cusolver_int_t              n,
        cusolver_int_t              nrhs,
        size_t                  *   lwork_bytes);
cusolverDnIRSXgels_bufferSize() 函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDn库上下文的句柄。

params

host

input

Xgels配置参数

m

host

input

矩阵 A 的行数。应为非负数且 n<=m

n

host

input

矩阵A的列数。应为非负数且n<=m。

nrhs

host

input

需要求解的右端项数量。应为非负值。注意,如果选择的IRS精化求解器是CUSOLVER_IRS_REFINE_GMRESCUSOLVER_IRS_REFINE_GMRES_GMRESCUSOLVER_IRS_REFINE_CLASSICAL_GMRES,则nrhs限制为1。

lwork_bytes

host

out

指向一个变量的指针,在调用cusolverDnIRSXgels_bufferSize后,工作空间所需的字节大小将被存储在该变量中。不能为NULL。

cusolverStatus_t cusolverDnIRSXgels(
        cusolverDnHandle_t          handle,
        cusolverDnIRSParams_t       gels_irs_params,
        cusolverDnIRSInfos_t        gels_irs_infos,
        int                         m,
        int                         n,
        int                         nrhs,
        void                    *   dA,
        int                         ldda,
        void                    *   dB,
        int                         lddb,
        void                    *   dX,
        int                         lddx,
        void                    *   dWorkspace,
        size_t                      lwork_bytes,
        int                     *   dinfo);
cusolverDnIRSXgels() 函数的参数

参数

内存

输入/输出

含义

handle

host

input

指向cusolverDn库上下文的句柄。

gels_irs_params

host

input

配置参数结构体,可用于对任何IRS求解器的一次或多次调用

gels_irs_infos

host

输入/输出

信息结构,用于存储特定求解的相关信息。gels_irs_infos结构对应特定调用。因此不同调用需要不同的gels_irs_infos结构,否则将被覆盖。

m

host

input

矩阵 A 的行数。应为非负数且 n<=m

n

host

input

矩阵A的列数。应为非负数且n<=m。

nrhs

host

input

需要求解的右端项数量。应为非负数。请注意,如果选择的IRS细化求解器为CUSOLVER_IRS_REFINE_GMRES、CUSOLVER_IRS_REFINE_GMRES_GMRES或CUSOLVER_IRS_REFINE_CLASSICAL_GMRES,则nrhs限制为1。

dA

device

输入/输出

矩阵 A 的大小为 m-by-n。不能为 NULL。返回时:若最低精度不等于主精度且迭代精化求解器收敛,则保持不变;否则返回无效数据。

ldda

host

input

用于存储矩阵A的二维数组的主维度。ldda >= m

dB

device

input

右侧矩阵集合 B,大小为 m-by-nrhs。不能为 NULL

lddb

host

input

用于存储右侧矩阵的二维数组的主维度 Blddb >= max(1,m)

dX

device

output

大小为n-by-nrhs的解向量集X。不能为NULL

lddx

host

input

用于存储解向量矩阵的二维数组的主维度 Xlddx >= max(1,n)

dWorkspace

device

input

指向设备内存中已分配工作空间的指针,大小为lwork_bytes。

lwork_bytes

host

input

分配的设备工作空间大小。应至少为cusolverDnIRSXgels_bufferSize()函数返回的值。

niters

host

output

如果 iter

  • <0 : 迭代优化失败,如果启用了回退机制,则已执行主精度(输入/输出精度)分解

  • -1 : 考虑到机器参数、n、nrhs,先验判断不值得使用较低精度进行计算

  • -2 : 从主精度移动到较低精度时条目溢出

  • -3 : 分解过程中失败

  • -5 : 计算过程中发生溢出

  • -maxiter: 求解器在达到最大允许迭代次数后停止迭代优化

  • >0 : iter 是求解器为达到收敛标准所执行的迭代次数

dinfo

device

output

IRS求解器在返回时的状态。如果为0 - 求解成功。如果dinfo = -i则表示第i个参数无效。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数,例如:

  • n<0

  • ldda

  • lddb

  • lddx

CUSOLVER_STATUS_ARCH_MISMATCH

IRS求解器支持计算能力7.0及以上版本。最低精度选项CUSOLVER_[CR]_16BF和CUSOLVER_[CR]_TF32仅在计算能力8.0及以上版本中可用。

CUSOLVER_STATUS_INVALID_WORKSPACE

lwork_bytes 小于所需的工作空间。如果用户调用了 cusolverDnIRSXgels_bufferSize() 函数后更改了某些配置设置(例如最低精度),则可能发生这种情况。

CUSOLVER_STATUS_IRS_OUT_OF_RANGE

niters <0相关的数值错误;详情请参阅niters描述。

CUSOLVER_STATUS_INTERNAL_ERROR

发生内部错误,请检查dinfoniters参数以获取更多详细信息。

CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED

配置参数 gels_irs_params 结构未被创建。

CUSOLVER_STATUS_IRS_PARAMS_INVALID

gels_irs_params 结构体中的某个配置参数无效。

CUSOLVER_STATUS_IRS_PARAMS_INVALID_PREC

gels_irs_params 结构中的主要和/或最低精度配置参数无效,请检查上表以获取支持的组合。

CUSOLVER_STATUS_IRS_PARAMS_INVALID_MAXITER

gels_irs_params 结构中的 maxiter 配置参数无效。

CUSOLVER_STATUS_IRS_PARAMS_INVALID_REFINE

gels_irs_params 结构体中的 refinement solver 配置参数无效。

CUSOLVER_STATUS_IRS_NOT_SUPPORTED

gels_irs_params 结构体中的某个配置参数不受支持。例如当 nrhs >1 且迭代求解器被设置为 CUSOLVER_IRS_REFINE_GMRES 时。

CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED

信息结构 gels_irs_infos 未被创建。

CUSOLVER_STATUS_ALLOC_FAILED

CPU内存分配失败,很可能是在存储残差范数的残差数组分配期间发生的。

2.4.2.16. cusolverDnormqr()

这些辅助函数用于计算所需工作缓冲区的大小。请访问cuSOLVER库示例 - ormqr查看代码示例。

cusolverStatus_t
cusolverDnSormqr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const float *A,
    int lda,
    const float *tau,
    const float *C,
    int ldc,
    int *lwork);

cusolverStatus_t
cusolverDnDormqr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const double *A,
    int lda,
    const double *tau,
    const double *C,
    int ldc,
    int *lwork);

cusolverStatus_t
cusolverDnCunmqr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const cuComplex *A,
    int lda,
    const cuComplex *tau,
    const cuComplex *C,
    int ldc,
    int *lwork);

cusolverStatus_t
cusolverDnZunmqr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    const cuDoubleComplex *C,
    int ldc,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSormqr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const float *A,
    int lda,
    const float *tau,
    float *C,
    int ldc,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDormqr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const double *A,
    int lda,
    const double *tau,
    double *C,
    int ldc,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCunmqr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const cuComplex *A,
    int lda,
    const cuComplex *tau,
    cuComplex *C,
    int ldc,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZunmqr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasOperation_t trans,
    int m,
    int n,
    int k,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    cuDoubleComplex *C,
    int ldc,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数会覆盖\(m \times n\)矩阵C的内容

image2

Q 的操作由以下定义

image3

Q 是由 A 的 QR 分解 (geqrf) 产生的一系列基本反射向量所构成的酉矩阵。

Q=H(1)H(2)H(k)

Q的阶数为mside = CUBLAS_SIDE_LEFT,阶数为nside = CUBLAS_SIDE_RIGHT

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由geqrf_bufferSize()ormqr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

用户可以通过组合geqrformqrtrsm来完成线性求解器或最小二乘求解器。

ormqr的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDn库上下文的句柄。

side

host

input

指示矩阵 Q 位于 C 的左侧还是右侧。

trans

host

input

操作 op(Q) 表示非转置或共轭转置。

m

host

input

矩阵C的行数。

n

host

input

矩阵C的列数。

k

host

input

定义矩阵Q的基本反射的数量。

A

device

输入/输出

维度为 lda * k 的数组,其中 lda 不小于 max(1,m)。矩阵 A 来自 geqrf,因此第i列包含基本反射向量。

lda

host

input

用于存储矩阵A的二维数组的主维数。如果sideCUBLAS_SIDE_LEFT,则lda >= max(1,m);如果sideCUBLAS_SIDE_RIGHT,则lda >= max(1,n)。

tau

device

input

至少为min(m,n)维的数组。向量tau来自geqrf,因此tau(i)表示第i个基本反射向量的标量。

C

device

输入/输出

大小为 ldc * n 的数组。退出时,C 会被 op(Q)*C 覆盖。

ldc

host

input

矩阵C的二维数组的主维度。ldc >= max(1,m)。

work

device

输入/输出

工作空间,大小为lwork数组。

lwork

host

input

工作数组 work 的大小。

devInfo

device

output

如果devInfo = 0,表示ormqr执行成功。如果devInfo = -i,表示第i-th个参数有误(不包含handle参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0 或错误的 ldaldc)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.17. cusolverDnorgqr()

这些辅助函数用于计算所需工作缓冲区的大小。请访问cuSOLVER库示例 - orgqr查看代码示例。

cusolverStatus_t
cusolverDnSorgqr_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    const float *A,
    int lda,
    const float *tau,
    int *lwork);

cusolverStatus_t
cusolverDnDorgqr_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    const double *A,
    int lda,
    const double *tau,
    int *lwork);

cusolverStatus_t
cusolverDnCungqr_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    const cuComplex *A,
    int lda,
    const cuComplex *tau,
    int *lwork);

cusolverStatus_t
cusolverDnZungqr_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSorgqr(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    float *A,
    int lda,
    const float *tau,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDorgqr(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    double *A,
    int lda,
    const double *tau,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCungqr(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    cuComplex *A,
    int lda,
    const cuComplex *tau,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZungqr(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int k,
    cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数会覆盖\(m \times n\)矩阵A

\[Q = {H(1)}*{H(2)}*{...}*{H(k)}\]

其中Q是一个由存储在A中的一系列基本反射向量构成的酉矩阵。

用户需要提供一个工作空间,该空间由输入参数work指定。输入参数lwork表示工作空间的大小,该值由orgqr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

用户可以结合geqrforgqr来完成正交化。

orgqr的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

m

host

input

矩阵Q的行数。m >= 0;

n

host

input

矩阵Q的列数。m >= n >= 0;

k

host

input

定义矩阵Q的基本反射的数量。n >= k >= 0;

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,m)A 的第 i 列包含基本反射向量。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda >= max(1,m)。

tau

device

input

维度为 k 的数组。tau(i) 表示第 i 个基本反射向量的标量。

work

device

输入/输出

工作空间,大小为lwork数组。

lwork

host

input

工作数组 work 的大小。

devInfo

device

output

如果 info = 0,表示 orgqr 执行成功。如果 info = -i,表示第 i-th 个参数有误(不包含 handle 参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n,k<0, n>m, k>nlda)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.18. cusolverDnsytrf()

这些辅助函数用于计算所需缓冲区的大小。

cusolverStatus_t
cusolverDnSsytrf_bufferSize(cusolverDnHandle_t handle,
                      int n,
                      float *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnDsytrf_bufferSize(cusolverDnHandle_t handle,
                      int n,
                      double *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnCsytrf_bufferSize(cusolverDnHandle_t handle,
                      int n,
                      cuComplex *A,
                      int lda,
                      int *Lwork );

cusolverStatus_t
cusolverDnZsytrf_bufferSize(cusolverDnHandle_t handle,
                      int n,
                      cuDoubleComplex *A,
                      int lda,
                      int *Lwork );

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsytrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           float *A,
           int lda,
           int *ipiv,
           float *work,
           int lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnDsytrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           double *A,
           int lda,
           int *ipiv,
           double *work,
           int lwork,
           int *devInfo );

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCsytrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           cuComplex *A,
           int lda,
           int *ipiv,
           cuComplex *work,
           int lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnZsytrf(cusolverDnHandle_t handle,
           cublasFillMode_t uplo,
           int n,
           cuDoubleComplex *A,
           int lda,
           int *ipiv,
           cuDoubleComplex *work,
           int lwork,
           int *devInfo );

该函数计算一个\(n \times n\)对称不定矩阵的Bunch-Kaufman分解

A 是一个 \(n \times n\) 对称矩阵,仅下三角或上三角部分有意义。输入参数 uplo 决定使用矩阵的哪一部分。该函数会保持其他部分不变。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角因子 L 和块对角矩阵 DD 的每个块可能是1x1或2x2块,具体取决于旋转操作。

\[P*A*P^{T} = L*D*L^{T}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角因子 U 和块对角矩阵 D

\[P*A*P^{T} = U*D*U^{T}\]

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由sytrf_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果Bunch-Kaufman分解失败,即A是奇异矩阵。输出参数devInfo = i将表示D(i,i)=0

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

输出参数 devIpiv 包含主元交换序列。如果 devIpiv(i) = k > 0,则 D(i,i) 是1x1块,且 A第i行/列第k行/列 交换。如果 uploCUBLAS_FILL_MODE_UPPERdevIpiv(i-1) = devIpiv(i) = -m < 0,则 D(i-1:i,i-1:i) 是2x2块,且 第(i-1)行/列第m行/列 交换。如果 uploCUBLAS_FILL_MODE_LOWERdevIpiv(i+1) = devIpiv(i) = -m < 0,则 D(i:i+1,i:i+1) 是2x2块,且 第(i+1)行/列第m行/列 交换。

sytrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

A

device

输入/输出

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

ipiv

device

output

大小至少为n的数组,包含主元索引。

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

工作空间 work 的大小。

devInfo

device

output

如果 devInfo = 0,表示LU分解成功。如果 devInfo = -i,表示第 i-th 个参数错误(不包含handle)。如果 devInfo = i,表示 D(i,i) = 0

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n<0lda<max(1,n))。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.19. cusolverDnpotrfBatched()

S和D数据类型分别是单精度和双精度的实数值。请访问cuSOLVER库示例 - potrfBatched查看代码示例。

cusolverStatus_t
cusolverDnSpotrfBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    float *Aarray[],
    int lda,
    int *infoArray,
    int batchSize);

cusolverStatus_t
cusolverDnDpotrfBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    double *Aarray[],
    int lda,
    int *infoArray,
    int batchSize);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCpotrfBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    cuComplex *Aarray[],
    int lda,
    int *infoArray,
    int batchSize);

cusolverStatus_t
cusolverDnZpotrfBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *Aarray[],
    int lda,
    int *infoArray,
    int batchSize);

该函数计算一系列埃尔米特正定矩阵的Cholesky分解。

每个Aarray[i] for i=0,1,..., batchSize-1都是一个\(n \times n\)埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数uplo指示使用矩阵的哪一部分。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L

\[A = L*L^{H}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U

\[A = U^{H}*U\]

如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说LU的某些对角线元素不是实数。输出参数infoArray将指示A中不是正定的最小前导子矩阵。

infoArray 是一个大小为 batchsize 的整数数组。如果 potrfBatched 返回 CUSOLVER_STATUS_INVALID_VALUE,则 infoArray[0] = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 potrfBatched 返回 CUSOLVER_STATUS_SUCCESSinfoArray[i] = k 为正数,则表示第 i 个矩阵不是正定矩阵,且 Cholesky 分解在第 k 行失败。

备注:A的另一部分用作工作区。例如,如果uploCUBLAS_FILL_MODE_UPPER,则A的上三角部分包含Cholesky因子U,而下三角部分在potrfBatched执行后会被破坏。

potrfBatched的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示存储的是下三角部分还是上三角部分;另一部分用作工作区。

n

host

input

矩阵A的行数和列数。

Aarray

device

输入/输出

指向维度为lda * n数组的指针数组,其中lda不小于max(1,n)

lda

host

input

用于存储每个矩阵Aarray[i]的二维数组的主维度。

infoArray

device

output

大小为batchSize的数组。infoArray[i]包含Aarray[i]的分解信息。如果potrfBatched返回CUSOLVER_STATUS_INVALID_VALUEinfoArray[0] = -i(小于零)表示第i个参数错误(不包含句柄)。如果potrfBatched返回CUSOLVER_STATUS_SUCCESSinfoArray[i] = 0表示第i个矩阵的Cholesky分解成功,而infoArray[i] = k表示第i个矩阵的k阶前导子矩阵不是正定的。

batchSize

host

input

Aarray中的指针数量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0ldabatchSize<1)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.2.20. cusolverDnpotrsBatched()

cusolverStatus_t
cusolverDnSpotrsBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    int nrhs,
    float *Aarray[],
    int lda,
    float *Barray[],
    int ldb,
    int *info,
    int batchSize);

cusolverStatus_t
cusolverDnDpotrsBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    int nrhs,
    double *Aarray[],
    int lda,
    double *Barray[],
    int ldb,
    int *info,
    int batchSize);

cusolverStatus_t
cusolverDnCpotrsBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    int nrhs,
    cuComplex *Aarray[],
    int lda,
    cuComplex *Barray[],
    int ldb,
    int *info,
    int batchSize);

cusolverStatus_t
cusolverDnZpotrsBatched(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    int nrhs,
    cuDoubleComplex *Aarray[],
    int lda,
    cuDoubleComplex *Barray[],
    int ldb,
    int *info,
    int batchSize);

该函数用于求解一系列线性方程组

\[{A\lbrack i\rbrack}*{X\lbrack i\rbrack} = {B\lbrack i\rbrack}\]

其中每个Aarray[i] for i=0,1,..., batchSize-1都是一个\(n \times n\)埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数uplo用于指定使用矩阵的哪一部分。

用户需要先调用potrfBatched来分解矩阵Aarray[i]。如果输入参数uploCUBLAS_FILL_MODE_LOWER,则A是对应\(A = L*L^{H}\)的下三角Cholesky因子L。如果输入参数uploCUBLAS_FILL_MODE_UPPER,则A是对应\(A = U^{H}*U\)的上三角Cholesky因子U

该操作是原地进行的,即矩阵 X 会覆盖矩阵 B,两者具有相同的前导维度 ldb

输出参数 info 是一个标量。如果 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄)。

备注1:仅支持 nrhs=1

备注2:来自potrfBatchedinfoArray表示矩阵是否为正定矩阵。来自potrsBatchedinfo仅显示哪个输入参数有误(不包含handle)。

备注3:A的另一部分被用作工作区。例如,如果uploCUBLAS_FILL_MODE_UPPER,则A的上三角部分包含Cholesky因子U,而下三角部分在potrsBatched执行后会被破坏。

请访问cuSOLVER库示例 - potrfBatched查看代码示例。

potrsBatched API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示矩阵 A 的下三角部分或上三角部分是否被存储。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

矩阵 XB 的列数。

Aarray

device

输入/输出

指向维度为lda * n数组的指针数组,其中lda不小于max(1,n)Aarray[i]可以是下Cholesky因子L或上Cholesky因子U

lda

host

input

用于存储每个矩阵Aarray[i]的二维数组的主维度。

Barray

device

输入/输出

指向维度为ldb * nrhs数组的指针数组。ldb不小于max(1,n)。作为输入时,Barray[i]是右侧矩阵;作为输出时,Barray[i]是解矩阵。

ldb

host

input

用于存储每个矩阵Barray[i]的二维数组的主维度。

信息

device

output

如果info = 0,表示所有参数都正确。如果info = -i,表示第i-th个参数有误(不包含handle参数)。

batchSize

host

input

Aarray中的指针数量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0, nrhs<0, lda, ldbbatchSize<0)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3. 稠密特征值求解器参考(旧版)

本章介绍cuSolverDN的特征值求解器API,包括双对角化和奇异值分解(SVD)。

2.4.3.1. cusolverDngebrd()

这些辅助函数用于计算所需工作缓冲区的大小。

cusolverStatus_t
cusolverDnSgebrd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *Lwork );

cusolverStatus_t
cusolverDnDgebrd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *Lwork );

cusolverStatus_t
cusolverDnCgebrd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *Lwork );

cusolverStatus_t
cusolverDnZgebrd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *Lwork );

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSgebrd(cusolverDnHandle_t handle,
           int m,
           int n,
           float *A,
           int lda,
           float *D,
           float *E,
           float *TAUQ,
           float *TAUP,
           float *Work,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnDgebrd(cusolverDnHandle_t handle,
           int m,
           int n,
           double *A,
           int lda,
           double *D,
           double *E,
           double *TAUQ,
           double *TAUP,
           double *Work,
           int Lwork,
           int *devInfo );

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCgebrd(cusolverDnHandle_t handle,
           int m,
           int n,
           cuComplex *A,
           int lda,
           float *D,
           float *E,
           cuComplex *TAUQ,
           cuComplex *TAUP,
           cuComplex *Work,
           int Lwork,
           int *devInfo );

cusolverStatus_t
cusolverDnZgebrd(cusolverDnHandle_t handle,
           int m,
           int n,
           cuDoubleComplex *A,
           int lda,
           double *D,
           double *E,
           cuDoubleComplex *TAUQ,
           cuDoubleComplex *TAUP,
           cuDoubleComplex *Work,
           int Lwork,
           int *devInfo );

该函数通过正交变换将一般的\(m \times n\)矩阵A约化为实上或下双对角形式B\(Q^{H}*A*P = B\)

如果 m>=nB 是上双对角矩阵;如果 mB 是下双对角矩阵。

矩阵 QP 会以下列方式覆盖写入矩阵 A

  • 如果 m>=n,对角线及第一条上对角线将被上双对角矩阵 B 覆盖;对角线以下的元素与数组 TAUQ 一起表示正交矩阵 Q 作为初等反射器的乘积,而第一条上对角线以上的元素与数组 TAUP 一起表示正交矩阵 P 作为初等反射器的乘积。

  • 如果 m,对角线及第一条次对角线将被下双对角矩阵 B 覆盖;第一条次对角线以下的元素与数组 TAUQ 共同表示正交矩阵 Q 作为初等反射器的乘积,而对角线以上的元素与数组 TAUP 共同表示正交矩阵 P 作为初等反射器的乘积。

用户需要提供由输入参数Work指向的工作空间。输入参数Lwork表示工作空间的大小,该值由gebrd_bufferSize()函数返回。

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

备注:gebrd 仅支持 m>=n

gebrd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

A

device

输入/输出

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

D

device

output

维度为min(m,n)的实数数组。表示双对角矩阵B的对角线元素:D(i) = A(i,i)

E

device

output

维度为min(m,n)的实数数组。表示双对角矩阵B的非对角线元素:若m>=n,则E(i) = A(i,i+1)对应i = 1,2,...,n-1;若m,则E(i) = A(i+1,i)对应i = 1,2,...,m-1

TAUQ

device

output

维度为 min(m,n) 的数组。表示正交矩阵 Q 的基本反射器的标量因子。

TAUP

device

output

维度为 min(m,n) 的数组。表示正交矩阵 P 的基本反射器的标量因子。

工作

device

输入/输出

工作空间,大小为Lwork的<type>数组。

Lwork

host

input

Work的大小,由gebrd_bufferSize返回。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i-th个参数错误(不包含handle)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0, 或 lda)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.2. cusolverDnorgbr()

这些辅助函数用于计算所需工作缓冲区的大小。

cusolverStatus_t
cusolverDnSorgbr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    const float *A,
    int lda,
    const float *tau,
    int *lwork);

cusolverStatus_t
cusolverDnDorgbr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    const double *A,
    int lda,
    const double *tau,
    int *lwork);

cusolverStatus_t
cusolverDnCungbr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    const cuComplex *A,
    int lda,
    const cuComplex *tau,
    int *lwork);

cusolverStatus_t
cusolverDnZungbr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSorgbr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    float *A,
    int lda,
    const float *tau,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDorgbr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    double *A,
    int lda,
    const double *tau,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCungbr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    cuComplex *A,
    int lda,
    const cuComplex *tau,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZungbr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    int m,
    int n,
    int k,
    cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数生成由gebrd在将矩阵A约化为双对角形式时确定的酉矩阵QP**H之一:\(Q^{H}*A*P = B\)

QP**H 分别定义为基本反射器 H(i) 或 G(i) 的乘积。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由orgbr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

orgbr的API

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

side

host

input

如果 side = CUBLAS_SIDE_LEFT,则生成 Q。如果 side = CUBLAS_SIDE_RIGHT,则生成 P**T。

m

host

input

矩阵 QP**T 的行数。

n

host

input

如果 side = CUBLAS_SIDE_LEFT,则 m >= n >= min(m,k)。如果 side = CUBLAS_SIDE_RIGHT,则 n >= m >= min(n,k)。

k

host

input

如果 side = CUBLAS_SIDE_LEFT,表示经过 gebrd 处理后原 m×k 矩阵的列数;如果 side = CUBLAS_SIDE_RIGHT,表示经过 gebrd 处理后原 k×n 矩阵的行数。

A

device

输入/输出

<类型> 维度为 lda * n 的数组。输入时包含由 gebrd 返回的定义基本反射器的向量。输出时为 m×n 矩阵 QP**T

lda

host

input

用于存储矩阵A的二维数组的主维度。lda >= max(1,m);

tau

device

input

维度的数组,当sideCUBLAS_SIDE_LEFT时维度为min(m,k);当sideCUBLAS_SIDE_RIGHT时维度为min(n,k);tau(i)必须包含基本反射器H(i)或G(i)的标量因子,这些因子决定了Q或P**T,如gebrd在其数组参数TAUQTAUP中所返回的。

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

工作数组 work 的大小。

devInfo

device

output

如果info = 0,表示ormqr执行成功。如果info = -i,表示第i-th个参数有误(不包含handle参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0 或错误的 lda)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.3. cusolverDnsytrd()

这些辅助函数用于计算所需工作缓冲区的大小。

cusolverStatus_t
cusolverDnSsytrd_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *d,
    const float *e,
    const float *tau,
    int *lwork);

cusolverStatus_t
cusolverDnDsytrd_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *d,
    const double *e,
    const double *tau,
    int *lwork);

cusolverStatus_t
cusolverDnChetrd_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const float *d,
    const float *e,
    const cuComplex *tau,
    int *lwork);

cusolverStatus_t
cusolverDnZhetrd_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const double *d,
    const double *e,
    const cuDoubleComplex *tau,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsytrd(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float *d,
    float *e,
    float *tau,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDsytrd(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double *d,
    double *e,
    double *tau,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnChetrd(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    float *d,
    float *e,
    cuComplex *tau,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t CUDENSEAPI cusolverDnZhetrd(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    double *d,
    double *e,
    cuDoubleComplex *tau,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数通过正交变换将一般的对称(厄米特)\(n \times n\)矩阵A约化为实对称三对角矩阵T\(Q^{H}*A*Q = T\)

作为输出,A包含T和豪斯霍尔德反射向量。如果uplo = CUBLAS_FILL_MODE_UPPER,则A的对角线和第一条上对角线将被三对角矩阵T的相应元素覆盖,而第一条上对角线上方的元素与数组tau一起表示正交矩阵Q作为初等反射器的乘积;如果uplo = CUBLAS_FILL_MODE_LOWER,则A的对角线和第一条下对角线将被三对角矩阵T的相应元素覆盖,而第一条下对角线下方的元素与数组tau一起表示正交矩阵Q作为初等反射器的乘积。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由sytrd_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

sytrd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行(列)数。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 A 的前导 n×n 上三角部分包含矩阵 A 的上三角部分,且 A 的严格下三角部分不被引用。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 A 的前导 n×n 下三角部分包含矩阵 A 的下三角部分,且 A 的严格上三角部分不被引用。退出时,A 会被 T 和豪斯霍尔德反射向量覆盖。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda >= max(1,n)

D

device

output

维度为n的实数数组。三对角矩阵T的对角线元素:D(i) = A(i,i)

E

device

output

维度为(n-1)的实数数组。三对角矩阵T的非对角元素:如果uplo = CUBLAS_FILL_MODE_UPPER,则E(i) = A(i,i+1);如果uplo = CUBLAS_FILL_MODE_LOWER,则E(i) = A(i+1,i)

tau

device

output

维度为 (n-1) 的数组。表示正交矩阵 Q 的基本反射器的标量因子。

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

work的大小,由sytrd_bufferSize返回。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i-th个参数错误(不包含handle)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.4. cusolverDnormtr()

这些辅助函数用于计算所需工作缓冲区的大小。

cusolverStatus_t
cusolverDnSormtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    const float *A,
    int lda,
    const float *tau,
    const float *C,
    int ldc,
    int *lwork);

cusolverStatus_t
cusolverDnDormtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    const double *A,
    int lda,
    const double *tau,
    const double *C,
    int ldc,
    int *lwork);

cusolverStatus_t
cusolverDnCunmtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    const cuComplex *A,
    int lda,
    const cuComplex *tau,
    const cuComplex *C,
    int ldc,
    int *lwork);

cusolverStatus_t
cusolverDnZunmtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    const cuDoubleComplex *C,
    int ldc,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSormtr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    float *A,
    int lda,
    float *tau,
    float *C,
    int ldc,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDormtr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    double *A,
    int lda,
    double *tau,
    double *C,
    int ldc,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCunmtr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    cuComplex *A,
    int lda,
    cuComplex *tau,
    cuComplex *C,
    int ldc,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZunmtr(
    cusolverDnHandle_t handle,
    cublasSideMode_t side,
    cublasFillMode_t uplo,
    cublasOperation_t trans,
    int m,
    int n,
    cuDoubleComplex *A,
    int lda,
    cuDoubleComplex *tau,
    cuDoubleComplex *C,
    int ldc,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数会覆盖\(m \times n\)矩阵C的内容

image2

其中Q是由sytrd生成的一系列基本反射向量构成的正交矩阵。

Q 的操作定义为

image3

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由ormtr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

ormtr的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

side

host

input

side = CUBLAS_SIDE_LEFT,表示从左侧应用Q或Q**T;side = CUBLAS_SIDE_RIGHT,表示从右侧应用Q或Q**T。

uplo

host

input

uplo = CUBLAS_FILL_MODE_LOWER: A的下三角区域包含来自sytrd的基本反射器。uplo = CUBLAS_FILL_MODE_UPPER: A的上三角区域包含来自sytrd的基本反射器。

trans

host

input

操作 op(Q) 表示非转置或共轭转置。

m

host

input

矩阵C的行数。

n

host

input

矩阵C的列数。

A

device

输入/输出

维度数组 lda * mside = CUBLAS_SIDE_LEFT; lda * nside = CUBLAS_SIDE_RIGHT。来自 sytrd 的矩阵 A 包含基本反射器。

lda

host

input

用于存储矩阵A的二维数组的主维数。如果sideCUBLAS_SIDE_LEFT,则lda >= max(1,m);如果sideCUBLAS_SIDE_RIGHT,则lda >= max(1,n)。

tau

device

output

维度为 (m-1) 的数组(当 sideCUBLAS_SIDE_LEFT 时);维度为 (n-1) 的数组(当 sideCUBLAS_SIDE_RIGHT 时);向量 tau 来自 sytrd,因此 tau(i) 表示第 i 个基本反射向量的标量。

C

device

输入/输出

大小为 ldc * n 的数组。退出时,C 会被 op(Q)*CC*op(Q) 覆盖。

ldc

host

input

矩阵C的二维数组的主维度。ldc >= max(1,m)。

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

工作数组 work 的大小。

devInfo

device

output

如果 devInfo = 0,表示ormqr执行成功。如果 devInfo = -i,表示第 i-th 个参数有误(不包含handle参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0 或错误的 ldaldc)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.5. cusolverDnorgtr()

这些辅助函数用于计算所需工作缓冲区的大小。

cusolverStatus_t
cusolverDnSorgtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *tau,
    int *lwork);

cusolverStatus_t
cusolverDnDorgtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *tau,
    int *lwork);

cusolverStatus_t
cusolverDnCungtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const cuComplex *tau,
    int *lwork);

cusolverStatus_t
cusolverDnZungtr_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSorgtr(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    const float *tau,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDorgtr(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    const double *tau,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCungtr(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    const cuComplex *tau,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZungtr(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *tau,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数生成一个酉矩阵Q,该矩阵定义为n-1个n阶初等反射器的乘积,由sytrd返回:

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由orgtr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

orgtr的API

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

uplo = CUBLAS_FILL_MODE_LOWER: A的下三角区域包含来自sytrd的基本反射器。uplo = CUBLAS_FILL_MODE_UPPER: A的上三角区域包含来自sytrd的基本反射器。

n

host

input

矩阵 Q 的行(列)数。

A

device

输入/输出

<类型> 维度为 lda * n 的数组。输入时,来自 sytrd 的矩阵 A 包含基本反射器。输出时,矩阵 A 包含 n×n 的正交矩阵 Q

lda

host

input

用于存储矩阵A的二维数组的主维度。lda >= max(1,n)。

tau

device

input

维度为 (n-1) 的数组 tau(i) 表示第i个基本反射向量的标量。

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

工作数组 work 的大小。

devInfo

device

output

如果devInfo = 0,表示orgtr操作成功。如果devInfo = -i,表示第i-th个参数有误(不包含handle参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0 或错误的 lda)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.6. cusolverDngesvd()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSgesvd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *lwork );

cusolverStatus_t
cusolverDnDgesvd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *lwork );

cusolverStatus_t
cusolverDnCgesvd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *lwork );

cusolverStatus_t
cusolverDnZgesvd_bufferSize(
    cusolverDnHandle_t handle,
    int m,
    int n,
    int *lwork );

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSgesvd (
    cusolverDnHandle_t handle,
    signed char jobu,
    signed char jobvt,
    int m,
    int n,
    float *A,
    int lda,
    float *S,
    float *U,
    int ldu,
    float *VT,
    int ldvt,
    float *work,
    int lwork,
    float *rwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDgesvd (
    cusolverDnHandle_t handle,
    signed char jobu,
    signed char jobvt,
    int m,
    int n,
    double *A,
    int lda,
    double *S,
    double *U,
    int ldu,
    double *VT,
    int ldvt,
    double *work,
    int lwork,
    double *rwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCgesvd (
    cusolverDnHandle_t handle,
    signed char jobu,
    signed char jobvt,
    int m,
    int n,
    cuComplex *A,
    int lda,
    float *S,
    cuComplex *U,
    int ldu,
    cuComplex *VT,
    int ldvt,
    cuComplex *work,
    int lwork,
    float *rwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZgesvd (
    cusolverDnHandle_t handle,
    signed char jobu,
    signed char jobvt,
    int m,
    int n,
    cuDoubleComplex *A,
    int lda,
    double *S,
    cuDoubleComplex *U,
    int ldu,
    cuDoubleComplex *VT,
    int ldvt,
    cuDoubleComplex *work,
    int lwork,
    double *rwork,
    int *devInfo);

该函数计算一个\(m \times n\)矩阵A的奇异值分解(SVD)以及对应的左右奇异向量。SVD分解公式表示为

\[A = U*\Sigma*V^{H}\]

其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外全为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负的,并按降序排列。UV 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由gesvd_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i(小于零),则第 i-th 个参数有误(不包含句柄)。如果 bdsqr 未收敛,devInfo 会指明中间双对角形式中有多少超对角线未能收敛到零。

rwork是一个维度为(min(m,n)-1)的实数数组。如果devInfo>0且rwork不为NULL,rwork将包含一个上双对角矩阵中未收敛的超对角线元素。这与LAPACK略有不同:当类型为real时LAPACK将未收敛超对角元素放在work中;当类型为complex时则放在rwork中。如果用户不需要超对角线的信息,rwork可以设为NULL指针。

请访问cuSOLVER库示例 - gesvd查看代码示例。

备注1: gesvd 仅支持 m>=n

备注2:该例程返回\(V^{H}\),而非V

gesvd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobu

host

input

指定计算矩阵U全部或部分内容的选项:= 'A':返回数组U中U的所有m列;= 'S':返回数组U中U的前min(m,n)列(左奇异向量);= 'O':将U的前min(m,n)列(左奇异向量)覆盖到数组A上;= 'N':不计算U的任何列(不计算左奇异向量)。

jobvt

host

input

指定计算矩阵V**T全部或部分内容的选项:= 'A':在数组VT中返回V**T的所有N行;= 'S':在数组VT中返回V**T的前min(m,n)行(右奇异向量);= 'O':将V**T的前min(m,n)行(右奇异向量)覆盖写入数组A;= 'N':不计算V**T的任何行(不计算右奇异向量)。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,m)。退出时,A 的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

S

device

output

维度为min(m,n)的实数数组。A的奇异值,按S(i) >= S(i+1)排序。

U

device

output

维度为 ldu * m 的数组,其中 ldu 不小于 max(1,m)U 包含 \(m \times m\) 酉矩阵 U

ldu

host

input

用于存储矩阵U的二维数组的主维度。

VT

device

output

维度为 ldvt * n 的数组,其中 ldvt 不小于 max(1,n)VT 包含 \(n \times n\) 酉矩阵 V**T。

ldvt

host

input

用于存储矩阵Vt的二维数组的主维度。

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

work的大小,由gesvd_bufferSize返回。

rwork

device

input

维度为min(m,n)-1的实数数组。如果devInfo > 0,它包含一个上双对角矩阵中未收敛的超对角线元素。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i-th个参数错误(不包含handle)。如果devInfo > 0devInfo表示中间双对角形式中有多少超对角线未能收敛到零。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0ldalduldvt)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.7. cusolverDnGesvd() [已弃用]

[[已弃用]] 请改用cusolverDnXgesvd()。该例程将在下一个主要版本中移除。

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t cusolverDnGesvd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    signed char jobu,
    signed char jobvt,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeS,
    const void *S,
    cudaDataType dataTypeU,
    const void *U,
    int64_t ldu,
    cudaDataType dataTypeVT,
    const void *VT,
    int64_t ldvt,
    cudaDataType computeType,
    size_t *workspaceInBytes);

以下例程:

cusolverStatus_t cusolverDnGesvd(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    signed char jobu,
    signed char jobvt,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeS,
    void *S,
    cudaDataType dataTypeU,
    void *U,
    int64_t ldu,
    cudaDataType dataTypeVT,
    void *VT,
    int64_t ldvt,
    cudaDataType computeType,
    void *pBuffer,
    size_t workspaceInBytes,
    int *info);

该函数计算一个\(m \times n\)矩阵A的奇异值分解(SVD)以及对应的左右奇异向量。SVD分解公式表示为

\[A = U*\Sigma*V^{H}\]

其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负,并按降序排列。UV 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。

用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnGesvd_bufferSize()函数返回。

如果输出参数 info = -i(小于零),表示第 i-th 个参数有误(不包含句柄)。如果 bdsqr 未收敛,info 会指明中间双对角形式中有多少条超对角线未能收敛到零。

目前,cusolverDnGesvd仅支持默认算法。

cusolverDnGesvd 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

备注1: gesvd 仅支持 m>=n

备注2:该例程返回\(V^{H}\),而非V

cusolverDnGesvd_bufferSizecusolverDnGesvd 的输入参数列表:

cusolverDnGesvd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobu

host

input

指定计算矩阵U全部或部分内容的选项:= 'A':返回数组U中U的所有m列;= 'S':返回数组U中U的前min(m,n)列(左奇异向量);= 'O':将U的前min(m,n)列(左奇异向量)覆盖到数组A上;= 'N':不计算U的任何列(不计算左奇异向量)。

jobvt

host

input

指定计算矩阵V**T全部或部分内容的选项:= 'A':在数组VT中返回V**T的所有N行;= 'S':在数组VT中返回V**T的前min(m,n)行(右奇异向量);= 'O':将V**T的前min(m,n)行(右奇异向量)覆盖写入数组A;= 'N':不计算V**T的任何行(不计算右奇异向量)。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

dataTypeA

host

input

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,m)。退出时,A的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeS

host

input

数组S的数据类型。

S

device

output

维度为min(m,n)的实数数组。A的奇异值,按S(i) >= S(i+1)排序。

dataTypeU

host

input

数组U的数据类型。

U

device

output

维度为ldu * m的数组,其中ldu不小于max(1,m)U包含\(m \times m\)酉矩阵U

ldu

host

input

用于存储矩阵U的二维数组的主维度。

dataTypeVT

host

input

数组VT的数据类型。

VT

device

output

维度为ldvt * n的数组,其中ldvt不小于max(1,n)VT包含\(n \times n\)酉矩阵V**T。

ldvt

host

input

用于存储矩阵Vt的二维数组的主维度。

computeType

host

input

计算的数据类型。

pBuffer

device

输入/输出

工作空间。类型为void的数组,大小为workspaceInBytes字节。

workspaceInBytes

host

input

pBuffer的字节大小,由cusolverDnGesvd_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle)。如果info > 0info表示中间双对角形式中有多少超对角线未能收敛到零。

通用API包含三种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeVT表示矩阵VT的数据类型,computeType表示运算的计算类型。cusolverDnGesvd仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

数据类型S

数据类型U

数据类型VT

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SGESVD

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DGESVD

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CGESVD

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZGESVD

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0lda<max(1,m)ldu<max(1,m)ldvt<max(1,n))。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.8. cusolverDngesvdj()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSgesvdj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    const float *A,
    int lda,
    const float *S,
    const float *U,
    int ldu,
    const float *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params);

cusolverStatus_t
cusolverDnDgesvdj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    const double *A,
    int lda,
    const double *S,
    const double *U,
    int ldu,
    const double *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params);

cusolverStatus_t
cusolverDnCgesvdj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    const cuComplex *A,
    int lda,
    const float *S,
    const cuComplex *U,
    int ldu,
    const cuComplex *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params);

cusolverStatus_t
cusolverDnZgesvdj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const double *S,
    const cuDoubleComplex *U,
    int ldu,
    const cuDoubleComplex *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSgesvdj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    float *A,
    int lda,
    float *S,
    float *U,
    int ldu,
    float *V,
    int ldv,
    float *work,
    int lwork,
    int *info,
    gesvdjInfo_t params);

cusolverStatus_t
cusolverDnDgesvdj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    double *A,
    int lda,
    double *S,
    double *U,
    int ldu,
    double *V,
    int ldv,
    double *work,
    int lwork,
    int *info,
    gesvdjInfo_t params);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCgesvdj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    cuComplex *A,
    int lda,
    float *S,
    cuComplex *U,
    int ldu,
    cuComplex *V,
    int ldv,
    cuComplex *work,
    int lwork,
    int *info,
    gesvdjInfo_t params);

cusolverStatus_t
cusolverDnZgesvdj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int econ,
    int m,
    int n,
    cuDoubleComplex *A,
    int lda,
    double *S,
    cuDoubleComplex *U,
    int ldu,
    cuDoubleComplex *V,
    int ldv,
    cuDoubleComplex *work,
    int lwork,
    int *info,
    gesvdjInfo_t params);

该函数计算一个\(m \times n\)矩阵A的奇异值分解(SVD)以及对应的左右奇异向量。SVD分解公式表示为:

\[A = U*\Sigma*V^{H}\]

其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负的,并按降序排列。UV 的前 min(m,n) 列分别是 A 的左右奇异向量。

gesvdj 的功能与 gesvd 相同。区别在于 gesvd 使用 QR 算法,而 gesvdj 使用 Jacobi 方法。Jacobi 方法的并行性使 GPU 在中小型矩阵上具有更好的性能。此外,用户可以配置 gesvdj 以执行达到特定精度的近似计算。

gesvdj 通过迭代生成一系列酉矩阵,将矩阵 A 转换为以下形式

\[U^{H}*A*V = S + E\]

其中 S 是对角矩阵,而 E 的对角线元素为零。

在迭代过程中,E的Frobenius范数单调递减。当E趋近于零时,S即为奇异值集合。实际应用中,当满足以下条件时Jacobi方法停止:

\[{\|E\|}_{F}\leq\operatorname{eps}*{\|A\|}_{F}\]

其中eps为给定的容差。请注意,如果实际残差范数

\[{\|{S} - {U}^{H}*{A}*{V}\|}_{F}\]

计算时,它与\({\|{E}\|}_{F}\)的差异将达到\(N = max(m, n)\)量级的舍入误差,但仍符合标准SVD精度预期

\[\frac{\|S - U^{H} * A * V\|_F}{O(N) * \|A\|_F} \leq \frac{\|E\|_F}{\|A\|_F} \leq \operatorname{eps}\]

\(O(N)\) 通常为 \(N\),但常数取决于扫描次数,这给出了 \(sweeps * N\) 的上界舍入误差。

gesvdj 有两个控制精度的参数。第一个参数是容差(eps),默认值为机器精度,但用户可以通过函数 cusolverDnXgesvdjSetTolerance 预先设置容差值。第二个参数是最大扫描次数,用于控制Jacobi方法的迭代次数,默认值为100,但用户可以使用函数 cusolverDnXgesvdjSetMaxSweeps 设置合适的上限。实验表明,15次扫描通常足以收敛到机器精度。gesvdj 会在达到容差要求或最大扫描次数时停止计算。

雅可比方法具有二次收敛性,因此精度与扫描次数不成正比。为保证特定精度,用户应仅配置容差参数。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由gesvdj_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 info = -i(小于零),表示第 i-th 个参数有误(不包含句柄)。如果 info = min(m,n)+1,说明 gesvdj 在给定的容差和最大扫描次数下未能收敛。

如果用户设置了不恰当的容差,gesvdj可能无法收敛。例如,容差值不应小于机器精度。

请访问cuSOLVER库示例 - gesvdj查看代码示例。

备注1: gesvdj 支持 mn 的任意组合。

备注2:该例程返回V,而非\(V^{H}\)。这与gesvd的行为不同。

gesvdj的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobz

host

input

指定计算选项:仅计算奇异值或同时计算奇异向量:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算奇异值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算奇异值和奇异向量。

econ

host

input

econ = 1 表示对 UV 使用经济型尺寸。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

A

device

输入/输出

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,m)。退出时,A 的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

S

device

output

维度为min(m,n)的实数数组。A的奇异值,按S(i) >= S(i+1)排序。

U

device

output

如果econ为零,则为维度ldu * m的数组。如果econ非零,则维度为ldu * min(m,n)U包含左奇异向量。

ldu

host

input

用于存储矩阵U的二维数组的主维度。ldu不小于max(1,m)

V

device

output

如果econ为零,则为维度ldv * n的数组。如果econ非零,则维度为ldv * min(m,n)V包含右奇异向量。

ldv

host

input

用于存储矩阵V的二维数组的主维度。ldv不小于max(1,n)

work

device

输入/输出

大小为 lwork 的数组,工作空间。

lwork

host

input

work的大小,由gesvdj_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle)。如果info = min(m,n)+1,表示gesvdj在给定的容差和最大扫描次数下未能收敛。

params

host

input

填充了Jacobi算法参数和gesvdj结果的结构体。params在主机线程退出该例程后即可销毁。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0ldalduldvjobz 不是 CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.9. cusolverDngesvdjBatched()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSgesvdjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    const float *A,
    int lda,
    const float *S,
    const float *U,
    int ldu,
    const float *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params,
    int batchSize);

cusolverStatus_t
cusolverDnDgesvdjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    const double *A,
    int lda,
    const double *S,
    const double *U,
    int ldu,
    const double *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params,
    int batchSize);

cusolverStatus_t
cusolverDnCgesvdjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    const cuComplex *A,
    int lda,
    const float *S,
    const cuComplex *U,
    int ldu,
    const cuComplex *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params,
    int batchSize);

cusolverStatus_t
cusolverDnZgesvdjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const double *S,
    const cuDoubleComplex *U,
    int ldu,
    const cuDoubleComplex *V,
    int ldv,
    int *lwork,
    gesvdjInfo_t params,
    int batchSize);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSgesvdjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    float *A,
    int lda,
    float *S,
    float *U,
    int ldu,
    float *V,
    int ldv,
    float *work,
    int lwork,
    int *info,
    gesvdjInfo_t params,
    int batchSize);

cusolverStatus_t
cusolverDnDgesvdjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    double *A,
    int lda,
    double *S,
    double *U,
    int ldu,
    double *V,
    int ldv,
    double *work,
    int lwork,
    int *info,
    gesvdjInfo_t params,
    int batchSize);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCgesvdjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    cuComplex *A,
    int lda,
    float *S,
    cuComplex *U,
    int ldu,
    cuComplex *V,
    int ldv,
    cuComplex *work,
    int lwork,
    int *info,
    gesvdjInfo_t params,
    int batchSize);

cusolverStatus_t
cusolverDnZgesvdjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int m,
    int n,
    cuDoubleComplex *A,
    int lda,
    double *S,
    cuDoubleComplex *U,
    int ldu,
    cuDoubleComplex *V,
    int ldv,
    cuDoubleComplex *work,
    int lwork,
    int *info,
    gesvdjInfo_t params,
    int batchSize);

该函数计算一系列通用\(m \times n\)矩阵的奇异值和奇异向量

\[A_{j} = U_{j}*\Sigma_{j}*V_{j}^{H}\]

其中\(\Sigma_{j}\)是一个实数的\(m \times n\)对角矩阵,除了其min(m,n)个对角元素外其余均为零。\(U_{j}\)(左奇异向量)是一个\(m \times m\)酉矩阵,\(V_{j}\)(右奇异向量)是一个\(n \times n\)酉矩阵。\(\Sigma_{j}\)的对角元素是\(A_{j}\)的奇异值,可以是降序排列或非排序形式。

gesvdjBatched 对每个矩阵执行 gesvdj 运算。要求所有矩阵必须具有相同的 m,n 尺寸(不超过32),并且采用连续存储方式排列。

\[\begin{split}A = \begin{pmatrix} {A0} & {A1} & \cdots \\ \end{pmatrix}\end{split}\]

每个矩阵都是列优先存储,其前导维度为lda,因此随机访问的公式为\(A_{k}\operatorname{(i,j)} = {A\lbrack\ i\ +\ lda*j\ +\ lda*n*k\rbrack}\)

参数 S 还以连续方式包含每个矩阵的奇异值,

\[\begin{split}S = \begin{pmatrix} {S0} & {S1} & \cdots \\ \end{pmatrix}\end{split}\]

S的随机访问公式为\(S_{k}\operatorname{(j)} = {S\lbrack\ j\ +\ min(m,n)*k\rbrack}\)

除了容差和最大扫描次数外,gesvdjBatched既可以通过cusolverDnXgesvdjSetSortEig函数将奇异值按降序排列(默认),也可以选择保持原样(不排序)。如果用户将多个微小矩阵打包成一个矩阵的对角块,不排序选项可以将这些微小矩阵的奇异值分开。

gesvdjBatched 无法通过函数 cusolverDnXgesvdjGetResidualcusolverDnXgesvdjGetSweeps 报告残差和执行扫描次数。调用上述两个函数将返回 CUSOLVER_STATUS_NOT_SUPPORTED。用户需要显式计算残差。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由gesvdjBatched_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

输出参数 info 是一个大小为 batchSize 的整数数组。如果函数返回 CUSOLVER_STATUS_INVALID_VALUE,第一个元素 info[0] = -i(小于零)表示第 i 个参数有误(不包含句柄)。否则,如果 info[i] = min(m,n)+1,表示 gesvdjBatched 在给定的容差和最大扫描次数下未能收敛于第 i 个矩阵。

请访问cuSOLVER库示例 - gesvdjBatched查看代码示例。

gesvdjBatched API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobz

host

input

指定选项以仅计算奇异值或同时计算奇异向量:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算奇异值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算奇异值和奇异向量。

m

host

input

矩阵Aj的行数。m不大于32。

n

host

input

矩阵Aj的列数。n不超过32。

A

device

输入/输出

<类型> 维度为 lda * n * batchSize 的数组,其中 lda 不小于 max(1,n)。退出时:Aj 的内容将被销毁。

lda

host

input

用于存储矩阵Aj的二维数组的加载维度。

S

device

output

维度为min(m,n)*batchSize的实数数组。它以降序或非排序顺序存储Aj的奇异值。

U

device

output

维度为 ldu * m * batchSize 的数组。Uj 包含 Aj 的左奇异向量。

ldu

host

input

用于存储矩阵Uj的二维数组的主维度。ldu不小于max(1,m)

V

device

output

维度为 ldv * n * batchSize 的数组。Vj 包含 Aj 的右奇异向量。

ldv

host

input

用于存储矩阵Vj的二维数组的主维度。ldv不小于max(1,n)

work

device

输入/输出

大小为 lwork 的数组,工作空间。

lwork

host

input

work的大小,由gesvdjBatched_bufferSize返回。

信息

device

output

一个维度为batchSize的整数数组。如果返回CUSOLVER_STATUS_INVALID_VALUEinfo[0] = -i(小于零)表示第i-th个参数错误(不包含句柄)。否则,如果info[i] = 0,表示操作成功。如果info[i] = min(m,n)+1,表示gesvdjBatched在给定的容差和最大扫描次数下未能收敛于第i-th个矩阵。

params

host

input

填充了Jacobi算法参数的结构体。params在主机线程退出该例程后即可销毁。

batchSize

host

input

矩阵数量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0ldalduldvjobz 不是 CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或 batchSize<0)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.10. cusolverDngesvdaStridedBatched()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSgesvdaStridedBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const float *A,
    int lda,
    long long int strideA,
    const float *S,
    long long int strideS,
    const float *U,
    int ldu,
    long long int strideU,
    const float *V,
    int ldv,
    long long int strideV,
    int *lwork,
    int batchSize);

cusolverStatus_t
cusolverDnDgesvdaStridedBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const double *A,
    int lda,
    long long int strideA,
    const double *S,
    long long int strideS,
    const double *U,
    int ldu,
    long long int strideU,
    const double *V,
    int ldv,
    long long int strideV,
    int *lwork,
    int batchSize);

cusolverStatus_t
cusolverDnCgesvdaStridedBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const cuComplex *A,
    int lda,
    long long int strideA,
    const float *S,
    long long int strideS,
    const cuComplex *U,
    int ldu,
    long long int strideU,
    const cuComplex *V,
    int ldv,
    long long int strideV,
    int *lwork,
    int batchSize);

cusolverStatus_t
cusolverDnZgesvdaStridedBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const cuDoubleComplex *A,
    int lda,
    long long int strideA,
    const double *S,
    long long int strideS,
    const cuDoubleComplex *U,
    int ldu,
    long long int strideU,
    const cuDoubleComplex *V,
    int ldv,
    long long int strideV,
    int *lwork,
    int batchSize);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSgesvdaStridedBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const float *A,
    int lda,
    long long int strideA,
    float *S,
    long long int strideS,
    float *U,
    int ldu,
    long long int strideU,
    float *V,
    int ldv,
    long long int strideV,
    float *work,
    int lwork,
    int *info,
    double *h_R_nrmF,
    int batchSize);

cusolverStatus_t
cusolverDnDgesvdaStridedBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const double *A,
    int lda,
    long long int strideA,
    double *S,
    long long int strideS,
    double *U,
    int ldu,
    long long int strideU,
    double *V,
    int ldv,
    long long int strideV,
    double *work,
    int lwork,
    int *info,
    double *h_R_nrmF,
    int batchSize);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCgesvdaStridedBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const cuComplex *A,
    int lda,
    long long int strideA,
    float *S,
    long long int strideS,
    cuComplex *U,
    int ldu,
    long long int strideU,
    cuComplex *V,
    int ldv,
    long long int strideV,
    cuComplex *work,
    int lwork,
    int *info,
    double *h_R_nrmF,
    int batchSize);

cusolverStatus_t
cusolverDnZgesvdaStridedBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    int rank,
    int m,
    int n,
    const cuDoubleComplex *A,
    int lda,
    long long int strideA,
    double *S,
    long long int strideS,
    cuDoubleComplex *U,
    int ldu,
    long long int strideU,
    cuDoubleComplex *V,
    int ldv,
    long long int strideV,
    cuDoubleComplex *work,
    int lwork,
    int *info,
    double *h_R_nrmF,
    int batchSize);

此函数gesvdaa代表近似)用于近似计算高瘦矩阵\(m \times n\) A的奇异值分解及其对应的左右奇异向量。SVD的经济形式表示为

\[A = U*\Sigma*V^{H}\]

其中 Σ 是一个 \(n \times n\) 矩阵。U 是一个 \(m \times n\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负的,并按降序排列。UV 分别是 A 的左奇异向量和右奇异向量。

gesvda 计算 A**T*AA**H*A(若 A 为复数矩阵)的特征值,用于近似奇异值和奇异向量。它会生成矩阵 UV,并将矩阵 A 转换为以下形式

\[U^{H}*A*V = S + E\]

其中S是对角矩阵,E取决于舍入误差。在特定条件下,UVS可以近似到单精度机器零点的奇异值和奇异向量。通常,V是酉矩阵,SU更精确。如果奇异值远离零,则左奇异向量U是精确的。换句话说,奇异值和左奇异向量的精度取决于奇异值与零的距离。由于计算A**T*AA**H*A会显著放大误差,建议仅在数据条件良好时使用gesvda

输入参数 rank 决定了在参数 SUV 中计算的奇异值和奇异向量的数量。

输出参数 h_RnrmF 计算残差的Frobenius范数。要计算 h_RnrmF,需要满足 info != NULL 的条件。

\[A - U*S*V^{H}\]

如果参数 rank 等于 n。否则,h_RnrmF 将报告

\[{\|}U*S*V^{H}{\|} - {\|S\|}\]

在Frobenius范数意义上,即衡量U距离酉矩阵有多远。

gesvdaStridedBatched 对每个矩阵执行 gesvda 操作。要求所有矩阵必须具有相同的尺寸 m,n 并且以连续方式打包存储。

\[\begin{split}A = \begin{pmatrix} {A0} & {A1} & \cdots \\ \end{pmatrix}\end{split}\]

每个矩阵都是列优先存储,主维度为lda,因此随机访问的公式为\(A_{k}\operatorname{(i,j)} = {A\lbrack\ i\ +\ lda*j\ +\ strideA*k\rbrack}\)。类似地,S的随机访问公式为\(S_{k}\operatorname{(j)} = {S\lbrack\ j\ +\ StrideS*k\rbrack}\)U的随机访问公式为\(U_{k}\operatorname{(i,j)} = {U\lbrack\ i\ +\ ldu*j\ +\ strideU*k\rbrack}\),而V的随机访问公式为\(V_{k}\operatorname{(i,j)} = {V\lbrack\ i\ +\ ldv*j\ +\ strideV*k\rbrack}\)

用户需要提供一个工作空间,该空间由输入参数work指定。输入参数lwork表示工作空间的大小,该值由gesvdaStridedBatched_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

输出参数 info 是一个大小为 batchSize 的整数数组。如果函数返回 CUSOLVER_STATUS_INVALID_VALUE,第一个元素 info[0] = -i(小于零)表示第 i 个参数有误(不包含句柄)。否则,如果 info[i] = min(m,n)+1,表示 gesvdaStridedBatched 在第 i 个矩阵上未收敛。如果 0 < info[i] < min(m,n)+1,表示 gesvdaStridedBatched 未能完全计算第 i 个矩阵的奇异值分解;前导奇异值 Si[k]0 <= k <= info[i]-1)及对应的奇异向量可能仍然有用。此时,如果请求了 h_RnrmFh_RnrmF 会报告残差,如同将 rank 设为 info[i]-1

请访问cuSOLVER库示例 - gesvdaStridedBatched查看代码示例。

备注1:该例程返回V,而非\(V^{H}\)。这与gesvd的行为不同。

备注2:该例程仅支持 m >=n

备注3:建议使用FP64数据类型,即DgesvdaStridedBatchedZgesvdaStridedBatched

备注4:如果用户对奇异值和奇异向量的准确性有信心,例如满足某些条件(所需奇异值远离零),则可以通过向h_RnrmF传递空指针来提高性能,即不计算残差范数。

gesvdaStridedBatched的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobz

host

input

指定选项以仅计算奇异值或同时计算奇异向量:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算奇异值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算奇异值和奇异向量。

rank

host

input

奇异值的数量(从大到小排列)。

m

host

input

矩阵 Aj 的行数。

n

host

input

矩阵Aj的列数。

A

device

input

维度为 strideA * batchSize 的数组,其中 lda 不小于 max(1,m)Aj 的维度为 m * n

lda

host

input

用于存储矩阵 Aj 的二维数组的主维度。

strideA

host

input

类型为long long int的值,表示A[i]A[i+1]之间的地址偏移量。strideA不小于lda*n

S

device

output

一个维度为strideS*batchSize的实数数组。它以降序存储Aj的奇异值。Sj的维度为rank * 1

strideS

host

input

类型为long long int的值,表示S[i]S[i+1]之间的地址偏移量。strideS不小于rank

U

device

output

维度为 strideU * batchSize 的数组。Uj 包含 Aj 的左奇异向量。Uj 的维度为 m * rank

ldu

host

input

用于存储矩阵Uj的二维数组的主维度。ldu不小于max(1,m)

strideU

host

input

类型为long long int的值,表示U[i]U[i+1]之间的地址偏移量。strideU不小于ldu*rank

V

device

output

维度为 strideV * batchSize 的数组。Vj 包含 Aj 的右奇异向量。Vj 的维度为 n * rank

ldv

host

input

用于存储矩阵Vj的二维数组的主维度。ldv不小于max(1,n)

strideV

host

input

类型为long long int的值,表示V[i]V[i+1]之间的地址偏移量。strideV不小于ldv*rank

work

device

输入/输出

大小为 lwork 的数组,工作空间。

lwork

host

input

work的大小,由gesvdaStridedBatched_bufferSize返回。

信息

device

output

一个维度为batchSize的整数数组。如果返回CUSOLVER_STATUS_INVALID_VALUEinfo[0] = -i(小于零)表示第i个参数错误(不包含句柄)。否则,如果info[i] = 0,表示操作成功。如果info[i] = min(m,n)+1,表示gesvdaStridedBatched在第i个矩阵上未收敛。如果0 < info[i] < min(m,n)+1,表示gesvdaStridedBatched仅计算了第i个矩阵的部分SVD。

h_RnrmF

host

output

大小为batchSize数组。h_RnrmF[i]表示第i个矩阵的残差范数。如果0 < info[i] < min(m,n)+1,则h_RnrmF[i]报告的残差相当于将第i个矩阵的设为info[i]-1

batchSize

host

input

矩阵数量。batchSize不小于1。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0ldalduldvstrideAstrideSstrideUstrideVbatchSize<1jobz 不是 CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.11. cusolverDnsyevd()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSsyevd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnDsyevd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *W,
    int *lwork);

cusolverStatus_t
cusolverDnCheevd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnZheevd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const double *W,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsyevd(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float *W,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDsyevd(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double *W,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCheevd(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    float *W,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZheevd(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    double *W,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数计算对称(厄米特)\(n \times n\)矩阵A的特征值和特征向量。标准对称特征值问题为

\[A*V = V*\Lambda\]

其中 Λ 是一个实数的 \(n \times n\) 对角矩阵。V 是一个 \(n \times n\) 酉矩阵。Λ 的对角线元素是 A 按升序排列的特征值。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由syevd_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 devInfo = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

请访问cuSOLVER库示例 - syevd查看代码示例。

syevd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 A 的前 n×n 上三角部分包含矩阵 A 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 A 的前 n×n 下三角部分包含矩阵 A 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORdevInfo = 0,则 A 包含矩阵 A 的标准正交特征向量。如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 A 的内容会被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

W

device

output

一个维度为n的实数数组。A的特征值按升序排列,即排序后满足W(i) <= W(i+1)

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

Lwork

host

input

work的大小,由syevd_bufferSize返回。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i个参数错误(不包含句柄)。如果devInfo = i (> 0)devInfo表示中间三对角矩阵中有i个非对角元素未能收敛到零;

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.12. cusolverDnSyevd() [已弃用]

[[已弃用]] 请改用cusolverDnXsyevd()。该例程将在下一个主要版本中移除。

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
    cusolverDnSyevd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverParams_t params,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType computeType,
    size_t *workspaceInBytes);

以下例程

cusolverStatus_t
    cusolverDnSyevd(
    cusolverDnHandle_t handle,
    cusolverParams_t params,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType computeType,
    void *pBuffer,
    size_t workspaceInBytes,
    int *info);

使用通用API接口计算对称(厄米特)\(n \times n\)矩阵A的特征值和特征向量。标准对称特征值问题为

\[A*V = V*\Lambda\]

其中 Λ 是一个实数的 \(n \times n\) 对角矩阵。V 是一个 \(n \times n\) 酉矩阵。Λ 的对角线元素是 A 的特征值,按升序排列。

用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnSyevd_bufferSize()函数返回。

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

目前,cusolverDnSyevd仅支持默认算法。

cusolverDnSyevd 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnSyevd_bufferSizecusolverDnSyevd 的输入参数列表:

cusolverDnSyevd的API接口

parameter

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)。如果uplo = CUBLAS_FILL_MODE_UPPER,则A的前n×n上三角部分包含矩阵A的上三角部分。如果uplo = CUBLAS_FILL_MODE_LOWER,则A的前n×n下三角部分包含矩阵A的下三角部分。退出时,如果jobz = CUSOLVER_EIG_MODE_VECTORinfo = 0,A包含矩阵A的标准正交特征向量。如果jobz = CUSOLVER_EIG_MODE_NOVECTOR,则A的内容会被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeW

host

in

数组W的数据类型。

W

device

output

一个维度为n的实数数组。A的特征值按升序排列,即排序后满足W(i) <= W(i+1)

computeType

host

in

计算的数据类型。

pBuffer

device

输入/输出

工作空间。类型为void的数组,大小为workspaceInBytes字节。

workspaceInBytes

host

input

pBuffer的字节大小,由cusolverDnSyevd_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i个参数错误(不包含handle)。如果info = i (> 0)info表示中间三对角矩阵中有i个非对角元素未能收敛到零;

通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,而computeType表示运算的计算类型。cusolverDnSyevd仅支持以下四种组合。

数据类型与计算类型的有效组合

DataTypeA

DataTypeW

ComputeType

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SSYEVD

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DSYEVD

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CHEEVD

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

ZHEEVD

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.13. cusolverDnsyevdx()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSsyevdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnDsyevdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    const double *W,
    int *lwork);

cusolverStatus_t
cusolverDnCheevdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnZheevdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    const double *W,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsyevdx(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    float *W,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDsyevdx(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    double *W,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCheevdx(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    float *W,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZheevdx(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    double *W,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数计算对称(厄米特)\(n \times n\)矩阵A的全部或部分特征值,并可选择计算其特征向量。标准对称特征值问题为:

\[A*V = V*\Lambda\]

其中 Λ 是一个实数的 n×h_meig 对角矩阵。V 是一个 n×h_meig 的酉矩阵。h_meig 是该例程计算得到的特征值/特征向量的数量,当请求整个谱时(例如 range = CUSOLVER_EIG_RANGE_ALL),h_meig 等于 nΛ 的对角元素是 A 的特征值,按升序排列。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由syevdx_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 devInfo = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

请访问cuSOLVER库示例 - syevdx查看代码示例。

syevdx的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

range

host

input

指定需要计算的特征值及可选特征向量的选择选项:range = CUSOLVER_EIG_RANGE_ALL:将计算所有特征值/特征向量,相当于经典的syevd/heevd例程;range = CUSOLVER_EIG_RANGE_V:将计算半开区间(vl,vu]内的所有特征值/特征向量;range = CUSOLVER_EIG_RANGE_I:将计算从第il个到第iu个的特征值/特征向量;

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 A 的前 n×n 上三角部分包含矩阵 A 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 A 的前 n×n 下三角部分包含矩阵 A 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORdevInfo = 0,则 A 包含矩阵 A 的标准正交特征向量。如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 A 的内容会被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda不小于max(1,n)

vl,vu

host

input

实数值浮点数或双精度数分别对应(C, S)或(Z, D)精度。如果range = CUSOLVER_EIG_RANGE_V,则vl和vu表示要搜索特征值的区间上下界,需满足vl > vu。当range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_I时,该参数不被引用。需要注意的是,当特征值非常接近时,不同的特征值计算例程可能会在同一区间内找到略微不同数量的特征值。这是由于不同特征值算法(甚至同一算法在不同运行时)可能会在机器精度级别的舍入误差范围内找到特征值。因此,如果用户希望确保不遗漏区间内的任何特征值,建议对区间边界加减epsilon(机器精度),例如(vl=vl-eps, vu=vu+eps]。此建议适用于cuSolver或LAPACK中的任何选择性例程。

il,iu

host

input

整数。如果range = CUSOLVER_EIG_RANGE_I,则表示要返回的最小和最大特征值的索引(按升序排列)。当n > 0时,1 <= il <= iu <= n;当n = 0时,il = 1且iu = 0。如果range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_V,则不引用此参数。

h_meig

host

output

整数。找到的特征值总数。0 <= h_meig <= n。如果 range = CUSOLVER_EIG_RANGE_ALL,则 h_meig = n;如果 range = CUSOLVER_EIG_RANGE_I,则 h_meig = iu-il+1。

W

device

output

一个维度为n的实数数组。A的特征值按升序排列,即排序后满足W(i) <= W(i+1)

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

work的大小,由syevdx_bufferSize返回。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i个参数错误(不包含句柄)。如果devInfo = i (> 0)devInfo表示中间三对角矩阵中有i个非对角元素未能收敛到零。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或range不是CUSOLVER_EIG_RANGE_ALLCUSOLVER_EIG_RANGE_VCUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.14. cusolverDnSyevdx() [已弃用]

[[已弃用]] 请改用cusolverDnXsyevdx()。该例程将在下一个主要版本中移除。

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
    cusolverDnSyevdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverParams_t params,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    void *vl,
    void *vu,
    int64_t il,
    int64_t iu,
    int64_t *h_meig,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType computeType,
    size_t *workspaceInBytes);

以下例程

cusolverStatus_t
    cusolverDnSyevdx (
    cusolverDnHandle_t handle,
    cusolverParams_t params,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    void *vl,
    void *vu,
    int64_t il,
    int64_t iu,
    int64_t *h_meig,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType computeType,
    void *pBuffer,
    size_t workspaceInBytes,
    int *info);

使用通用API接口计算对称(厄米特)\(n \times n\)矩阵A的全部或部分特征值,并可选择计算特征向量。标准对称特征值问题为

\[A*V = V*\Lambda\]

其中Λ是一个实数的n×h_meig对角矩阵。V是一个n×h_meig酉矩阵。h_meig是该例程计算得到的特征值/特征向量数量,当请求整个频谱时(例如range = CUSOLVER_EIG_RANGE_ALL),h_meig等于nΛ的对角线元素是A按升序排列的特征值。

用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnSyevdx_bufferSize()函数返回。

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

目前,cusolverDnSyevdx仅支持默认算法。

cusolverDnSyevdx 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnSyevdx_bufferSizecusolverDnSyevdx 的输入参数列表:

cusolverDnSyevdx的API接口

parameter

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

range

host

input

指定需要计算的特征值及可选特征向量的选择选项:range = CUSOLVER_EIG_RANGE_ALL:将计算所有特征值/特征向量,相当于经典的syevd/heevd例程;range = CUSOLVER_EIG_RANGE_V:将计算半开区间(vl,vu]内的所有特征值/特征向量;range = CUSOLVER_EIG_RANGE_I:将计算从第il个到第iu个的特征值/特征向量;

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)。如果uplo = CUBLAS_FILL_MODE_UPPER,则A的前n×n上三角部分包含矩阵A的上三角部分。如果uplo = CUBLAS_FILL_MODE_LOWER,则A的前n×n下三角部分包含矩阵A的下三角部分。退出时,如果jobz = CUSOLVER_EIG_MODE_VECTORinfo = 0,则A包含矩阵A的标准正交特征向量。如果jobz = CUSOLVER_EIG_MODE_NOVECTOR,则A的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda不小于max(1,n)

vl,vu

host

input

如果 range = CUSOLVER_EIG_RANGE_V,则表示要搜索特征值的区间上下界。vl > vu。如果 range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_I 则不引用该参数。需要注意的是,当特征值非常接近时,众所周知,两种不同的特征值计算例程可能会在同一区间内找到略微不同数量的特征值。这是由于不同的特征值算法,甚至相同算法但不同运行可能会在接近机器精度的舍入误差范围内找到特征值。因此,如果用户希望确保不遗漏区间内的任何特征值,我们建议用户对区间边界加减一个极小值(机器精度),例如 (vl=vl-eps, vu=vu+eps]。此建议适用于 cuSolver 或 LAPACK 中的任何选择性例程。

il,iu

host

input

整数。如果range = CUSOLVER_EIG_RANGE_I,则表示要返回的最小和最大特征值的索引(按升序排列)。当n > 0时,需满足1 <= il <= iu <= n;当n = 0时,il = 1且iu = 0。如果range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_V,则不引用此参数。

h_meig

host

output

整数。找到的特征值总数。0 <= h_meig <= n。如果 range = CUSOLVER_EIG_RANGE_ALL,则 h_meig = n;如果 range = CUSOLVER_EIG_RANGE_I,则 h_meig = iu-il+1。

dataTypeW

host

in

数组W的数据类型。

W

device

output

一个维度为n的实数数组。A的特征值按升序排列,即排序后满足W(i) <= W(i+1)

computeType

host

in

计算的数据类型。

pBuffer

device

输入/输出

工作空间。类型为void的数组,大小为workspaceInBytes字节。

workspaceInBytes

host

input

pBuffer的字节大小,由cusolverDnSyevdx_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i个参数错误(不包含handle)。如果info = i (> 0)info表示中间三对角矩阵中有i个非对角元素未能收敛到零;

通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,computeType表示运算的计算类型。cusolverDnSyevdx仅支持以下四种组合。

数据类型与计算类型的有效组合

DataTypeA

DataTypeW

ComputeType

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SSYEVDX

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DSYEVDX

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CHEEVDX

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

ZHEEVDX

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或range不是CUSOLVER_EIG_RANGE_ALLCUSOLVER_EIG_RANGE_VCUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。 |

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.15. cusolverDnsygvd()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSsygvd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *B,
    int ldb,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnDsygvd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *B,
    int ldb,
    const double *W,
    int *lwork);

cusolverStatus_t
cusolverDnChegvd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const cuComplex *B,
    int ldb,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnZhegvd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *B,
    int ldb,
    const double *W,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsygvd(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float *B,
    int ldb,
    float *W,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDsygvd(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double *B,
    int ldb,
    double *W,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnChegvd(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    cuComplex *B,
    int ldb,
    float *W,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZhegvd(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    cuDoubleComplex *B,
    int ldb,
    double *W,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数计算对称(厄米特)\(n \times n\)矩阵对(A,B)的特征值和特征向量。广义对称正定特征值问题为

image4

其中矩阵 B 是正定的。Λ 是一个实数的 \(n \times n\) 对角矩阵。Λ 的对角元素是 (A, B) 按升序排列的特征值。V 是一个 \(n \times n\) 正交矩阵。特征向量按如下方式归一化:

image5

用户需要提供一个工作空间,该空间由输入参数work指定。输入参数lwork表示工作空间的大小,该值由sygvd_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i(小于零),则表示第 i 个参数有误(不包含句柄)。如果 devInfo = i(i > 0 且 i<=n)且 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则表示中间三对角形式的 i 个非对角元素未能收敛到零。如果 devInfo = N + i(i > 0),则表示 B 的第 i 阶前导子矩阵不是正定的。B 的分解无法完成,因此未计算任何特征值或特征向量。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。特征向量通过分治算法计算得出。

请访问cuSOLVER库示例 - sygvd查看代码示例。

sygvd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

itype

host

input

指定要解决的问题类型:

  • itype=CUSOLVER_EIG_TYPE_1: A*x = (lambda)*B*x.

  • itype=CUSOLVER_EIG_TYPE_2: A*B*x = (lambda)*x.

  • itype=CUSOLVER_EIG_TYPE_3: B*A*x = (lambda)*x.

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定AB的哪部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储AB的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储AB的上三角部分。

n

host

input

矩阵 AB 的行数(或列数)。

A

device

输入/输出

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 A 的前 n×n 上三角部分包含矩阵 A 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 A 的前 n×n 下三角部分包含矩阵 A 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORdevInfo = 0,则 A 包含矩阵 A 的标准正交特征向量。如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 A 的内容会被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda不小于max(1,n)

B

device

输入/输出

<类型> 维度为 ldb * n 的数组。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 B 的前导 n×n 上三角部分包含矩阵 B 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 B 的前导 n×n 下三角部分包含矩阵 B 的下三角部分。退出时,如果 devInfo 小于 n,则 B 会被 B 的 Cholesky 分解中的三角因子 UL 覆盖。

ldb

host

input

用于存储矩阵B的二维数组的主维度。ldb不小于max(1,n)

W

device

output

一个维度为n的实数数组。A的特征值,已排序使得W(i) >= W(i+1)

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

Lwork

host

input

work的大小,由sygvd_bufferSize返回。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i个参数错误(不包含handle)。如果devInfo = i (> 0)devInfo表示potrfsyevd出现错误。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或ldb,或itype不是1、2或3,或jobz不是'N'或'V',或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.16. cusolverDnsygvdx()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSsygvdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *B,
    int ldb,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnDsygvdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *B,
    int ldb,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    const double *W,
    int *lwork);

cusolverStatus_t
cusolverDnChegvdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const cuComplex *B,
    int ldb,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    const float *W,
    int *lwork);

cusolverStatus_t
cusolverDnZhegvdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *B,
    int ldb,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    const double *W,
    int *lwork);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsygvdx(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float *B,
    int ldb,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    float *W,
    float *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnDsygvdx(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double *B,
    int ldb,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    double *W,
    double *work,
    int lwork,
    int *devInfo);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnChegvdx(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    cuComplex *B,
    int ldb,
    float vl,
    float vu,
    int il,
    int iu,
    int *h_meig,
    float *W,
    cuComplex *work,
    int lwork,
    int *devInfo);

cusolverStatus_t
cusolverDnZhegvdx(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    cuDoubleComplex *B,
    int ldb,
    double vl,
    double vu,
    int il,
    int iu,
    int *h_meig,
    double *W,
    cuDoubleComplex *work,
    int lwork,
    int *devInfo);

该函数计算对称(厄米特)\(n \times n\)矩阵对(A,B)的全部或部分特征值,并可选择计算特征向量。广义对称正定特征值问题为

image4

其中矩阵B是正定的。Λ是一个实数的\(n \times {h\_meig}\)对角矩阵。Λ的对角元素是(A, B)按升序排列的特征值。V是一个\(n \times {h\_meig}\)正交矩阵。h_meig是该例程计算的特征值/特征向量的数量,当请求整个谱时(例如range = CUSOLVER_EIG_RANGE_ALL),h_meig等于n。特征向量按以下方式归一化:

image5

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由sygvdx_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 devInfo = -i(小于零),则表示第 i 个参数有误(不包含句柄)。如果 devInfo = i(i > 0 且 i<=n)且 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则表示中间三对角形式的 i 个非对角元素未能收敛至零。如果 devInfo = n + i(i > 0),则表明矩阵 Bi 阶前导主子矩阵非正定。此时 B 的分解无法完成,且无法计算任何特征值或特征向量。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

请访问cuSOLVER库示例 - sygvdx查看代码示例。

sygvdx的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

itype

host

input

指定要解决的问题类型:

  • itype =CUSOLVER_EIG_TYPE_1: A*x = (lambda)*B*x

  • itype =CUSOLVER_EIG_TYPE_2: A*B*x = (λ)*x

  • itype =CUSOLVER_EIG_TYPE_3: B*A*x = (lambda)*x

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

range

host

input

指定需要计算的特征值及可选特征向量的选择选项:range = CUSOLVER_EIG_RANGE_ALL:将计算所有特征值/特征向量,相当于经典的syevd/heevd例程;range = CUSOLVER_EIG_RANGE_V:将计算半开区间(vl,vu]内的所有特征值/特征向量;range = CUSOLVER_EIG_RANGE_I:将计算从第il个到第iu个的特征值/特征向量;

uplo

host

input

指定AB的哪部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储AB的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储AB的上三角部分。

n

host

input

矩阵 AB 的行数(或列数)。

A

device

输入/输出

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 A 的前 n×n 上三角部分包含矩阵 A 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 A 的前 n×n 下三角部分包含矩阵 A 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORdevInfo = 0,则 A 包含矩阵 A 的标准正交特征向量。如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 A 的内容会被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda不小于max(1,n)

B

device

输入/输出

<类型> 维度为 ldb * n 的数组。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 B 的前导 n×n 上三角部分包含矩阵 B 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 B 的前导 n×n 下三角部分包含矩阵 B 的下三角部分。退出时,如果 devInfo 小于 n,则 B 会被 B 的 Cholesky 分解中的三角因子 UL 覆盖。

ldb

host

input

用于存储矩阵B的二维数组的主维度。ldb不小于max(1,n)

vl,vu

host

input

实数值float或double分别对应(C, S)或(Z, D)精度。如果range = CUSOLVER_EIG_RANGE_V,则vl和vu表示要搜索特征值的区间上下界,且vl必须大于vu。当range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_I时该参数不被引用。需要注意的是,当特征值非常接近时,不同的特征值计算例程可能会在相同区间内找到略微不同数量的特征值。这是由于不同特征值算法(甚至同一算法不同运行)可能会在机器精度级别的舍入误差范围内找到特征值。因此,若用户希望确保不遗漏区间内的任何特征值,建议对区间边界加减epsilon(机器精度),例如调整为(vl=vl-eps, vu=vu+eps]。该建议适用于cuSolver或LAPACK中的所有选择性计算例程。

il,iu

host

input

整数。如果range = CUSOLVER_EIG_RANGE_I,则表示要返回的最小和最大特征值的索引(按升序排列)。当n > 0时,需满足1 <= il <= iu <= n;当n = 0时,il = 1且iu = 0。如果range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_V,则不引用此参数。

h_meig

host

output

整数。找到的特征值总数。0 <= h_meig <= n。如果 range = CUSOLVER_EIG_RANGE_ALL,则 h_meig = n;如果 range = CUSOLVER_EIG_RANGE_I,则 h_meig = iu-il+1。

W

device

output

一个维度为n的实数数组。A的特征值,已排序使得W(i) >= W(i+1)

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

work的大小,由sygvdx_bufferSize返回。

devInfo

device

output

如果devInfo = 0,表示操作成功。如果devInfo = -i,表示第i个参数错误(不包含handle)。如果devInfo = i (> 0)devInfo表示potrfsyevd出现错误。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传入了无效参数(n<0,或lda,或ldb,或itype不是CUSOLVER_EIG_TYPE_1CUSOLVER_EIG_TYPE_2CUSOLVER_EIG_TYPE_3,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTORL,或range不是CUSOLVER_EIG_RANGE_ALLCUSOLVER_EIG_RANGE_VCUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.17. cusolverDnsyevj()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSsyevj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *W,
    int *lwork,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnDsyevj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *W,
    int *lwork,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnCheevj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const float *W,
    int *lwork,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnZheevj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const double *W,
    int *lwork,
    syevjInfo_t params);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsyevj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float *W,
    float *work,
    int lwork,
    int *info,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnDsyevj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double *W,
    double *work,
    int lwork,
    int *info,
    syevjInfo_t params);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCheevj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    float *W,
    cuComplex *work,
    int lwork,
    int *info,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnZheevj(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    double *W,
    cuDoubleComplex *work,
    int lwork,
    int *info,
    syevjInfo_t params);

该函数计算对称(厄米特)\(n \times n\)矩阵A的特征值和特征向量。标准对称特征值问题为

\[A*Q = Q*\Lambda\]

其中 Λ 是一个实数的 \(n \times n\) 对角矩阵。Q 是一个 \(n \times n\) 酉矩阵。Λ 的对角线元素是 A 按升序排列的特征值。

syevj 的功能与 syevd 相同。区别在于 syevd 使用 QR 算法,而 syevj 使用 Jacobi 方法。Jacobi 方法的并行性使 GPU 在中小型矩阵上具有更好的性能。此外,用户可以配置 syevj 以执行达到特定精度的近似计算。

它是如何工作的?

syevj 通过迭代生成一系列酉矩阵,将矩阵 A 转换为以下形式

\[V^{H}*A*V = W + E\]

其中 W 是对角矩阵,E 是无对角元素的对称矩阵。

在迭代过程中,E的Frobenius范数单调递减。当E趋近于零时,W即为特征值集合。实际应用中,当满足以下条件时Jacobi方法停止:

\[{\|E\|}_{F}\leq\operatorname{eps}*{\|A\|}_{F}\]

其中 eps 是给定的容差。

syevj 有两个控制精度的参数。第一个参数是容差(eps),默认值为机器精度,但用户可以通过函数 cusolverDnXsyevjSetTolerance 预先设置容差值。第二个参数是最大扫描次数,用于控制雅可比方法的迭代次数,默认值为100,但用户可以通过函数 cusolverDnXsyevjSetMaxSweeps 设置合适的上限。实验表明,15次扫描通常足以收敛至机器精度。syevj 会在达到容差要求或最大扫描次数时停止计算。

雅可比方法具有二次收敛性,因此精度不与扫描次数成正比。为保证特定精度,用户应仅配置容差参数。

syevj之后,用户可以通过函数cusolverDnXsyevjGetResidual查询残差,并通过函数cusolverDnXsyevjGetSweeps查询已执行的扫描次数。但用户需要注意,残差是E的Frobenius范数,而非单个特征值的精度,即

\[{residual}={\|E\|}_{F} = {{\|}\Lambda - W{\|}}_{F}\]

syevd相同,用户需要提供由输入参数work指向的工作空间。输入参数lwork是工作空间的大小,由syevj_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = n+1,说明 syevj 在给定的容差和最大扫描次数下未能收敛。

如果用户设置了不恰当的容差,syevj可能无法收敛。例如,容差值不应小于机器精度。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含正交特征向量 V

请访问cuSOLVER库示例 - syevj查看代码示例。

syevj的API

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 A 的前 n×n 上三角部分包含矩阵 A 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 A 的前 n×n 下三角部分包含矩阵 A 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORinfo = 0,则 A 包含矩阵 A 的标准正交特征向量。如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 A 的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

W

device

output

一个维度为n的实数数组。A的特征值按升序排列,即排序后满足W(i) <= W(i+1)

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

work的大小,由syevj_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle)。如果info = n+1,表示syevj在给定的容差和最大扫描次数下未能收敛。

params

host

输入/输出

填充了Jacobi算法参数和syevj结果的结构体。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda<max(1,n),或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.18. cusolverDnsygvj()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSsygvj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *B,
    int ldb,
    const float *W,
    int *lwork,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnDsygvj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *B,
    int ldb,
    const double *W,
    int *lwork,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnChegvj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const cuComplex *B,
    int ldb,
    const float *W,
    int *lwork,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnZhegvj_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const cuDoubleComplex *B,
    int ldb,
    const double *W,
    int *lwork,
    syevjInfo_t params);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsygvj(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float *B,
    int ldb,
    float *W,
    float *work,
    int lwork,
    int *info,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnDsygvj(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double *B,
    int ldb,
    double *W,
    double *work,
    int lwork,
    int *info,
    syevjInfo_t params);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnChegvj(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    cuComplex *B,
    int ldb,
    float *W,
    cuComplex *work,
    int lwork,
    int *info,
    syevjInfo_t params);

cusolverStatus_t
cusolverDnZhegvj(
    cusolverDnHandle_t handle,
    cusolverEigType_t itype,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    cuDoubleComplex *B,
    int ldb,
    double *W,
    cuDoubleComplex *work,
    int lwork,
    int *info,
    syevjInfo_t params);

该函数计算对称(厄米特)\(n \times n\)矩阵对(A,B)的特征值和特征向量。广义对称正定特征值问题为

image4

其中矩阵 B 是正定的。Λ 是一个实数的 \(n \times n\) 对角矩阵。Λ 的对角元素是 (A, B) 按升序排列的特征值。V 是一个 \(n \times n\) 正交矩阵。特征向量按如下方式归一化:

image5

该函数与sygvd功能相同,只是sygvd中的syevd被替换为sygvj中的syevj。因此,sygvj继承了syevj的特性,用户可以使用cusolverDnXsyevjSetTolerancecusolverDnXsyevjSetMaxSweeps来配置容差和最大扫描次数。

然而残差的含义与syevj不同。sygvj首先计算矩阵B的Cholesky分解,

\[B = L*L^{H}\]

将问题转换为标准特征值问题,然后调用syevj

例如,标准类型I的特征值问题为

\[M*Q = Q*\Lambda\]

其中矩阵 M 是对称的

\[M = L^{-1}*A*L^{-H}\]

残差是矩阵Msyevj的结果,而非A

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由sygvj_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(i > 0 且 i<=n),说明 B 不是正定矩阵,无法完成 B 的因式分解,且未计算特征值或特征向量。如果 info = n+1,表示 syevj 在给定容差和最大扫描次数下未收敛。此时仍会计算特征值和特征向量,因为不收敛是由于容差或最大扫描次数设置不当所致。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含正交特征向量 V

请访问cuSOLVER库示例 - sygvj查看代码示例。

sygvj的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

itype

host

input

指定要解决的问题类型:itype=CUSOLVER_EIG_TYPE_1: A*x = (lambda)*B*x。 itype=CUSOLVER_EIG_TYPE_2: A*B*x = (lambda)*x。 itype=CUSOLVER_EIG_TYPE_3: B*A*x = (lambda)*x。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定AB的哪部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储AB的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储AB的上三角部分。

n

host

input

矩阵 AB 的行数(或列数)。

A

device

输入/输出

维度为 lda * n 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 A 的前 n×n 上三角部分包含矩阵 A 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 A 的前 n×n 下三角部分包含矩阵 A 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORinfo = 0,则 A 包含矩阵 A 的标准正交特征向量。如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 A 的内容会被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda不小于max(1,n)

B

device

输入/输出

<类型> 维度为 ldb * n 的数组。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 B 的前导 n×n 上三角部分包含矩阵 B 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 B 的前导 n×n 下三角部分包含矩阵 B 的下三角部分。退出时,如果 info 小于 n,则 B 会被 B 的 Cholesky 分解中的三角因子 UL 覆盖。

ldb

host

input

用于存储矩阵B的二维数组的主维度。ldb不小于max(1,n)

W

device

output

一个维度为n的实数数组。A的特征值,已排序使得W(i) >= W(i+1)

work

device

输入/输出

工作空间,大小为lwork的<type>数组。

lwork

host

input

work的大小,由sygvj_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle)。如果info = i (> 0)info表示要么B不是正定矩阵,要么syevj(由sygvj调用)未能收敛。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或ldb,或itype不是1、2或3,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.3.19. cusolverDnsyevjBatched()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnSsyevjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const float *A,
    int lda,
    const float *W,
    int *lwork,
    syevjInfo_t params,
    int batchSize
    );

cusolverStatus_t
cusolverDnDsyevjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const double *A,
    int lda,
    const double *W,
    int *lwork,
    syevjInfo_t params,
    int batchSize
    );

cusolverStatus_t
cusolverDnCheevjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuComplex *A,
    int lda,
    const float *W,
    int *lwork,
    syevjInfo_t params,
    int batchSize
    );

cusolverStatus_t
cusolverDnZheevjBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    const cuDoubleComplex *A,
    int lda,
    const double *W,
    int *lwork,
    syevjInfo_t params,
    int batchSize
    );

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverDnSsyevjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    float *A,
    int lda,
    float *W,
    float *work,
    int lwork,
    int *info,
    syevjInfo_t params,
    int batchSize
    );

cusolverStatus_t
cusolverDnDsyevjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    double *A,
    int lda,
    double *W,
    double *work,
    int lwork,
    int *info,
    syevjInfo_t params,
    int batchSize
    );

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverDnCheevjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuComplex *A,
    int lda,
    float *W,
    cuComplex *work,
    int lwork,
    int *info,
    syevjInfo_t params,
    int batchSize
    );

cusolverStatus_t
cusolverDnZheevjBatched(
    cusolverDnHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int n,
    cuDoubleComplex *A,
    int lda,
    double *W,
    cuDoubleComplex *work,
    int lwork,
    int *info,
    syevjInfo_t params,
    int batchSize
    );

该函数计算一系列对称(厄米特)\(n \times n\)矩阵的特征值和特征向量

\[A_{j}*Q_{j} = Q_{j}*\Lambda_{j}\]

其中\(\Lambda_{j}\)是一个实数的\(n \times n\)对角矩阵。\(Q_j\)是一个\(n \times n\)酉矩阵。\(\Lambda_j\)的对角线元素是\(A_j\)的特征值,可以是升序排列或非排序顺序。

syevjBatched 对每个矩阵执行 syevj。它要求所有矩阵具有相同的尺寸 n 并且以连续方式打包。

\[\begin{split}A = \begin{pmatrix} {A0} & {A1} & \cdots \\ \end{pmatrix}\end{split}\]

每个矩阵都是列优先存储,其前导维度为lda,因此随机访问的公式为\(A_{k}\operatorname{(i,j)} = {A\lbrack\ i\ +\ lda*j\ +\ lda*n*k\rbrack}\)

参数 W 还以连续方式包含每个矩阵的特征值,

\[\begin{split}W = \begin{pmatrix} {W0} & {W1} & \cdots \\ \end{pmatrix}\end{split}\]

W随机访问的公式为\(W_{k}\operatorname{(j)} = {W\lbrack\ j\ +\ n*k\rbrack}\)

除了容差和最大扫描次数外,syevjBatched既可以通过cusolverDnXsyevjSetSortEig函数选择将特征值按升序排序(默认),也可以选择保持原样(不排序)。如果用户将多个微小矩阵打包成一个矩阵的对角块,不排序选项可以将这些微小矩阵的频谱分开。

syevjBatched 无法通过函数 cusolverDnXsyevjGetResidualcusolverDnXsyevjGetSweeps 报告残差和执行扫描次数。调用上述两个函数都会返回 CUSOLVER_STATUS_NOT_SUPPORTED。用户需要显式计算残差。

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由syevjBatched_bufferSize()返回。请注意,工作空间的字节大小等于sizeof() * lwork

输出参数 info 是一个大小为 batchSize 的整数数组。如果函数返回 CUSOLVER_STATUS_INVALID_VALUE,第一个元素 info[0] = -i(小于零)表示第 i-th 个参数有误(不包含句柄)。否则,如果 info[i] = n+1,表示 syevjBatched 在给定的容差和最大扫描次数下未能收敛于第 i-th 个矩阵。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,\(A_j\) 包含标准正交特征向量 \(V_j\)

请访问cuSOLVER库示例 - syevjBatched查看代码示例。

syevjBatched API

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定Aj的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储Aj的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储Aj的上三角部分。

n

host

input

每个矩阵Aj的行数(或列数)。

A

device

输入/输出

维度为 lda * n * batchSize 的数组,其中 lda 不小于 max(1,n)。如果 uplo = CUBLAS_FILL_MODE_UPPER,则 Aj 的前导 n×n 上三角部分包含矩阵 Aj 的上三角部分。如果 uplo = CUBLAS_FILL_MODE_LOWER,则 Aj 的前导 n×n 下三角部分包含矩阵 Aj 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORinfo[j] = 0,则 Aj 包含矩阵 Aj 的标准正交特征向量。如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 Aj 的内容将被销毁。

lda

host

input

用于存储矩阵 Aj 的二维数组的主维度。

W

device

output

一个维度为n*batchSize的实数数组。它按升序或非排序顺序存储Aj的特征值。

work

device

输入/输出

大小为 lwork 的数组,工作空间。

lwork

host

input

work的大小,由syevjBatched_bufferSize返回。

信息

device

output

一个维度为batchSize的整数数组。如果返回CUSOLVER_STATUS_INVALID_VALUEinfo[0] = -i(小于零)表示第i个参数错误(不包含句柄)。否则,如果info[i] = 0,则表示操作成功。如果info[i] = n+1,表示syevjBatched在给定的容差和最大扫描次数下未能收敛于第i个矩阵。

params

host

输入/输出

填充Jacobi算法参数的结构体。

batchSize

host

input

矩阵数量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER),或batchSize<0

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4. 稠密线性求解器参考(64位API)

本节介绍cuSolverDN的64位线性求解器API,包括Cholesky分解、带部分主元的LU分解以及QR分解。

2.4.4.1. cusolverDnXpotrf()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXpotrf_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t
cusolverDnXpotrf(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info )

使用通用API接口计算埃尔米特正定矩阵的Cholesky分解。

A 是一个 \(n \times n\) 埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数 uplo 指示使用矩阵的哪一部分。该函数将保持其他部分不变。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L

\[A = L*L^{H}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U

\[A = U^{H}*U\]

用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXpotrf_bufferSize()返回。

如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说LU的某些对角线元素不是实数。输出参数info将指示A中不是正定的最小前导子矩阵。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnXpotrf仅支持默认算法。

请访问cuSOLVER库示例 - Xpotrf查看代码示例。

cusolverDnXpotrf 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXpotrf_bufferSizecusolverDnXpotrf 的输入参数列表:

potrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

computeType

host

in

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXpotrf_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXpotrf_bufferSize返回。

信息

device

output

如果info = 0,表示Cholesky分解成功。如果info = -i,表示第i个参数有误(不包含handle)。如果info = i,表示第i阶前导子矩阵不是正定的。

通用API有两种不同类型,dataTypeA是矩阵A的数据类型,computeType是运算的计算类型。cusolverDnXpotrf仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

计算类型

含义

CUDA_R_32F

CUDA_R_32F

SPOTRF

CUDA_R_64F

CUDA_R_64F

DPOTRF

CUDA_C_32F

CUDA_C_32F

CPOTRF

CUDA_C_64F

CUDA_C_64F

ZPOTRF

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n<0lda<max(1,n))。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4.2. cusolverDnXpotrs()

cusolverStatus_t
cusolverDnXpotrs(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasFillMode_t uplo,
    int64_t n,
    int64_t nrhs,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeB,
    void *B,
    int64_t ldb,
    int *info)

该函数用于求解线性方程组

\[A*X = B\]

其中 A 是一个 \(n \times n\) 埃尔米特矩阵,使用通用API接口时仅需提供下三角或上三角部分。输入参数 uplo 用于指定使用矩阵的哪一部分。函数将保持另一部分不变。

用户需要先调用cusolverDnXpotrf来分解矩阵A。如果输入参数uploCUBLAS_FILL_MODE_LOWER,则A是对应\(A = L*L^{H}\)的下三角Cholesky因子L。如果输入参数uploCUBLAS_FILL_MODE_UPPER,则A是对应\(A = U^{H}*U\)的上三角Cholesky因子U

该操作是原地进行的,即矩阵 X 会覆盖矩阵 B,两者具有相同的前导维度 ldb

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnXpotrs仅支持默认算法。

请访问cuSOLVER库示例 - Xpotrf查看代码示例。

cusolverDnXpotrs支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXpotrs的输入参数列表:

potrs的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

矩阵 XB 的列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

input

维度为lda * n的数组,其中lda不小于max(1,n)A可以是下Cholesky因子L或上Cholesky因子U

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeB

host

in

数组 B 的数据类型。

B

device

输入/输出

维度为ldb * nrhs的数组。ldb不小于max(1,n)。作为输入时,B是右侧矩阵;作为输出时,B是解矩阵。

信息

device

output

如果info = 0,表示Cholesky分解成功。如果info = -i,表示第i-th个参数有误(不包含handle参数)。

通用API有两种不同类型,dataTypeA是矩阵A的数据类型,dataTypeB是矩阵B的数据类型。cusolverDnXpotrs仅支持以下四种组合。

数据类型与计算类型的有效组合

dataTypeA

dataTypeB

含义

CUDA_R_32F

CUDA_R_32F

SPOTRS

CUDA_R_64F

CUDA_R_64F

DPOTRS

CUDA_C_32F

CUDA_C_32F

CPOTRS

CUDA_C_64F

CUDA_C_64F

ZPOTRS

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0nrhs<0lda<max(1,n)ldb<max(1,n))。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4.3. cusolverDnXgetrf()

下面的辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t cusolverDnXgetrf_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

下面的函数

cusolverStatus_t
cusolverDnXgetrf(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    int64_t *ipiv,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info )

计算一个\(m \times n\)矩阵的LU分解

\[P*A = L*U\]

其中 A 是一个 \(m \times n\) 矩阵,P 是置换矩阵,L 是单位对角线的下三角矩阵,U 是使用通用API接口的上三角矩阵。

如果LU分解失败,即矩阵A (U)是奇异的,输出参数info=i表示U(i,i) = 0

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

如果 ipiv 为空,则不进行主元选择。因式分解结果为 A=L*U,这种分解在数值上不稳定。

无论LU分解是否成功,输出参数ipiv都包含主元交换序列,第i行会与第ipiv(i)行进行交换。

用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该大小由cusolverDnXgetrf_bufferSize()返回。

用户可以结合cusolverDnXgetrfcusolverDnGetrs来完成线性求解器。

目前,cusolverDnXgetrf支持两种算法。要选择旧版实现,用户需要调用cusolverDnSetAdvOptions

请访问cuSOLVER库示例 - Xgetrf查看代码示例。

cusolverDnXgetrf 支持的算法

CUSOLVER_ALG_0NULL

默认算法。速度最快,需要一个包含m*n元素的大型工作空间。

CUSOLVER_ALG_1

旧版实现

cusolverDnXgetrf_bufferSizecusolverDnXgetrf 的输入参数列表:

cusolverDnXgetrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

<type> 维度为 lda * n 的数组,其中 lda 不小于 max(1,m)

lda

host

input

用于存储矩阵A的二维数组的主维度。

ipiv

device

output

大小至少为min(m,n)的数组,包含主元索引。

computeType

host

in

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXgetrf_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXgetrf_bufferSize返回。

信息

device

output

如果info = 0,表示LU分解成功。如果info = -i,表示第i个参数有误(不包含handle)。如果info = i,表示U(i,i) = 0

通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型。cusolverDnXgetrf仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

计算类型

含义

CUDA_R_32F

CUDA_R_32F

SGETRF

CUDA_R_64F

CUDA_R_64F

DGETRF

CUDA_C_32F

CUDA_C_32F

CGETRF

CUDA_C_64F

CUDA_C_64F

ZGETRF

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (m,n<0lda<max(1,m))。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4.4. cusolverDnXgetrs()

cusolverStatus_t
cusolverDnXgetrs(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cublasOperation_t trans,
    int64_t n,
    int64_t nrhs,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    const int64_t *ipiv,
    cudaDataType dataTypeB,
    void *B,
    int64_t ldb,
    int *info )

该函数用于求解具有多个右端项的线性方程组

\[op(A)*X = B\]

其中A是一个\(n \times n\)矩阵,并且已经通过cusolverDnXgetrf进行了LU分解,即A的下三角部分是L,而A的上三角部分(包括对角元素)是UB是一个\(n \times {nrhs}\)的右侧矩阵,使用通用API接口。

输入参数 trans 的定义如下

image1

输入参数 ipivcusolverDnXgetrf 的输出结果。它包含用于置换右侧项的枢轴索引。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

用户可以结合cusolverDnXgetrfcusolverDnXgetrs来完成线性求解器。

目前,cusolverDnXgetrs仅支持默认算法。

请访问cuSOLVER库示例 - Xgetrf查看代码示例。

cusolverDnXgetrs 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXgetrs函数的输入参数列表:

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

trans

host

input

操作 op(A) 表示非转置或共轭转置。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

右侧的数量。

dataTypeA

host

in

数组 A 的数据类型。

A

device

input

维度为lda * n的数组,其中lda不小于max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

ipiv

device

input

大小至少为n的数组,包含主元索引。

dataTypeB

host

in

数组 B 的数据类型。

B

device

output

<type> 维度为 ldb * nrhs 的数组,其中 ldb 不小于 max(1,n)

ldb

host

input

用于存储矩阵B的二维数组的主维度。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle参数)。

通用API有两种不同类型:dataTypeA是矩阵A的数据类型,dataTypeB是矩阵B的数据类型。cusolverDnXgetrs仅支持以下四种组合:

数据类型与计算类型的有效组合

数据类型A

数据类型B

含义

CUDA_R_32F

CUDA_R_32F

SGETRS

CUDA_R_64F

CUDA_R_64F

DGETRS

CUDA_C_32F

CUDA_C_32F

CGETRS

CUDA_C_64F

CUDA_C_64F

ZGETRS

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0lda<max(1,n)ldb<max(1,n))。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4.5. cusolverDnXgeqrf()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXgeqrf_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeTau,
    const void *tau,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t cusolverDnXgeqrf(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeTau,
    void *tau,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info )

计算一个\(m \times n\)矩阵的QR分解

\[A = Q*R\]

其中 A 是一个 \(m \times n\) 矩阵,Q 是一个 \(m \times n\) 矩阵,而 R 是一个通过通用API接口生成的 \(n \times n\) 上三角矩阵。

用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgeqrf_bufferSize()返回。

矩阵 R 会被覆盖写入 A 的上三角部分,包括对角线元素。

矩阵 Q 不会显式生成,而是将一系列豪斯霍尔德向量存储在 A 的下三角部分。假设豪斯霍尔德向量的前导非零元素为1,因此输出参数 TAU 包含缩放因子 τ。如果 v 是原始豪斯霍尔德向量,q 是对应于 τ 的新豪斯霍尔德向量,满足以下关系

\[I - 2*v*v^{H} = I - \tau*q*q^{H}\]

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnXgeqrf仅支持默认算法。

请访问cuSOLVER库示例 - Xgeqrf查看代码示例。

cusolverDnXgeqrf 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXgeqrf_bufferSizecusolverDnXgeqrf 的输入参数列表:

geqrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,m)

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeTau

host

in

数组tau的数据类型。

tau

device

output

维度至少为min(m,n)的数组。

computeType

host

in

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXgeqrf_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXgeqrf_bufferSize返回。

信息

device

output

如果 info = 0,表示QR分解成功。如果 info = -i,表示第 i-th 个参数有误(不包含句柄)。

通用API有两种不同类型,dataTypeA是矩阵A的数据类型,dataTypeTau是数组tau的数据类型,computeType是运算的计算类型。cusolverDnXgeqrf仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

计算类型

含义

CUDA_R_32F

CUDA_R_32F

SGEQRF

CUDA_R_64F

CUDA_R_64F

DGEQRF

CUDA_C_32F

CUDA_C_32F

CGEQRF

CUDA_C_64F

CUDA_C_64F

ZGEQRF

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (m,n<0lda<max(1,m))。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4.6. cusolverDnXsytrs()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXsytrs_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int64_t n,
    int64_t nrhs,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    const int64_t *devIpiv,
    cudaDataType dataTypeB,
    void *B,
    int64_t ldb,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost);

以下例程:

cusolverStatus_t cusolverDnXsytrs(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    int64_t n,
    int64_t nrhs,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    const int64_t *devIpiv,
    cudaDataType dataTypeB,
    void *B,
    int64_t ldb,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *devInfo);

使用通用API接口求解线性方程组。

A 包含来自 cusolverDnXsytrf() 的因式分解结果,只有下三角或上三角部分有意义,另一部分未被修改。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则分解的详细信息存储为:

\[A = L*D*L^{T}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则分解的详细信息存储为:

\[A = U*D*U^{T}\]

用户需要提供可通过cusolverDnXsytrf()获取的主元索引,以及由输入参数bufferOnDevicebufferOnHost指向的设备和主机工作空间。输入参数workspaceInBytesOnDeviceworkspaceInBytesOnHost分别表示设备和主机工作空间的字节大小,这些值由cusolverDnXsytrs_bufferSize()返回。 若要在不使用主元旋转的情况下分解和求解对称系统,用户在调用cusolverDnXsytrfcusolverDnXsytrs时应设置devIpiv = NULL

如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

cusolverDnXsytrs_bufferSizecusolverDnXsytrs 的输入参数列表:

sytrs的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

n

host

input

矩阵A的行数和列数。

nrhs

host

input

右侧的数量。

dataTypeA

host

in

数组 A 的数据类型。

A

device

input

维度为lda * n的数组,其中lda不小于max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

devIpiv

device

input

大小至少为n的数组,包含主元索引。若要在不进行主元消去的情况下求解系统,请将参数设为NULL

dataTypeB

host

in

数组 B 的数据类型。

B

device

输入/输出

维度为ldb * nrhs的数组,其中ldb不小于max(1,nrhs)

ldb

host

input

用于存储矩阵B的二维数组的主维度。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXsytrs_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXsytrs_bufferSize返回。

devInfo

device

output

如果 devInfo = -i,表示第 i-th 个参数有误(不包含句柄参数)。否则设置 devInfo = 0 表示所有参数均有效。

通用API有两种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeB表示矩阵A的数据类型。cusolverDnXsytrs仅支持以下四种组合:

数据类型与计算类型的有效组合

数据类型A

数据类型B

含义

CUDA_R_32F

CUDA_R_32F

SSYTRS

CUDA_R_64F

CUDA_R_64F

DSYTRS

CUDA_C_32F

CUDA_C_32F

CSYTRS

CUDA_C_64F

CUDA_C_64F

ZSYTRS

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n<0lda<max(1,n))。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持的数据类型。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4.7. cusolverDnXtrtri()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXtrtri_bufferSize(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    cublasDiagType_t diag,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost);

以下例程:

cusolverStatus_t
cusolverDnXtrtri(
    cusolverDnHandle_t handle,
    cublasFillMode_t uplo,
    cublasDiagType_t diag,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info);

使用通用API接口计算三角矩阵的逆矩阵。

A 是一个 \(n \times n\) 三角矩阵,只有下三角或上三角部分有意义。输入参数 uplo 表示使用矩阵的哪一部分。该函数会保持其他部分不变。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角逆矩阵。

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角逆矩阵。

用户需要提供由输入参数bufferOnDevicebufferOnHost指向的设备端和主机端工作空间。输入参数workspaceInBytesOnDeviceworkspaceInBytesOnHost分别表示设备端和主机端工作空间的字节大小,这些值由cusolverDnXtrtri_bufferSize()函数返回。

如果矩阵求逆失败,输出参数 info = i 表示 A(i,i) = 0

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

请访问cuSOLVER库示例 - Xtrtri查看代码示例。

cusolverDnXtrtri_bufferSizecusolverDnXtrtri 的输入参数列表:

trtri的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

uplo

host

input

指示矩阵A的下三角部分或上三角部分是否被存储,另一部分未被引用。

diag

host

input

枚举的单位对角类型。

n

host

input

矩阵A的行数和列数。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)

lda

host

input

用于存储矩阵A的二维数组的主维度。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice 的字节大小,由 cusolverDnXtrtri_bufferSize 返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXtrtri_bufferSize返回。

信息

device

output

如果info = 0,表示矩阵求逆成功。如果info = -i,表示第i-th个参数错误(不包含handle)。如果info = i,表示A(i,i) = 0

有效数据类型

DataTypeA

含义

CUDA_R_32F

STRTRI

CUDA_R_64F

DTRTRI

CUDA_C_32F

CTRTRI

CUDA_C_64F

ZTRTRI

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_NOT_SUPPORTED

不支持的数据类型。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n<0lda<max(1,n))。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.4.8. cusolverDnXlarft()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t cusolverDnXlarft_bufferSize(
   cusolverDnHandle_t handle,
   cusolverDnParams_t params,
   cusolverDirectMode_t direct,
   cusolverStorevMode_t storev,
   int64_t n,
   int64_t k,
   cudaDataType dataTypeV,
   const void *V,
   int64_t ldv,
   cudaDataType dataTypeTau,
   const void *tau,
   cudaDataType dataTypeT,
   void *T,
   int64_t ldt,
   cudaDataType computeType,
   size_t *workspaceInBytesOnDevice,
   size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t cusolverDnXlarft(
   cusolverDnHandle_t handle,
   cusolverDnParams_t params,
   cusolverDirectMode_t direct,
   cusolverStorevMode_t storev,
   int64_t n,
   int64_t k,
   cudaDataType dataTypeV,
   const void *V,
   int64_t ldv,
   cudaDataType dataTypeTau,
   const void *tau,
   cudaDataType dataTypeT,
   void *T,
   int64_t ldt,
   cudaDataType computeType,
   void *bufferOnDevice,
   size_t workspaceInBytesOnDevice,
   void *bufferOnHost,
   size_t workspaceInBytesOnHost)

形成一个实块反射器H的三角因子T,该反射器阶数为n,定义为k个基本反射器的乘积。 如果:

  • direct == CUBLAS_DIRECT_FORWARD: \(H = H(1) H(2) ... H(k)\)T 是上三角矩阵;

  • direct == CUBLAS_DIRECT_BACKWARD: \(H = H(k) ... H(2) H(1)\)T 是下三角矩阵。

仅支持storev == CUBLAS_STOREV_COLUMNWISE,表示定义基本反射器H(i)的向量存储在数组V的第i列中,且\(H = I - V * T * V^{T}\)(对于复数类型为\(H = I - V * T * V^{H}\))。

用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXlarft_bufferSize()返回。

目前仅支持n >= k的场景。

larft的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

direct

host

input

指定基本反射器相乘形成块反射器的顺序。

storev

host

input

指定定义基本反射器的向量如何存储。

n

host

input

块反射器H的阶数。n >= 0

k

host

input

三角因子T的顺序(即基本反射器的数量)。k >= 1

dataTypeV

host

input

数组V的数据类型。

V

device

input

维度为lda * k的矩阵V

ldv

host

input

数组V的主维度。ldv >= max(1,n)

dataTypeTau

host

input

数组tau的数据类型。

tau

device

input

维度 ktau(i) 必须包含初等反射器 H(i) 的标量因子。

dataTypeT

host

input

数组T的数据类型。

T

device

output

维度 ldt * k。块反射器的\(k \times k\)三角因子T。如果direct == CUBLAS_DIRECT_FORWARD,则T为上三角矩阵;如果direct == CUBLAS_DIRECT_BACKWARD,则T为下三角矩阵。

ldt

host

input

数组T的主维度。ldt >= k

computeType

host

input

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXlarft_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXlarft_bufferSize返回。

通用API包含四种不同类型:

  • dataTypeV 是数组 V 的数据类型

  • dataTypeTau 是数组 tau 的数据类型

  • dataTypeT 是数组 T 的数据类型

  • computeType 是运算的计算类型

cusolverDnXlarft 仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型V

数据类型Tau

数据类型T

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SLARFT

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DLARFT

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CLARFT

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZLARFT

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (n == 0, k > n, 或 storev == CUBLAS_STOREV_ROWWISE)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.5. 稠密特征值求解器参考(64位API)

本节介绍cuSolverDN的特征值求解器API,包括双对角化和奇异值分解(SVD)。

2.4.5.1. cusolverDnXgesvd()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXgesvd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    signed char jobu,
    signed char jobvt,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeS,
    const void *S,
    cudaDataType dataTypeU,
    const void *U,
    int64_t ldu,
    cudaDataType dataTypeVT,
    const void *VT,
    int64_t ldvt,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t
cusolverDnXgesvd(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    signed char jobu,
    signed char jobvt,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeS,
    void *S,
    cudaDataType dataTypeU,
    void *U,
    int64_t ldu,
    cudaDataType dataTypeVT,
    void *VT,
    int64_t ldvt,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info)

该函数计算一个\(m \times n\)矩阵A的奇异值分解(SVD)以及对应的左右奇异向量。SVD分解公式表示为

\[A = U*\Sigma*V^{H}\]

其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负,并按降序排列。UV 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。

用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgesvd_bufferSize()返回。

如果输出参数 info = -i(小于零),表示第 i-th 个参数有误(不包含句柄)。如果 bdsqr 未收敛,info 会指明中间双对角形式中有多少条超对角线未能收敛到零。

目前,cusolverDnXgesvd仅支持默认算法。

cusolverDnXgesvd 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

请访问cuSOLVER库示例 - Xgesvd查看代码示例。

备注1: gesvd 仅支持 m>=n

备注2:该例程返回\(V^H\),而非V

cusolverDnXgesvd_bufferSizecusolverDnXgesvd 的输入参数列表:

cusolverDnXgesvd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobu

host

input

指定计算矩阵U全部或部分内容的选项:= 'A':返回数组U中U的所有m列;= 'S':返回数组U中U的前min(m,n)列(左奇异向量);= 'O':将U的前min(m,n)列(左奇异向量)覆盖到数组A上;= 'N':不计算U的任何列(不计算左奇异向量)。

jobvt

host

input

指定计算矩阵V**T全部或部分内容的选项:= 'A':在数组VT中返回V**T的所有N行;= 'S':在数组VT中返回V**T的前min(m,n)行(右奇异向量);= 'O':将V**T的前min(m,n)行(右奇异向量)覆盖写入数组A;= 'N':不计算V**T的任何行(不计算右奇异向量)。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

dataTypeA

host

input

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,m)。退出时,A的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeS

host

input

数组S的数据类型。

S

device

output

维度为min(m,n)的实数数组。A的奇异值,按S(i) >= S(i+1)排序。

dataTypeU

host

input

数组U的数据类型。

U

device

output

维度为ldu * m的数组,其中ldu不小于max(1,m)U包含\(m \times m\)酉矩阵U

ldu

host

input

用于存储矩阵U的二维数组的主维度。

dataTypeVT

host

input

数组VT的数据类型。

VT

device

output

维度为ldvt * n的数组,其中ldvt不小于max(1,n)VT包含\(n \times n\)酉矩阵V**T。

ldvt

host

input

用于存储矩阵Vt的二维数组的主维度。

computeType

host

input

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXgesvd_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXgesvd_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle)。如果info > 0info表示中间双对角形式中有多少超对角线未能收敛到零。

通用API包含三种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeVT表示矩阵VT的数据类型,computeType表示运算的计算类型。cusolverDnXgesvd仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

数据类型S

数据类型U

数据类型VT

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SGESVD

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DGESVD

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CGESVD

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZGESVD

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0ldalduldvt)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.5.2. cusolverDnXgesvdp()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXgesvdp_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobz,
    int econ,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeS,
    const void *S,
    cudaDataType dataTypeU,
    const void *U,
    int64_t ldu,
    cudaDataType dataTypeV,
    const void *V,
    int64_t ldv,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t
cusolverDnXgesvdp(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobz,
    int econ,
    int64_t m,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeS,
    void *S,
    cudaDataType dataTypeU,
    void *U,
    int64_t ldu,
    cudaDataType dataTypeV,
    void *V,
    int64_t ldv,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *d_info,
    double *h_err_sigma)

该函数计算一个\(m \times n\)矩阵A的奇异值分解(SVD)以及对应的左右奇异向量。SVD分解公式表示为

\[A = U*\Sigma*V^H\]

其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负,并按降序排列。UV 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。

cusolverDnXgesvdp 结合了文献[14]中的极分解和cusolverDnXsyevd来计算SVD。它比基于QR算法的cusolverDnXgesvd快得多。然而,当矩阵A具有接近零的奇异值时,文献[14]中的极分解可能无法提供完整的酉矩阵。为了解决奇异值接近零时的问题,我们添加了一个小的扰动,使极分解能够提供正确的结果。这样做的后果是奇异值会因这个扰动而产生偏移而不准确。输出参数h_err_sigma就是这个扰动的大小。换句话说,h_err_sigma显示了SVD的准确性。

用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgesvdp_bufferSize()返回。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnXgesvdp仅支持默认算法。

cusolverDnXgesvdp 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

请访问cuSOLVER库示例 - Xgesvdp查看代码示例。

备注1: gesvdp 也支持 n>=m

备注2:该例程返回V,而非\(V^{H}\)

cusolverDnXgesvdp_bufferSizecusolverDnXgesvdp 的输入参数列表:

cusolverDnXgesvdp的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobz

host

input

指定选项以仅计算奇异值或同时计算奇异向量:

jobz = CUSOLVER_EIG_MODE_NOVECTOR : 仅计算奇异值。

jobz = CUSOLVER_EIG_MODE_VECTOR : 计算奇异值和奇异向量。

econ

host

input

econ = 1 表示对 UV 采用经济型尺寸。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

dataTypeA

host

input

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,m)。退出时,A的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeS

host

input

数组S的数据类型。

S

device

output

维度为min(m,n)的实数数组。A的奇异值,按S(i) >= S(i+1)排序。

dataTypeU

host

input

数组U的数据类型。

U

device

output

维度为ldu * m的数组,其中ldu不小于max(1,m)U包含\(m \times m\)酉矩阵U。如果econ=1,则仅报告U的前min(m,n)列。

ldu

host

input

用于存储矩阵U的二维数组的主维度。

dataTypeV

host

input

数组V的数据类型。

V

device

output

维度为ldv * n的数组,其中ldv不小于max(1,n)V包含\(n \times n\)酉矩阵V。如果econ=1,则仅报告V的前min(m,n)列。

ldv

host

input

用于存储矩阵V的二维数组的主维度。

computeType

host

input

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXgesvdp_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的大小(以字节为单位),由cusolverDnXgesvdp_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle参数)。

h_err_sigma

host

output

扰动幅度,显示SVD的准确性。

通用API包含三种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeV表示矩阵V的数据类型,computeType表示运算的计算类型。cusolverDnXgesvdp仅支持以下四种组合:

数据类型与计算类型的有效组合

数据类型A

数据类型S

数据类型U

数据类型V

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SGESVDP

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DGESVDP

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CGESVDP

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZGESVDP

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n<0ldalduldv)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.5.3. cusolverDnXgesvdr()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXgesvdr_bufferSize (
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    signed char jobu,
    signed char jobv,
    int64_t m,
    int64_t n,
    int64_t k,
    int64_t p,
    int64_t niters,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeSrand,
    const void *Srand,
    cudaDataType dataTypeUrand,
    const void *Urand,
    int64_t ldUrand,
    cudaDataType dataTypeVrand,
    const void *Vrand,
    int64_t ldVrand,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost )

以下例程

cusolverStatus_t
cusolverDnXgesvdr(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    signed char jobu,
    signed char jobv,
    int64_t m,
    int64_t n,
    int64_t k,
    int64_t p,
    int64_t niters,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeSrand,
    void *Srand,
    cudaDataType  dataTypeUrand,
    void *Urand,
    int64_t ldUrand,
    cudaDataType dataTypeVrand,
    void *Vrand,
    int64_t ldVrand,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *d_info)

该函数计算一个\(m \times n\)矩阵A的近似秩k奇异值分解(k-SVD)以及对应的左右奇异向量。k-SVD可表示为

\[A_{k}\approx U*\Sigma*V^{H}\]

其中Σ是一个\(k \times k\)矩阵,除对角线元素外其余均为零,U是一个\(m \times k\)正交矩阵,V是一个\(k \times n\)正交矩阵。Σ的对角线元素是A的近似奇异值,这些值为实数且非负,并按降序排列。UV的列向量分别是A的前k个左右奇异向量。

cusolverDnXgesvdr 实现了文献[15]中描述的随机化方法来计算k-SVD,当满足[15]所述条件时,该方法能以高概率保证计算精度。cusolverDnXgesvdr 专用于快速高质量地计算矩阵A的极小部分谱(即k远小于min(m,n)),尤其适用于大维度矩阵的情况。

该方法的精度取决于矩阵A的谱特性、幂迭代次数niters、过采样参数p以及p与矩阵A维度之间的比率。较大的过采样值p或更多的迭代次数niters可能会产生更精确的近似结果,但也会增加cusolverDnXgesvdr的运行时间。

我们建议使用两次迭代,并将过采样设置为至少2k。一旦求解器提供足够的精度,可以调整kniters的值以获得更好的性能。

用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgesvdr_bufferSize()函数返回。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

目前,cusolverDnXgesvdr仅支持默认算法。

cusolverDnXgesvdr 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

请访问cuSOLVER库示例 - Xgesvdr查看代码示例。

备注1: gesvdr 也支持 n>=m

备注2:该例程返回V,而非\(V^{H}\)

cusolverDnXgesvdr_bufferSizecusolverDnXgesvdr 的输入参数列表:

cusolverDnXgesvdr API

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobu

host

input

指定计算矩阵U全部或部分内容的选项:= 'S':在数组U中返回U的前k列(左奇异向量);= 'N':不计算U的任何列(不计算左奇异向量)。

jobv

host

input

指定计算矩阵V全部或部分内容的选项:= 'S':将V的前k行(右奇异向量)返回到数组V中;= 'N':不计算V的任何行(不计算右奇异向量)。

m

host

input

矩阵A的行数。

n

host

input

矩阵A的列数。

k

host

input

矩阵A的k-SVD分解的秩。rank小于min(m,n)

p

host

input

过采样。子空间的大小将为(k + p)(k+p)小于min(m,n)

niters

host

input

幂方法的迭代次数。

dataTypeA

host

input

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,m)。退出时,A的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeS

host

input

数组S的数据类型。

S

device

output

维度为min(m,n)的实数数组。A的奇异值,按S(i) >= S(i+1)排序。

dataTypeU

host

input

数组U的数据类型。

U

device

output

维度为ldu * m的数组,其中ldu不小于max(1,m)U包含\(m \times m\)酉矩阵U。如果jobu=S,则仅报告U的前min(m,n)列。

ldu

host

input

用于存储矩阵U的二维数组的主维度。

dataTypeV

host

input

数组V的数据类型。

V

device

output

维度为ldv * n的数组,其中ldv不小于max(1,n)V包含\(n \times n\)酉矩阵V。如果jobv=S,则仅报告V的前min(m,n)列。

ldv

host

input

用于存储矩阵V的二维数组的主维度。

computeType

host

input

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXgesvdr_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXgesvdr_bufferSize返回。

d_info

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i-th个参数错误(不包含handle参数)。

通用API包含五种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeV表示矩阵V的数据类型,computeType表示运算的计算类型。cusolverDnXgesvdr仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

数据类型S

数据类型U

数据类型V

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SGESVDR

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DGESVDR

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CGESVDR

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZGESVDR

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (m,n<0ldalduldv )。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.5.4. cusolverDnXsyevd()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXsyevd_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t
cusolverDnXsyevd(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    void *W,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info)

使用通用API接口计算对称(厄米特)\(n \times n\)矩阵A的特征值和特征向量。标准对称特征值问题为

\[A*V = V*\Lambda\]

其中 Λ 是一个实数的 \(n \times n\) 对角矩阵。V 是一个 \(n \times n\) 酉矩阵。Λ 的对角线元素是 A 的特征值,按升序排列。

用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXsyevd_bufferSize()返回。

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

请访问cuSOLVER库示例 - Xsyevd查看代码示例。

目前,cusolverDnXsyevd仅支持默认算法。

cusolverDnXsyevd支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXsyevd_bufferSizecusolverDnXsyevd 的输入参数列表:

cusolverDnXsyevd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)。如果uplo = CUBLAS_FILL_MODE_UPPER,则A的前n×n上三角部分包含矩阵A的上三角部分。如果uplo = CUBLAS_FILL_MODE_LOWER,则A的前n×n下三角部分包含矩阵A的下三角部分。退出时,如果jobz = CUSOLVER_EIG_MODE_VECTORinfo = 0,则A包含矩阵A的标准正交特征向量。如果jobz = CUSOLVER_EIG_MODE_NOVECTOR,则A的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeW

host

in

数组W的数据类型。

W

device

output

一个维度为n的实数数组。A的特征值按升序排列,即排序满足W(i) <= W(i+1)

computeType

host

in

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXsyevd_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXsyevd_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i个参数错误(不包含handle)。如果info = i (> 0)info表示中间三对角矩阵中有i个非对角元素未能收敛到零。

通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,computeType表示运算的计算类型。cusolverDnXsyevd仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

数据类型W

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SSYEVD

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DSYEVD

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CHEEVD

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

ZHEEVD

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda<max(1,n),或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.5.5. cusolverDnXsyevdx()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXsyevdx_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    void *vl,
    void *vu,
    int64_t il,
    int64_t iu,
    int64_t *h_meig,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t cusolverDnXsyevdx(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobz,
    cusolverEigRange_t range,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    void * vl,
    void * vu,
    int64_t il,
    int64_t iu,
    int64_t *meig64,
    cudaDataType dataTypeW,
    void *W,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info)

使用通用API接口计算对称(厄米特)\(n \times n\)矩阵A的全部或部分特征值,并可选择计算特征向量。标准对称特征值问题为

\[A*V = V*\Lambda\]

其中Λ是一个实数的n×h_meig对角矩阵。V是一个n×h_meig酉矩阵。h_meig是该例程计算得到的特征值/特征向量数量,当请求整个频谱时(例如range = CUSOLVER_EIG_RANGE_ALL),h_meig等于nΛ的对角线元素是A按升序排列的特征值。

用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXsyevdx_bufferSize()返回。

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

目前,cusolverDnXsyevdx仅支持默认算法。

请访问cuSOLVER库示例 - Xsyevdx查看代码示例。

cusolverDnXsyevdx 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXsyevdx_bufferSizecusolverDnXsyevdx 的输入参数列表:

cusolverDnXsyevdx的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

range

host

input

指定需要计算的特征值及可选特征向量的选择选项:range = CUSOLVER_EIG_RANGE_ALL:将计算所有特征值/特征向量,相当于经典的syevd/heevd例程;range = CUSOLVER_EIG_RANGE_V:将计算半开区间(vl,vu]内的所有特征值/特征向量;range = CUSOLVER_EIG_RANGE_I:将计算从第il个到第iu个的特征值/特征向量;

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)。如果uplo = CUBLAS_FILL_MODE_UPPER,则A的前n×n上三角部分包含矩阵A的上三角部分。如果uplo = CUBLAS_FILL_MODE_LOWER,则A的前n×n下三角部分包含矩阵A的下三角部分。退出时,如果jobz = CUSOLVER_EIG_MODE_VECTORinfo = 0,则A包含矩阵A的标准正交特征向量。如果jobz = CUSOLVER_EIG_MODE_NOVECTOR,则A的内容将被销毁。

lda

host

input

用于存储矩阵A的二维数组的主维度。lda不小于max(1,n)

vl,vu

host

input

如果 range = CUSOLVER_EIG_RANGE_V,则表示要搜索特征值的区间上下界。vl > vu。如果 range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_I 则不引用该参数。需要注意的是,当特征值非常接近时,众所周知,两种不同的特征值计算例程可能会在同一区间内找到略微不同数量的特征值。这是由于不同的特征值算法,甚至相同算法但不同运行可能会在接近机器精度的舍入误差范围内找到特征值。因此,如果用户希望确保不遗漏区间内的任何特征值,我们建议用户对区间边界加减一个极小值(机器精度),例如 (vl=vl-eps, vu=vu+eps]。此建议适用于 cuSolver 或 LAPACK 中的任何选择性例程。

il,iu

host

input

整数。如果range = CUSOLVER_EIG_RANGE_I,则表示要返回的最小和最大特征值的索引(按升序排列)。当n > 0时,需满足1 <= il <= iu <= n;当n = 0时,il = 1且iu = 0。如果range = CUSOLVER_EIG_RANGE_ALLrange = CUSOLVER_EIG_RANGE_V,则不引用此参数。

h_meig

host

output

整数。找到的特征值总数。0 <= h_meig <= n。如果 range = CUSOLVER_EIG_RANGE_ALL,则 h_meig = n;如果 range = CUSOLVER_EIG_RANGE_I,则 h_meig = iu-il+1。

dataTypeW

host

in

数组W的数据类型。

W

device

output

一个维度为n的实数数组。A的特征值按升序排列,即排序满足W(i) <= W(i+1)

computeType

host

in

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXsyevdx_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXsyevdx_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i个参数错误(不包含handle)。如果info = i (> 0)info表示中间三对角矩阵中有i个非对角元素未能收敛到零。

通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,而computeType表示运算的计算类型。cusolverDnXsyevdx仅支持以下四种组合:

数据类型与计算类型的有效组合

数据类型A

数据类型W

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SSYEVDX

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DSYEVDX

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CHEEVDX

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

ZHEEVDX

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda<max(1,n),或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或range不是CUSOLVER_EIG_RANGE_ALLCUSOLVER_EIG_RANGE_VCUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.5.6. cusolverDnXsyevBatched()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXsyevBatched_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t  jobz,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost,
    int64_t batchSize)

以下例程:

cusolverStatus_t
cusolverDnXsyevBatched(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    void *W,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info,
    int64_t batchSize)

计算一系列对称(厄米特)\(n \times n\)矩阵的特征值和特征向量

\[A_j*V_j = V_j*\Lambda_j\]

其中\(\Lambda_j\)是一个实数的\(n \times n\)对角矩阵。\(V_j\)是一个\(n \times n\)酉矩阵。\(\Lambda_j\)的对角线元素是\(A_j\)按升序排列的特征值。

syevBatched 对每个矩阵执行特征分解。它要求所有矩阵具有相同的大小 n 并且以连续方式打包。

\[\begin{split}A = \begin{pmatrix} {A0} & {A1} & \cdots \\ \end{pmatrix}\end{split}\]

每个矩阵都是列优先存储,其前导维度为lda,因此随机访问的公式为\(A_{k}\operatorname{(i,j)} = {A\lbrack\ i\ +\ lda*j\ +\ lda*n*k\rbrack}\)

参数 W 还以连续方式包含每个矩阵的特征值,

\[\begin{split}W = \begin{pmatrix} {W0} & {W1} & \cdots \\ \end{pmatrix}\end{split}\]

W随机访问的公式为\(W_{k}\operatorname{(j)} = {W\lbrack\ j\ +\ n*k\rbrack}\)

用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDeviceworkspaceInBytesOnHost表示设备和主机工作空间的字节大小,这些值由cusolverDnXsyevBatched_bufferSize()返回。

输出参数 info 是一个大小为 batchSize 的整数数组。如果函数返回 CUSOLVER_STATUS_INVALID_VALUE,第一个元素 info[0] = -i(小于零)表示第 i-th 个参数有误(不包含句柄)。否则,如果 info[i] > 0,表示 syevBatched 在第 i-th 个矩阵上未收敛。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,\(A_{j}\) 包含矩阵 \(A_{j}\) 的标准正交特征向量。

目前,cusolverDnXsyevBatched仅支持默认算法。

cusolverDnXsyevBatched支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXsyevBatched_bufferSizecusolverDnXsyevBatched 的输入参数列表:

cusolverDnXsyevBatched的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobz

host

input

指定计算选项:仅计算特征值或计算特征对:jobz = CUSOLVER_EIG_MODE_NOVECTOR:仅计算特征值;jobz = CUSOLVER_EIG_MODE_VECTOR:计算特征值和特征向量。

uplo

host

input

指定A的哪一部分被存储。uplo = CUBLAS_FILL_MODE_LOWER:存储A的下三角部分。uplo = CUBLAS_FILL_MODE_UPPER:存储A的上三角部分。

n

host

input

矩阵A的行数(或列数)。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n * batchSize的数组,其中lda不小于max(1,n)。如果uplo = CUBLAS_FILL_MODE_UPPER,则Aj的前n×n上三角部分包含矩阵Aj的上三角部分。如果uplo = CUBLAS_FILL_MODE_LOWER,则Aj的前n×n下三角部分包含矩阵Aj的下三角部分。退出时,如果jobz = CUSOLVER_EIG_MODE_VECTORinfo[j] = 0,则Aj包含矩阵Aj的标准正交特征向量。如果jobz = CUSOLVER_EIG_MODE_NOVECTOR,则Aj的内容将被销毁。

lda

host

input

用于存储矩阵Aj的二维数组的主维度。lda不小于max(1,n)

dataTypeW

host

in

数组W的数据类型。

W

device

output

一个维度为n * batchSize的实数数组。包含Aj的特征值,按升序排列,即排序满足Wj(i) <= Wj(i+1)

computeType

host

in

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXsyevBatched_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXsyevBatched_bufferSize返回。

信息

device

output

一个维度为batchSize的整数数组。如果返回CUSOLVER_STATUS_INVALID_VALUEinfo[0] = -i(小于零)表示第i个参数错误(不包含句柄)。否则,如果info[i] = 0,则表示操作成功。如果info[i] > 0,则syevBatched在第i个矩阵上未收敛。

batchSize

host

input

矩阵数量。

通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示数组W的数据类型,computeType表示运算的计算类型。cusolverDnXsyevBatched仅支持以下四种组合:

数据类型与计算类型的有效组合

数据类型A

数据类型W

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SSYEVBATCHED

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DSYEVBATCHED

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CSYEVBATCHED

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

ZSYEVBATCHED

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR,或uplo不是CUBLAS_FILL_MODE_LOWERCUBLAS_FILL_MODE_UPPER,或batchSize<0)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.4.5.7. cusolverDnXgeev()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverDnXgeev_bufferSize(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobvl,
    cusolverEigMode_t jobvr,
    int64_t n,
    cudaDataType dataTypeA,
    const void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    const void *W,
    cudaDataType dataTypeVL,
    const void *VL,
    int64_t ldvl,
    cudaDataType dataTypeVR,
    const void *VR,
    int64_t ldvr,
    cudaDataType computeType,
    size_t *workspaceInBytesOnDevice,
    size_t *workspaceInBytesOnHost)

以下例程:

cusolverStatus_t
cusolverDnXgeev(
    cusolverDnHandle_t handle,
    cusolverDnParams_t params,
    cusolverEigMode_t jobvl,
    cusolverEigMode_t jobvr,
    int64_t n,
    cudaDataType dataTypeA,
    void *A,
    int64_t lda,
    cudaDataType dataTypeW,
    void *W,
    cudaDataType dataTypeVL,
    void *VL,
    int64_t ldvl,
    cudaDataType dataTypeVR,
    void *VR,
    int64_t ldvr,
    cudaDataType computeType,
    void *bufferOnDevice,
    size_t workspaceInBytesOnDevice,
    void *bufferOnHost,
    size_t workspaceInBytesOnHost,
    int *info)

计算一个n×n实数非对称或复数非埃尔米特矩阵A的特征值,并可选择计算左和/或右特征向量。矩阵A的右特征向量v(j)满足

\[A*v(j) = w(j)*v(j)\]

其中 w(j) 是其特征值。矩阵 A 的左特征向量 u(j) 满足

\[u(j)^{H}*A = w(j)*v(j)^{H}\]

其中 \(u(j)^{H}\) 表示 u(j) 的共轭转置。

计算得到的特征向量经过归一化处理,使其欧几里得范数等于1,且最大分量为实数。

如果A是实数值,有两种方式可以在W中返回特征值。第一种选项将所有数据类型设置为实数值类型。此时W包含2*n个条目,前n个条目存储实部,后n个条目存储虚部。通过设置指针WR = WWI = W+n,可以恢复使用独立数组WRWI分别存储实部和虚部的LAPACK接口。第二种选项对W使用复数数据类型。此时W长度为n个条目;每个实特征值存储为复数,对于每个共轭复数对,两个特征值都会被返回。计算过程仍然完全以实数运算执行。

用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevicebufferOnHost指向。输入参数workspaceInBytesOnDeviceworkspaceInBytesOnHost表示设备和主机工作空间的字节大小,这些值由cusolverDnXsyevBatched_bufferSize()返回。

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。若 info = 0,则 QR 算法收敛且 W 包含计算得到的 A 的特征值;若请求,则已计算对应的左和/或右特征向量。若 info = i(大于零),则 QR 算法未能计算所有特征值且未计算任何特征向量。Wi+1:n 元素包含已收敛的特征值。

备注1: geev 仅支持计算右特征向量。因此,必须设置 jobvl = CUSOLVER_EIG_MODE_NOVECTOR

备注2:geev 使用平衡技术来改善特征值和特征向量的条件数。

备注3: geev 是一种混合CPU-GPU算法。使用固定主机内存可获得最佳性能。

目前,cusolverDnXgeev仅支持默认算法。

cusolverDnXgeev 支持的算法

CUSOLVER_ALG_0NULL

默认算法。

cusolverDnXgeev_bufferSizecusolverDnXgeev 的输入参数列表:

cusolverDnXgeev的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverDN库上下文的句柄。

params

host

input

包含由cusolverDnSetAdvOptions收集信息的结构体。

jobvl

host

input

指定是否计算左特征向量。jobvl = CUSOLVER_EIG_MODE_NOVECTOR:不计算A的左特征向量;jobvl = CUSOLVER_EIG_MODE_VECTOR:计算A的左特征向量。

jobvr

host

input

指定是否计算右特征向量。jobvl = CUSOLVER_EIG_MODE_NOVECTOR:不计算A的左特征向量;jobvl = CUSOLVER_EIG_MODE_VECTOR:计算A的左特征向量。

n

host

input

矩阵A的行数(或列数)。

dataTypeA

host

in

数组 A 的数据类型。

A

device

输入/输出

维度为lda * n的数组,其中lda不小于max(1,n)。输入时是n×n矩阵A。输出时,A已被覆盖。

lda

host

input

用于存储矩阵A的二维数组的主维度。

dataTypeW

host

in

数组W的数据类型。

W

device

output

存储计算得到的A特征值的数组。如果dataTypeA = CUDA_R_32FdataTypeW = CUDA_R_32F,或者dataTypeA = CUDA_R_64FdataTypeW = CUDA_R_64F,则其长度为2*n,其中W的前n个元素存储特征值的实部,后n个元素存储特征值的虚部。否则,长度为n

dataTypeVL

host

in

数组VL的数据类型。

VL

device

output

维度为ldvl * n的数组。如果jobvl = CUSOLVER_EIG_MODE_VECTOR,则左特征向量u(j)会按特征值的顺序依次存储在VL的列中。如果datatypeVL为复数或第j-th个特征值为实数,则u(j) = VL(:,j)(即VL的第j-th列)。如果dataTypeVL为实数且第j-th与第(j+1)-st个特征值构成共轭复数对,则u(j) = VL(:,j) + i*VL(:,j+1)u(j+1) = VL(:,j) - i*VL(:,j+1)。如果jobvl = CUSOLVER_EIG_MODE_NOVECTOR,则不会引用VL

ldvl

host

input

用于存储矩阵VL的二维数组的主维度,其中ldvl >= 1。如果jobvl = CUSOLVER_EIG_MODE_VECTOR,则ldvl >= n

dataTypeVR

host

in

数组VR的数据类型。

VR

device

output

维度为ldvr * n的数组。如果jobvr = CUSOLVER_EIG_MODE_VECTOR,则右特征向量v(j)会按特征值顺序依次存储在VR的列中。若datatypeVR为复数或第j-th个特征值为实数,则v(j) = VR(:,j)(即VR的第j-th列)。若dataTypeVR为实数且第j-th与第(j+1)-st个特征值构成共轭复数对,则v(j) = VR(:,j) + i*VR(:,j+1)v(j+1) = VR(:,j) - i*VR(:,j+1)。如果jobvr = CUSOLVER_EIG_MODE_NOVECTOR,则不会引用VR

ldvr

host

input

用于存储矩阵VR的二维数组的主维度,其中ldvr >= 1。如果jobvr = CUSOLVER_EIG_MODE_VECTOR,则ldvr >= n

computeType

host

in

计算的数据类型。

bufferOnDevice

device

输入/输出

设备工作空间。一个类型为void的数组,大小为workspaceInBytesOnDevice字节。

workspaceInBytesOnDevice

host

input

bufferOnDevice的字节大小,由cusolverDnXsyevBatched_bufferSize返回。

bufferOnHost

host

输入/输出

主机工作区。大小为workspaceInBytesOnHost字节的void类型数组。

workspaceInBytesOnHost

host

input

bufferOnHost的字节大小,由cusolverDnXsyevBatched_bufferSize返回。

信息

device

output

如果info = 0,表示操作成功。如果info = -i,表示第i个参数错误(不包含handle)。如果info = i(大于零),表示QR算法未能计算出所有特征值且未计算出任何特征向量;Wi+1:n的元素包含已收敛的特征值。

通用API包含五种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示数组W的数据类型,dataTypeVL表示矩阵VL的数据类型,dataTypeVR表示矩阵VR的数据类型,而computeType表示运算的计算类型。cusolverDnXgeev仅支持以下四种组合:

数据类型与计算类型的有效组合

DataTypeA

DataTypeW

DataTypeVL

DataTypeVR

ComputeType

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SGEEV

CUDA_R_32F

CUDA_C_32F

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

32位混合实数-复数

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DGEEV

CUDA_R_64F

CUDA_C_64F

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

64位混合实数-复数

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CGEEV

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZGEEV

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(jobvl不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或jobvr不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTORn<0,或lda < max(1,n),或当jobvlCUSOLVER_EIG_MODE_VECTORldvl < n,或当jobvrCUSOLVER_EIG_MODE_VECTORldvr < n)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.5. cuSolverSP: 稀疏线性代数函数库参考

本节介绍cuSolverSP的API,它为CSR或CSC格式的稀疏矩阵提供了LAPACK函数的一个子集。

2.5.1. 辅助函数参考

2.5.1.1. cusolverSpCreate()

cusolverStatus_t
cusolverSpCreate(cusolverSpHandle_t *handle)

该函数用于初始化cuSolverSP库并在cuSolver上下文中创建一个句柄。在调用任何其他cuSolverSP API函数之前,必须先调用此函数。它会分配访问GPU所需的硬件资源。

输出

handle

指向cuSolverSP上下文句柄的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

初始化成功。

CUSOLVER_STATUS_NOT_INITIALIZED

CUDA运行时初始化失败。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

2.5.1.2. cusolverSpDestroy()

cusolverStatus_t
cusolverSpDestroy(cusolverSpHandle_t handle)

该函数释放由cuSolverSP库使用的CPU端资源。

输入

handle

cuSolverSP上下文的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

关闭成功。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.5.1.3. cusolverSpSetStream()

cusolverStatus_t
cusolverSpSetStream(cusolverSpHandle_t handle, cudaStream_t streamId)

此函数设置cuSolverSP库用于执行其例程的流。

输入

handle

cuSolverSP上下文的句柄。

streamId

该库要使用的流。

返回状态

CUSOLVER_STATUS_SUCCESS

流设置成功。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.5.1.4. cusolverSpXcsrissym()

cusolverStatus_t
cusolverSpXcsrissymHost(cusolverSpHandle_t handle,
              int m,
              int nnzA,
              const cusparseMatDescr_t descrA,
              const int *csrRowPtrA,
              const int *csrEndPtrA,
              const int *csrColIndA,
              int *issym);

该函数检查A是否具有对称模式。如果A是对称的,输出参数issym将返回1;否则返回0。

矩阵 A 是一个 \(m \times m\) 稀疏矩阵,由四个数组 csrValAcsrRowPtrAcsrEndPtrAcsrColIndA 以 CSR 存储格式定义。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL

csrlsvlucsrlsvqr 不接受非通用矩阵。用户需要将矩阵扩展至其缺失的上/下三角部分,否则结果将不符合预期。用户可以使用 csrissym 来检查矩阵是否具有对称模式。

备注1:仅提供CPU路径。

Remark 2: the user has to check returned status to get valid information. The function converts A to CSC format and compare CSR and CSC format. If the CSC failed because of insufficient resources, issym is undefined, and this state can only be detected by the return status code.

输入

参数

内存空间

描述

handle

host

cuSolverSP库上下文的句柄。

m

host

矩阵A的行数和列数。

nnzA

host

矩阵A的非零元素数量。它是csrValAcsrColIndA的大小。

描述A

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrRowPtrA

host

包含每行起始位置的m个元素的整数数组。

csrEndPtrA

host

包含最后一行末尾加1的m个元素的整数数组。

csrColIndA

host

矩阵A非零元素的nnzA列索引整数数组。

输出

参数

内存空间

描述

issym

host

1 如果 A 是对称的;否则为 0。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.2. 高级函数参考

This section describes high level API of cuSolverSP, including linear solver, least-square solver and eigenvalue solver. The high-level API is designed for ease-of-use, so it allocates any required memory under the hood automatically. If the host or GPU system memory is not enough, an error is returned.

2.5.2.1. cusolverSpcsrlsvlu() [已弃用]

[[已弃用]] 请使用cuDSS库。该例程将在下一个主要版本中移除。 我们还提供了一个示例来描述其工作流程。

cusolverStatus_t
cusolverSpScsrlsvlu[Host](cusolverSpHandle_t handle,
                 int n,
                 int nnzA,
                 const cusparseMatDescr_t descrA,
                 const float *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const float *b,
                 float tol,
                 int reorder,
                 float *x,
                 int *singularity);

cusolverStatus_t
cusolverSpDcsrlsvlu[Host](cusolverSpHandle_t handle,
                 int n,
                 int nnzA,
                 const cusparseMatDescr_t descrA,
                 const double *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const double *b,
                 double tol,
                 int reorder,
                 double *x,
                 int *singularity);

cusolverStatus_t
cusolverSpCcsrlsvlu[Host](cusolverSpHandle_t handle,
                 int n,
                 int nnzA,
                 const cusparseMatDescr_t descrA,
                 const cuComplex *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const cuComplex *b,
                 float tol,
                 int reorder,
                 cuComplex *x,
                 int *singularity);

cusolverStatus_t
cusolverSpZcsrlsvlu[Host](cusolverSpHandle_t handle,
                 int n,
                 int nnzA,
                 const cusparseMatDescr_t descrA,
                 const cuDoubleComplex *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const cuDoubleComplex *b,
                 double tol,
                 int reorder,
                 cuDoubleComplex *x,
                 int *singularity);

该函数用于求解线性系统

\[A*x = b\]

其中 A 是一个 \(n \times n\) 稀疏矩阵,由三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。b 是大小为 n 的右侧向量,x 是大小为 n 的解向量。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果矩阵A是对称/厄米特矩阵且仅使用或需要下/上三角部分,用户必须将矩阵扩展至缺失的上/下三角部分,否则结果将出错。

该线性系统通过带部分主元消去的稀疏LU分解求解:

\[P*A = L*U\]

cusolver库提供了三种重排序方案:symrcmsymamdcsrmetisnd,用于减少零填充,这会显著影响LU分解的性能。当输入参数reorder为1(2或3)时,可启用symrcmsymamdcsrmetisnd),否则不执行重排序。

如果 reorder 非零,csrlsvlu 会执行

\[P*A*Q^{T} = L*U\]

其中 \(Q = {symrcm}(A + A^{T})\)

如果 A 在给定容差 (max(tol,0)) 下是奇异的,那么 U 的某些对角线元素为零,即

\[{|U(j,j)|} < {tol\ for\ some\ j}\]

输出参数 singularity 是此类 j 的最小索引。如果 A 是非奇异的,则 singularity 为 -1。该索引基于0,与 A 的基索引无关。例如,如果 A 的第二列与第一列相同,则 A 是奇异的且 singularity = 1,这意味着 U(1,1)≈0

备注1:csrlsvlu执行带部分主元消去的传统LU分解,第k列的主元根据中间矩阵的第k列动态确定。csrlsvlu遵循Gilbert和Peierls提出的算法[4],该算法使用深度优先搜索和拓扑排序来求解三角系统(Davis在其著作[1]中也详细描述了该算法)。自CUDA 10.1起,csrlsvlu将增量式重新分配内存以存储LU。此特性可避免QR分解时的内存高估。在某些情况下,QR分解的零填充量可能比LU分解高出一个数量级。

备注2:仅提供CPU(主机)路径。

输入

参数

cusolverSp 内存空间

*主机内存空间

描述

handle

host

host

cuSolverSP库上下文的句柄。

n

host

host

矩阵A的行数和列数。

nnzA

host

host

矩阵A的非零元素数量。

描述A

host

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

device

host

数组,包含矩阵 AnnzA\(( =\)csrRowPtrA(n)\(-\)csrRowPtrA(0)\()\) 个非零元素。

csrRowPtrA

device

host

一个包含每行起始位置及最后一行末尾加1的n\(+ 1\)个元素的整数数组。

csrColIndA

device

host

整数数组,长度为nnzA\(( =\)csrRowPtrA(n)\(-\)csrRowPtrA(0)\()\),表示矩阵A非零元素的列索引。

b

device

host

右侧向量,大小为 n

tol

host

host

用于判断是否为奇异值的容差。

reorder

host

host

如果reorder=0则不进行排序。否则将使用symrcmsymamdcsrmetisnd来减少零填充。

输出

参数

cusolverSp 内存空间

*主机内存空间

描述

x

device

host

大小为 n 的解向量,x = inv(A)*b。

singularity

host

host

如果A可逆则返回-1。否则返回第一个满足U(j,j)≈0的索引j

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n,nnzA<=0, 基索引不是0或1, reorder不是0,1,2,3)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.2.2. cusolverSpcsrlsvqr()

cusolverStatus_t
cusolverSpScsrlsvqr[Host](cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const float *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const float *b,
                 float tol,
                 int reorder,
                 float *x,
                 int *singularity);

cusolverStatus_t
cusolverSpDcsrlsvqr[Host](cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const double *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const double *b,
                 double tol,
                 int reorder,
                 double *x,
                 int *singularity);

cusolverStatus_t
cusolverSpCcsrlsvqr[Host](cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const cuComplex *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const cuComplex *b,
                 float tol,
                 int reorder,
                 cuComplex *x,
                 int *singularity);

cusolverStatus_t
cusolverSpZcsrlsvqr[Host](cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const cuDoubleComplex *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 const cuDoubleComplex *b,
                 double tol,
                 int reorder,
                 cuDoubleComplex *x,
                 int *singularity);

该函数用于求解线性系统

\[A*x = b\]

A 是一个 \(m \times m\) 的稀疏矩阵,由三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。b 是大小为 m 的右侧向量,x 是大小为 m 的解向量。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果矩阵A是对称/厄米特矩阵且仅使用或需要下/上三角部分,用户必须将矩阵扩展至缺失的上/下三角部分,否则结果将出错。

线性系统通过稀疏QR分解求解,

\[A\ =\ Q*R\]

如果 A 在给定容差 (max(tol,0)) 下是奇异的,那么 R 的某些对角元素为零,即

\[{|R(j,j)|} < {tol\ for\ some\ j}\]

输出参数 singularity 是此类 j 的最小索引。如果 A 是非奇异的,则 singularity 为 -1。singularity 采用基0计数,与 A 的基索引无关。例如,如果 A 的第二列与第一列相同,则 A 是奇异的且 singularity = 1,这意味着 R(1,1)≈0

cusolver库提供了三种重排序方案:symrcmsymamdcsrmetisnd,用于减少零填充现象,这对QR分解的性能有显著影响。当输入参数reorder为1(2或3)时,可启用symrcmsymamdcsrmetisnd)方案,否则不执行重排序。

输入

参数

cusolverSp 内存空间

*主机内存空间

描述

handle

host

host

cuSolverSP库上下文的句柄。

m

host

host

矩阵A的行数和列数。

nnz

host

host

矩阵A的非零元素数量。

描述A

host

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

device

host

<type> 矩阵 Annz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\) 个非零元素的数组。

csrRowPtrA

device

host

一个包含每行起始位置及最后一行末尾加1的m\(+ 1\)个元素的整数数组。

csrColIndA

device

host

矩阵A非零元素的nnz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\)个列索引的整数数组。

b

device

host

右侧向量,大小为 m

tol

host

host

用于判断是否为奇异值的容差。

reorder

host

host

如果reorder=0则不进行排序。否则将使用symrcmsymamdcsrmetisnd来减少零填充。

输出

参数

cusolverSp 内存空间

*主机内存空间

描述

x

device

host

大小为m的解向量,x = inv(A)*b。

singularity

host

host

如果A可逆则为-1。否则返回第一个满足R(j,j)≈0的索引j

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,nnz<=0,基索引不是0或1,reorder不是0,1,2,3)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.2.3. cusolverSpcsrlsvchol() [已弃用]

[[已弃用]] 请使用cuDSS库。该例程将在下一个主要版本中移除。 我们还提供了一个示例来描述其工作流程。

cusolverStatus_t
cusolverSpScsrlsvchol[Host](cusolverSpHandle_t handle,
                     int m,
                     int nnz,
                     const cusparseMatDescr_t descrA,
                     const float *csrVal,
                     const int *csrRowPtr,
                     const int *csrColInd,
                     const float *b,
                     float tol,
                     int reorder,
                     float *x,
                     int *singularity);

cusolverStatus_t
cusolverSpDcsrlsvchol[Host](cusolverSpHandle_t handle,
                     int m,
                     int nnz,
                     const cusparseMatDescr_t descrA,
                     const double *csrVal,
                     const int *csrRowPtr,
                     const int *csrColInd,
                     const double *b,
                     double tol,
                     int reorder,
                     double *x,
                     int *singularity);

cusolverStatus_t
cusolverSpCcsrlsvchol[Host](cusolverSpHandle_t handle,
                     int m,
                     int nnz,
                     const cusparseMatDescr_t descrA,
                     const cuComplex *csrVal,
                     const int *csrRowPtr,
                     const int *csrColInd,
                     const cuComplex *b,
                     float tol,
                     int reorder,
                     cuComplex *x,
                     int *singularity);

cusolverStatus_t
cusolverSpZcsrlsvchol[Host](cusolverSpHandle_t handle,
                     int m,
                     int nnz,
                     const cusparseMatDescr_t descrA,
                     const cuDoubleComplex *csrVal,
                     const int *csrRowPtr,
                     const int *csrColInd,
                     const cuDoubleComplex *b,
                     double tol,
                     int reorder,
                     cuDoubleComplex *x,
                     int *singularity);

该函数用于求解线性系统

\[A*x = b\]

A 是一个 \(m \times m\) 对称正定稀疏矩阵,由三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。b 是大小为 m 的右侧向量,x 是大小为 m 的解向量。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL,且会忽略A的上三角部分(如果参数reorder为零)。换句话说,假设输入矩阵A可分解为\(A = L + D + U\),其中L是下三角矩阵,D是对角矩阵,U是上三角矩阵。该函数将忽略U,并将A视为对称矩阵,公式为\(A = L + D + L^{H}\)。如果参数reorder非零,用户需要将A扩展为完整矩阵,否则计算结果将出错。

该线性系统通过稀疏Cholesky分解求解,

\[A = G*G^{H}\]

其中 G 是Cholesky因子,一个下三角矩阵。

输出参数 singularity 具有两种含义:

  • 如果A不是正定矩阵,则存在某个整数k使得A(0:k, 0:k)不是正定矩阵。singularity是此类k的最小值。

  • 如果 A 在容差范围内(max(tol,0))是正定但接近奇异的,即存在某个整数 k 使得 \(G\begin{pmatrix} {k,k} \\ \end{pmatrix}<={tol}\)singularity 是此类 k 的最小值。

singularity 是基于0的。如果 A 是正定矩阵且在容差范围内不接近奇异,singularity 值为-1。如果用户想知道 A 是否是正定矩阵,设置 tol=0 即可。

cusolver库提供了三种重排序方案:symrcmsymamdcsrmetisnd,用于减少零填充,这会显著影响Cholesky分解的性能。输入参数reorder可以启用symrcm(当reorder为1时)、symamd(为2时)或csrmetisnd(为3时),否则不执行重排序。

备注1:该函数支持原地操作(xb指向同一内存块)和非原地操作。

备注2:该函数仅适用于32位索引,如果矩阵G存在大量零填充导致非零元素数量超过\(2^{31}\),则会返回CUSOLVER_STATUS_ALLOC_FAILED

输入

参数

cusolverSp 内存空间

*主机内存空间

描述

handle

host

host

cuSolverSP库上下文的句柄。

m

host

host

矩阵A的行数和列数。

nnz

host

host

矩阵A的非零元素数量。

描述A

host

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

device

host

<type> 矩阵 Annz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\) 个非零元素的数组。

csrRowPtrA

device

host

一个包含每行起始位置及最后一行末尾加1的m\(+ 1\)个元素的整数数组。

csrColIndA

device

host

矩阵A非零元素的nnz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\)个列索引的整数数组。

b

device

host

右侧向量,大小为 m

tol

host

host

用于判断奇异性的容差。

reorder

host

host

如果reorder=0则不进行排序。否则将使用symrcmsymamdcsrmetisnd来减少零填充。

输出

参数

cusolverSp 内存空间

*主机内存空间

描述

x

device

host

大小为m的解向量,x = inv(A)*b。

singularity

host

host

如果 A 是对称正定矩阵,则返回 -1。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,nnz<=0,基索引不是0或1,reorder不是0,1,2,3)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.2.4. cusolverSpcsrlsqvqr()

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverSpScsrlsqvqr[Host](cusolverSpHandle_t handle,
                  int m,
                  int n,
                  int nnz,
                  const cusparseMatDescr_t descrA,
                  const float *csrValA,
                  const int *csrRowPtrA,
                  const int *csrColIndA,
                  const float *b,
                  float tol,
                  int *rankA,
                  float *x,
                  int *p,
                  float *min_norm);

cusolverStatus_t
cusolverSpDcsrlsqvqr[Host](cusolverSpHandle_t handle,
                  int m,
                  int n,
                  int nnz,
                  const cusparseMatDescr_t descrA,
                  const double *csrValA,
                  const int *csrRowPtrA,
                  const int *csrColIndA,
                  const double *b,
                  double tol,
                  int *rankA,
                  double *x,
                  int *p,
                  double *min_norm);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverSpCcsrlsqvqr[Host](cusolverSpHandle_t handle,
                  int m,
                  int n,
                  int nnz,
                  const cusparseMatDescr_t descrA,
                  const cuComplex *csrValA,
                  const int *csrRowPtrA,
                  const int *csrColIndA,
                  const cuComplex *b,
                  float tol,
                  int *rankA,
                  cuComplex *x,
                  int *p,
                  float *min_norm);

cusolverStatus_t
cusolverSpZcsrlsqvqr[Host](cusolverSpHandle_t handle,
                  int m,
                  int n,
                  int nnz,
                  const cusparseMatDescr_t descrA,
                  const cuDoubleComplex *csrValA,
                  const int *csrRowPtrA,
                  const int *csrColIndA,
                  const cuDoubleComplex *b,
                  double tol,
                  int *rankA,
                  cuDoubleComplex *x,
                  int *p,
                  double *min_norm);

该函数解决以下最小二乘问题:

\[x = {argmin}{\|}A*z - b{\|}\]

A 是一个 \(m \times n\) 稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。b 是大小为 m 的右侧向量,x 是大小为 n 的最小二乘解向量。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果A是方阵、对称/厄米特矩阵且仅使用或需要下/上三角部分,用户必须将矩阵扩展至其缺失的上/下三角部分,否则结果将出错。

该函数仅在m大于或等于n时有效,换句话说,A是一个高矩阵。

最小二乘问题通过带列主元的稀疏QR分解求解,

\[A*P^{T} = Q*R\]

如果A是满秩的(即A的所有列线性无关),那么矩阵P是一个单位矩阵。假设A的秩为k,小于n,置换矩阵P会以如下方式对A的列进行重新排序:

\[\begin{split}A*P^{T} = \begin{pmatrix} A_1 & A_2 \\ \end{pmatrix} = \begin{pmatrix} Q_1 & Q_2 \\ \end{pmatrix}\begin{pmatrix} R_{11} & R_{12} \\ & R_{22} \\ \end{pmatrix}\end{split}\]

其中 \(R_{11}\)A 具有相同的秩,但 \(R_{22}\) 几乎为零,即 \(A_{2}\) 的每一列都是 \(A_{1}\) 的线性组合。

输入参数 tol 决定数值秩。矩阵 \(R_{22}\) 中每个元素的绝对值都小于等于 tolerance=max(tol,0)

输出参数 rankA 表示 A 的数值秩。

假设 \(y = P*x\)\(c = Q^{H}*b\) ,最小二乘问题可以重新表述为

\[\left. \min\|A*x - b\| = \min\|R*y - c \right.\|\]

或以矩阵形式

\[\begin{split}\begin{pmatrix} R_{11} & R_{12} \\ & R_{22} \\ \end{pmatrix}\begin{pmatrix} y_{1} \\ y_{2} \\ \end{pmatrix} = \begin{pmatrix} c_{1} \\ c_{2} \\ \end{pmatrix}\end{split}\]

输出参数 min_norm\(\left. \|c_{2} \right.\|\),这是最小二乘问题的最小值。

如果A不是满秩矩阵,上述方程没有唯一解。最小二乘问题等价于

\[\begin{split}\begin{matrix} \left. \min\|y \right.\| \\ {{约束条件}R_{11}*y_{1} + R_{12}*y_{2} = c_{1}} \\ \end{matrix}\end{split}\]

或者等价地表示为另一个最小二乘问题

\[\begin{split} \left.min\| \begin{pmatrix} R_{11} \backslash R_{12} \\ I \end{pmatrix} * y_2 - \begin{pmatrix} R_{11} \backslash c_1 \\ O \end{pmatrix} \right.\|\end{split}\]

输出参数 x\(P^{T}*y\),即最小二乘问题的解。

输出参数 p 是一个大小为 n 的向量。它对应一个置换矩阵 Pp(i)=j 表示 (P*x)(i) = x(j)。如果 A 是满秩的,则 p=0:n-1

备注1: p始终基于0,与A的基础索引无关。

备注2:仅提供CPU(主机)路径。

输入

参数

cusolverSp 内存空间

*主机内存空间

描述

handle

host

host

cuSolver库上下文的句柄。

m

host

host

矩阵A的行数。

n

host

host

矩阵A的列数。

nnz

host

host

矩阵A的非零元素数量。

描述A

host

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

device

host

<type> 矩阵 Annz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\) 个非零元素的数组。

csrRowPtrA

device

host

一个包含每行起始位置及最后一行末尾加1的m\(+ 1\)个元素的整数数组。

csrColIndA

device

host

矩阵A非零元素的nnz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\)个列索引的整数数组。

b

device

host

右侧向量,大小为 m

tol

host

host

用于决定A矩阵秩的容差阈值。

输出

参数

cusolverSp 内存空间

*主机内存空间

描述

rankA

host

host

A的数值秩。

x

device

host

大小为 n 的解向量,x=pinv(A)*b。

p

device

host

一个大小为 n 的向量,表示满足 A*P^T=Q*R 的置换矩阵 P

min_norm

host

host

||A*x-b||, x=pinv(A)*b.

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n,nnz<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.2.5. cusolverSpcsreigvsi()

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverSpScsreigvsi[Host](cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const float *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 float mu0,
                 const float *x0,
                 int maxite,
                 float tol,
                 float *mu,
                 float *x);

cusolverStatus_t
cusolverSpDcsreigvsi[Host](cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const double *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 double mu0,
                 const double *x0,
                 int maxite,
                 double tol,
                 double *mu,
                 double *x);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverSpCcsreigvsi[Host](cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const cuComplex *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 cuComplex mu0,
                 const cuComplex *x0,
                 int maxite,
                 float tol,
                 cuComplex *mu,
                 cuComplex *x);

cusolverStatus_t
cusolverSpZcsreigvsi(cusolverSpHandle_t handle,
                 int m,
                 int nnz,
                 const cusparseMatDescr_t descrA,
                 const cuDoubleComplex *csrValA,
                 const int *csrRowPtrA,
                 const int *csrColIndA,
                 cuDoubleComplex mu0,
                 const cuDoubleComplex *x0,
                 int maxite,
                 double tol,
                 cuDoubleComplex *mu,
                 cuDoubleComplex *x);

该函数通过位移逆方法求解简单特征值问题 \(A*x = \lambda*x\)

A 是一个 \(m \times m\) 的稀疏矩阵,由三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。输出参数 x 是大小为 m 的近似特征向量,

以下移位逆方法逐步修正特征对直至收敛。

它接受以下参数:

mu0 是特征值的初始猜测值。如果 mu 是单根,则移位逆方法将收敛到最接近 mu0 的特征值 mu。否则,移位逆方法可能不会收敛。

x0 是初始特征向量。如果用户没有偏好,可以随机选择 x0x0 必须是非零向量,可以是非单位长度。

tol 是用于判断收敛的容差值。如果 tol 小于零,将被视为零。

maxite 是最大迭代次数。当逆位移法因容差过小或所需特征值非单重而导致不收敛时,该参数非常有用。

移位逆方法

给定特征值μ0的初始猜测和初始向量x0

\[\begin{split}x (0) = x0 \text{ 单位长度向量} \\ \text{循环 }j = 0 : 最大迭代次数 \\ & \text{求解方程 } ( A - \mu0 * I ) * x^{k+1} = x^{k} \\ & \text{将 } x^{k+1} \text{ 归一化为单位长度} \\ & \text{计算近似特征值 } \mu = x^H * A * x \text{ 其中 } x = x^{k+1} \\ & if \| A * x^{k+1} - \mu * x^{k+1} \| < \text{ 容差, 则停止迭代} \\ \text{结束循环}\end{split}\]

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果A是对称/厄米特矩阵且仅使用或需要下/上三角部分,用户必须将矩阵扩展至缺失的上/下三角部分,否则结果将出错。

备注1: [cu|h]solver[S|D]csreigvsi 仅允许 mu0 为实数。这在 A 为对称矩阵时适用。否则,非实数特征值在复平面上会有共轭对应值,此时即使该特征值是单根,位移逆迭代法也无法收敛到该特征值。用户需要将 A 扩展到复数域,并调用 [cu|h]solver[C|Z]csreigvsi 且确保 mu0 不在实轴上。

备注2:容差tol不应小于|mu0|*eps,其中eps是机器零值。否则,由于容差过小,位移逆迭代可能无法收敛。

输入

参数

cusolverSp 内存空间

*主机内存空间

描述

handle

host

host

cuSolver库上下文的句柄。

m

host

host

矩阵A的行数和列数。

nnz

host

host

矩阵A的非零元素数量。

描述A

host

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

device

host

<type> 矩阵 Annz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\) 个非零元素的数组。

csrRowPtrA

device

host

一个包含每行起始位置及最后一行末尾加1的m\(+ 1\)个元素的整数数组。

csrColIndA

device

host

矩阵A非零元素的nnz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\)个列索引的整数数组。

mu0

host

host

特征值的初始猜测。

x0

device

host

特征向量的初始猜测,一个大小为m的向量。

maxite

host

host

移位逆方法中的最大迭代次数。

tol

host

host

收敛容差。

输出

参数

cusolverSp 内存空间

*主机内存空间

描述

mu

device

host

在容忍度范围内最接近mu0的近似特征值。

x

device

host

大小为 m 的近似特征向量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,nnz<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.2.6. cusolverSpcsreigs()

cusolverStatus_t
solverspScsreigs[Host](cusolverSpHandle_t handle,
                int m,
                int nnz,
                const cusparseMatDescr_t descrA,
                const float *csrValA,
                const int *csrRowPtrA,
                const int *csrColIndA,
                cuComplex left_bottom_corner,
                cuComplex right_upper_corner,
                int *num_eigs);

cusolverStatus_t
cusolverSpDcsreigs[Host](cusolverSpHandle_t handle,
                int m,
                int nnz,
                const cusparseMatDescr_t descrA,
                const double *csrValA,
                const int *csrRowPtrA,
                const int *csrColIndA,
                cuDoubleComplex left_bottom_corner,
                cuDoubleComplex right_upper_corner,
                int *num_eigs);

cusolverStatus_t
cusolverSpCcsreigs[Host](cusolverSpHandle_t handle,
                int m,
                int nnz,
                const cusparseMatDescr_t descrA,
                const cuComplex *csrValA,
                const int *csrRowPtrA,
                const int *csrColIndA,
                cuComplex left_bottom_corner,
                cuComplex right_upper_corner,
                int *num_eigs);

cusolverStatus_t
cusolverSpZcsreigs[Host](cusolverSpHandle_t handle,
                int m,
                int nnz,
                const cusparseMatDescr_t descrA,
                const cuDoubleComplex *csrValA,
                const int *csrRowPtrA,
                const int *csrColIndA,
                cuDoubleComplex left_bottom_corner,
                cuDoubleComplex right_upper_corner,
                int *num_eigs);

该函数通过轮廓积分计算给定框B内的代数特征值数量

\[\text{box B中的代数特征值数量} = \frac{1}{2*\pi*\sqrt{- 1}}\oint_{C}\frac{P^{\prime}{(z)}}{P(z)}dz\]

其中闭合线C是盒子B的边界,该盒子是由两个点指定的矩形:一个是左下角(输入参数left_bottom_corner),另一个是右上角(输入参数right_upper_corner)。P(z)=det(A - z*I)A的特征多项式。

A 是一个 \(m \times m\) 的稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。

输出参数 num_eigs 表示在区域 B 内的代数特征值数量。由于多种原因,该数值可能不准确:

  1. 轮廓线 C 接近某些特征值,甚至穿过某些特征值。

  2. 由于网格尺寸较粗,数值积分不够精确。默认分辨率是沿轮廓C均匀分布的1200个网格。

尽管csreigs可能不够精确,但它仍能让用户大致了解在圆盘定理分辨率较差的区域中有多少特征值。例如,拉普拉斯算子的标准三点有限差分格式是一个三对角矩阵,圆盘定理会显示"所有特征值都在区间[0, 4*N^2]内",其中N是网格数量。在这种情况下,csreigs对于[0, 4*N^2]内的任何区间都很有用。

备注1:如果A在实数情况下对称或在复数情况下为厄米特矩阵,则所有特征值均为实数。用户仍需指定一个矩形区域而非区间,该矩形的高度可以远小于其宽度。

备注2:仅提供CPU(主机)路径。

输入

参数

cusolverSp 内存空间

*主机内存空间

描述

handle

host

host

cuSolverSP库上下文的句柄。

m

host

host

矩阵A的行数和列数。

nnz

host

host

矩阵A的非零元素数量。

描述A

host

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

device

host

<type> 矩阵 Annz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\) 个非零元素的数组。

csrRowPtrA

device

host

一个包含每行起始位置及最后一行末尾加1的m\(+ 1\)个元素的整数数组。

csrColIndA

device

host

矩阵A非零元素的nnz\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\)个列索引的整数数组。

left_bottom_corner

host

host

方框的左下角。

right_upper_corner

host

host

方框的右上角。

输出

参数

cusolverSp 内存空间

*主机内存空间

描述

num_eigs

host

host

盒子中的代数特征值数量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,nnz<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.3. 底层函数参考

本节介绍cuSolverSP的低级API,包括symrcm和批量QR。

2.5.3.1. cusolverSpXcsrsymrcm()

cusolverStatus_t
cusolverSpXcsrsymrcmHost(cusolverSpHandle_t handle,
             int n,
             int nnzA,
             const cusparseMatDescr_t descrA,
             const int *csrRowPtrA,
             const int *csrColIndA,
             int *p);

此函数实现了对称反向Cuthill-McKee排序算法。它返回一个置换向量p,使得A(p,p)能将非零元素集中到对角线附近。这相当于MATLAB中的symrcm函数,但由于伪外围节点查找器采用不同的启发式方法,结果可能有所不同。cuSolverSP库实现的symrcm基于以下两篇论文:

  • E. Cuthill 和 J. McKee,《减少稀疏对称矩阵的带宽》,ACM '69 第24届全国会议论文集,1969年,第157-172页

  • Alan George, Joseph W. H. Liu, 《伪周边节点查找器的实现》,ACM数学软件汇刊(TOMS) 第5卷第3期,1979年9月,284-295页

输出参数 p 是一个包含 n 个元素的整数数组。它表示一个置换数组,并使用基于0的索引约定。置换数组 p 对应一个置换矩阵 P,并满足以下关系:

\[{A(p,p)} = P*A*P^{T}\]

A 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部rcm算法作用于\(A + A^{T}\),如果矩阵不对称,用户无需扩展该矩阵。

备注1:仅提供CPU(主机)路径。

输入

参数

*主机内存空间

描述

handle

host

cuSolverSP库上下文的句柄。

n

host

矩阵A的行数和列数。

nnzA

host

矩阵A的非零元素数量。它是csrValAcsrColIndA的大小。

描述A

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrRowPtrA

host

一个包含每行起始位置及最后一行末尾加一的n+1个元素的整数数组。

csrColIndA

host

矩阵A非零元素的nnzA列索引整数数组。

输出

参数

hsolver

描述

p

host

大小为n的排列向量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.3.2. cusolverSpXcsrsymmdq()

cusolverStatus_t
cusolverSpXcsrsymmdqHost(cusolverSpHandle_t handle,
             int n,
             int nnzA,
             const cusparseMatDescr_t descrA,
             const int *csrRowPtrA,
             const int *csrColIndA,
             int *p);

该函数实现了基于商图(Quotient Graph)的对称最小度算法。它返回一个置换向量p,使得A(p,p)在Cholesky分解过程中具有更少的零填充。cuSolverSP库中的symmdq实现基于以下两篇论文:

帕特里克·R·阿梅斯托伊、蒂莫西·A·戴维斯、伊恩·S·达夫,《一种近似最小度排序算法》,SIAM矩阵分析与应用期刊,第17卷第4期,886-905页,1996年12月。

艾伦·乔治,约瑟夫·W·刘,《使用商图实现最小度算法的一种快速方法》,ACM数学软件汇刊,第6卷第3期,1980年9月,第337-358页。

输出参数 p 是一个包含 n 个元素的整数数组。它表示一个基于0索引的置换数组。置换数组 p 对应一个置换矩阵 P,并满足以下关系:

\[{A(p,p)} = P*A*P^{T}\]

A 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部mdq会处理\(A + A^{T}\),如果矩阵不对称,用户无需扩展该矩阵。

备注1:仅提供CPU(主机)路径。

输入

参数

*主机内存空间

描述

handle

host

cuSolverSP库上下文的句柄。

n

host

矩阵A的行数和列数。

nnzA

host

矩阵A的非零元素数量。它是csrValAcsrColIndA的大小。

描述A

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrRowPtrA

host

包含每行起始位置及最后一行末尾加1的n+1个元素的整数数组。

csrColIndA

host

矩阵A非零元素的nnzA列索引整数数组。

输出

参数

hsolver

描述

p

host

大小为n的排列向量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.3.3. cusolverSpXcsrsymamd()

cusolverStatus_t
cusolverSpXcsrsymamdHost(cusolverSpHandle_t handle,
             int n,
             int nnzA,
             const cusparseMatDescr_t descrA,
             const int *csrRowPtrA,
             const int *csrColIndA,
             int *p);

该函数实现了基于商图(Quotient Graph)的对称近似最小度算法。它返回一个置换向量p,使得A(p,p)在Cholesky分解过程中具有更少的零填充。该cuSolverSP库中的symamd实现基于以下论文:

帕特里克·R·阿梅斯托伊、蒂莫西·A·戴维斯、伊恩·S·达夫,《一种近似最小度排序算法》,SIAM矩阵分析与应用期刊,第17卷第4期,886-905页,1996年12月。

输出参数 p 是一个包含 n 个元素的整数数组。它表示一个基于0索引的置换数组。置换数组 p 对应一个置换矩阵 P,并满足以下关系:

\[{A(p,p)} = P*A*P^{T}\]

A 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部,amd作用于\(A + A^{T}\),如果矩阵不对称,用户不需要扩展矩阵。

备注1:仅提供CPU(主机)路径。

输入

参数

*主机内存空间

描述

handle

host

cuSolverSP库上下文的句柄。

n

host

矩阵A的行数和列数。

nnzA

host

矩阵A的非零元素数量。它是csrValAcsrColIndA的大小。

描述A

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrRowPtrA

host

一个包含每行起始位置及最后一行末尾加一的n+1个元素的整数数组。

csrColIndA

host

矩阵A非零元素的nnzA列索引整数数组。

输出

参数

hsolver

描述

p

host

大小为n的排列向量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.3.4. cusolverSpXcsrmetisnd()

cusolverStatus_t
cusolverSpXcsrmetisndHost(
    cusolverSpHandle_t handle,
    int n,
    int nnzA,
    const cusparseMatDescr_t descrA,
    const int *csrRowPtrA,
    const int *csrColIndA,
    const int64_t *options,
    int *p);

此函数是METIS_NodeND的封装器。它返回一个置换向量p,使得A(p,p)在嵌套剖分过程中产生较少的零填充。cuSolverSP库链接了libcusolver_metis_static.a,这是64位的metis-5.1.0版本。

参数 optionsmetis 的配置项。对于没有 metis 使用经验的用户,可以设置 options = NULL 来使用默认配置。

输出参数 p 是一个包含 n 个元素的整数数组。它表示一个基于0索引的置换数组。置换数组 p 对应一个置换矩阵 P,并满足以下关系:

\[{A(p,p)} = P*A*P^{T}\]

A 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部csrmetisnd会处理\(A + A^{T}\),如果矩阵不对称,用户无需自行扩展矩阵。

备注1:仅提供CPU(主机)路径。

输入

参数

*主机内存空间

描述

handle

host

cuSolverSP库上下文的句柄。

n

host

矩阵A的行数和列数。

nnzA

host

矩阵A的非零元素数量。它是csrValAcsrColIndA的大小。

描述A

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrRowPtrA

host

一个包含每行起始位置及最后一行末尾加一的n+1个元素的整数数组。

csrColIndA

host

矩阵A非零元素的nnzA列索引整数数组。

options

host

用于配置metis的整数数组。

输出

参数

*主机内存空间

描述

p

host

大小为n的排列向量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.3.5. cusolverSpXcsrzfd()

cusolverStatus_t
cusolverSpScsrzfdHost(
    cusolverSpHandle_t handle,
    int n,
    int nnzA,
    const cusparseMatDescr_t descrA,
    const float *csrValA,
    const int *csrRowPtrA,
    const int *csrColIndA,
    int *P,
    int *numnz)

cusolverStatus_t
cusolverSpDcsrzfdHost(
    cusolverSpHandle_t handle,
    int n,
    int nnzA,
    const cusparseMatDescr_t descrA,
    const double *csrValA,
    const int *csrRowPtrA,
    const int *csrColIndA,
    int *P,
    int *numnz)

cusolverStatus_t
cusolverSpCcsrzfdHost(
    cusolverSpHandle_t handle,
    int n,
    int nnzA,
    const cusparseMatDescr_t descrA,
    const cuComplex *csrValA,
    const int *csrRowPtrA,
    const int *csrColIndA,
    int *P,
    int *numnz)

cusolverStatus_t
cusolverSpZcsrzfdHost(
    cusolverSpHandle_t handle,
    int n,
    int nnzA,
    const cusparseMatDescr_t descrA,
    const cuDoubleComplex *csrValA,
    const int *csrRowPtrA,
    const int *csrColIndA,
    int *P,
    int *numnz)

该函数实现了MC21算法,即无零对角线算法。它返回一个置换向量p,使得A(p,:)不包含零对角线。

A 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。支持的矩阵类型为 CUSPARSE_MATRIX_TYPE_GENERAL

输出参数 p 是一个包含 n 个元素的整数数组。它表示一个基于0索引的置换数组。置换数组 p 对应一个置换矩阵 P,并满足以下关系:

\[{A(p,:)} = P*A\]

输出参数 numnz 描述了置换矩阵 A(p,:) 中非零对角元的数量。如果 numnz 小于 n,则矩阵 A 存在结构奇异性。

备注1:仅提供CPU(主机)路径。

备注2:此例程不会最大化置换矩阵的对角线值。用户不应期望此例程能使"无主元LU分解"变得稳定。

输入

参数

*主机内存空间

描述

handle

host

cuSolverSP库上下文的句柄。

n

host

矩阵A的行数和列数。

nnzA

host

矩阵A的非零元素数量。它是csrValAcsrColIndA的大小。

描述A

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

host

<type> 数组,包含矩阵 AnnzA\(( =\)csrRowPtrA(m)\(-\)csrRowPtrA(0)\()\) 个非零元素。

csrRowPtrA

host

一个包含每行起始位置及最后一行末尾加一的n+1个元素的整数数组。

csrColIndA

host

矩阵A非零元素的nnzA列索引整数数组。

输出

参数

*主机内存空间

描述

p

host

大小为n的排列向量。

numnz

host

置换矩阵对角线上非零元素的数量。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(n,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.3.6. cusolverSpXcsrperm()

cusolverStatus_t
cusolverSpXcsrperm_bufferSizeHost(cusolverSpHandle_t handle,
                          int m,
                          int n,
                          int nnzA,
                          const cusparseMatDescr_t descrA,
                          int *csrRowPtrA,
                          int *csrColIndA,
                          const int *p,
                          const int *q,
                          size_t *bufferSizeInBytes);

cusolverStatus_t
cusolverSpXcsrpermHost(cusolverSpHandle_t handle,
                int m,
                int n,
                int nnzA,
                const cusparseMatDescr_t descrA,
                int *csrRowPtrA,
                int *csrColIndA,
                const int *p,
                const int *q,
                int *map,
                void *pBuffer);

给定一个左置换向量p对应置换矩阵P,以及一个右置换向量q对应置换矩阵Q,该函数通过以下方式计算矩阵A的置换:

\[B = P*A*Q^T\]

A 是一个 \(m \times n\) 稀疏矩阵,通过三个数组 csrValAcsrRowPtrAcsrColIndA 以 CSR 存储格式定义。

该操作是原地进行的,即矩阵 A 会被 B 覆盖。

置换向量pq是基于0的索引。p执行行置换,而q执行列置换。也可以使用MATLAB命令\(B = {A(p,q)}\)来置换矩阵A

此函数仅计算B的稀疏模式。用户也可以通过参数map获取csrValB。参数map既是输入也是输出。如果在调用csrperm前用户设置map=0:1:(nnzA-1),则csrValB=csrValA(map)

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果A是对称矩阵且仅提供下/上三角部分,用户需要将\(A + A^{T}\)传入此函数。

此函数需要由csrperm_bufferSize()返回的缓冲区大小。pBuffer的地址必须是128字节的倍数。如果不是,将返回CUSOLVER_STATUS_INVALID_VALUE

例如,如果矩阵 A

\[\begin{split}A = \begin{pmatrix} {1.0} & {2.0} & {3.0} \\ {4.0} & {5.0} & {6.0} \\ {7.0} & {8.0} & {9.0} \\ \end{pmatrix}\end{split}\]

以及左置换向量 p=(0,2,1),右置换向量 q=(2,1,0),那么 \(P*A*Q^{T}\) 的结果为

\[\begin{split}P*A*Q^{T} = \begin{pmatrix} {3.0} & {2.0} & {1.0} \\ {9.0} & {8.0} & {7.0} \\ {6.0} & {5.0} & {4.0} \\ \end{pmatrix}\end{split}\]

备注1:仅提供CPU(主机)路径。

备注2:用户可以结合csrsymrcmcsrperm来获得\(P*A*P^{T}\),该矩阵在QR分解过程中具有更少的零填充。

输入

参数

cusolverSp 内存空间

描述

handle

host

cuSolver库上下文的句柄。

m

host

矩阵A的行数。

n

host

矩阵A的列数。

nnzA

host

矩阵A的非零元素数量。它是csrValAcsrColIndA的大小。

描述A

host

矩阵A的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrRowPtrA

host

整数数组,包含矩阵A每行的起始位置及最后一行末尾加一的位置,共m+1个元素。

csrColIndA

host

矩阵A非零元素的nnzA列索引整数数组。

p

host

大小为 m 的左置换向量。

q

host

大小为 n 的正确置换向量。

map

host

长度为nnzA的整数索引数组。如果用户需要获取AB之间的对应关系,必须将map设置为0:1:(nnzA-1)

pBuffer

host

用户分配的缓冲区,其大小由csrperm_bufferSize()返回。

输出

参数

hsolver

描述

csrRowPtrA

host

整数数组,包含m+1个元素,表示矩阵B每行的起始位置以及最后一行末尾的下一个位置。

csrColIndA

host

矩阵B非零元素的nnzA列索引整数数组。

map

host

长度为nnzA的整数数组,用于将矩阵A映射到矩阵B

pBufferSizeInBytes

host

缓冲区的字节数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.5.3.7. cusolverSpXcsrqrBatched()

create和destroy方法分别开始和结束csrqrInfo对象的生命周期。

cusolverStatus_t
cusolverSpCreateCsrqrInfo(csrqrInfo_t *info);

cusolverStatus_t
cusolverSpDestroyCsrqrInfo(csrqrInfo_t info);

所有数据类型的分析过程相同,但每种数据类型具有独特的缓冲区大小。

cusolverStatus_t
cusolverSpXcsrqrAnalysisBatched(cusolverSpHandle_t handle,
                           int m,
                           int n,
                           int nnzA,
                           const cusparseMatDescr_t descrA,
                           const int *csrRowPtrA,
                           const int *csrColIndA,
                           csrqrInfo_t info);

cusolverStatus_t
cusolverSpScsrqrBufferInfoBatched(cusolverSpHandle_t handle,
                           int m,
                           int n,
                           int nnzA,
                           const cusparseMatDescr_t descrA,
                           const float *csrValA,
                           const int *csrRowPtrA,
                           const int *csrColIndA,
                           int batchSize,
                           csrqrInfo_t info,
                           size_t *internalDataInBytes,
                           size_t *workspaceInBytes);

cusolverStatus_t
cusolverSpDcsrqrBufferInfoBatched(cusolverSpHandle_t handle,
                           int m,
                           int n,
                           int nnzA,
                           const cusparseMatDescr_t descrA,
                           const double *csrValA,
                           const int *csrRowPtrA,
                           const int *csrColIndA,
                           int batchSize,
                           csrqrInfo_t info,
                           size_t *internalDataInBytes,
                           size_t *workspaceInBytes);

计算复数数据类型所需的缓冲区大小。

cusolverStatus_t
cusolverSpCcsrqrBufferInfoBatched(cusolverSpHandle_t handle,
                           int m,
                           int n,
                           int nnzA,
                           const cusparseMatDescr_t descrA,
                           const cuComplex *csrValA,
                           const int *csrRowPtrA,
                           const int *csrColIndA,
                           int batchSize,
                           csrqrInfo_t info,
                           size_t *internalDataInBytes,
                           size_t *workspaceInBytes);

cusolverStatus_t
cusolverSpZcsrqrBufferInfoBatched(cusolverSpHandle_t handle,
                           int m,
                           int n,
                           int nnzA,
                           const cusparseMatDescr_t descrA,
                           const cuDoubleComplex *csrValA,
                           const int *csrRowPtrA,
                           const int *csrColIndA,
                           int batchSize,
                           csrqrInfo_t info,
                           size_t *internalDataInBytes,
                           size_t *workspaceInBytes);

S和D数据类型分别是单精度和双精度的实数值。

cusolverStatus_t
cusolverSpScsrqrsvBatched(cusolverSpHandle_t handle,
                        int m,
                        int n,
                        int nnzA,
                        const cusparseMatDescr_t descrA,
                        const float *csrValA,
                        const int *csrRowPtrA,
                        const int *csrColIndA,
                        const float *b,
                        float *x,
                        int batchSize,
                        csrqrInfo_t info,
                        void *pBuffer);

cusolverStatus_t
cusolverSpDcsrqrsvBatched(cusolverSpHandle_t handle,
                        int m,
                        int n,
                        int nnz,
                        const cusparseMatDescr_t descrA,
                        const double *csrValA,
                        const int *csrRowPtrA,
                        const int *csrColIndA,
                        const double *b,
                        double *x,
                        int batchSize,
                        csrqrInfo_t info,
                        void *pBuffer);

C和Z数据类型分别是单精度和双精度的复数类型。

cusolverStatus_t
cusolverSpCcsrqrsvBatched(cusolverSpHandle_t handle,
                        int m,
                        int n,
                        int nnzA,
                        const cusparseMatDescr_t descrA,
                        const cuComplex *csrValA,
                        const int *csrRowPtrA,
                        const int *csrColIndA,
                        const cuComplex *b,
                        cuComplex *x,
                        int batchSize,
                        csrqrInfo_t info,
                        void *pBuffer);

cusolverStatus_t
cusolverSpZcsrqrsvBatched(cusolverSpHandle_t handle,
                        int m,
                        int n,
                        int nnzA,
                        const cusparseMatDescr_t descrA,
                        const cuDoubleComplex *csrValA,
                        const int *csrRowPtrA,
                        const int *csrColIndA,
                        const cuDoubleComplex *b,
                        cuDoubleComplex *x,
                        int batchSize,
                        csrqrInfo_t info,
                        void *pBuffer);

批处理稀疏QR分解用于解决一组最小二乘问题

\[x_j = {argmin}{\|}A_{j}*z - b_{j}{\|}{,\ j\ =\ 1,2,...,\ batchSize}\]

或一组线性系统

\[A_{j}x_{j} = b_{j}{,\ j\ =\ 1,2,...,\ batchSize}\]

其中每个\(A_{j}\)是一个\(m \times n\)稀疏矩阵,通过四个数组csrValAcsrRowPtrAcsrColIndA以CSR存储格式定义。

支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果A是对称矩阵且仅提供下/上三角部分,用户需要将\(A + A^{H}\)传入此函数。

使用批量稀疏QR分解的前提条件有两个方面。首先,所有矩阵\(A_{j}\)必须具有相同的稀疏模式。其次,在最小二乘问题中不使用列主元交换,因此只有当\(A_{j}\)对所有j = 1,2,..., batchSize都是满秩时,解才有效。由于所有矩阵具有相同的稀疏模式,因此只需要使用一份csrRowPtrAcsrColIndA的副本。但数组csrValA会依次存储所有\(A_{j}\)的系数值。换句话说,csrValA[k*nnzA : (k+1)*nnzA]表示矩阵\(A_{k}\)的数值。

批处理QR使用不透明的数据结构csrqrInfo来保存中间数据,例如QR分解中的矩阵Q和矩阵R。用户需要在执行批处理QR操作中的任何函数之前,先通过cusolverSpCreateCsrqrInfo创建csrqrInfo。在调用cusolverSpDestroyCsrqrInfo之前,csrqrInfo不会释放内部数据。

批处理稀疏QR分解包含三个例程:cusolverSpXcsrqrAnalysisBatchedcusolverSp[S|D|C|Z]csrqrBufferInfoBatchedcusolverSp[S|D|C|Z]csrqrsvBatched

First, cusolverSpXcsrqrAnalysisBatched is the analysis phase, used to analyze sparsity pattern of matrix Q and matrix R of QR factorization. Also parallelism is extracted during analysis phase. Once analysis phase is done, the size of working space to perform QR is known. However cusolverSpXcsrqrAnalysisBatched uses CPU to analyze the structure of matrix A, and this may consume a lot of memory. If host memory is not sufficient to finish the analysis, CUSOLVER_STATUS_ALLOC_FAILED is returned. The required memory for analysis is proportional to zero fill-in in QR factorization. The user may need to perform some kind of reordering to minimize zero fill-in, for example, colamd or symrcm in MATLAB. cuSolverSP library provides symrcm (cusolverSpXcsrsymrcm).

其次,用户需要选择合适的batchSize并为稀疏QR准备工作空间。批处理稀疏QR使用两个内存块:一个是用于存储矩阵Q和矩阵R的内部内存块;另一个是用于执行数值分解的工作空间。前者的内存大小与batchSize成正比,其大小由cusolverSp[S|D|C|Z]csrqrBufferInfoBatched的返回参数internalDataInBytes指定;而后者的内存大小几乎与batchSize无关,其大小由cusolverSp[S|D|C|Z]csrqrBufferInfoBatched的返回参数workspaceInBytes指定。内部内存块会在首次调用cusolverSp[S|D|C|Z]csrqrsvBatched时隐式分配。用户只需为cusolverSp[S|D|C|Z]csrqrsvBatched分配工作空间即可。

用户无需尝试所有批处理矩阵,可以通过查询cusolverSp[S|D|C|Z]csrqrBufferInfoBatched来找到最大batchSize。例如,用户可以逐步增加batchSize,直到internalDataInBytesworkspaceInBytes的总和超过可用设备内存的大小。

假设用户需要执行253个线性求解器且可用设备内存为2GB。如果cusolverSp[S|D|C|Z]csrqrsvBatched只能支持batchSize为100,那么用户需要调用三次cusolverSp[S|D|C|Z]csrqrsvBatched才能完成所有计算。用户使用batchSize为100调用cusolverSp[S|D|C|Z]csrqrBufferInfoBatched。不透明的info会记住这个batchSize值,后续任何对cusolverSp[S|D|C|Z]csrqrsvBatched的调用都不能超过这个值。在本例中,前两次调用cusolverSp[S|D|C|Z]csrqrsvBatched将使用batchSize为100,最后一次调用将使用batchSize为53。

示例:假设A0, A1, ..., A9具有相同的稀疏模式,以下代码通过批量稀疏QR求解10个线性方程组 \(A_{j}x_{j} = b_{j}{,\ j\ =\ 0,2,...,\ 9}\)

// Suppose that A0, A1, .., A9 are m x m sparse matrix represented by CSR format,
// Each matrix Aj has nonzero nnzA, and shares the same csrRowPtrA and csrColIndA.
// csrValA is aggregation of A0, A1, ..., A9.
int m ; // number of rows and columns of each Aj
int nnzA ; // number of nonzeros of each Aj
int *csrRowPtrA ; // each Aj has the same csrRowPtrA
int *csrColIndA ; // each Aj has the same csrColIndA
double *csrValA ; // aggregation of A0,A1,...,A9
const int batchSize = 10; // 10 linear systems

cusolverSpHandle_t handle; // handle to cusolver library
csrqrInfo_t info = NULL;
cusparseMatDescr_t descrA = NULL;
void *pBuffer = NULL; // working space for numerical factorization

// step 1: create a descriptor
cusparseCreateMatDescr(&descrA);
cusparseSetMatIndexBase(descrA, CUSPARSE_INDEX_BASE_ONE); // A is base-1
cusparseSetMatType(descrA, CUSPARSE_MATRIX_TYPE_GENERAL); // A is a general matrix

// step 2: create empty info structure
cusolverSpCreateCsrqrInfo(&info);

// step 3: symbolic analysis
cusolverSpXcsrqrAnalysisBatched(
    handle, m, m, nnzA,
    descrA, csrRowPtrA, csrColIndA, info);
// step 4: allocate working space for Aj*xj=bj
cusolverSpDcsrqrBufferInfoBatched(
    handle, m, m, nnzA,
    descrA,
    csrValA, csrRowPtrA, csrColIndA,
    batchSize,
    info,
    &internalDataInBytes,
    &workspaceInBytes);

cudaMalloc(&pBuffer, workspaceInBytes);

// step 5: solve Aj*xj = bj
cusolverSpDcsrqrsvBatched(
    handle, m, m, nnzA,
    descrA, csrValA, csrRowPtrA, csrColIndA,
    b,
    x,
    batchSize,
    info,
    pBuffer);

// step 7: destroy info
cusolverSpDestroyCsrqrInfo(info);

请参考cuSOLVER库示例 - csrqr查看代码示例。

备注1:仅提供GPU(设备)路径。

输入

参数

cusolverSp 内存空间

描述

handle

host

cuSolverSP库上下文的句柄。

m

host

每个矩阵Aj的行数。

n

host

每个矩阵 Aj 的列数。

nnzA

host

每个矩阵Aj的非零元素数量。它等于csrColIndA的大小。

描述A

host

每个矩阵Aj的描述符。支持的矩阵类型为CUSPARSE_MATRIX_TYPE_GENERAL。同时,支持的索引基数为CUSPARSE_INDEX_BASE_ZEROCUSPARSE_INDEX_BASE_ONE

csrValA

device

数组,包含 nnzA*batchSize 个矩阵 A0, A1, ... 的非零元素。所有矩阵按顺序依次聚合。

csrRowPtrA

device

包含每行起始位置及最后一行末尾加1的m+1个元素的整数数组。

csrColIndA

device

每个矩阵Aj的非零元素的nnzA列索引的整数数组。

b

device

m*batchSize 个右侧向量 b0, b1, ... 组成的数组。所有向量按顺序依次聚合。

batchSize

host

需要求解的系统数量。

信息

host

用于QR分解的不透明结构体。

pBuffer

device

由用户分配的缓冲区,其大小由cusolverSpXcsrqrBufferInfoBatched()返回。

输出

参数

cusolverSp 内存空间

描述

x

device

m*batchSize 个解向量 x0, x1, ... 组成的数组。所有向量按顺序聚合在一起。

internalDataInBytes

host

内部数据的字节数。

workspaceInBytes

host

数值分解中缓冲区的字节数。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(m,n,nnzA<=0),基索引不是0或1。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED

不支持该矩阵类型。

2.6. cuSolverRF:重构参考

本节介绍cuSolverRF的API,这是一个用于快速重构的库。

2.6.1. cusolverRfAccessBundledFactorsDevice()

cusolverStatus_t
cusolverRfAccessBundledFactorsDevice(/* Input */
                                  cusolverRfHandle_t handle,
                                  /* Output (in the host memory) */
                                  int* nnzM,
                                  /* Output (in the device memory) */
                                  int** Mp,
                                  int** Mi,
                                  double** Mx);

该例程允许直接访问存储在cuSolverRF库句柄中的下三角矩阵L和上三角矩阵U因子。这些因子被压缩为单个矩阵M=(L-I)+U,其中L的单位对角元素未被存储。假设在此之前已调用cusolverRfRefactor()来生成这些三角因子。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

nnzM

host

output

矩阵M中非零元素的数量。

Mp

device

output

对应于数组MiMx中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵M中的非零元素数量。数组大小为n+1

Mi

device

output

对应矩阵M中非零元素的列索引数组。假定该数组已按行优先且每行内按列排序。数组大小为nnzM

Mx

device

output

对应于矩阵M中非零元素的数值数组。假设该数组已按行排序,且每行内按列排序。数组大小为nnzM

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

2.6.2. cusolverRfAnalyze()

cusolverStatus_t
cusolverRfAnalyze(cusolverRfHandle_t handle);

该例程根据用户选择的算法,对LU重分解中可用的并行性进行适当分析。

\[A = L*U\]

假设之前已经调用了cusolverRfSetup[Host|Device]()来创建分析所需的内部数据结构。

对于单个线性系统,此例程只需调用一次

\[A_{i}x_{i} = f_{i}\]

参数

内存空间

输入/输出

含义

handle

host

输入/输出

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.3. cusolverRfSetupDevice()

cusolverStatus_t
cusolverRfSetupDevice(/* Input (in the device memory) */
                    int n,
                    int nnzA,
                    int* csrRowPtrA,
                    int* csrColIndA,
                    double* csrValA,
                    int nnzL,
                    int* csrRowPtrL,
                    int* csrColIndL,
                    double* csrValL,
                    int nnzU,
                    int* csrRowPtrU,
                    int* csrColIndU,
                    double* csrValU,
                    int* P,
                    int* Q,
                    /* Output */
                    cusolverRfHandle_t handle);

该例程用于组装cuSolverRF库的内部数据结构。通常在调用cusolverRfCreate()例程后,这是第一个需要调用的例程。

该例程接受输入(在设备上)原始矩阵A、下三角因子(L)和上三角因子(U),以及来自第一个(i=1)线性系统完全LU分解得到的左置换矩阵(P)和右置换矩阵(Q)

\[A_{i}x_{i} = f_{i}\]

排列 PQ 分别表示应用于原始矩阵 A 的所有左右重排序操作的最终组合。不过,这些排列通常分别与部分主元选取和用于最小化填充量的重排序相关联。

对于单个线性系统,此例程只需调用一次

\[A_{i}x_{i} = f_{i}\]

参数

内存空间

输入/输出

含义

n

host

input

矩阵 A 的行数(和列数)。

nnzA

host

input

矩阵A中非零元素的数量。

csrRowPtrA

device

input

对应于数组csrColIndAcsrValA中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵中非零元素的数量。数组大小为n+1

csrColIndA

device

input

与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

csrValA

device

input

对应于矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

nnzL

host

input

矩阵L中非零元素的数量。

csrRowPtrL

device

input

对应于数组csrColIndLcsrValL中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵L中的非零元素数量。数组大小为n+1

csrColIndL

device

input

对应于矩阵L中非零元素的列索引数组。假设该数组按行排序,并在每行内按列排序。数组大小为nnzL

csrValL

device

input

对应矩阵L中非零元素的数值数组。假定该数组已按行排序,且每行内按列排序。数组大小为nnzL

nnzU

host

input

矩阵U中非零元素的数量。

csrRowPtrU

device

input

该偏移量数组对应于csrColIndUcsrValU数组中每行的起始位置。该数组末尾还有一个额外条目,用于存储矩阵U中的非零元素数量。数组大小为n+1

csrColIndU

device

input

与矩阵U中非零元素对应的列索引数组。假定该数组已按行及每行内的列排序。数组大小为nnzU

csrValU

device

input

对应矩阵U中非零元素的数值数组。假设该数组已按行排序,且每行内按列排序。数组大小为nnzU

P

device

input

左侧排列(通常与主元选择相关)。数组的大小为n

Q

device

input

正确的排列(通常与重新排序相关)。数组的大小为n

handle

host

output

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了不支持的值或参数。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.4. cusolverRfSetupHost()

cusolverStatus_t
cusolverRfSetupHost(/* Input (in the host memory) */
                  int n,
                  int nnzA,
                  int* h_csrRowPtrA,
                  int* h_csrColIndA,
                  double* h_csrValA,
                  int nnzL,
                  int* h_csrRowPtrL,
                  int* h_csrColIndL,
                  double* h_csrValL,
                  int nnzU,
                  int* h_csrRowPtrU,
                  int* h_csrColIndU,
                  double* h_csrValU,
                  int* h_P,
                  int* h_Q,
                  /* Output */
                  cusolverRfHandle_t handle);

该例程用于组装cuSolverRF库的内部数据结构。通常在调用cusolverRfCreate()例程后,这是第一个需要调用的例程。

该例程接受输入(在主机上)原始矩阵 A、下三角因子 (L) 和上三角因子 (U),以及来自第一个 (i=1) 线性系统完全LU分解得到的左置换矩阵 (P) 和右置换矩阵 (Q)

\[A_{i}x_{i} = f_{i}\]

排列 PQ 分别表示应用于原始矩阵 A 的所有左右重排序操作的最终组合。不过,这些排列通常分别与部分主元选取和用于最小化填充量的重排序相关联。

对于单个线性系统,此例程只需调用一次

\[A_{i}x_{i} = f_{i}\]

参数

内存空间

输入/输出

含义

n

host

input

矩阵 A 的行数(和列数)。

nnzA

host

input

矩阵A中非零元素的数量。

h_csrRowPtrA

host

input

该偏移量数组对应于h_csrColIndAh_csrValA数组中每行的起始位置。该数组末尾还有一个额外条目,用于存储矩阵中非零元素的数量。数组大小为n+1

h_csrColIndA

host

input

与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

h_csrValA

host

input

对应于矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

nnzL

host

input

矩阵L中非零元素的数量。

h_csrRowPtrL

host

input

该偏移量数组对应于h_csrColIndLh_csrValL数组中每行的起始位置。该数组末尾还有一个额外条目,用于存储矩阵L中的非零元素数量。数组大小为n+1

h_csrColIndL

host

input

对应于矩阵L中非零元素的列索引数组。假设该数组按行排序,并在每行内按列排序。数组大小为nnzL

h_csrValL

host

input

对应矩阵L中非零元素的数值数组。假设该数组已按行排序,且每行内按列排序。数组大小为nnzL

nnzU

host

input

矩阵U中非零元素的数量。

h_csrRowPtrU

host

input

对应于数组h_csrColIndUh_csrValU中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵U中的非零元素数量。数组大小为n+1

h_csrColIndU

host

input

与矩阵U中非零元素对应的列索引数组。假定该数组已按行及每行内的列排序。数组大小为nnzU

h_csrValU

host

input

对应矩阵U中非零元素的数值数组。假定该数组已按行排序,且每行内按列排序。数组大小为nnzU

h_P

host

input

左侧排列(通常与主元选择相关)。数组的大小为n

h_Q

host

input

正确的排列(通常与重新排序相关)。数组的大小为n

handle

host

output

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了不支持的值或参数。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.5. cusolverRfCreate()

cusolverStatus_t cusolverRfCreate(cusolverRfHandle_t *handle);

该例程用于初始化cuSolverRF库。它会分配所需的资源,必须在调用任何其他cuSolverRF库例程之前执行。

参数

内存空间

输入/输出

含义

handle

host

output

指向cuSolverRF库句柄的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.6. cusolverRfExtractBundledFactorsHost()

cusolverStatus_t
cusolverRfExtractBundledFactorsHost(/* Input */
                                 cusolverRfHandle_t handle,
                                 /* Output (in the host memory) */
                                 int* h_nnzM,
                                 int** h_Mp,
                                 int** h_Mi,
                                 double** h_Mx);

该例程从cuSolverRF库句柄中提取下三角(L)和上三角(U)因子到主机内存中。这些因子被压缩为单个矩阵M=(L-I)+U,其中(L)的单位对角元素未被存储。假设在此之前已调用cusolverRfRefactor()来生成这些三角因子。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

h_nnzM

host

output

矩阵M中非零元素的数量。

h_Mp

host

output

对应于数组h_Mih_Mx中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵M中的非零元素数量。数组大小为n+1

h_Mi

host

output

对应矩阵中非零元素的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为h_nnzM

h_Mx

host

output

对应矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为h_nnzM

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

2.6.7. cusolverRfExtractSplitFactorsHost()

cusolverStatus_t
cusolverRfExtractSplitFactorsHost(/* Input */
                               cusolverRfHandle_t handle,
                               /* Output (in the host memory) */
                               int* h_nnzL,
                               int** h_Lp,
                               int** h_Li,
                               double** h_Lx,
                               int* h_nnzU,
                               int** h_Up,
                               int** h_Ui,
                               double** h_Ux);

该例程从cuSolverRF库句柄中提取下三角因子(L)和上三角因子(U)到主机内存。假设在此之前已调用cusolverRfRefactor()函数来生成这些三角因子。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

h_nnzL

host

output

矩阵L中非零元素的数量。

h_Lp

host

output

对应于数组h_Lih_Lx中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵L中的非零元素数量。数组大小为n+1

h_Li

host

output

对应于矩阵L中非零元素的列索引数组。假设该数组按行排序,并在每行内按列排序。数组大小为h_nnzL

h_Lx

host

output

对应矩阵L中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为h_nnzL

h_nnzU

host

output

矩阵U中非零元素的数量。

h_Up

host

output

对应于数组h_Uih_Ux中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵U中的非零元素数量。数组大小为n+1

h_Ui

host

output

对应矩阵U中非零元素的列索引数组。假定该数组已按行排序,且每行内按列排序。数组大小为h_nnzU

h_Ux

host

output

对应于矩阵U中非零元素的数值数组。假设该数组已按行排序,且每行内按列排序。数组大小为h_nnzU

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

2.6.8. cusolverRfDestroy()

cusolverStatus_t cusolverRfDestroy(cusolverRfHandle_t handle);

此例程用于关闭cuSolverRF库。它会释放已获取的资源,必须在调用完所有cuSolverRF库例程后执行。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF 库句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.9. cusolverRfGetMatrixFormat()

cusolverStatus_t
cusolverRfGetMatrixFormat(cusolverRfHandle_t handle,
                      cusolverRfMatrixFormat_t *format,
                      cusolverRfUnitDiagonal_t *diag);

该例程获取在cusolverRfSetupDevice()cusolverRfSetupHost()cusolverRfResetValues()cusolverRfExtractBundledFactorsHost()cusolverRfExtractSplitFactorsHost()例程中使用的矩阵格式。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

format

host

output

枚举矩阵格式类型。

diag

host

output

枚举的单位对角类型。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.10. cusolverRfGetNumericProperties()

cusolverStatus_t
cusolverRfGetNumericProperties(cusolverRfHandle_t handle,
                           double *zero,
                           double *boost);

此例程获取用于检查"零"主元并在cusolverRfRefactor()cusolverRfSolve()例程中对其进行提升的数值。仅当boost > 0.0时才会使用数值提升。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

zero

host

output

标记为零主元的下限值。

boost

host

output

用于替换零主元(如果后者被标记)的值。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.11. cusolverRfGetNumericBoostReport()

cusolverStatus_t
cusolverRfGetNumericBoostReport(cusolverRfHandle_t handle,
                             cusolverRfNumericBoostReport_t *report);

该例程用于获取报告,判断在cusolverRfRefactor()cusolverRfSolve()例程中是否使用了数值提升技术。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

report

host

output

枚举的增强报告类型。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.12. cusolverRfGetResetValuesFastMode()

cusolverStatus_t
cusolverRfGetResetValuesFastMode(cusolverRfHandle_t handle,
                               cusolverRfResetValuesFastMode_t *fastMode);

此例程获取在cusolverRfResetValues例程中使用的模式。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

fastMode

host

output

枚举的模式类型。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.13. cusolverRfGetAlgs()

cusolverStatus_t
cusolverRfGetAlgs(cusolverRfHandle_t handle,
             cusolverRfFactorization_t* fact_alg,
             cusolverRfTriangularSolve_t* solve_alg);

此例程获取用于cusolverRfRefactor()中重分解算法以及cusolverRfSolve()中三角求解的算法。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

alg

host

output

枚举算法类型。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.14. cusolverRfRefactor()

cusolverStatus_t cusolverRfRefactor(cusolverRfHandle_t handle);

该例程执行LU重新分解:

\[A = L*U\]

探索GPU上的可用并行性。假设之前已调用cusolverRfAnalyze()以发现可用并行性。

该例程可能会被多次调用,每次对应一个线性方程组:

\[A_{i}x_{i} = f_{i}\]

用于重分解和求解例程的算法组合存在一些限制条件,cusolverRfRefactor()cusolverRfSolve()。错误的组合会产生错误代码CUSOLVER_STATUS_INVALID_VALUE。下表总结了支持的算法组合:

用于求解和重构例程的兼容算法。

因式分解

求解

CUSOLVERRF_FACTORIZATION_ALG0

TRIANGULAR_SOLVE_ALG1

CUSOLVERRF_FACTORIZATION_ALG1

TRIANGULAR_SOLVE_ALG2, TRIANGULAR_SOLVE_ALG3

CUSOLVERRF_FACTORIZATION_ALG2

TRIANGULAR_SOLVE_ALG2, TRIANGULAR_SOLVE_ALG3

参数

内存空间

输入/输出

含义

handle

host

输入/输出

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_ZERO_PIVOT

在计算过程中遇到了零主元。

2.6.15. cusolverRfResetValues()

cusolverStatus_t
cusolverRfResetValues(/* Input (in the device memory) */
                 int n,
                 int nnzA,
                 int* csrRowPtrA,
                 int* csrColIndA,
                 double* csrValA,
                 int* P,
                 int* Q,
                 /* Output */
                 cusolverRfHandle_t handle);

该例程使用新系数矩阵的值更新内部数据结构。假设自上次调用cusolverRfSetup[Host|Device]例程以来,数组csrRowPtrAcsrColIndAPQ未发生变化。这一假设反映了以下事实:在方程组集合中,系数矩阵的稀疏模式以及用于最小化填充和旋转的重新排序保持不变:

\[A_{i}x_{i} = f_{i}\]

该例程可能会被多次调用,每次对应一个线性方程组:

\[A_{i}x_{i} = f_{i}\]

参数

内存空间

输入/输出

含义

n

host

input

矩阵 A 的行数(和列数)。

nnzA

host

input

矩阵A中非零元素的数量。

csrRowPtrA

device

input

对应于数组csrColIndAcsrValA中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵中非零元素的数量。数组大小为n+1

csrColIndA

device

input

与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

csrValA

device

input

对应于矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

P

device

input

左侧排列(通常与主元选择相关)。数组的大小为n

Q

device

input

正确的排列(通常与重新排序相关)。数组的大小为n

handle

host

output

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了不支持的值或参数。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

2.6.16. cusolverRfSetMatrixFormat()

cusolverStatus_t
cusolverRfSetMatrixFormat(cusolverRfHandle_t handle,
                      cusolverRfMatrixFormat_t format,
                      cusolverRfUnitDiagonal_t diag);

此例程设置用于cusolverRfSetupDevice()cusolverRfSetupHost()cusolverRfResetValues()cusolverRfExtractBundledFactorsHost()cusolverRfExtractSplitFactorsHost()例程的矩阵格式。可以在调用cusolverRfSetupDevice()cusolverRfSetupHost()例程之前调用一次。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

format

host

input

枚举矩阵格式类型。

diag

host

input

枚举的单位对角类型。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

枚举模式参数错误。

2.6.17. cusolverRfSetNumericProperties()

cusolverStatus_t
cusolverRfSetNumericProperties(cusolverRfHandle_t handle,
                           double zero,
                           double boost);

此例程设置用于检查"零"主元并在cusolverRfRefactor()cusolverRfSolve()例程中提升主元的数值。可以在调用cusolverRfRefactor()cusolverRfSolve()例程前多次调用此函数。仅当boost > 0.0时才会使用数值提升功能。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

zero

host

input

标记为零主元的下限值。

boost

host

input

用于替换零主元(如果后者被标记)的值。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.18. cusolverRfSetResetValuesFastMode()

cusolverStatus_t
cusolverRfSetResetValuesFastMode(cusolverRfHandle_t handle,
                               cusolverRfResetValuesFastMode_t fastMode);

此例程设置cusolverRfResetValues例程中使用的模式。快速模式需要额外内存,仅当需要非常快速地调用cusolverRfResetValues()时才推荐使用。可以在调用cusolverRfAnalyze()例程之前调用一次。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

fastMode

host

input

枚举的模式类型。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

枚举模式参数错误。

2.6.19. cusolverRfSetAlgs()

cusolverStatus_t
cusolverRfSetAlgs(cusolverRfHandle_t handle,
             cusolverRfFactorization_t fact_alg,
             cusolverRfTriangularSolve_t alg);

此例程设置用于cusolverRfRefactor()中重分解算法以及cusolverRfSolve()中三角求解的算法。可以在调用cusolverRfAnalyze()例程之前调用一次。

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

alg

host

input

枚举算法类型。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

2.6.20. cusolverRfSolve()

cusolverStatus_t
cusolverRfSolve(/* Input (in the device memory) */
          cusolverRfHandle_t handle,
          int *P,
          int *Q,
          int nrhs,
          double *Temp,
          int ldt,
          /* Input/Output (in the device memory) */
          double *XF,
          /* Input */
          int ldxf);

该例程使用由LU重分解产生的下三角矩阵\(L\in R^{nxn}\)和上三角矩阵\(U\in R^{nxn}\)执行前向和后向求解:

\[A = L*U\]

假设该结果已通过先前调用cusolverRfRefactor()例程计算得出。

该例程可以求解具有多个右端项(RHS)的线性系统:

\[AX = {(LU)}X = L{(UX)} = LY = F~{其中}~UX = Y\]

尽管目前仅支持单个右侧表达式(RHS)。

该例程可能会被多次调用,每次对应一个线性方程组:

\[A_{i}x_{i} = f_{i}\]

参数

内存空间

输入/输出

含义

handle

host

output

cuSolverRF库的句柄。

P

device

input

左侧排列(通常与主元选择相关)。数组的大小为n

Q

device

input

正确的排列(通常与重新排序相关)。数组的大小为n

nrhs

host

input

需要求解的右侧项数量。

Temp

device

input

包含临时工作空间的稠密矩阵(大小为ldt*nrhs)。

ldt

host

input

稠密矩阵Temp的前导维度(ldt >= n)。

XF

device

输入/输出

包含右侧项F和解X的稠密矩阵(大小为ldxf*nrhs)。

ldxf

host

input

稠密矩阵XF的主维度(ldxf >= n)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了不支持的值或参数。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.21. cusolverRfBatchSetupHost()

cusolverStatus_t
cusolverRfBatchSetupHost(/* Input (in the host memory) */
                       int batchSize,
                       int n,
                       int nnzA,
                       int* h_csrRowPtrA,
                       int* h_csrColIndA,
                       double *h_csrValA_array[],
                       int nnzL,
                       int* h_csrRowPtrL,
                       int* h_csrColIndL,
                       double *h_csrValL,
                       int nnzU,
                       int* h_csrRowPtrU,
                       int* h_csrColIndU,
                       double *h_csrValU,
                       int* h_P,
                       int* h_Q,
                       /* Output */
                       cusolverRfHandle_t handle);

此例程用于组装cuSolverRF库的内部数据结构以支持批量操作。该调用应在执行cusolverRfCreate()例程之后,且在调用任何其他批量例程之前进行。

批量操作假设用户有以下线性系统:

\[A_{j}x_{j} = b_{j}{, j = 1,2,..., batchSize}\]

其中集合中的每个矩阵:\(\{ A_{j}\}\)都具有相同的稀疏模式,并且非常相似,因此可以通过相同的置换PQ进行分解。换句话说,\(A_{j}{,\ j>1}\)\(A_{1}\)的一个小扰动。

该例程接受主机端输入的原始矩阵A(稀疏模式及批量值)、下三角矩阵(L)和上三角矩阵(U),以及第一个线性系统(i=1)完全LU分解生成的左置换矩阵(P)和右置换矩阵(Q)

\[A_{i}x_{i} = f_{i}\]

排列 PQ 分别表示应用于原始矩阵 A 的所有左右重排序操作的最终组合。不过,这些排列通常分别与部分主元选取和用于最小化填充量的重排序相关联。

备注1:矩阵 ALU 必须采用 CSR 格式且基于0索引。

备注2:为了获得最佳性能,batchSize应为32的倍数且不小于32。该算法受内存带宽限制,一旦达到带宽上限,通过增大batchSize来提升性能的空间将非常有限。实际应用中,32-128的batchSize通常足以获得良好性能,但在某些情况下更大的batchSize可能更有优势。

以下例程对于单个线性系统只需调用一次:

\[A_{i}x_{i} = f_{i}\]

参数

内存空间

输入/输出

含义

batchSize

host

input

批处理模式中的矩阵数量。

n

host

input

矩阵 A 的行数(和列数)。

nnzA

host

input

矩阵A中非零元素的数量。

h_csrRowPtrA

host

input

该偏移量数组对应于h_csrColIndAh_csrValA数组中每行的起始位置。该数组末尾还有一个额外条目,用于存储矩阵中非零元素的数量。数组大小为n+1

h_csrColIndA

host

input

与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

h_csrValA_array

host

input

大小为batchSize的指针数组,每个指针指向与矩阵中非零元素对应的值数组。

nnzL

host

input

矩阵L中非零元素的数量。

h_csrRowPtrL

host

input

该偏移量数组对应于h_csrColIndLh_csrValL数组中每行的起始位置。该数组末尾还有一个额外条目,用于存储矩阵L中的非零元素数量。数组大小为n+1

h_csrColIndL

host

input

对应于矩阵L中非零元素的列索引数组。假设该数组按行排序,并在每行内按列排序。数组大小为nnzL

h_csrValL

host

input

对应矩阵L中非零元素的数值数组。假设该数组已按行排序,且每行内按列排序。数组大小为nnzL

nnzU

host

input

矩阵U中非零元素的数量。

h_csrRowPtrU

host

input

对应于数组h_csrColIndUh_csrValU中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵U中的非零元素数量。数组大小为n+1

h_csrColIndU

host

input

与矩阵U中非零元素对应的列索引数组。假定该数组已按行及每行内的列排序。数组大小为nnzU

h_csrValU

host

input

对应矩阵U中非零元素的数值数组。假定该数组已按行排序,且每行内按列排序。数组大小为nnzU

h_P

host

input

左侧排列(通常与主元选择相关)。数组的大小为n

h_Q

host

input

正确的排列(通常与重新排序相关)。数组的大小为n

handle

host

output

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了不支持的值或参数。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.22. cusolverRfBatchAnalyze()

cusolverStatus_t cusolverRfBatchAnalyze(cusolverRfHandle_t handle);

该例程对批量LU重分解中可用的并行性进行适当分析。

假设之前已经调用了cusolverRfBatchSetup[Host]()函数,以便创建分析所需的内部数据结构。

以下例程对于单个线性系统只需调用一次:

\[A_{j}x_{j} = b_{j}{, j = 1,2,..., batchSize}\]

参数

内存

输入/输出

含义

handle

host

输入/输出

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_ALLOC_FAILED

内存分配失败。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.23. cusolverRfBatchResetValues()

cusolverStatus_t
cusolverRfBatchResetValues(/* Input (in the device memory) */
                      int batchSize,
                      int n,
                      int nnzA,
                      int* csrRowPtrA,
                      int* csrColIndA,
                      double* csrValA_array[],
                      int *P,
                      int *Q,
                      /* Output */
                      cusolverRfHandle_t handle);

该例程使用新系数矩阵的值更新内部数据结构。假设自上次调用cusolverRfbatch_setup_host例程以来,数组csrRowPtrAcsrColIndAPQ未发生变化。

这一假设反映了以下事实:系数矩阵的稀疏模式以及为最小化填充和旋转而进行的重排序在方程组集合中保持不变:

\[A_{j}x_{j} = b_{j}{, j\ = 1,2,..., batchSize}\]

输入参数 csrValA_array 是设备内存上的指针数组。csrValA_array(j) 指向同样位于设备内存上的矩阵:\(A_{j}\)

参数

内存空间

输入/输出

含义

batchSize

host

input

批处理模式中的矩阵数量。

n

host

input

矩阵 A 的行数(和列数)。

nnzA

host

input

矩阵A中非零元素的数量。

csrRowPtrA

device

input

对应于数组csrColIndAcsrValA中每行起始位置的偏移量数组。该数组末尾还有一个额外条目,用于存储矩阵中非零元素的数量。数组大小为n+1

csrColIndA

device

input

与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为nnzA

csrValA_array

device

input

大小为batchSize的指针数组,每个指针指向与矩阵中非零元素对应的值数组。

P

device

input

左侧排列(通常与主元选择相关)。数组的大小为n

Q

device

input

正确的排列(通常与重新排序相关)。数组的大小为n

handle

host

output

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了不支持的值或参数。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

2.6.24. cusolverRfBatchRefactor()

cusolverStatus_t cusolverRfBatchRefactor(cusolverRfHandle_t handle);

该例程执行LU重新分解:

\[M_{j} = P*A_{j}*Q^{T} = L_{j}*U_{j}\]

探索GPU上的可用并行性。假设之前已调用cusolverRfBatchAnalyze()以查找可用并行性。

备注:cusolverRfBatchRefactor()不会报告LU重分解的任何失败情况。用户需要调用cusolverRfBatchZeroPivot()来了解哪个矩阵的LU重分解失败了。

参数

内存

输入/输出

含义

handle

host

输入/输出

cuSolverRF库的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

2.6.25. cusolverRfBatchSolve()

cusolverStatus_t
cusolverRfBatchSolve(/* Input (in the device memory) */
               cusolverRfHandle_t handle,
               int *P,
               int *Q,
               int nrhs,
               double *Temp,
               int ldt,
               /* Input/Output (in the device memory) */
               double *XF_array[],
               /* Input */
               int ldxf);

要求解 \(A_{j}*x_{j} = b_{j}\),我们首先通过 \(M_{j}*Q*x_{j} = P*b_{j}\) 重构方程,其中 \(M_{j} = P*A_{j}*Q^{T}\)。然后通过 cusolverRfBatch_Refactor() 进行因式分解 \(M_{j} = L_{j}*U_{j}\)。接着 cusolverRfBatch_Solve() 会处理剩余步骤,包括:

\(z_{j} = P*b_{j}\)

\(M_{j}*y_{j} = z_{j}\)

\(x_{j} = Q^{T}*y_{j}\)

输入参数 XF_array 是一个指向设备内存的指针数组。XF_array(j) 指向同样位于设备内存中的矩阵 \(x_{j}\)

备注1:仅支持单个右侧表达式(rhs)。

备注2:在反向求解过程中未报告奇异点。如果某些矩阵\(A_{j}\)重构失败且\(U_{j}\)存在零对角线元素,反向求解将计算出NAN值。用户需要调用cusolverRfBatch_Zero_Pivot来检查重构是否成功。

参数

内存空间

输入/输出

含义

handle

host

output

cuSolverRF库的句柄。

P

device

input

左侧排列(通常与主元选择相关)。数组的大小为n

Q

device

input

正确的排列(通常与重新排序相关)。数组的大小为n

nrhs

host

input

需要求解的右侧项数量。

Temp

device

input

包含临时工作空间的稠密矩阵(大小为ldt*nrhs)。

ldt

host

input

稠密矩阵Temp的前导维度(ldt >= n)。

XF_array

device

输入/输出

大小为batchSize的指针数组,每个指针指向包含右侧项F和解X的稠密矩阵(大小为ldxf*nrhs)。

ldxf

host

input

稠密矩阵XF的主维度(ldxf >= n)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了不支持的值或参数。

CUSOLVER_STATUS_EXECUTION_FAILED

内核无法在GPU上启动。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

2.6.26. cusolverRfBatchZeroPivot()

cusolverStatus_t
cusolverRfBatchZeroPivot(/* Input */
                    cusolverRfHandle_t handle
                    /* Output (in the host memory) */
                    int *position);

尽管\(A_{j}\)彼此接近,但这并不意味着对每个j都存在\(M_{j} = P*A_{j}*Q^{T} = L_{j}*U_{j}\)。用户可以通过检查position数组中的对应值来查询哪些矩阵的LU分解失败。输入参数position是一个大小为batchSize的整数数组。

j-th个分量表示矩阵\(A_{j}\)的重构结果。如果position(j)为-1,则矩阵\(A_{j}\)的LU重构成功。如果position(j)k >= 0,则矩阵\(A_{j}\)不可进行LU分解且其矩阵\(U_{j}{(j,j)}\)为零。

如果存在任何一个\(A_{j}\)的LU重分解失败,cusolverRfBatch_Zero_Pivot的返回值将是CUSOLVER_STATUS_ZERO_PIVOT。当返回错误代码CUSOLVER_STATUS_ZERO_PIVOT时,用户可以重新进行LU分解以获得新的置换矩阵PQ

参数

内存空间

输入/输出

含义

handle

host

input

cuSolverRF库的句柄。

position

host

output

大小为batchSize的整数数组。position(j)的值表示矩阵Aj的奇异性:若无结构/数值零则为-1,若Aj(k,k)存在结构零或数值零则返回k >= 0

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_ZERO_PIVOT

在计算过程中遇到了零主元。

3. 使用CUSOLVERMG API

3.1. 概述

本节介绍如何使用cuSolverMG库API。它并非cuSolverMG API数据类型和函数的参考文档,相关内容将在后续章节中提供。

3.1.1. 线程安全

该库仅在每个线程拥有一个cuSolverMG上下文时才是线程安全的。

3.1.2. 确定性

目前,当满足以下条件时,给定工具包版本中的所有cuSolverMG API例程都会生成相同的位级结果:

  • 参与计算的所有GPU具有相同的计算能力和相同数量的SM。

  • 每次运行时瓦片大小保持一致。

  • 逻辑GPU的数量保持不变。GPU的顺序并不重要,因为它们都具有相同的计算能力。

3.1.3. 分块策略

cuSolverMG的分块策略与ScaLAPACK兼容。当前版本仅支持一维列块循环、列主序PACKED格式。

图1.a展示了维度为M_A乘以N_A的矩阵A的分块情况。每个列块包含T_A列。共有七个列块,编号为0,1,2,3,4,5,6,以cyclic方式分布在三个GPU上,即每个GPU轮流获取一个列块。例如,GPU 0包含列块0、3、6(黄色块),而GPU 1则获取GPU 0相邻的列块(蓝色块)。并非所有GPU都拥有相同数量的块;在本例中,GPU 0有三个块,其他GPU仅有两个块。

图1.b展示了两种在每块GPU本地存储这些列分片的可能格式。左侧称为PACKED格式,右侧称为UNPACKED格式。PACKED格式将三个列分片聚合在连续的内存块中,而UNPACKED格式则将这三个列分片分散到不同的内存块中。两者唯一的区别在于:PACKED格式可以执行一次大型GEMM调用,而UNPACKED格式需要执行三次GEMM调用。因此从理论上说,PACKED格式能提供比UNPACKED格式更好的性能。cuSolverMG在API中仅支持PACKED格式。为了获得最佳性能,用户只需选择合适的分片尺寸T_A来划分矩阵——尺寸不宜过小,例如256或更大的值就足够。

还有一个参数名为LLD_A,用于控制每个GPU中本地矩阵的前导维度。LLD_A必须大于或等于M_A。设置LLD_A的目的是为了提升GEMM运算性能。对于小规模问题,若LLD_A为2的幂次方时GEMM运算更快。但对于大规模问题,LLD_A带来的性能提升不明显。cuSolverMG仅支持LLD_A=M_A的配置。

Example of ``cuSolverMG`` tiling for 3 GPUs

针对3个GPU的cuSolverMG分块示例

cuSolverMG中的处理网格是一个GPU ID列表,类似于ScaLAPACK中的进程ID。cuSolverMG仅支持一维列块循环,因此也只支持一维网格。假设deviceId是一个GPU ID列表,那么deviceId=1,1,1deviceId=2,1,0都是有效的。前者描述了三个被选中运行cuSolverMG例程的逻辑设备,它们都具有相同的物理ID 0;后者同样使用三个逻辑设备,但每个设备的物理ID都不同。当前设计最多接受32个逻辑设备,即deviceId的长度小于或等于32。图1使用了deviceId=0,1,2

在实践中,矩阵A会被分配到deviceId所列出的GPU上。如果用户选择deviceId=1,1,1,所有列块都将位于GPU 1上,这会因单个GPU的内存容量而限制问题规模。此外,多GPU例程会通过片外总线增加额外的数据通信开销,在不支持或未使用NVLINK的情况下将显著影响性能。此时在单个GPU上运行反而会比在相同GPU ID设备上运行多GPU版本更快。

3.1.4. 全局矩阵与局部矩阵

在密集线性代数中操作矩阵A的子矩阵非常简单,只需将指针相对于A移动到子矩阵的起始点即可。例如,gesvd(10,10, A)表示对A(0:9,0:9)进行奇异值分解(SVD)。而gesvd(10,10, A + 5 + 2*lda )则表示从A(5,2)开始的10×10子矩阵的SVD分解。

然而,在分布式矩阵的子矩阵上进行操作并不简单,因为子矩阵的不同起始点会改变该子矩阵的布局分布。ScaLAPACK引入了两个参数IAJA来定位子矩阵。图2展示了维度为M_A乘以N_A的(全局)矩阵A。sub(A)是A的一个M乘以N的子矩阵,起始于IAJA。请注意IAJA是基于1的索引。

给定一个分布式矩阵A,用户可以通过调用syevd(A, IA, JA)或者将sub(A)收集到另一个分布式矩阵B并调用syevd(B, IB=1, JB=1)来计算子矩阵sub(A)的特征值。

global matrix and local matrix

全局矩阵与局部矩阵

3.1.5. _bufferSize参数的使用

cuSolverMG库内部没有cudaMalloc功能,因此用户必须显式分配设备工作空间。例程xyz_bufferSize用于查询例程xyz所需的工作空间大小,例如xyz = syevd。为了简化API设计,xyz_bufferSize几乎完全遵循xyz的函数签名,尽管它实际上仅依赖部分参数(例如设备指针并不用于决定工作空间大小)。在大多数情况下,xyz_bufferSize会在实际设备数据(由设备指针指向)准备就绪之前或分配设备指针之前被调用。这种情况下,用户可以向xyz_bufferSize传递空指针而不会影响功能。

xyz_bufferSize 返回每个设备的bufferSize。该大小是元素数量,而非字节数。

3.1.6. 同步

所有例程均以同步(阻塞调用)方式运行。例程执行完毕后数据即准备就绪。但在调用例程前,用户需预先准备好分布式数据。例如,若用户需要通过多流设置矩阵,则必须进行流同步或设备同步,以确保分布式矩阵准备就绪。

3.1.7. 上下文切换

用户无需在每次调用cuSolverMG后通过cudaSetDevice()恢复设备。所有例程都会将设备设置回调用者原有的状态。

3.2. cuSolverMG 类型参考

3.2.1. cuSolverMG 类型

支持floatdoublecuComplexcuDoubleComplex数据类型。前两种是标准C语言数据类型,后两种是从cuComplex.h导出的。此外,cuSolverMG还使用了cuBLAS中的一些常见类型。

3.2.2. cusolverMgHandle_t

这是一个指向不透明cuSolverMG上下文的指针类型,用户必须在调用任何其他库函数之前通过调用cusolverMgCreate()来初始化它。未初始化的句柄对象将导致意外行为,包括cuSolverMG崩溃。由cusolverMgCreate()创建并返回的句柄必须传递给每个cuSolverMG函数。

3.2.3. cusolverMgGridMapping_t

该类型表示网格的布局。

含义

CUDALIBMG_GRID_MAPPING_ROW_MAJOR

行优先排序。

CUDALIBMG_GRID_MAPPING_COL_MAJOR

列主序排列。

3.2.4. cudaLibMgGrid_t

分布式网格的不透明结构。

3.2.5. cudaLibMgMatrixDesc_t

分布式矩阵描述符的不透明结构。

3.3. 辅助函数参考

3.3.1. cusolverMgCreate()

cusolverStatus_t
cusolverMgCreate(cusolverMgHandle_t *handle)

该函数用于初始化cuSolverMG库并在cuSolverMG上下文中创建一个句柄。在调用任何其他cuSolverMG API函数之前必须先调用此函数。它会分配访问GPU所需的硬件资源。

输出

handle

指向cuSolverMG上下文句柄的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

初始化成功。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

3.3.2. cusolverMgDestroy()

cusolverStatus_t
cusolverMgDestroy( cusolverMgHandle_t handle)

该函数释放由cuSolverMG库使用的CPU端资源。

输入

handle

cuSolverMG上下文的句柄。

返回状态

CUSOLVER_STATUS_SUCCESS

关闭成功。

3.3.3. cusolverMgDeviceSelect()

cusolverStatus_t
cusolverMgDeviceSelect(
    cusolverMgHandle_t handle,
    int nbDevices,
    int deviceId[] )

此函数将一组设备(GPU)子集注册到cuSolverMG句柄中。该设备子集将在后续API调用中使用。数组deviceId包含逻辑设备ID列表。术语logical表示允许重复的设备ID。例如,假设用户系统中只有一个GPU,即设备0。如果用户设置deviceId=0,0,0,那么cuSolverMG会将其视为三个独立的GPU,每个GPU对应一个流,因此仍支持并发内核启动。当前设计最多支持32个逻辑设备。

输入

handle

指向cuSolverMG上下文句柄的指针。

nbDevices

逻辑设备的数量。

deviceId

一个大小为 nbDevices 的整数数组。

返回状态

CUSOLVER_STATUS_SUCCESS

初始化成功。

CUSOLVER_STATUS_INVALID_VALUE

nbDevices 必须大于零且小于或等于32。

CUSOLVER_STATUS_ALLOC_FAILED

资源无法分配。

CUSOLVER_STATUS_INTERNAL_ERROR

设置内部流和事件时发生内部错误。

3.3.4. cusolverMgCreateDeviceGrid()

cusolverStatus_t
cusolverMgCreateDeviceGrid(
    cusolverMgGrid_t* grid,
    int32_t numRowDevices,
    int32_t numColDevices,
    const int32_t deviceId[],
    cusolverMgGridMapping_t mapping)

此函数用于设置设备网格。

仅支持一维列块循环,因此numRowDevices必须等于1。

警告

cusolverMgCreateDeviceGrid() 必须与 cusolverMgDeviceSelect() 保持一致,即 numColDevices 必须等于 cusolverMgDeviceSelect() 中的 nbDevices

参数

内存空间

输入/输出

含义

grid

host

output

指向不透明结构的指针。

numRowDevices

host

input

行中的设备数量。

numColDevices

host

input

列中的设备数量。

deviceId

host

input

大小为numColDevices的整数数组,包含设备ID。

mapping

host

input

行优先或列优先排序。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_INVALID_VALUE

numColDevices 不大于0。 numRowDevices 不是1。

3.3.5. cusolverMgDestroyGrid()

cusolverStatus_t
cusolverMgDestroyGrid(
    cusolverMgGrid_t grid)

该函数释放网格的资源。

参数

内存空间

输入/输出

含义

grid

host

输入/输出

指向不透明结构的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

3.3.6. cusolverMgCreateMatrixDesc()

cusolverStatus_t
cusolverMgCreateMatrixDesc(
    cusolverMgMatrixDesc_t * desc,
    int64_t numRows,
    int64_t numCols,
    int64_t rowBlockSize,
    int64_t colBlockSize,
    cudaDataType_t dataType,
    const cusolverMgGrid_t grid)

该函数用于设置矩阵描述符 desc

仅支持一维列块循环,因此numRows必须等于rowBlockSize

参数

内存

输入/输出

含义

描述

host

output

矩阵描述符。

numRows

host

input

全局A的行数。

numCols

host

input

全局A的列数。

rowBlockSize

host

input

每个图块的行数。

colBlockSize

host

input

每个图块的列数。

dataType

host

input

矩阵的数据类型。

grid

host

input

指向网格结构的指针。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_INVALID_VALUE

numRowsnumColsrowBlockSizecolBlockSize小于0。numRows不等于rowBlockSize

3.3.7. cusolverMgDestroyMatrixDesc()

cusolverStatus_t
cusolverMgDestroyMatrixDesc(
    cusolverMgMatrixDesc_t desc)

该函数释放矩阵描述符 desc

参数

内存

输入/输出

含义

描述

host

输入/输出

矩阵描述符。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

3.4. 稠密线性求解器参考

本节介绍cuSolverMG的线性求解器API。

3.4.1. cusolverMgPotrf()

以下辅助函数可以计算cusolverMgPotrf所需的预分配缓冲区大小:

cusolverStatus_t
cusolverMgPotrf_bufferSize(
    cusolverMgHandle_t handle,
    cublasFillMode_t uplo,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    cudaDataType computeType,
    int64_t *lwork)

以下例程:

cusolverStatus_t
cusolverMgPotrf(
    cusolverMgHandle_t handle,
    cublasFillMode_t uplo,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    cudaDataType computeType,
    void *array_d_work[],
    int64_t lwork,
    int *info)

使用通用API接口计算埃尔米特正定矩阵的Cholesky分解。

A 是一个 \(n \times n\) 埃尔米特矩阵;仅下三角或上三角部分有意义。输入参数 uplo 指示使用矩阵的哪一部分。该函数将保持其他部分不变。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L

\[A = L*L^{H}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U

\[A = U^{H}*U\]

用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备上设备内存的设备指针。array_d_work[j]的数据类型为computeType。其大小为lwork,即每个设备的元素数量,该值由cusolverMgPotrf_bufferSize()返回。

如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说LU的某些对角线元素不是实数。输出参数info将指示A中不是正定的最小前导子矩阵。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

通用API包含两种不同类型:dataTypeA表示矩阵A的数据类型,而computeType表示运算的计算类型及工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。cusolverMgPotrf仅支持以下四种组合。

请访问cuSOLVER库示例 - MgPotrf查看代码示例。

数据类型与计算类型的有效组合

数据类型A

计算类型

含义

CUDA_R_32F

CUDA_R_32F

SPOTRF

CUDA_R_64F

CUDA_R_64F

DPOTRF

CUDA_C_32F

CUDA_C_32F

CPOTRF

CUDA_C_64F

CUDA_C_64F

ZPOTRF

potrf的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverMg库上下文的句柄。

uplo

host

input

指示矩阵A的下三角或上三角部分是否被存储,另一部分不被引用。目前仅支持CUBLAS_FILL_MODE_LOWER模式。

N

host

input

矩阵 sub(A) 的行数和列数。

array_d_A

host

输入/输出

一个维度为G的主机指针数组。它包含一个分布式<类型>数组,该数组包含维度为N * Nsub(A)。退出时,sub(A)包含因子LU

IA

host

input

全局数组A中的行索引,表示sub(A)的第一行。

JA

host

input

全局数组A中的列索引,表示sub(A)的第一列。

描述A

host

input

分布式矩阵A的矩阵描述符。

computeType

host

input

用于计算的数据类型。

array_d_work

host

输入/输出

一个维度为G的主机指针数组。array_d_work[j]指向第j个设备中的设备工作空间,大小为lwork数组。

lwork

host

input

array_d_work[j]的大小,由cusolverMgPotrf_bufferSize返回。lwork表示元素数量,而非字节数。

信息

host

output

如果 info = 0,则Cholesky分解成功。

如果 info = -i,表示第 i-th 个参数有误(不包含句柄参数)。

如果 info = i,则第 i 阶的前主子式不是正定的。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (M,N<0)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

3.4.2. cusolverMgPotrs()

下面的辅助函数可以计算为cusolverMgPotrs预分配缓冲区所需的大小。

cusolverStatus_t
cusolverMgPotrs_bufferSize(
    cusolverMgHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    int nrhs,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    void *array_d_B[],
    int IB,
    int JB,
    cudaLibMgMatrixDesc_t descrB,
    cudaDataType computeType,
    int64_t *lwork )

以下例程:

cusolverStatus_t
cusolverMgPotrs(
    cusolverMgHandle_t handle,
    cublasFillMode_t uplo,
    int n,
    int nrhs,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    void *array_d_B[],
    int IB,
    int JB,
    cudaLibMgMatrixDesc_t descrB,
    cudaDataType computeType,
    void *array_d_work[],
    int64_t lwork,
    int *info)

该函数用于求解线性方程组:

\[A*X = B\]

其中A是一个\(n \times n\)埃尔米特矩阵,使用通用API接口时仅需关注下三角或上三角部分。输入参数uplo用于指定矩阵的哪一部分将被使用。该函数会保持矩阵其他部分不变。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则矩阵 A 应包含先前由 cusolverMgPotrf 例程计算的 Cholesky 分解的下三角因子。

\[A = L*L^{H}\]

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则矩阵 A 应包含先前由 cusolverMgPotrf 例程计算的Cholesky分解的上三角因子。

\[A = U^{H}*U\]

该操作是原地进行的,即矩阵 B 在退出时包含线性方程组的解。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备上设备内存的设备指针。array_d_work[j]的数据类型为computeType,其大小为lwork(即每个设备的元素数量),该值由cusolverMgPotrs_bufferSize()函数返回。

如果输出参数 info = -i (小于零),表示第 i 个参数有误(不包含句柄参数)。

通用API包含四种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeB表示矩阵B的数据类型,computeType表示运算的计算类型和工作空间(array_d_work)的数据类型。descrA包含dataTypeAdescrB包含dataTypeB,因此没有显式的dataTypeAdataTypeB参数。cusolverMgPotrs仅支持以下四种组合。

请访问cuSOLVER库示例 - MgPotrf查看代码示例。

数据类型与计算类型的有效组合

数据类型A

数据类型B

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SPOTRS

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DPOTRS

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CPOTRS

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZPOTRS

potrs的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverMg库上下文的句柄。

uplo

host

input

指示矩阵A的下三角或上三角部分是否被存储,另一部分不被引用。目前仅支持CUBLAS_FILL_MODE_LOWER模式。

N

host

input

矩阵 sub(A) 的行数和列数。

NRHS

host

input

矩阵 sub(A)sub(B) 的列数。

array_d_A

host

输入/输出

一个维度为G的主机指针数组。它包含一个分布式的数组,该数组包含维度为M * Nsub(A)。退出时,sub(A)包含因子LU

IA

host

input

全局数组A中的行索引,表示sub(A)的第一行。

JA

host

input

全局数组A中表示sub(A)首列的列索引。

描述A

host

input

分布式矩阵A的矩阵描述符。

array_d_B

host

输入/输出

一个维度为G的主机指针数组。它包含一个分布式<类型>数组,该数组包含维度为N * NRHSsub(B)。退出时,sub(A)包含线性系统的解。

IB

host

input

全局数组B中表示sub(B)首行的行索引。

JB

host

input

全局数组B中表示sub(B)首列的列索引。

描述B

host

input

分布式矩阵B的矩阵描述符。

computeType

host

input

用于计算的数据类型。

array_d_work

host

输入/输出

一个维度为G的主机指针数组。array_d_work[j]指向第j个设备中的设备工作空间,类型为lwork大小的数组。

lwork

host

input

array_d_work[j]的大小,由cusolverMgPotrs_bufferSize返回。lwork表示元素数量,而非字节数。

信息

host

output

如果 info = 0,表示该例程执行成功。

如果 info = -i,表示第 i-th 个参数有误(不包含句柄参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (M,N<0)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

3.4.3. cusolverMgPotri()

下面的辅助函数可以计算为cusolverMgPotri预分配缓冲区所需的大小。

cusolverStatus_t
cusolverMgPotri_bufferSize(
    cusolverMgHandle_t handle,
    cublasFillMode_t uplo,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    cudaDataType computeType,
    int64_t *lwork)

以下例程:

cusolverStatus_t
cusolverMgPotri(
    cusolverMgHandle_t handle,
    cublasFillMode_t uplo,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    cudaDataType computeType,
    void *array_d_work[],
    int64_t lwork,
    int *info)

该函数使用Cholesky分解计算埃尔米特正定矩阵A的逆矩阵

\[A = L*L^{H} = U^{H}*U\]

cusolverMgPotrf()计算得出。

如果输入参数 uploCUBLAS_FILL_MODE_LOWER,则输入时矩阵 A 包含由 cusolverMgPotrf 计算得出的 A 的下三角因子。仅处理 A 的下三角部分,并将其替换为 A 逆矩阵的下三角部分。

如果输入参数 uploCUBLAS_FILL_MODE_UPPER,则输入时矩阵 A 包含由 cusolverMgPotrf 计算得出的 A 的上三角因子。仅处理 A 的上三角部分,并将其替换为 A 逆矩阵的上三角部分。

用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备中设备内存的设备指针。array_d_work[j]的数据类型为computeType。其大小为lwork(即每个设备的元素数量),该值由cusolverMgPotri_bufferSize()返回。

如果逆矩阵计算失败,即LU的某个前导子矩阵为空,输出参数info将指示LU中不是正定的最小前导子矩阵。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型和工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。cusolverMgPotri仅支持以下四种组合。

请访问cuSOLVER库示例 - MgPotrf查看代码示例。

数据类型与计算类型的有效组合

数据类型A

计算类型

含义

CUDA_R_32F

CUDA_R_32F

SPOTRI

CUDA_R_64F

CUDA_R_64F

DPOTRI

CUDA_C_32F

CUDA_C_32F

CPOTRI

CUDA_C_64F

CUDA_C_64F

ZPOTRI

potri的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverMg库上下文的句柄。

uplo

host

input

指示矩阵A的下三角或上三角部分是否被存储,另一部分不被引用。目前仅支持CUBLAS_FILL_MODE_LOWER模式。

N

host

input

矩阵 sub(A) 的行数和列数。

array_d_A

host

输入/输出

一个维度为G的主机指针数组。它包含一个分布式<类型>数组,该数组包含维度为N * Nsub(A)。退出时,sub(A)包含A的逆矩阵的上三角或下三角部分,具体取决于uplo参数的值。

IA

host

input

全局数组A中的行索引,表示sub(A)的第一行。

JA

host

input

全局数组A中表示sub(A)首列的列索引。

描述A

host

input

分布式矩阵A的矩阵描述符。

computeType

host

input

用于计算的数据类型。

array_d_work

host

输入/输出

一个维度为G的主机指针数组。array_d_work[j]指向第j个设备中的设备工作空间,大小为lwork的<type>数组。

lwork

host

input

array_d_work[j]的大小,由cusolverMgPotri_bufferSize返回。lwork表示元素数量,而非字节数。

信息

host

output

如果 info = 0,则Cholesky分解成功。

如果 info = -i,表示第 i-th 个参数有误(不包含句柄参数)。

如果 info =  i,则第i阶前主子式为零。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_NOT_INITIALIZED

库未初始化。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (M,N<0)。

CUSOLVER_STATUS_ARCH_MISMATCH

该设备仅支持计算能力5.0及以上版本。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

3.4.4. cusolverMgGetrf()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverMgGetrf_bufferSize(
    cusolverMgHandle_t handle,
    int M,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    int *array_d_IPIV[],
    cudaDataType_t computeType,
    int64_t *lwork);
cusolverStatus_t
cusolverMgGetrf(
    cusolverMgHandle_t handle,
    int M,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    int *array_d_IPIV[],
    cudaDataType_t computeType,
    void *array_d_work[],
    int64_t lwork,
    int *info );

该函数计算一个\(M \times N\)矩阵的LU分解

\[P*A = L*U\]

其中 A 是一个 \(M \times N\) 矩阵,P 是置换矩阵,L 是单位下三角矩阵,U 是上三角矩阵。

用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备上设备内存的设备指针。array_d_work[j]的数据类型为computeType。其大小为lwork(由cusolverMgGetrf_bufferSize()返回的每个设备元素数量)。

如果LU分解失败,即矩阵A (U)是奇异的,输出参数info=i表示U(i,i) = 0

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

如果 array_d_IPIV 为空,则不执行主元选择。因式分解结果为 A=L*U,这种分解在数值上不稳定。

array_d_IPIV 必须与 array_d_A 保持一致,即 JAsub(A) 的第一列,也是 sub(IPIV) 的第一列。

无论LU分解是否成功,输出参数array_d_IPIV都包含主元交换序列,第i行将与第array_d_IPIV(i)行进行交换。

通用API包含三种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型和工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。cusolverMgGetrf仅支持以下四种组合。

请访问cuSOLVER库示例 - MgGetrf查看代码示例。

数据类型与计算类型的有效组合

数据类型A

计算类型

含义

CUDA_R_32F

CUDA_R_32F

SGETRF

CUDA_R_64F

CUDA_R_64F

DGETRF

CUDA_C_32F

CUDA_C_32F

CGETRF

CUDA_C_64F

CUDA_C_64F

ZGETRF

备注1: 分块大小 TA 必须小于或等于512。

getrf API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverMg库上下文的句柄。

M

host

input

矩阵 sub(A) 的行数。

N

host

input

矩阵 sub(A) 的列数。

array_d_A

host

输入/输出

一个维度为G的主机指针数组。它包含一个分布式的<type>数组,该数组包含维度为M * Nsub(A)。退出时,sub(A)包含因子LU

IA

host

input

全局数组A中的行索引,表示sub(A)的第一行。

JA

host

input

全局数组A中表示sub(A)首列的列索引。

描述A

host

input

分布式矩阵A的矩阵描述符。

array_d_IPIV

host

output

一个维度为G的主机指针数组。它包含一个分布式整数数组,其中存储了大小为min(M,N)sub(IPIV)sub(IPIV)包含主元索引。

computeType

host

input

用于计算的数据类型。

array_d_work

host

输入/输出

一个维度为G的主机指针数组。array_d_work[j]指向第j个设备中的设备工作空间,类型为lwork大小的<type>数组。

lwork

host

input

array_d_work[j]的大小,由cusolverMgGetrf_bufferSize返回。lwork表示元素数量,而非字节数。

信息

host

output

如果 info = 0,则LU分解成功。

如果 info = -i,表示第 i-th 个参数有误(不包含句柄参数)。

如果 info =  i,则 U(i,i) = 0

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (M,N<0)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

3.4.5. cusolverMgGetrs()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverMgGetrs_bufferSize(
    cusolverMgHandle_t handle,
    cublasOperation_t TRANS,
    int N,
    int NRHS,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    int *array_d_IPIV[],
    void *array_d_B[],
    int IB,
    int JB,
    cudaLibMgMatrixDesc_t descrB,
    cudaDataType_t computeType,
    int64_t *lwork);
cusolverStatus_t
cusolverMgGetrs(
    cusolverMgHandle_t handle,
    cublasOperation_t TRANS,
    int N,
    int NRHS,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    int *array_d_IPIV[],
    void *array_d_B[],
    int IB,
    int JB,
    cudaLibMgMatrixDesc_t descrB,
    cudaDataType_t computeType,
    void *array_d_work[],
    int64_t lwork,
    int *info );

该函数用于求解具有多个右端项的线性方程组

\[op(A)*X = B\]

其中A是一个\(N \times N\)矩阵,并且已经通过getrf进行了LU分解,即A的下三角部分是L,而A的上三角部分(包括对角元素)是UB是一个\(N \times {NRHS}\)的右侧矩阵。解矩阵X会覆盖右侧矩阵B

输入参数 TRANS 的定义如下

image1

用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备上设备内存的设备指针。array_d_work[j]的数据类型为computeTypearray_d_work[j]的大小为lwork,即每个设备的元素数量,该值由cusolverMgGetrs_bufferSize()返回。

如果array_d_IPIV为空,则不执行主元置换。否则,array_d_IPIVgetrf的输出结果。它包含用于置换右侧项的主元索引。

如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。

通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeB表示矩阵B的数据类型,而computeType表示运算的计算类型及工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。descrB已包含dataTypeB信息,因此无需显式传递dataTypeB参数。cusolverMgGetrs仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

数据类型B

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SGETRS

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DGETRS

CUDA_C_32F

CUDA_C_32F

CUDA_C_32F

CGETRS

CUDA_C_64F

CUDA_C_64F

CUDA_C_64F

ZGETRS

备注1: 分块大小 TA 必须小于或等于512。

备注2:仅支持 TRANS=CUBLAS_OP_N

请访问cuSOLVER库示例 - MgGetrf查看代码示例。

getrs的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverMG库上下文的句柄。

TRANS

host

input

操作 op(A) 表示非转置或共轭转置。

N

host

input

矩阵 sub(A) 的行数和列数。

NRHS

host

input

矩阵 sub(B) 的列数。

array_d_A

host

input

一个维度为G的主机指针数组。它包含一个分布式<类型>数组,该数组包含维度为M * Nsub(A)sub(A)包含因子LU

IA

host

input

全局数组A中的行索引,表示sub(A)的第一行。

JA

host

input

全局数组A中表示sub(A)首列的列索引。

描述A

host

input

分布式矩阵A的矩阵描述符。

array_d_IPIV

host

input

一个维度为G的主机指针数组。它包含一个分布式整数数组,其中存储了维度为min(M,N)sub(IPIV)sub(IPIV)包含主元索引。

array_d_B

host

输入/输出

一个维度为G的主机指针数组。它包含一个分布式<类型>数组,该数组含有维度为N * NRHSsub(B)

IB

host

input

全局数组B中表示sub(B)首行的行索引。

JB

host

input

全局数组B中表示sub(B)首列的列索引。

描述B

host

input

分布式矩阵B的矩阵描述符。

computeType

host

input

用于计算的数据类型。

array_d_work

host

输入/输出

一个维度为G的主机指针数组。array_d_work[j]指向第j个设备中的设备工作空间,类型为lwork大小的<type>数组。

lwork

host

input

array_d_work[j]的大小,由cusolverMgGetrs_bufferSize返回。lwork表示元素数量,而非字节数。

信息

host

output

如果 info = 0,表示操作成功。

如果 info = -i,表示第 i-th 个参数有误(不包含句柄参数)。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数 (N<0NRHS<0)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

3.5. 稠密特征值求解器参考

本节介绍cuSolverMG的特征值求解器API。

3.5.1. cusolverMgSyevd()

以下辅助函数可以计算预分配缓冲区所需的大小。

cusolverStatus_t
cusolverMgSyevd_bufferSize(
    cusolverMgHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    void *W,
    cudaDataType_t dataTypeW,
    cudaDataType_t computeType,
    int64_t *lwork
    );
cusolverStatus_t
cusolverMgSyevd(
    cusolverMgHandle_t handle,
    cusolverEigMode_t jobz,
    cublasFillMode_t uplo,
    int N,
    void *array_d_A[],
    int IA,
    int JA,
    cudaLibMgMatrixDesc_t descrA,
    void *W,
    cudaDataType_t dataTypeW,
    cudaDataType_t computeType,
    void *array_d_work[],
    int64_t lwork,
    int *info );

该函数计算对称(厄米特)\(N \times N\)矩阵A的特征值和特征向量。标准对称特征值问题为:

\[A*V = V*\Lambda\]

其中 Λ 是一个实数的 \(N \times N\) 对角矩阵。V 是一个 \(N \times N\) 酉矩阵。Λ 的对角线元素是 A 的特征值,按升序排列。

cusolverMgSyevd 返回特征值到 W 中,并将特征向量覆盖写入 AW 是一个主机端的 \(1 \times N\) 向量。

通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示向量W的数据类型,computeType表示运算的计算类型和工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。cusolverMgSyevd仅支持以下四种组合。

数据类型与计算类型的有效组合

数据类型A

数据类型W

计算类型

含义

CUDA_R_32F

CUDA_R_32F

CUDA_R_32F

SSYEVD

CUDA_R_64F

CUDA_R_64F

CUDA_R_64F

DSYEVD

CUDA_C_32F

CUDA_R_32F

CUDA_C_32F

CHEEVD

CUDA_C_64F

CUDA_R_64F

CUDA_C_64F

ZHEEVD

用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备上设备内存的设备指针。array_d_work[j]的数据类型为computeType。其大小为lwork(由cusolverMgSyevd_bufferSize()返回的每个设备元素数量)。

array_d_A 也是一个维度为 G 的主机指针数组。array_d_A[j] 是指向第 j 个设备上设备内存的设备指针。array_d_A[j] 的数据类型为 dataTypeAarray_d_A[j] 的大小约为 N*TA*(blocks per device)。用户需要手动准备 array_d_A(代码示例请参阅cuSOLVER Library Samples - MgSyevd)。

如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(大于零),表示算法未能收敛所有特征值。

如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。

备注1:仅支持CUBLAS_FILL_MODE_LOWER模式,因此用户需要准备矩阵A的下三角部分。

备注2:仅支持 IA=1JA=1

备注3:瓦片大小 TA 必须小于或等于1024。为了获得最佳性能,TA 应设为256或512。

请访问cuSOLVER库示例 - MgSyevd查看代码示例。

syevd的API接口

参数

内存

输入/输出

含义

handle

host

input

cuSolverMG库上下文的句柄。

jobz

host

input

指定选项以仅计算特征值或计算特征对:

jobz = CUSOLVER_EIG_MODE_NOVECTOR : 仅计算特征值

jobz = CUSOLVER_EIG_MODE_VECTOR : 计算特征值和特征向量

uplo

host

input

指定A的哪一部分被存储。

uplo = CUBLAS_FILL_MODE_LOWER: 存储的是A的下三角部分。

uplo = CUBLAS_FILL_MODE_UPPER: 存储的是A的上三角部分。

仅支持 CUBLAS_FILL_MODE_LOWER

N

host

input

矩阵 sub(A) 的行数(或列数)。

array_d_A

host

输入/输出

一个维度为G的主机指针数组。它包含一个分布式的数组,该数组包含维度为N * Nsub(A)

如果 uplo = CUBLAS_FILL_MODE_UPPER,则 sub(A) 的前导 N×N 上三角部分包含矩阵 sub(A) 的上三角部分。

如果 uplo = CUBLAS_FILL_MODE_LOWER,则 sub(A) 的前 N×N 下三角部分包含矩阵 sub(A) 的下三角部分。退出时,如果 jobz = CUSOLVER_EIG_MODE_VECTORinfo = 0,sub(A) 将包含矩阵 sub(A) 的标准正交特征向量。

如果 jobz = CUSOLVER_EIG_MODE_NOVECTOR,则 A 的内容将被销毁。

IA

host

input

全局数组A中的行索引,表示sub(A)的第一行。

JA

host

input

全局数组A中表示sub(A)首列的列索引。

描述A

host

input

分布式矩阵A的矩阵描述符。

W

host

output

一个维度为N的实数数组。sub(A)的特征值按升序排列,即排序后满足W(i) <= W(i+1)

dataTypeW

host

input

向量W的数据类型。

computeType

host

input

用于计算的数据类型。

array_d_work

host

输入/输出

一个维度为G的主机指针数组。array_d_work[j]指向第j个设备中的设备工作空间,类型为lwork大小的<type>数组。

lwork

host

input

array_d_work[j]的大小,由cusolverMgSyevd_bufferSize返回。lwork表示元素数量,而非字节数。

信息

host

output

如果 info = 0,表示操作成功。

如果 info = -i,表示第 i-th 个参数有误(不包含句柄参数)。

如果 info =  i (> 0),表示并非所有特征值都已收敛。

返回状态

CUSOLVER_STATUS_SUCCESS

操作成功完成。

CUSOLVER_STATUS_INVALID_VALUE

传递了无效参数(N<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTORCUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER,或IAJA不为1,或N大于全局A的维度,或dataTypecomputeType的组合无效)。

CUSOLVER_STATUS_INTERNAL_ERROR

内部操作失败。

4. 致谢

NVIDIA 谨此感谢以下个人和机构所作出的贡献:

以下是CLAPACK-3.2.1的许可证。

版权所有 (c) 1992-2008 田纳西大学。保留所有权利。

在满足以下条件的前提下,允许以源代码和二进制形式进行再分发和使用,无论是否经过修改:

  • 源代码的再分发必须保留上述版权声明、本条件列表以及以下免责声明。

  • 以二进制形式重新分发时,必须在随分发提供的文档和/或其他材料中复制上述版权声明、本条件列表以及本许可证中列出的以下免责声明。

  • 未经事先书面许可,不得使用版权持有者的名称或其贡献者的名称来认可或推广基于此软件衍生的产品。

本软件按"原样"提供,版权持有人和贡献者不承担任何明示或默示的担保责任,包括但不限于对适销性和特定用途适用性的默示担保。在任何情况下,无论基于何种法律理论(无论是合同责任、严格责任还是侵权责任,包括疏忽或其他原因),版权所有者或贡献者均不对因使用本软件而导致的任何直接、间接、附带、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购成本、使用损失、数据丢失或利润损失,或业务中断)承担责任,即使已被告知可能发生此类损害。

以下是METIS的许可证(Apache 2.0许可证)。

版权所有 1995-2013,明尼苏达大学董事会

根据Apache许可证2.0版("许可证")授权;除非符合许可证要求,否则不得使用此文件。您可以在以下网址获取许可证副本:

http://www.apache.org/licenses/LICENSE-2.0

除非适用法律要求或书面同意,依据许可证分发的软件均按"原样"提供,不附带任何明示或暗示的担保或条件。有关许可证下管理权限和限制的具体条款,请参阅许可证内容。

以下是QD的许可证(修改后的BSD许可证)。

版权所有 (c) 2003-2009,加利福尼亚大学董事会,经由劳伦斯伯克利国家实验室(需获得美国能源部任何必要批准)保留所有权利。

  1. 允许以源代码和二进制形式进行再分发和使用,无论是否修改,只要满足以下条件:

  1. 源代码的再分发必须保留版权声明、本条件列表以及以下免责声明。

  2. 以二进制形式重新分发时,必须在随附的文档和/或其他材料中复制版权声明、本条件列表以及以下免责声明。

  3. 未经事先书面许可,不得使用加州大学、劳伦斯伯克利国家实验室或美国能源部的名称,或其贡献者的名称,来认可或推广由本软件衍生的产品。

  1. 本软件按"原样"提供,版权持有人和贡献者不承担任何明示或默示的担保责任,包括但不限于对适销性和特定用途适用性的默示担保。在任何情况下,无论基于何种法律理论(无论是合同责任、严格责任还是侵权责任,包括疏忽或其他原因),版权所有者或贡献者均不对因使用本软件而导致的任何直接、间接、附带、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购成本、使用损失、数据丢失或利润损失、业务中断)承担责任,即使已被告知可能发生此类损害。

  2. 您没有任何义务必须向任何人提供源代码功能、性能方面的错误修复、补丁或升级(统称"增强功能");但如果您选择公开或直接向劳伦斯伯克利国家实验室提供您的增强功能,且未对这些增强功能另行施加书面许可协议,则您特此授予以下许可:非排他性、免版税的永久许可,允许以二进制和源代码形式安装、使用、修改、准备衍生作品、整合到其他计算机软件中、分发及再许可此类增强功能或其衍生作品。

5. 参考文献

[1] Timothy A. Davis,《稀疏线性系统的直接解法》,siam出版社 2006年。

[2] E. Chuthill 和 J. McKee,《减少稀疏对称矩阵的带宽》,ACM '69 第24届全国会议论文集,第157-172页。

[3] Alan George, Joseph W. H. Liu, 《伪外围节点查找器的实现》,ACM数学软件汇刊(TOMS)第5卷第3期,1979年9月,第284-295页。

[4] J. R. Gilbert 和 T. Peierls,《稀疏部分主元消去法的时间复杂度与算术运算成正比》,SIAM 科学与统计计算期刊,第9卷(1988年),第862-874页。

[5] Alan George 和 Esmond Ng,《稀疏系统部分主元高斯消元法的实现》,SIAM 科学与统计计算期刊,6(2),390-409页。

[6] Alan George 和 Esmond Ng,《稀疏高斯消元部分主元法中的符号分解》,SIAM 科学与统计计算期刊,8(6),877-898页。

[7] John R. Gilbert, Xiaoye S. Li, Esmond G. Ng, Barry W. Peyton, 计算稀疏QR和LU分解的行列计数, BIT 2001, 第41卷, 第4期, 第693-711页。

[8] Patrick R. Amestoy, Timothy A. Davis, Iain S. Duff, 一种近似最小度排序算法, SIAM 矩阵分析与应用期刊 第17卷第4期 第886-905页 1996年12月。

[9] Alan George, Joseph W. Liu,《使用商图实现最小度算法的快速实现》,ACM数学软件汇刊,第6卷第3期,1980年9月,第337-358页。

[10] Alan George, Joseph W. Liu,《大型稀疏正定系统的计算机解法》,新泽西州恩格尔伍德克利夫斯:Prentice-Hall出版社,1981年。

[11] Iain S. Duff, 算法575 零对角线置换, ACM数学软件汇刊, 第7卷第3期, 1981年9月, 第387-390页

[12] Iain S. Duff 和 Jacko Koster,《关于将稀疏矩阵中大元素置换到对角线上的算法》,SIAM矩阵分析与应用期刊,2001年,第22卷,第4期:第973-996页

[13] "一种快速高质量的多层次不规则图划分方案"。George Karypis 和 Vipin Kumar。《SIAM科学计算杂志》,第20卷,第1期,第359-392页,1999年。

[14] 中务裕治、柏兆俊与弗朗索瓦·吉吉,《优化Halley迭代法用于计算矩阵极分解》,SIAM矩阵分析与应用期刊,31(5): 2700-2720,2010

[15] Halko, Nathan, Per-Gunnar Martinsson, 和 Joel A. Tropp. "通过随机性发现结构:构建近似矩阵分解的概率算法." SIAM评论 53.2 (2011): 217-288.

6. 公告

6.1. 注意事项

本文档仅供信息参考之用,不应视为对产品功能、状态或质量的保证。NVIDIA公司(“NVIDIA”)对本文件所含信息的准确性或完整性不作任何明示或暗示的陈述或保证,并对其中可能存在的错误不承担任何责任。NVIDIA对于因使用此类信息而产生的后果、或因使用该信息导致的第三方专利或其他权利侵权概不负责。本文件不构成对开发、发布或交付任何材料(定义见下文)、代码或功能的承诺。

NVIDIA保留随时对本文件进行更正、修改、增强、改进以及任何其他变更的权利,恕不另行通知。

客户在下单前应获取最新的相关信息,并确认这些信息是最新且完整的。

除非NVIDIA与客户授权代表签署的单独销售协议中另有约定,否则NVIDIA产品的销售均以订单确认时提供的NVIDIA标准销售条款和条件为准(以下简称"销售条款")。NVIDIA特此明确反对将任何客户通用条款适用于本文件所述NVIDIA产品的采购。本文件不直接或间接构成任何合同义务。

NVIDIA产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命支持设备,也不适用于那些可以合理预期NVIDIA产品故障或失灵会导致人身伤害、死亡、财产或环境损害的应用场景。NVIDIA对于在此类设备或应用中使用和/或包含NVIDIA产品不承担任何责任,因此客户需自行承担相关风险。

NVIDIA不声明或保证基于本文档的产品适用于任何特定用途。NVIDIA未必会对每个产品的所有参数进行测试。客户应全权负责评估和确定本文档所含信息的适用性,确保产品适合并满足客户计划的应用需求,并执行必要的应用测试以避免应用或产品出现故障。客户产品设计中的缺陷可能会影响NVIDIA产品的质量和可靠性,并可能导致超出本文档范围的其他或不同的条件和/或要求。对于任何因以下原因导致的故障、损坏、成本或问题,NVIDIA不承担任何责任:(i) 以违反本文档的任何方式使用NVIDIA产品或(ii) 客户产品设计。

本文档不授予任何NVIDIA专利权、版权或其他NVIDIA知识产权的明示或暗示许可。NVIDIA发布的关于第三方产品或服务的信息,不构成NVIDIA对这些产品或服务的使用许可或担保认可。使用此类信息可能需要获得第三方基于其专利或其他知识产权的许可,或需要获得NVIDIA基于其专利或其他知识产权的许可。

本文件中的信息仅可在获得NVIDIA事先书面批准、未经改动完整复制且完全符合所有适用的出口法律法规,并附带所有相关条件、限制和声明的情况下进行复制。

本文件及所有NVIDIA设计规格、参考板、文件、图纸、诊断工具、清单和其他文档(统称及单独称为"材料")均以"现状"提供。NVIDIA不对材料作出任何明示或默示的保证,包括但不限于对不侵权、适销性和特定用途适用性的默示保证免责。在法律允许的最大范围内,NVIDIA不就因使用本文件导致的任何损害承担责任,包括但不限于任何直接、间接、特殊、附带、惩罚性或后果性损害,无论损害成因如何,也无论责任理论为何,即使NVIDIA已被告知发生此类损害的可能性。不论客户因任何原因可能遭受的任何损害,NVIDIA对客户就本文所述产品的全部及累计责任应受产品销售条款的限制。

6.2. OpenCL

OpenCL是苹果公司的商标,经Khronos Group Inc.授权使用。

6.3. 商标

NVIDIA和NVIDIA标识是美国及其他国家NVIDIA公司的商标或注册商标。其他公司及产品名称可能是其各自关联公司的商标。