cuSOLVER API参考文档
cuSOLVER API参考指南,这是一个用于稠密和稀疏矩阵分解及线性系统求解的GPU加速库。
1. 简介
cuSolver库是基于cuBLAS和cuSPARSE库的高级软件包。它包含两个模块,分别对应两组API:
单GPU上的cuSolver API
单节点多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库旨在求解以下形式的稠密线性系统
其中系数矩阵 \(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库主要设计用于求解稀疏线性系统
以及最小二乘问题
其中稀疏矩阵 \(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}\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中的函数支持以下数据类型:float、double、cuComplex和cuDoubleComplex。传统API的命名规范如下:
|
其中 <t> 可以是 S、D、C、Z 或 X,分别对应数据类型 float、double、cuComplex、cuDoubleComplex 以及通用类型。<operation> 可以是 Cholesky 分解 (potrf)、带部分主元的 LU 分解 (getrf)、QR 分解 (geqrf) 以及 Bunch-Kaufman 分解 (sytrf)。
通用API中的函数为每个例程提供单一入口点,并支持使用64位整数定义矩阵和向量维度。通用API的命名规范与数据类型无关,具体如下:
|
其中 <operation> 可以是 Cholesky 分解 (potrf)、带部分主元的 LU 分解 (getrf) 和 QR 分解 (geqrf)。
cuSolverSP库函数支持以下数据类型:float、double、cuComplex和cuDoubleComplex。其命名规则如下:
|
其中cuSolverSp是GPU路径,cusolverSpHost是对应的CPU路径。<t>可以是S、D、C、Z或X,分别对应数据类型float、double、cuComplex、cuDoubleComplex以及通用类型。
matrix data format 是 csr,即压缩稀疏行格式。
<operation> 可以是 ls、lsq、eig 或 eigs,分别对应线性求解器、最小二乘求解器、特征值求解器以及计算指定区间内的特征值数量。
output matrix data format可以是v或m,分别对应向量或矩阵。
<based on> 描述了所使用的算法。例如,在线性求解器和最小二乘求解器中使用了qr(稀疏QR分解)。
所有函数的返回类型均为cusolverStatus_t,具体说明将在后续章节中详细展开。
例程 |
数据格式 |
操作 |
输出格式 |
基于 |
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
cuSolverRF库例程支持数据类型double。大多数例程遵循以下命名规范:
|
其中可选的尾部Host限定符表示数据是在主机上访问的,而不是在设备上访问的,后者是默认情况。<operation>可以是Setup、Analyze、Refactor、Solve、ResetValues、AccessBundledFactors和ExtractSplitFactors。
最后,cuSolverRF库例程的返回类型是cusolverStatus_t。
1.5. 异步执行
cuSolver库函数倾向于尽可能保持异步执行。开发者始终可以使用cudaDeviceSynchronize()函数来确保特定cuSolver库例程的执行已完成。
开发者也可以使用cudaMemcpy()例程,通过分别指定cudaMemcpyDeviceToHost和cudaMemcpyHostToDevice参数,将数据从设备复制到主机或反之。在这种情况下,无需额外调用cudaDeviceSynchronize(),因为使用上述参数的cudaMemcpy()调用是阻塞式的,只有当结果在主机端准备就绪时才会完成。
1.6. 库属性
libraryPropertyType 数据类型是一个库属性类型的枚举(例如,CUDA 版本 X.Y.Z 将生成 MAJOR_VERSION=X、MINOR_VERSION=Y、PATCH_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流来重叠这些任务。
应用程序可以在概念上将每个任务与一个流关联起来。为了实现任务之间的计算重叠,开发者应该:
使用函数
cudaStreamCreate()创建 CUDA 流,并且在调用实际的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.4. 如何链接cusolver库
cusolver库提供动态库libcusolver.so和静态库libcusolver_static.a。如果用户将应用程序与libcusolver.so链接,则还需要libcublas.so、libcublasLt.so和libcusparse.so。如果用户将应用程序与libcusolver_static.a链接,则还需要以下库:libcudart_static.a、libculibos.a、libcusolver_lapack_static.a、libcusolver_metis_static.a、libcublas_static.a和libcusparse_static.a。
2.1.5. 链接第三方LAPACK库
从CUDA 10.1更新2开始,NVIDIA LAPACK库libcusolver_lapack_static.a是LAPACK的一个子集,仅包含GPU加速的stedc和bdsqr。用户必须将libcusolver_static.a与libcusolver_lapack_static.a链接才能成功构建应用程序。在CUDA 10.1更新2之前,用户可以用第三方LAPACK库(例如MKL)替换libcusolver_lapack_static.a。在CUDA 10.1更新2中,第三方LAPACK库不再影响cusolver库的行为,无论是功能还是性能。此外,用户不能将libcusolver_lapack_static.a作为独立的LAPACK库使用,因为它只是LAPACK的一个子集。
如果使用
libcusolver_static.a,则必须显式链接libcusolver_lapack_static.a,否则链接器会报告符号缺失。libcusolver_lapack_static.a与其他第三方LAPACK库之间不存在符号冲突,因此可以将同一应用程序同时链接到libcusolver_lapack_static.a和另一个第三方LAPACK库。libcusolver_lapack_static.a被内置在libcusolver.so中。因此,如果您使用libcusolver.so,则无需指定 LAPACK 库。libcusolver.so不会从第三方 LAPACK 库中调用任何例程,即使您将其与应用程序链接也是如此。
2.1.6. 信息规范
每个LAPACK例程都会返回一个info值,用于指示无效参数的位置。如果info = -i,则表示第i个参数无效。为了与LAPACK的基1索引保持一致,cusolver不会将无效的handle报告到info中。相反,对于无效的handle,cusolver会返回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. 确定性结果
在本文档中,如果一个函数在相同的输入参数、硬件和软件环境下每次执行都能计算出完全相同的二进制结果,则该函数被声明为确定性的。相反,非确定性函数可能由于浮点运算顺序的变化而计算出不同的二进制结果,例如四个值a、b、c、d的和s可以通过不同的顺序计算:
s = (a + b) + (c + d)s = (a + (b + c)) + ds = a + (b + (c + d))…
由于浮点运算的非结合性,所有结果可能在位级别上存在差异。
默认情况下,cuSolverDN会计算确定性结果。为了提高某些函数的性能,可以通过cusolverDnSetDeterministicMode()允许非确定性结果。
2.2. cuSolver 类型参考
2.2.1. cuSolverDN 类型
支持float、double、cuComplex和cuDoubleComplex数据类型。前两种是标准C语言数据类型,后两种是从cuComplex.h导出的。此外,cuSolverDN还使用了cuBLAS中一些常见的数据类型。
2.2.1.1. cusolverDnHandle_t
这是一个指向不透明cuSolverDN上下文的指针类型,用户必须在调用任何其他库函数之前通过调用cusolverDnCreate()来初始化它。未初始化的Handle对象将导致意外行为,包括cuSolverDN崩溃。由cusolverDnCreate()创建并返回的句柄必须传递给每个cuSolverDN函数。
2.2.1.2. cublasFillMode_t
该类型指示密集矩阵的哪一部分(下三角或上三角)已被填充,因此应由函数使用。
值 |
含义 |
|---|---|
|
矩阵的下半部分已填充。 |
|
矩阵的上半部分已填充。 |
|
完整矩阵已填充。 |
请注意,BLAS实现通常使用Fortran字符‘L’或‘l’(下三角)以及‘U’或‘u’(上三角)来描述矩阵的哪一部分被填充。
2.2.1.3. cublasOperation_t
cublasOperation_t 类型表示需要对密集矩阵执行哪种操作。
值 |
含义 |
|---|---|
|
选择非转置操作。 |
|
已选择转置操作。 |
|
选择了共轭转置操作。 |
请注意,BLAS实现通常使用Fortran字符‘N’或‘n’(非转置)、‘T’或‘t’(转置)以及‘C’或‘c’(共轭转置)来描述需要对密集矩阵执行的操作。
2.2.1.4. cusolverEigType_t
cusolverEigType_t 类型表示求解器处理的是哪种特征值类型。
值 |
含义 |
|---|---|
|
A*x = lambda*B*x |
|
A*B*x = lambda*x |
|
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 类型指示是否计算特征向量。
值 |
含义 |
|---|---|
|
仅计算特征值。 |
|
计算特征值和特征向量。 |
请注意,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。
值 |
含义 |
|---|---|
|
对应 |
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 是一个回调函数指针类型。
参数
参数 |
内存 |
输入/输出 |
描述 |
|---|---|---|---|
|
输出 |
||
|
输出 |
记录此消息的API名称。 |
|
|
输出 |
日志消息。 |
使用以下函数设置回调函数:cusolverDnLoggerSetCallback()。
2.2.1.13. cusolverDeterministicMode_t
cusolverDeterministicMode_t 类型用于指示多次执行相同输入的 cuSolver 函数是否会得到完全相同的位级结果(确定性模式),还是可能产生位级差异的结果(非确定性模式)。与仅涉及原子函数使用的 cublasAtomicsMode_t 不同,cusolverDeterministicMode_t 涵盖了所有非确定性的编程模式。可以通过 cusolverDnSetDeterministicMode() 和 cusolverDnGetDeterministicMode() 函数分别设置和查询确定性模式。
值 |
含义 |
|---|---|
|
计算确定性结果。 |
|
允许非确定性结果。 |
2.2.1.14. cusolverStorevMode_t
指定定义基本反射器的向量如何存储。
值 |
含义 |
|---|---|
|
按列。 |
|
按行处理。 |
2.2.1.15. cusolverDirectMode_t
指定基本反射器相乘形成块反射器的顺序。
值 |
含义 |
|---|---|
|
前进。 |
|
反向传播。 |
2.2.2. cuSolverSP 类型
支持float、double、cuComplex和cuDoubleComplex数据类型。前两种是标准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() 例程所采用的输入/输出矩阵格式。
值 |
含义 |
|---|---|
|
假设矩阵格式为CSR。(默认) |
|
假设矩阵格式为CSC。 |
2.2.3.3. cusolverRfNumericBoostReport_t
cusolverRfNumericBoostReport_t 是一个枚举类型,用于指示在 cusolverRfRefactor() 和 cusolverRfSolve() 例程期间是否使用了(主元的)数值增强功能。数值增强功能默认是禁用的。
值 |
含义 |
|---|---|
|
未使用数值提升。(默认) |
|
使用了数值提升。 |
2.2.3.4. cusolverRfResetValuesFastMode_t
cusolverRfResetValuesFastMode_t 是一个枚举类型,用于指示 cusolverRfResetValues() 例程使用的模式。快速模式需要额外的内存,仅当需要非常快速地调用 cusolverRfResetValues() 时才推荐使用。
值 |
含义 |
|---|---|
|
快速模式已禁用。(默认) |
|
快速模式已启用。 |
2.2.3.5. cusolverRfFactorization_t
cusolverRfFactorization_t 是一个枚举类型,用于指示在 cusolverRfRefactor() 例程中使用哪种(内部)算法进行重新分解。
值 |
含义 |
|---|---|
|
算法 0. (默认) |
|
算法1. |
|
算法2. 基于Domino的方案。 |
2.2.3.6. cusolverRfTriangularSolve_t
cusolverRfTriangularSolve_t 是一个枚举类型,用于指示在 cusolverRfSolve() 例程中使用哪种(内部)算法进行三角求解。
值 |
含义 |
|---|---|
|
算法1. (默认) |
|
算法2. 基于Domino的方案。 |
|
算法3. 基于Domino的方案。 |
2.2.3.7. cusolverRfUnitDiagonal_t
cusolverRfUnitDiagonal_t 是一个枚举类型,用于指示在cusolverRfSetupDevice()、cusolverRfSetupHost()和cusolverRfExtractSplitFactorsHost()例程中,输入/输出三角因子是否以及何处存储了单位对角线。
值 |
含义 |
|---|---|
|
单位对角线存储在下三角因子中(默认)。 |
|
单位对角线存储在上三角因子中。 |
|
假设下三角因子具有单位对角线。 |
|
假设上三角因子具有单位对角线。 |
2.2.3.8. cusolverStatus_t
cusolverStatus_t 是一个枚举类型,用于指示 cuSolverRF 库调用成功或失败。所有 cuSolver 库例程都会返回此状态值,它使用与稀疏和密集 Lapack 例程相同的枚举值。
2.3. cuSolver格式参考
2.3.1. 索引基础格式
cuSolver 支持基于1和基于0的索引方式。
2.3.2. 向量(稠密)格式
假设向量在内存中是线性存储的。例如,向量
表示为
2.3.3. 矩阵(密集)格式
假设密集矩阵在内存中以列优先顺序存储。可以使用原始矩阵的主维来访问子矩阵。例如,m*n(子)矩阵
表示为
其元素在内存中线性排列为
其中 lda \(\geq\) m 是 A 的主维度。
2.3.4. 矩阵 (CSR) 格式
在CSR格式中,矩阵由以下参数表示:
参数 |
类型 |
大小 |
含义 |
|---|---|---|---|
|
|
矩阵中的行数(和列数)。 |
|
|
|
矩阵中非零元素的数量。 |
|
|
|
|
对应于数组 |
|
|
|
对应矩阵中非零元素的列索引数组。假设该数组按行排序,且每行内按列排序。 |
|
|
|
对应矩阵中非零元素的数值数组。假设该数组已按行排序,且每行内按列排序。 |
请注意,在我们的CSR格式中,稀疏矩阵默认按行优先顺序存储。换句话说,索引数组首先按行索引排序,然后在每行内按列索引排序。此外,假定每对行和列索引仅出现一次。
例如,4x4矩阵
表示为
2.3.5. 矩阵 (CSC) 格式
在CSC格式中,矩阵由以下参数表示:
参数 |
类型 |
大小 |
含义 |
|---|---|---|---|
|
|
矩阵中的行数(和列数)。 |
|
|
|
矩阵中非零元素的数量。 |
|
|
|
|
对应于数组 |
|
|
|
对应矩阵中非零元素的行索引数组。假设该数组按列排序,且每列内按行排序。 |
|
|
|
与矩阵中非零元素对应的值数组。假设该数组按列排序,并且每列内按行排序。 |
请注意,在我们的CSC格式中,稀疏矩阵默认按列主序存储,换句话说,索引数组首先按列索引排序,然后在每列内按行索引排序。此外,假定每对行和列索引仅出现一次。
例如,4x4矩阵
表示为
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将管理自己的工作区。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向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端资源。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
关闭成功。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.4.1.3. cusolverDnSetStream()
cusolverStatus_t
cusolverDnSetStream(cusolverDnHandle_t handle, cudaStream_t streamId)
此函数设置cuSolverDN库用于执行其例程的流。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
该库要使用的流。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
流设置成功。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.4.1.4. cusolverDnGetStream()
cusolverStatus_t
cusolverDnGetStream(cusolverDnHandle_t handle, cudaStream_t *streamId)
此函数查询将由cuSolverDN库用于执行其例程的流。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
该流由 |
返回状态
CUSOLVER_STATUS_SUCCESS-
流设置成功。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.4.1.5. cusolverDnLoggerSetCallback()
cusolverStatus_t cusolverDnLoggerSetCallback(cusolverDnLoggerCallback_t callback);
此函数用于设置日志回调函数。
参数
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
指向回调函数的指针。参见 cusolverDnLoggerCallback_t。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
如果回调函数设置成功。
查看cusolverStatus_t获取完整的有效返回代码列表。
2.4.1.6. cusolverDnLoggerSetFile()
cusolverStatus_t cusolverDnLoggerSetFile(FILE* file);
此函数用于设置日志输出文件。注意:一旦通过此函数调用注册后,除非再次调用该函数切换到不同的文件句柄,否则不得关闭提供的文件句柄。
参数
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
指向一个已打开文件的指针。该文件应具有写入权限。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
如果日志文件设置成功。
查看cusolverStatus_t获取完整的有效返回代码列表。
2.4.1.7. cusolverDnLoggerOpenFile()
cusolverStatus_t cusolverDnLoggerOpenFile(const char* logFile);
此函数在给定路径下打开一个日志输出文件。
参数
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
日志输出文件的路径。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
如果日志文件成功打开。
查看cusolverStatus_t获取完整的状态返回码列表。
2.4.1.8. cusolverDnLoggerSetLevel()
cusolverStatus_t cusolverDnLoggerSetLevel(int level);
此函数用于设置日志记录级别的值。
参数
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
日志记录级别的值。请参阅cuSOLVERDn 日志记录。 |
返回状态
CUSOLVER_STATUS_INVALID_VALUE-
如果该值不是有效的日志级别。请参阅cuSOLVERDn Logging。
CUSOLVER_STATUS_SUCCESS-
如果日志级别设置成功。
查看cusolverStatus_t获取完整的有效返回代码列表。
2.4.1.9. cusolverDnLoggerSetMask()
cusolverStatus_t cusolverDnLoggerSetMask(int mask);
此函数设置日志掩码的值。
参数
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
日志掩码的值。请参阅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函数的确定性模式。为了提高性能,可以允许非确定性结果。受影响的函数包括cusolverDn、cusolverDn、cusolverDn、cusolverDn(当m > n时)、cusolverDn、cusolverDnXgeqrf()、cusolverDnXsyevd()、cusolverDnXsyevdx()、cusolverDnXgesvd()(当m > n时)、cusolverDnXgesvdr()以及cusolverDnXgesvdp()。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
与 |
返回状态
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设置的确定性模式。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
模式设置成功。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
mode是一个NULL指针。
2.4.1.13. cusolverDnCreateSyevjInfo()
cusolverStatus_t
cusolverDnCreateSyevjInfo(
syevjInfo_t *info);
该函数创建并初始化syevj、syevjBatched和sygvj的结构为默认值。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
返回状态
CUSOLVER_STATUS_SUCCESS-
结构初始化成功。
CUSOLVER_STATUS_ALLOC_FAILED-
资源无法分配。
2.4.1.14. cusolverDnDestroySyevjInfo()
cusolverStatus_t
cusolverDnDestroySyevjInfo(
syevjInfo_t info);
该函数销毁并释放该结构所需的任何内存。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
资源已成功释放。
2.4.1.15. cusolverDnXsyevjSetTolerance()
cusolverStatus_t
cusolverDnXsyevjSetTolerance(
syevjInfo_t info,
double tolerance)
此函数用于配置syevj的容差。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
|
|
|
数值特征值的准确性。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
2.4.1.16. cusolverDnXsyevjSetMaxSweeps()
cusolverStatus_t
cusolverDnXsyevjSetMaxSweeps(
syevjInfo_t info,
int max_sweeps)
此函数用于配置syevj中的最大扫描次数。默认值为100。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
|
|
|
最大扫描次数。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
2.4.1.17. cusolverDnXsyevjSetSortEig()
cusolverStatus_t
cusolverDnXsyevjSetSortEig(
syevjInfo_t info,
int sort_eig)
如果sort_eig为零,则不对特征值进行排序。此函数仅适用于syevjBatched。syevj和sygvj始终按升序对特征值进行排序。默认情况下,特征值始终按升序排序。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向syevj结构的指针。 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
2.4.1.18. cusolverDnXsyevjGetResidual()
cusolverStatus_t
cusolverDnXsyevjGetResidual(
cusolverDnHandle_t handle,
syevjInfo_t info,
double *residual)
此函数报告syevj或sygvj的残差。它不支持syevjBatched。如果用户在调用syevjBatched后调用此函数,将返回错误CUSOLVER_STATUS_NOT_SUPPORTED。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指向 |
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_SUPPORTED-
不支持批量版本。
2.4.1.19. cusolverDnXsyevjGetSweeps()
cusolverStatus_t
cusolverDnXsyevjGetSweeps(
cusolverDnHandle_t handle,
syevjInfo_t info,
int *executed_sweeps)
此函数报告syevj或sygvj已执行的扫描次数。它不支持syevjBatched。如果用户在调用syevjBatched后调用此函数,将返回错误CUSOLVER_STATUS_NOT_SUPPORTED。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指向 |
|
|
|
已执行的扫描次数。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_SUPPORTED-
不支持批量版本。
2.4.1.20. cusolverDnCreateGesvdjInfo()
cusolverStatus_t
cusolverDnCreateGesvdjInfo(
gesvdjInfo_t *info);
该函数创建并初始化gesvdj和gesvdjBatched的结构为默认值。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
返回状态
CUSOLVER_STATUS_SUCCESS-
结构初始化成功。
CUSOLVER_STATUS_ALLOC_FAILED-
资源无法分配。
2.4.1.21. cusolverDnDestroyGesvdjInfo()
cusolverStatus_t
cusolverDnDestroyGesvdjInfo(
gesvdjInfo_t info);
该函数销毁并释放该结构所需的任何内存。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
资源已成功释放。
2.4.1.22. cusolverDnXgesvdjSetTolerance()
cusolverStatus_t
cusolverDnXgesvdjSetTolerance(
gesvdjInfo_t info,
double tolerance)
此函数用于配置gesvdj的容差。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
|
|
|
数值奇异值的准确性。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
2.4.1.23. cusolverDnXgesvdjSetMaxSweeps()
cusolverStatus_t
cusolverDnXgesvdjSetMaxSweeps(
gesvdjInfo_t info,
int max_sweeps)
此函数用于配置gesvdj中的最大扫描次数。默认值为100。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
|
|
|
最大扫描次数。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
2.4.1.24. cusolverDnXgesvdjSetSortEig()
cusolverStatus_t
cusolverDnXgesvdjSetSortEig(
gesvdjInfo_t info,
int sort_svd)
如果sort_svd为零,则不对奇异值进行排序。此函数仅适用于gesvdjBatched。gesvdj始终按降序对奇异值进行排序。默认情况下,奇异值始终按降序排序。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
2.4.1.25. cusolverDnXgesvdjGetResidual()
cusolverStatus_t
cusolverDnXgesvdjGetResidual(
cusolverDnHandle_t handle,
gesvdjInfo_t info,
double *residual)
此函数报告由gesvdj返回的内部残差的Frobenius范数。请注意,这并非通过以下公式计算的精确残差的Frobenius范数:
此函数不支持gesvdjBatched。如果用户在调用gesvdjBatched后调用此函数,将返回错误CUSOLVER_STATUS_NOT_SUPPORTED。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指向 |
|
|
|
|
返回状态
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。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指向 |
|
|
|
已执行的扫描次数。 |
返回状态
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实例,但需确保前次调用已完成,因为在未完成前次调用时修改配置可能会影响其执行。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
返回状态
CUSOLVER_STATUS_SUCCESS-
结构已成功创建并初始化。
CUSOLVER_STATUS_ALLOC_FAILED-
资源无法分配。
2.4.1.28. cusolverDnIRSParamsDestroy()
cusolverStatus_t
cusolverDnIRSParamsDestroy(cusolverDnIRSParams_t params);
该函数销毁并释放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倍加速。合理的策略应同时考虑右端项数量、矩阵规模以及收敛速率等因素。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
允许的输入/输出数据类型(例如CUSOLVER_R_FP64表示双精度实数数据)。支持的精度类型请参阅下表。 |
|
|
|
允许的最低计算类型(例如CUSOLVER_R_16F用于半精度计算)。支持的精度请参阅下表。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_IRS_PARAMS_NOT_INITIALIZED-
Params结构未被创建。
输入/输出数据类型(例如主精度) |
最低精度支持的值 |
|---|---|
|
|
|
|
|
|
|
|
2.4.1.30. cusolverDnIRSParamsSetSolverMainPrecision()
cusolverStatus_t
cusolverDnIRSParamsSetSolverMainPrecision(
cusolverDnIRSParams_t params,
cusolverPrecType_t solver_main_precision);
此函数用于设置迭代精化求解器(IRS)的主精度。所谓主精度,指的是输入和输出数据的类型。需要注意的是,用户必须在首次调用IRS求解器之前同时设置主精度和最低精度,因为它们不会随params结构体的创建而默认设置,这取决于输入输出数据类型和用户需求。用户可以通过调用本函数或调用cusolverDnIRSParamsSetSolverPrecisions()来设置这两种精度(该函数会同时设置主精度和最低精度)。所有可能的主/最低精度组合方案都记录在上文cusolverDnIRSParamsSetSolverPrecisions()章节中的表格里。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
允许的输入/输出数据类型(例如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倍加速。合理的策略应综合考虑右端项数量、矩阵规模以及收敛速率等因素。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
允许的最低计算类型(例如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求解器之前设置精化算法,因为在创建参数时默认不会设置该算法。下表详细描述了可以设置的值及其含义。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
IRS求解器使用的细化求解器类型,例如 |
返回状态
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求解器的每个细节。请注意,无论输入/输出数据类型如何,容差值始终以双精度实数表示。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
设置优化容差的双精度实数值。 |
返回状态
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求解器的每个细节。请注意,无论输入/输出数据类型如何,容差值始终以双精度实数表示。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
双精度实数值,用于设置内部精化求解器的容差。 |
返回状态
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求解器的每个细节。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
允许优化求解器运行的最大总迭代次数。 |
返回状态
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)中的较小值。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
内部精化求解器允许的最大内部迭代次数。当精化求解器为双层求解器(如CUSOLVER_IRS_REFINE_CLASSICAL_GMRES或CUSOLVER_IRS_REFINE_GMRES_GMRES)时此参数有效。该值应小于或等于 |
返回状态
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允许用户禁用回退功能,而这个函数则允许用户重新启用它。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
返回状态
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重新启用该功能。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
返回状态
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值。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
当前设置的最大迭代次数。 |
返回状态
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结构体。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
返回状态
CUSOLVER_STATUS_SUCCESS-
结构初始化成功。
CUSOLVER_STATUS_ALLOC_FAILED-
资源无法分配。
2.4.1.41. cusolverDnIRSInfosDestroy()
cusolverStatus_t
cusolverDnIRSInfosDestroy(
cusolverDnIRSInfos_t infos );
该函数销毁并释放Infos结构所需的任何内存。此函数会清除求解器调用的所有信息(例如已执行的Niters次数、已执行的OuterNiters次数、残差历史记录等);因此,仅当用户完成信息使用后才应调用此函数。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
返回状态
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值。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
当前设置的最大迭代次数。 |
返回状态
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()中的描述。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
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_CLASSICAL或CUSOLVER_IRS_REFINE_GMRES)组成时,其值与Niters相同。当精化解算器由双层解算器(如CUSOLVER_IRS_REFINE_CLASSICAL_GMRES或CUSOLVER_IRS_REFINE_GMRES_GMRES)组成时,它表示外部循环的迭代次数。更多详情请参阅cusolverIRSRefinement_t的描述。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
IRS求解器外部细化循环的迭代次数。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_IRS_INFOS_NOT_INITIALIZED-
Infos结构未被创建。
2.4.1.45. cusolverDnIRSInfosRequestResidual()
cusolverStatus_t cusolverDnIRSInfosRequestResidual(
cusolverDnIRSInfos_t infos );
此函数指示IRS求解器将细化阶段的收敛历史(残差范数)存储在一个矩阵中,该矩阵可通过cusolverDnIRSInfosGetResidualHistory()函数返回的指针访问。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
返回状态
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_CLASSICAL或CUSOLVER_IRS_REFINE_GMRES,那么OuterNiters=Niters(Niters是执行的总迭代次数)并且有Niters+1行的范数对应于Niters次外部迭代。
如果精化求解器是CUSOLVER_IRS_REFINE_CLASSICAL_GMRES或CUSOLVER_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]则对应此次外部迭代的残差范数。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
返回一个指向收敛历史残差范数矩阵的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的结构,将其设置为默认值。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
返回状态
CUSOLVER_STATUS_SUCCESS-
结构初始化成功。
CUSOLVER_STATUS_ALLOC_FAILED-
资源无法分配。
2.4.1.48. cusolverDnDestroyParams()
cusolverStatus_t
cusolverDnDestroyParams(
cusolverDnParams_t params);
该函数销毁并释放该结构所需的任何内存。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
|
返回状态
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例程。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向 |
|
|
|
需要配置的例程。 |
|
|
|
需要配置的算法。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_INVALID_VALUE-
function和algo的组合错误。
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 指示使用矩阵的哪一部分。该函数不会修改其他部分。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U。
用户需要提供由输入参数Workspace指向的工作空间。输入参数Lwork表示工作空间的大小,该值由potrf_bufferSize()函数返回。
如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说L或U的某些对角线元素不是实数。输出参数devInfo将指示A中不是正定的最小前导子矩阵。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
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.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 指示使用矩阵的哪一部分。该函数将保持其他部分不变。
如果输入参数 uplo 为 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U。
用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnPotrf_bufferSize()函数返回。
如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说L或U的某些对角线元素不是实数。输出参数info将指示A中不是正定的最小前导子矩阵。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnPotrf仅支持默认算法。
|
默认算法。 |
cusolverDnPotrf_bufferSize 和 cusolverDnPotrf 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
计算的数据类型。 |
|
|
|
工作空间。类型为 |
|
|
|
|
|
|
|
如果 |
通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型。cusolverDnPotrf仅支持以下四种组合。
数据类型与计算类型的有效组合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
n<0或lda<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 是一个 \(n \times n\) 的埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数 uplo 表示使用矩阵的哪一部分。该函数将保持其他部分不变。
用户需要先调用potrf来分解矩阵A。如果输入参数uplo是CUBLAS_FILL_MODE_LOWER,则A是下三角Cholesky因子L,对应\(A = L*L^H\)。如果输入参数uplo是CUBLAS_FILL_MODE_UPPER,则A是上三角Cholesky因子U,对应\(A = U^{H}*U\)。
该操作是原地进行的,即矩阵 X 会覆盖矩阵 B,两者具有相同的前导维度 ldb。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0、nrhs<0、lda或ldb)。 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 是一个 \(n \times n\) 埃尔米特矩阵,使用通用API接口时仅需提供下三角或上三角部分。输入参数 uplo 用于指定使用矩阵的哪一部分。函数将保持另一部分不变。
用户需要先调用cusolverDnPotrf来分解矩阵A。如果输入参数uplo是CUBLAS_FILL_MODE_LOWER,则A是对应\(A = L*L^H\)的下三角Cholesky因子L。如果输入参数uplo是CUBLAS_FILL_MODE_UPPER,则A是对应\(A = U^{H}*U\)的上三角Cholesky因子U。
该操作是原地进行的,即矩阵 X 会覆盖具有相同主维度 ldb 的矩阵 B。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnPotrs仅支持默认算法。
|
默认算法。 |
cusolverDnPotrs的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
如果 |
通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeB表示矩阵B的数据类型。cusolverDnPotrs仅支持以下四种组合。
数据类型与计算类型的有效组合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0、nrhs<0、lda或ldb)。 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的逆矩阵
由potrf()计算得出。
A 是一个 \(n \times n\) 矩阵,包含由 Cholesky 分解计算得到的三角因子 L 或 U。仅下三角或上三角部分有意义,输入参数 uplo 指示矩阵的哪一部分被使用。该函数将保持另一部分不变。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并将其替换为 A 逆矩阵的下三角部分。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并将其替换为 A 逆矩阵的上三角部分。
用户需要提供由输入参数Workspace指向的工作空间。输入参数Lwork表示工作空间的大小,由potri_bufferSize()返回。
如果逆矩阵计算失败,即L或U的某个前导子矩阵为空,输出参数devInfo将指示L或U中不是正定的最小前导子矩阵。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
n<0或lda<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分解
其中 A 是一个 \(m \times n\) 矩阵,P 是置换矩阵,L 是单位下三角矩阵,U 是上三角矩阵。
用户需要提供由输入参数Workspace指向的工作空间。输入参数Lwork表示工作空间的大小,该值由getrf_bufferSize()函数返回。
如果LU分解失败,即矩阵A(U)是奇异矩阵,输出参数devInfo=i表示U(i,i) = 0。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
如果 devIpiv 为空,则不执行主元选择。因式分解形式为 A=L*U,这种形式在数值上不稳定。
无论LU分解是否成功,输出参数devIpiv都包含主元置换序列,第i行将与第devIpiv(i)行进行交换。
用户可以结合getrf和getrs来完成线性求解器。
备注:getrf 使用具有大型工作空间(大小为 m*n)的最快实现。用户可以通过 Getrf 和 cusolverDnSetAdvOptions(params, CUSOLVERDN_GETRF, CUSOLVER_ALG_1) 选择具有最小工作空间的传统实现。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
工作空间,大小为 |
|
|
|
大小至少为 |
|
|
|
如果 |
返回状态
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.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分解
其中 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()函数返回。
用户可以结合cusolverDnGetrf和cusolverDnGetrs来完成线性求解器。
目前,cusolverDnGetrf支持两种算法。要选择旧版实现,用户需要调用cusolverDnSetAdvOptions。
|
默认算法。速度最快,需要一个包含 |
|
旧版实现 |
cusolverDnGetrf_bufferSize 和 cusolverDnGetrf 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
大小至少为 |
|
|
|
计算的数据类型。 |
|
|
|
工作空间。类型为 |
|
|
|
|
|
|
|
如果 |
通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型。cusolverDnGetrf仅支持以下四种组合。
数据类型与计算类型的有效组合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
m,n<0或lda<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 );
该函数用于求解具有多个右侧项的线性方程组
其中 A 是一个 \(n \times n\) 矩阵,并且已通过 getrf 进行LU分解,即A的下三角部分是 L,而 A 的上三角部分(包括对角元素)是 U。B 是一个 \(n\times {nrhs}\) 的右侧矩阵。
输入参数 trans 的定义如下

输入参数 devIpiv 是 getrf 的输出结果。它包含主元索引,用于置换右侧项。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
用户可以结合getrf和getrs来完成线性求解器。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
操作 |
|
|
|
矩阵 |
|
|
|
右侧的数量。 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
大小至少为 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0或lda或ldb)。 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 )
该函数用于求解具有多个右端项的线性方程组
其中A是一个\(n \times n\)矩阵,并且已经通过cusolverDnGetrf进行了LU分解,即A的下三角部分是L,而A的上三角部分(包括对角元素)是U。B是一个n×nrhs :math:` times nrhs`的右侧矩阵,使用通用API接口。
输入参数 trans 的定义如下

输入参数 ipiv 是 cusolverDnGetrf 的输出结果。它包含用于置换右侧项的枢轴索引。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
用户可以结合cusolverDnGetrf和cusolverDnGetrs来完成线性求解器。
目前,cusolverDnGetrs仅支持默认算法。
cusolverDnGetrs 支持的算法
|
默认算法。 |
cusolverDnGetrs的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
操作 |
|
|
|
矩阵 |
|
|
|
右侧的数量。 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
大小至少为 |
|
|
|
数组 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
如果 |
通用API有两种不同类型,dataTypeA是矩阵A的数据类型,dataTypeB是矩阵B的数据类型。cusolverDnGetrs仅支持以下四种组合。
数据类型与计算类型的有效组合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0或lda或ldb)。 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 是 n-by-n 矩阵,X 和 B 是 n-by-nrhs 矩阵。
函数API的设计尽可能接近LAPACK API,以便作为快速简便的直接替代方案。参数和行为大多与LAPACK对应函数相同。以下描述这些函数及其与LAPACK的区别。函数由两种浮点精度指定,其中cusolver首先尝试以较低精度对矩阵进行因式分解,并在迭代细化过程中使用此因式分解,以获得与主精度
迭代优化过程在以下情况下停止
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参数存在错误或函数未成功完成。更多错误详情可通过niters和dinfoAPI参数获取。具体说明请参阅下文描述。用户需提供预先在设备内存中分配的所需工作空间,可通过调用相应的函数查询所需字节数。
请注意,除了LAPACK中提供的两种混合精度函数(例如dsgesv和zcgesv),我们还提供了一组广泛的混合精度函数,其中包括半精度(half)、bfloat和tensorfloat作为较低精度,以及相同精度函数(主精度和最低精度相等,即
张量浮点(TF32)是NVIDIA安培架构GPU引入的运算模式,它是迭代精化求解器中最强大的张量核心加速计算模式。该模式能够解决高性能计算(HPC)中由不同应用产生的最广泛问题,并为实数和复数系统分别提供高达4倍和5倍的加速效果。对于Volta和图灵架构GPU,建议采用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,输入输出数据精度)时,建议将主精度作为内部最低精度使用(例如FP64情况下使用cusolverDn[DD,ZZ]gesv)。
接口函数 |
主要精度 (矩阵、右侧项和解的数据类型) |
允许的最低内部使用精度 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* 具有LAPACK对应功能
cusolverDn 函数将返回对应 cusolverDn 函数所需的工作缓冲区大小(以字节为单位)。
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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDN库上下文的句柄。 |
|
|
|
方阵 |
|
|
|
需要求解的右侧项数量。应为非负数。 |
|
|
|
矩阵 |
|
|
|
用于存储矩阵 |
|
|
|
枢轴序列。未使用,可以为 |
|
|
|
右侧项集合 |
|
|
|
用于存储右侧矩阵的二维数组的主维度 |
|
|
|
大小为 |
|
|
|
用于存储解向量矩阵的二维数组的主维度 |
|
|
|
指向设备工作区的指针。未使用,可以为 |
|
|
|
指向一个变量的指针,该变量将存储临时工作空间所需的字节大小。不能为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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDN库上下文的句柄。 |
|
|
|
方阵 |
|
|
|
需要求解的右侧项数量。应为非负数。 |
|
|
|
矩阵 |
|
|
|
用于存储矩阵 |
|
|
|
定义因式分解置换的向量 - 行 |
|
|
|
右侧项集合 |
|
|
|
用于存储右侧矩阵的二维数组的主维度 |
|
|
|
大小为 |
|
|
|
用于存储解向量矩阵的二维数组的主维度 |
|
|
|
指向设备内存中已分配工作空间的指针,大小为 |
|
|
|
分配的设备工作空间大小。至少应为 |
|
|
|
如果
|
|
|
|
IRS求解器在返回时的状态。如果为0 - 求解成功。如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数,例如:
n<0ldaldbldx
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-
发生内部错误,请检查
dinfo和niters参数以获取更多详细信息。
2.4.2.11. cusolverDnIRSXgesv()
该函数旨在实现与cusolverDn相同的功能,但封装在一个更通用和专业的接口中,使用户能够更好地控制参数设置,并提供更详细的输出信息。cusolverDnIRSXgesv()允许对求解器参数进行额外控制,例如设置:
求解器的主要精度(输入/输出精度)
求解器内部使用的最低精度
优化求解器类型
精炼阶段允许的最大迭代次数
优化求解器的容差
回退到主精度
以及更多
通过配置参数结构体gesv_irs_params及其辅助函数。关于可设置配置项及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSParamsxxxx()开头的函数。此外,cusolverDnIRSXgesv()还提供了诸如每次迭代的收敛历史(例如残差范数)和收敛所需迭代次数等额外输出信息。关于可获取信息及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSInfosxxxx()开头的函数。
该函数返回值描述了求解过程的结果。CUSOLVER_STATUS_SUCCESS表示函数成功完成,否则表示API参数有误、params/infos结构配置不正确或函数未成功完成。通过检查niters和dinfoAPI参数可获取更多错误详情(详见下文描述)。用户需为cusolverDnIRSXgesv()函数提供设备上分配的所需工作空间,可通过调用对应的cusolverDnIRSXgesv_bufferSize()函数查询所需字节数。请注意,若用户希望通过params结构设置特定配置,应在调用cusolverDnIRSXgesv_bufferSize()获取所需工作空间大小之前完成设置。
张量浮点(TF32)是NVIDIA安培架构GPU引入的,它是迭代精化求解器中最强大的张量核心加速计算模式。该技术能够解决高性能计算(HPC)中来自不同应用的最广泛问题,对实数和复数系统分别提供高达4倍和5倍的加速。对于Volta和图灵架构GPU,建议使用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,输入输出数据精度)时,建议使用主精度作为内部最低精度。
下表提供了输入/输出数据类型对应的最低精度所有可能组合值。请注意,如果最低精度与输入/输出数据类型匹配,则将使用主精度分解。
输入/输出数据类型(例如主精度) |
最低精度支持的值 |
|---|---|
|
|
|
|
|
|
|
|
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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDn库上下文的句柄。 |
|
|
|
|
|
|
|
方阵 |
|
|
|
需要求解的右侧向量数量。应为非负数。请注意,如果选择的IRS细化求解器为CUSOLVER_IRS_REFINE_GMRES、CUSOLVER_IRS_REFINE_GMRES_GMRES或CUSOLVER_IRS_REFINE_CLASSICAL_GMRES时, |
|
|
|
指向一个变量的指针,在调用 |
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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDn库上下文的句柄。 |
|
|
|
配置参数结构体,可用于对任何IRS求解器的一次或多次调用 |
|
|
|
信息结构,用于存储特定求解的相关信息。 |
|
|
|
方阵 |
|
|
|
需要求解的右端项数量。应为非负数。请注意,如果选择的IRS细化求解器为CUSOLVER_IRS_REFINE_GMRES、CUSOLVER_IRS_REFINE_GMRES_GMRES或CUSOLVER_IRS_REFINE_CLASSICAL_GMRES,则nrhs限制为1。 |
|
|
|
矩阵 |
|
|
|
用于存储矩阵 |
|
|
|
右侧项集合 |
|
|
|
用于存储右侧矩阵的二维数组的主维度 |
|
|
|
大小为 |
|
|
|
用于存储解向量矩阵的二维数组的主维度 |
|
|
|
指向设备内存中已分配工作空间的指针,大小为lwork_bytes。 |
|
|
|
分配的设备工作空间大小。应至少为 |
|
|
|
如果迭代是
|
|
|
|
IRS求解器在返回时的状态。如果为0 - 求解成功。如果dinfo = - |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数,例如:
n<0ldaldbldx
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-
发生内部错误,请检查
dinfo和niters参数以获取更多详细信息。 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 是一个 \(m \times n\) 矩阵,Q 是一个 \(m \times n\) 矩阵,而 R 是一个 \(n \times n\) 上三角矩阵。
用户需要提供一个工作空间,该空间由输入参数Workspace指定。输入参数Lwork表示工作空间的大小,该值由geqrf_bufferSize()函数返回。
矩阵 R 会被覆盖写入 A 的上三角部分,包括对角线元素。
矩阵 Q 不会显式生成,而是将一系列豪斯霍尔德向量存储在 A 的下三角部分。假设豪斯霍尔德向量的前导非零元素为1,因此输出参数 TAU 包含缩放因子 τ。如果 v 是原始豪斯霍尔德向量,q 是对应于 τ 的新豪斯霍尔德向量,满足以下关系
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
工作空间,大小为 |
|
|
|
工作数组 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
m,n<0或lda<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 是一个 \(m \times n\) 矩阵,Q 是一个 \(m \times n\) 矩阵,而 R 是一个 \(n \times n\) 上三角矩阵,使用的是通用API接口。
用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnGeqrf_bufferSize()返回。
矩阵 R 会被覆盖写入 A 的上三角部分,包括对角线元素。
矩阵 Q 不会显式生成,而是将一系列豪斯霍尔德向量存储在 A 的下三角部分。假设豪斯霍尔德向量的首非零元素为1,因此输出参数 TAU 包含缩放因子 τ。如果 v 是原始豪斯霍尔德向量,q 是对应于 τ 的新豪斯霍尔德向量,满足以下关系:
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnGeqrf仅支持默认算法。
cusolverDnGeqrf 支持的算法
|
默认算法。 |
cusolverDnGeqrf_bufferSize 和 cusolverDnGeqrf 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
维度至少为 |
|
|
|
计算的数据类型。 |
|
|
|
工作空间。类型为 |
|
|
|
工作数组 |
|
|
|
如果 |
通用API有两种不同类型,dataTypeA表示矩阵A和数组tau的数据类型,而computeType表示运算的计算类型。cusolverDnGeqrf仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
计算类型 |
含义 |
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
m,n<0或lda<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 是 m-by-n 矩阵,X 是 n-by-nrhs 矩阵,B 是 m-by-nrhs 矩阵。
函数API的设计尽可能接近LAPACK API,以便作为快速简便的直接替代方案。以下是对这些函数的描述。函数由两种浮点精度指定,对应主精度(例如输入/输出数据类型精度),表示进行因子分解的内部较低精度。cusolver首先尝试以较低精度对矩阵进行因子分解,并在迭代细化过程中使用此因子分解,以获得与主精度具有相同范数后向误差的解。如果该方法未能收敛,则回退到主精度因子分解和求解(Xgels),从而确保这些函数的输出始终有良好的解。如果等于,则这不是混合精度过程,而是在同一主精度下的完整单精度因子分解、求解和细化。
迭代优化过程在以下情况下停止:
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参数存在错误或函数未能成功完成。更多错误详情可通过niters和dinfo这两个API参数获取,具体说明请参阅下文描述。用户需要提供预先在设备内存中分配的所需工作空间,可通过调用相应的函数查询所需字节数。
我们提供了大量混合精度函数,其中包含半精度(half)、bfloat和tensorfloat作为较低精度,以及相同精度函数(例如主精度和最低精度相等时,等于)。下表指定了各接口函数将使用的精度:
张量浮点(TF32)是NVIDIA安培架构GPU引入的运算模式,它是迭代精化求解器中最强大的张量核心加速计算模式。该模式能够解决高性能计算(HPC)中由不同应用产生的最广泛问题,对实数和复数系统分别提供高达4倍和5倍的加速效果。对于Volta和图灵架构GPU,建议采用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,即输入输出数据精度)时,建议将主精度作为内部最低精度使用(例如FP64情况下使用cusolverDn[DD,ZZ]gels)。
接口函数 |
主要精度(矩阵、右侧项和解的数据类型) |
内部允许使用的最低精度 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cusolverDn 函数将返回对应 cusolverDn 函数所需的以字节为单位的工作缓冲区大小。
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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDN库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
需要求解的右侧项数量。应为非负数。 |
|
|
|
矩阵 |
|
|
|
用于存储矩阵 |
|
|
|
右侧项集合 |
|
|
|
用于存储右侧矩阵的二维数组的主维度 |
|
|
|
大小为 |
|
|
|
用于存储解向量矩阵的二维数组的主维度 |
|
|
|
指向设备工作区的指针。未使用,可以为 |
|
|
|
指向一个变量的指针,该变量将存储临时工作空间所需的字节大小。不能为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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDN库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
需要求解的右侧项数量。应为非负数。 |
|
|
|
矩阵 |
|
|
|
用于存储矩阵 |
|
|
|
右侧矩阵集合 |
|
|
|
用于存储右侧矩阵的二维数组的主维度 |
|
|
|
大小为 |
|
|
|
用于存储解向量矩阵的二维数组的主维度 |
|
|
|
指向设备内存中已分配工作空间的指针,大小为lwork_bytes。 |
|
|
|
分配的设备工作空间大小。应至少为 |
|
|
|
如果迭代是
|
|
|
|
IRS求解器在返回时的状态。如果为0 - 求解成功。如果dinfo = - |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数,例如:
n<0ldda小于max(1,m)lddblddx
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-
发生内部错误;请检查
dinfo和niters参数以获取更多详细信息。
2.4.2.15. cusolverDnIRSXgels()
此函数旨在实现与cusolverDn相同的功能,但封装在一个更通用和专业的接口中,使用户能够更好地控制参数设置,并提供更详细的输出信息。cusolverDnIRSXgels()允许对求解器参数进行额外控制,例如设置:
求解器的主要精度(输入/输出精度),
求解器内部使用的最低精度,
优化求解器类型
精炼阶段允许的最大迭代次数
优化求解器的容差
回退到主精度
以及其他
通过配置参数结构体gels_irs_params及其辅助函数。关于可设置配置项及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSParamsxxxx()开头的函数。此外,cusolverDnIRSXgels()还提供了额外的输出信息,例如每次迭代的收敛历史(如残差范数)和收敛所需的迭代次数。关于可获取信息及其含义的详细信息,请参阅cuSolverDN辅助函数章节中所有以cusolverDnIRSInfosxxxx()开头的函数。
该函数返回值描述了求解过程的结果。CUSOLVER_STATUS_SUCCESS表示函数成功完成,否则表示API参数不正确、params/infos结构配置错误或函数未成功完成。通过检查niters和dinfoAPI参数可以获取更多错误详情。具体描述请参阅下文。用户需要为cusolverDnIRSXgels()函数提供设备上分配的所需工作空间。可通过调用相应的cusolverDnIRSXgels_bufferSize()函数查询所需字节数。请注意,如果用户希望通过params结构设置特定配置,应在调用cusolverDnIRSXgels_bufferSize()获取所需工作空间大小之前进行设置。
下表提供了输入/输出数据类型对应的最低精度所有可能的组合值。请注意,如果最低精度与输入/输出数据类型匹配,则将使用主精度分解方法。
张量浮点(TF32)是NVIDIA安培架构GPU引入的运算模式,它是迭代精化求解器中最强大的张量核心加速计算模式。它能够解决高性能计算(HPC)中由不同应用产生的最广泛问题,并为实数和复数系统分别提供高达4倍和5倍的加速。对于Volta和图灵架构GPU,建议使用半精度张量核心加速。当迭代精化求解器无法收敛到所需精度(主精度,输入输出数据精度)时,建议使用主精度作为内部最低精度。
输入/输出数据类型(例如主精度) |
最低精度支持的值 |
|---|---|
|
|
|
|
|
|
|
|
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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDn库上下文的句柄。 |
|
|
|
Xgels配置参数 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
需要求解的右端项数量。应为非负值。注意,如果选择的IRS精化求解器是 |
|
|
|
指向一个变量的指针,在调用 |
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);
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向cusolverDn库上下文的句柄。 |
|
|
|
配置参数结构体,可用于对任何IRS求解器的一次或多次调用 |
|
|
|
信息结构,用于存储特定求解的相关信息。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
需要求解的右端项数量。应为非负数。请注意,如果选择的IRS细化求解器为CUSOLVER_IRS_REFINE_GMRES、CUSOLVER_IRS_REFINE_GMRES_GMRES或CUSOLVER_IRS_REFINE_CLASSICAL_GMRES,则nrhs限制为1。 |
|
|
|
矩阵 |
|
|
|
用于存储矩阵 |
|
|
|
右侧矩阵集合 |
|
|
|
用于存储右侧矩阵的二维数组的主维度 |
|
|
|
大小为 |
|
|
|
用于存储解向量矩阵的二维数组的主维度 |
|
|
|
指向设备内存中已分配工作空间的指针,大小为lwork_bytes。 |
|
|
|
分配的设备工作空间大小。应至少为 |
|
|
|
如果
|
|
|
|
IRS求解器在返回时的状态。如果为0 - 求解成功。如果dinfo = - |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数,例如:
n<0lddalddblddx
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-
发生内部错误,请检查
dinfo和niters参数以获取更多详细信息。 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的内容

Q 的操作由以下定义

Q 是由 A 的 QR 分解 (geqrf) 产生的一系列基本反射向量所构成的酉矩阵。
Q=H(1)H(2) … H(k)
Q的阶数为m当side = CUBLAS_SIDE_LEFT,阶数为n当side = CUBLAS_SIDE_RIGHT。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由geqrf_bufferSize()或ormqr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
用户可以通过组合geqrf、ormqr和trsm来完成线性求解器或最小二乘求解器。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDn库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
操作 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
定义矩阵Q的基本反射的数量。 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
|
|
|
|
矩阵 |
|
|
|
工作空间,大小为 |
|
|
|
工作数组 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或错误的lda或ldc)。 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是一个由存储在A中的一系列基本反射向量构成的酉矩阵。
用户需要提供一个工作空间,该空间由输入参数work指定。输入参数lwork表示工作空间的大小,该值由orgqr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
用户可以结合geqrf、orgqr来完成正交化。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
定义矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
工作空间,大小为 |
|
|
|
工作数组 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n,k<0,n>m,k>n或lda)。 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 决定使用矩阵的哪一部分。该函数会保持其他部分不变。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角因子 L 和块对角矩阵 D。D 的每个块可能是1x1或2x2块,具体取决于旋转操作。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角因子 U 和块对角矩阵 D。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由sytrf_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果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行/列 交换。如果 uplo 为 CUBLAS_FILL_MODE_UPPER 且 devIpiv(i-1) = devIpiv(i) = -m < 0,则 D(i-1:i,i-1:i) 是2x2块,且 第(i-1)行/列 与 第m行/列 交换。如果 uplo 为 CUBLAS_FILL_MODE_LOWER 且 devIpiv(i+1) = devIpiv(i) = -m < 0,则 D(i:i+1,i:i+1) 是2x2块,且 第(i+1)行/列 与 第m行/列 交换。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
大小至少为 |
|
|
|
工作空间,大小为 |
|
|
|
工作空间 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
n<0或lda<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指示使用矩阵的哪一部分。
如果输入参数 uplo 为 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U。
如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说L或U的某些对角线元素不是实数。输出参数infoArray将指示A中不是正定的最小前导子矩阵。
infoArray 是一个大小为 batchsize 的整数数组。如果 potrfBatched 返回 CUSOLVER_STATUS_INVALID_VALUE,则 infoArray[0] = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 potrfBatched 返回 CUSOLVER_STATUS_SUCCESS 但 infoArray[i] = k 为正数,则表示第 i 个矩阵不是正定矩阵,且 Cholesky 分解在第 k 行失败。
备注:A的另一部分用作工作区。例如,如果uplo为CUBLAS_FILL_MODE_UPPER,则A的上三角部分包含Cholesky因子U,而下三角部分在potrfBatched执行后会被破坏。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示存储的是下三角部分还是上三角部分;另一部分用作工作区。 |
|
|
|
矩阵 |
|
|
|
指向维度为 |
|
|
|
用于存储每个矩阵 |
|
|
|
大小为 |
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0或lda或batchSize<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);
该函数用于求解一系列线性方程组
其中每个Aarray[i] for i=0,1,..., batchSize-1都是一个\(n \times n\)埃尔米特矩阵,仅下三角或上三角部分有意义。输入参数uplo用于指定使用矩阵的哪一部分。
用户需要先调用potrfBatched来分解矩阵Aarray[i]。如果输入参数uplo为CUBLAS_FILL_MODE_LOWER,则A是对应\(A = L*L^{H}\)的下三角Cholesky因子L。如果输入参数uplo为CUBLAS_FILL_MODE_UPPER,则A是对应\(A = U^{H}*U\)的上三角Cholesky因子U。
该操作是原地进行的,即矩阵 X 会覆盖矩阵 B,两者具有相同的前导维度 ldb。
输出参数 info 是一个标量。如果 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄)。
备注1:仅支持 nrhs=1。
备注2:来自potrfBatched的infoArray表示矩阵是否为正定矩阵。来自potrsBatched的info仅显示哪个输入参数有误(不包含handle)。
备注3:A的另一部分被用作工作区。例如,如果uplo为CUBLAS_FILL_MODE_UPPER,则A的上三角部分包含Cholesky因子U,而下三角部分在potrsBatched执行后会被破坏。
请访问cuSOLVER库示例 - potrfBatched查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
指向维度为 |
|
|
|
用于存储每个矩阵 |
|
|
|
指向维度为 |
|
|
|
用于存储每个矩阵 |
|
|
|
如果 |
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,nrhs<0,lda,ldb或batchSize<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>=n,B 是上双对角矩阵;如果 m,B 是下双对角矩阵。
矩阵 Q 和 P 会以下列方式覆盖写入矩阵 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。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
维度为 |
|
|
|
维度为 |
|
|
|
|
|
|
|
|
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
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约化为双对角形式时确定的酉矩阵Q或P**H之一:\(Q^{H}*A*P = B\)
Q 和 P**H 分别定义为基本反射器 H(i) 或 G(i) 的乘积。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由orgbr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
如果 |
|
|
|
矩阵 |
|
|
|
如果 |
|
|
|
如果 |
|
|
|
<类型> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
工作空间,大小为 |
|
|
|
工作数组 |
|
|
|
如果 |
返回状态
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(。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
维度为 |
|
|
|
维度为 |
|
|
|
|
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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的内容

其中Q是由sytrd生成的一系列基本反射向量构成的正交矩阵。
对 Q 的操作定义为

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由ormtr_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
|
|
|
|
|
|
|
|
操作 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
|
|
|
|
矩阵 |
|
|
|
工作空间,大小为 |
|
|
|
工作数组 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或错误的lda或ldc)。 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(。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
|
|
|
|
矩阵 |
|
|
|
<类型> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
工作空间,大小为 |
|
|
|
工作数组 |
|
|
|
如果 |
返回状态
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分解公式表示为
其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外全为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负的,并按降序排列。U 和 V 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由gesvd_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 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。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定计算矩阵 |
|
|
|
指定计算矩阵V**T全部或部分内容的选项:= 'A':在数组VT中返回V**T的所有N行;= 'S':在数组VT中返回V**T的前min(m,n)行(右奇异向量);= 'O':将V**T的前min(m,n)行(右奇异向量)覆盖写入数组A;= 'N':不计算V**T的任何行(不计算右奇异向量)。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
维度为 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
维度为min(m,n)-1的实数数组。如果 |
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或lda或ldu或ldvt)。 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分解公式表示为
其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负,并按降序排列。U 和 V 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。
用户需要提供一个工作空间,由输入参数pBuffer指向。输入参数workspaceInBytes表示工作空间的字节大小,该值由cusolverDnGesvd_bufferSize()函数返回。
如果输出参数 info = -i(小于零),表示第 i-th 个参数有误(不包含句柄)。如果 bdsqr 未收敛,info 会指明中间双对角形式中有多少条超对角线未能收敛到零。
目前,cusolverDnGesvd仅支持默认算法。
cusolverDnGesvd 支持的算法
|
默认算法。 |
备注1: gesvd 仅支持 m>=n。
备注2:该例程返回\(V^{H}\),而非V。
cusolverDnGesvd_bufferSize 和 cusolverDnGesvd 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算矩阵 |
|
|
|
指定计算矩阵V**T全部或部分内容的选项:= 'A':在数组VT中返回V**T的所有N行;= 'S':在数组VT中返回V**T的前min(m,n)行(右奇异向量);= 'O':将V**T的前min(m,n)行(右奇异向量)覆盖写入数组A;= 'N':不计算V**T的任何行(不计算右奇异向量)。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
计算的数据类型。 |
|
|
|
工作空间。类型为 |
|
|
|
|
|
|
|
如果 |
通用API包含三种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeVT表示矩阵VT的数据类型,computeType表示运算的计算类型。cusolverDnGesvd仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
数据类型S |
数据类型U |
数据类型VT |
计算类型 |
含义 |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或lda<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分解公式表示为:
其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负的,并按降序排列。U 和 V 的前 min(m,n) 列分别是 A 的左右奇异向量。
gesvdj 的功能与 gesvd 相同。区别在于 gesvd 使用 QR 算法,而 gesvdj 使用 Jacobi 方法。Jacobi 方法的并行性使 GPU 在中小型矩阵上具有更好的性能。此外,用户可以配置 gesvdj 以执行达到特定精度的近似计算。
gesvdj 通过迭代生成一系列酉矩阵,将矩阵 A 转换为以下形式
其中 S 是对角矩阵,而 E 的对角线元素为零。
在迭代过程中,E的Frobenius范数单调递减。当E趋近于零时,S即为奇异值集合。实际应用中,当满足以下条件时Jacobi方法停止:
其中eps为给定的容差。请注意,如果实际残差范数
计算时,它与\({\|{E}\|}_{F}\)的差异将达到\(N = max(m, n)\)量级的舍入误差,但仍符合标准SVD精度预期
\(O(N)\) 通常为 \(N\),但常数取决于扫描次数,这给出了 \(sweeps * N\) 的上界舍入误差。
gesvdj 有两个控制精度的参数。第一个参数是容差(eps),默认值为机器精度,但用户可以通过函数 cusolverDnXgesvdjSetTolerance 预先设置容差值。第二个参数是最大扫描次数,用于控制Jacobi方法的迭代次数,默认值为100,但用户可以使用函数 cusolverDnXgesvdjSetMaxSweeps 设置合适的上限。实验表明,15次扫描通常足以收敛到机器精度。gesvdj 会在达到容差要求或最大扫描次数时停止计算。
雅可比方法具有二次收敛性,因此精度与扫描次数不成正比。为保证特定精度,用户应仅配置容差参数。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由gesvdj_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 info = -i(小于零),表示第 i-th 个参数有误(不包含句柄)。如果 info = min(m,n)+1,说明 gesvdj 在给定的容差和最大扫描次数下未能收敛。
如果用户设置了不恰当的容差,gesvdj可能无法收敛。例如,容差值不应小于机器精度。
请访问cuSOLVER库示例 - gesvdj查看代码示例。
备注1: gesvdj 支持 m 和 n 的任意组合。
备注2:该例程返回V,而非\(V^{H}\)。这与gesvd的行为不同。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定计算选项:仅计算奇异值或同时计算奇异向量: |
|
|
|
|
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
维度为 |
|
|
|
如果 |
|
|
|
用于存储矩阵 |
|
|
|
如果 |
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
|
|
|
|
如果 |
|
|
|
填充了Jacobi算法参数和 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或lda或ldu或ldv或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_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\)矩阵的奇异值和奇异向量
其中\(\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),并且采用连续存储方式排列。
每个矩阵都是列优先存储,其前导维度为lda,因此随机访问的公式为\(A_{k}\operatorname{(i,j)} = {A\lbrack\ i\ +\ lda*j\ +\ lda*n*k\rbrack}\)。
参数 S 还以连续方式包含每个矩阵的奇异值,
S的随机访问公式为\(S_{k}\operatorname{(j)} = {S\lbrack\ j\ +\ min(m,n)*k\rbrack}\)。
除了容差和最大扫描次数外,gesvdjBatched既可以通过cusolverDnXgesvdjSetSortEig函数将奇异值按降序排列(默认),也可以选择保持原样(不排序)。如果用户将多个微小矩阵打包成一个矩阵的对角块,不排序选项可以将这些微小矩阵的奇异值分开。
gesvdjBatched 无法通过函数 cusolverDnXgesvdjGetResidual 和 cusolverDnXgesvdjGetSweeps 报告残差和执行扫描次数。调用上述两个函数将返回 CUSOLVER_STATUS_NOT_SUPPORTED。用户需要显式计算残差。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由gesvdjBatched_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
输出参数 info 是一个大小为 batchSize 的整数数组。如果函数返回 CUSOLVER_STATUS_INVALID_VALUE,第一个元素 info[0] = -i(小于零)表示第 i 个参数有误(不包含句柄)。否则,如果 info[i] = min(m,n)+1,表示 gesvdjBatched 在给定的容差和最大扫描次数下未能收敛于第 i 个矩阵。
请访问cuSOLVER库示例 - gesvdjBatched查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定选项以仅计算奇异值或同时计算奇异向量: |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<类型> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
维度为 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
|
|
|
|
|
|
|
|
一个维度为 |
|
|
|
填充了Jacobi算法参数的结构体。 |
|
|
|
矩阵数量。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或lda或ldu或ldv或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_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);
此函数gesvda(a代表近似)用于近似计算高瘦矩阵\(m \times n\) A的奇异值分解及其对应的左右奇异向量。SVD的经济形式表示为
其中 Σ 是一个 \(n \times n\) 矩阵。U 是一个 \(m \times n\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负的,并按降序排列。U 和 V 分别是 A 的左奇异向量和右奇异向量。
gesvda 计算 A**T*A 或 A**H*A(若 A 为复数矩阵)的特征值,用于近似奇异值和奇异向量。它会生成矩阵 U 和 V,并将矩阵 A 转换为以下形式
其中S是对角矩阵,E取决于舍入误差。在特定条件下,U、V和S可以近似到单精度机器零点的奇异值和奇异向量。通常,V是酉矩阵,S比U更精确。如果奇异值远离零,则左奇异向量U是精确的。换句话说,奇异值和左奇异向量的精度取决于奇异值与零的距离。由于计算A**T*A或A**H*A会显著放大误差,建议仅在数据条件良好时使用gesvda。
输入参数 rank 决定了在参数 S、U 和 V 中计算的奇异值和奇异向量的数量。
输出参数 h_RnrmF 计算残差的Frobenius范数。要计算 h_RnrmF,需要满足 info != NULL 的条件。
如果参数 rank 等于 n。否则,h_RnrmF 将报告
在Frobenius范数意义上,即衡量U距离酉矩阵有多远。
gesvdaStridedBatched 对每个矩阵执行 gesvda 操作。要求所有矩阵必须具有相同的尺寸 m,n 并且以连续方式打包存储。
每个矩阵都是列优先存储,主维度为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(。
输出参数 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_RnrmF,h_RnrmF 会报告残差,如同将 rank 设为 info[i]-1。
请访问cuSOLVER库示例 - gesvdaStridedBatched查看代码示例。
备注1:该例程返回V,而非\(V^{H}\)。这与gesvd的行为不同。
备注2:该例程仅支持 m >=n。
备注3:建议使用FP64数据类型,即DgesvdaStridedBatched或ZgesvdaStridedBatched。
备注4:如果用户对奇异值和奇异向量的准确性有信心,例如满足某些条件(所需奇异值远离零),则可以通过向h_RnrmF传递空指针来提高性能,即不计算残差范数。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定选项以仅计算奇异值或同时计算奇异向量: |
|
|
|
奇异值的数量(从大到小排列)。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
类型为long long int的值,表示 |
|
|
|
一个维度为 |
|
|
|
类型为long long int的值,表示 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
类型为long long int的值,表示 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
类型为long long int的值,表示 |
|
|
|
|
|
|
|
|
|
|
|
一个维度为 |
|
|
|
大小为 |
|
|
|
矩阵数量。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或lda或ldu或ldv或strideA或strideS或strideU或strideV或batchSize<1或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_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的特征值和特征向量。标准对称特征值问题为
其中 Λ 是一个实数的 \(n \times n\) 对角矩阵。V 是一个 \(n \times n\) 酉矩阵。Λ 的对角线元素是 A 按升序排列的特征值。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由syevd_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 devInfo = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 devInfo = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。
如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。
请访问cuSOLVER库示例 - syevd查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
一个维度为 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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的特征值和特征向量。标准对称特征值问题为
其中 Λ 是一个实数的 \(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 支持的算法
|
默认算法。 |
cusolverDnSyevd_bufferSize 和 cusolverDnSyevd 的输入参数列表:
|
|
|
|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
一个维度为 |
|
|
|
计算的数据类型。 |
|
|
|
工作空间。类型为 |
|
|
|
|
|
|
|
如果 |
通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,而computeType表示运算的计算类型。cusolverDnSyevd仅支持以下四种组合。
数据类型与计算类型的有效组合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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的全部或部分特征值,并可选择计算其特征向量。标准对称特征值问题为:
其中 Λ 是一个实数的 n×h_meig 对角矩阵。V 是一个 n×h_meig 的酉矩阵。h_meig 是该例程计算得到的特征值/特征向量的数量,当请求整个谱时(例如 range = CUSOLVER_EIG_RANGE_ALL),h_meig 等于 n。Λ 的对角元素是 A 的特征值,按升序排列。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由syevdx_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 devInfo = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 devInfo = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。
如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。
请访问cuSOLVER库示例 - syevdx查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定需要计算的特征值及可选特征向量的选择选项: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
实数值浮点数或双精度数分别对应(C, S)或(Z, D)精度。如果 |
|
|
|
整数。如果 |
|
|
|
整数。找到的特征值总数。0 <= |
|
|
|
一个维度为 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或range不是CUSOLVER_EIG_RANGE_ALL或CUSOLVER_EIG_RANGE_V或CUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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的全部或部分特征值,并可选择计算特征向量。标准对称特征值问题为
其中Λ是一个实数的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 支持的算法
|
默认算法。 |
cusolverDnSyevdx_bufferSize 和 cusolverDnSyevdx 的输入参数列表:
|
|
|
|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定需要计算的特征值及可选特征向量的选择选项: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
如果 |
|
|
|
整数。如果 |
|
|
|
整数。找到的特征值总数。0 <= h_meig <= n。如果 |
|
|
|
数组 |
|
|
|
一个维度为 |
|
|
|
计算的数据类型。 |
|
|
|
工作空间。类型为 |
|
|
|
|
|
|
|
如果 |
通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,computeType表示运算的计算类型。cusolverDnSyevdx仅支持以下四种组合。
数据类型与计算类型的有效组合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或range不是CUSOLVER_EIG_RANGE_ALL或CUSOLVER_EIG_RANGE_V或CUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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)的特征值和特征向量。广义对称正定特征值问题为

其中矩阵 B 是正定的。Λ 是一个实数的 \(n \times n\) 对角矩阵。Λ 的对角元素是 (A, B) 按升序排列的特征值。V 是一个 \(n \times n\) 正交矩阵。特征向量按如下方式归一化:

用户需要提供一个工作空间,该空间由输入参数work指定。输入参数lwork表示工作空间的大小,该值由sygvd_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 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查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定要解决的问题类型:
|
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
<类型> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
一个维度为 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
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_LOWER或CUBLAS_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)的全部或部分特征值,并可选择计算特征向量。广义对称正定特征值问题为

其中矩阵B是正定的。Λ是一个实数的\(n \times {h\_meig}\)对角矩阵。Λ的对角元素是(A, B)按升序排列的特征值。V是一个\(n \times {h\_meig}\)正交矩阵。h_meig是该例程计算的特征值/特征向量的数量,当请求整个谱时(例如range = CUSOLVER_EIG_RANGE_ALL),h_meig等于n。特征向量按以下方式归一化:

用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由sygvdx_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 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库示例 - sygvdx查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定要解决的问题类型:
|
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定需要计算的特征值及可选特征向量的选择选项: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
<类型> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
实数值float或double分别对应(C, S)或(Z, D)精度。如果 |
|
|
|
整数。如果 |
|
|
|
整数。找到的特征值总数。0 <= h_meig <= n。如果 |
|
|
|
一个维度为 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传入了无效参数(
n<0,或lda,或ldb,或itype不是CUSOLVER_EIG_TYPE_1、CUSOLVER_EIG_TYPE_2、CUSOLVER_EIG_TYPE_3,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR、CUSOLVER_EIG_MODE_VECTORL,或range不是CUSOLVER_EIG_RANGE_ALL、CUSOLVER_EIG_RANGE_V、CUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWER、CUBLAS_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的特征值和特征向量。标准对称特征值问题为
其中 Λ 是一个实数的 \(n \times n\) 对角矩阵。Q 是一个 \(n \times n\) 酉矩阵。Λ 的对角线元素是 A 按升序排列的特征值。
syevj 的功能与 syevd 相同。区别在于 syevd 使用 QR 算法,而 syevj 使用 Jacobi 方法。Jacobi 方法的并行性使 GPU 在中小型矩阵上具有更好的性能。此外,用户可以配置 syevj 以执行达到特定精度的近似计算。
它是如何工作的?
syevj 通过迭代生成一系列酉矩阵,将矩阵 A 转换为以下形式
其中 W 是对角矩阵,E 是无对角元素的对称矩阵。
在迭代过程中,E的Frobenius范数单调递减。当E趋近于零时,W即为特征值集合。实际应用中,当满足以下条件时Jacobi方法停止:
其中 eps 是给定的容差。
syevj 有两个控制精度的参数。第一个参数是容差(eps),默认值为机器精度,但用户可以通过函数 cusolverDnXsyevjSetTolerance 预先设置容差值。第二个参数是最大扫描次数,用于控制雅可比方法的迭代次数,默认值为100,但用户可以通过函数 cusolverDnXsyevjSetMaxSweeps 设置合适的上限。实验表明,15次扫描通常足以收敛至机器精度。syevj 会在达到容差要求或最大扫描次数时停止计算。
雅可比方法具有二次收敛性,因此精度不与扫描次数成正比。为保证特定精度,用户应仅配置容差参数。
在syevj之后,用户可以通过函数cusolverDnXsyevjGetResidual查询残差,并通过函数cusolverDnXsyevjGetSweeps查询已执行的扫描次数。但用户需要注意,残差是E的Frobenius范数,而非单个特征值的精度,即
与syevd相同,用户需要提供由输入参数work指向的工作空间。输入参数lwork是工作空间的大小,由syevj_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = n+1,说明 syevj 在给定的容差和最大扫描次数下未能收敛。
如果用户设置了不恰当的容差,syevj可能无法收敛。例如,容差值不应小于机器精度。
如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含正交特征向量 V。
请访问cuSOLVER库示例 - syevj查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
一个维度为 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
|
|
|
填充了Jacobi算法参数和 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda<max(1,n),或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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)的特征值和特征向量。广义对称正定特征值问题为

其中矩阵 B 是正定的。Λ 是一个实数的 \(n \times n\) 对角矩阵。Λ 的对角元素是 (A, B) 按升序排列的特征值。V 是一个 \(n \times n\) 正交矩阵。特征向量按如下方式归一化:

该函数与sygvd功能相同,只是sygvd中的syevd被替换为sygvj中的syevj。因此,sygvj继承了syevj的特性,用户可以使用cusolverDnXsyevjSetTolerance和cusolverDnXsyevjSetMaxSweeps来配置容差和最大扫描次数。
然而残差的含义与syevj不同。sygvj首先计算矩阵B的Cholesky分解,
将问题转换为标准特征值问题,然后调用syevj。
例如,标准类型I的特征值问题为
其中矩阵 M 是对称的
残差是矩阵M上syevj的结果,而非A。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由sygvj_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(i > 0 且 i<=n),说明 B 不是正定矩阵,无法完成 B 的因式分解,且未计算特征值或特征向量。如果 info = n+1,表示 syevj 在给定容差和最大扫描次数下未收敛。此时仍会计算特征值和特征向量,因为不收敛是由于容差或最大扫描次数设置不当所致。
如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含正交特征向量 V。
请访问cuSOLVER库示例 - sygvj查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定要解决的问题类型: |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
<类型> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
一个维度为 |
|
|
|
工作空间,大小为 |
|
|
|
|
|
|
|
如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或ldb,或itype不是1、2或3,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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\)矩阵的特征值和特征向量
其中\(\Lambda_{j}\)是一个实数的\(n \times n\)对角矩阵。\(Q_j\)是一个\(n \times n\)酉矩阵。\(\Lambda_j\)的对角线元素是\(A_j\)的特征值,可以是升序排列或非排序顺序。
syevjBatched 对每个矩阵执行 syevj。它要求所有矩阵具有相同的尺寸 n 并且以连续方式打包。
每个矩阵都是列优先存储,其前导维度为lda,因此随机访问的公式为\(A_{k}\operatorname{(i,j)} = {A\lbrack\ i\ +\ lda*j\ +\ lda*n*k\rbrack}\)。
参数 W 还以连续方式包含每个矩阵的特征值,
W随机访问的公式为\(W_{k}\operatorname{(j)} = {W\lbrack\ j\ +\ n*k\rbrack}\)。
除了容差和最大扫描次数外,syevjBatched既可以通过cusolverDnXsyevjSetSortEig函数选择将特征值按升序排序(默认),也可以选择保持原样(不排序)。如果用户将多个微小矩阵打包成一个矩阵的对角块,不排序选项可以将这些微小矩阵的频谱分开。
syevjBatched 无法通过函数 cusolverDnXsyevjGetResidual 和 cusolverDnXsyevjGetSweeps 报告残差和执行扫描次数。调用上述两个函数都会返回 CUSOLVER_STATUS_NOT_SUPPORTED。用户需要显式计算残差。
用户需要提供由输入参数work指向的工作空间。输入参数lwork表示工作空间的大小,该值由syevjBatched_bufferSize()返回。请注意,工作空间的字节大小等于sizeof(。
输出参数 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查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
每个矩阵 |
|
|
|
|
|
|
|
用于存储矩阵 |
|
|
|
一个维度为 |
|
|
|
|
|
|
|
|
|
|
|
一个维度为 |
|
|
|
填充Jacobi算法参数的结构体。 |
|
|
|
矩阵数量。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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 指示使用矩阵的哪一部分。该函数将保持其他部分不变。
如果输入参数 uplo 为 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U。
用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXpotrf_bufferSize()返回。
如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说L或U的某些对角线元素不是实数。输出参数info将指示A中不是正定的最小前导子矩阵。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnXpotrf仅支持默认算法。
请访问cuSOLVER库示例 - Xpotrf查看代码示例。
cusolverDnXpotrf 支持的算法
|
默认算法。 |
cusolverDnXpotrf_bufferSize 和 cusolverDnXpotrf 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API有两种不同类型,dataTypeA是矩阵A的数据类型,computeType是运算的计算类型。cusolverDnXpotrf仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
计算类型 |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
n<0或lda<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 是一个 \(n \times n\) 埃尔米特矩阵,使用通用API接口时仅需提供下三角或上三角部分。输入参数 uplo 用于指定使用矩阵的哪一部分。函数将保持另一部分不变。
用户需要先调用cusolverDnXpotrf来分解矩阵A。如果输入参数uplo为CUBLAS_FILL_MODE_LOWER,则A是对应\(A = L*L^{H}\)的下三角Cholesky因子L。如果输入参数uplo为CUBLAS_FILL_MODE_UPPER,则A是对应\(A = U^{H}*U\)的上三角Cholesky因子U。
该操作是原地进行的,即矩阵 X 会覆盖矩阵 B,两者具有相同的前导维度 ldb。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnXpotrs仅支持默认算法。
请访问cuSOLVER库示例 - Xpotrf查看代码示例。
cusolverDnXpotrs支持的算法
|
默认算法。 |
cusolverDnXpotrs的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
如果 |
通用API有两种不同类型,dataTypeA是矩阵A的数据类型,dataTypeB是矩阵B的数据类型。cusolverDnXpotrs仅支持以下四种组合。
数据类型与计算类型的有效组合
dataTypeA |
dataTypeB |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0、nrhs<0、lda<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分解
其中 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)行进行交换。
用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该大小由cusolverDnXgetrf_bufferSize()返回。
用户可以结合cusolverDnXgetrf和cusolverDnGetrs来完成线性求解器。
目前,cusolverDnXgetrf支持两种算法。要选择旧版实现,用户需要调用cusolverDnSetAdvOptions。
请访问cuSOLVER库示例 - Xgetrf查看代码示例。
cusolverDnXgetrf 支持的算法
|
默认算法。速度最快,需要一个包含 |
|
旧版实现 |
cusolverDnXgetrf_bufferSize 和 cusolverDnXgetrf 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
大小至少为 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型。cusolverDnXgetrf仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
计算类型 |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
m,n<0或lda<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 )
该函数用于求解具有多个右端项的线性方程组
其中A是一个\(n \times n\)矩阵,并且已经通过cusolverDnXgetrf进行了LU分解,即A的下三角部分是L,而A的上三角部分(包括对角元素)是U。B是一个\(n \times {nrhs}\)的右侧矩阵,使用通用API接口。
输入参数 trans 的定义如下

输入参数 ipiv 是 cusolverDnXgetrf 的输出结果。它包含用于置换右侧项的枢轴索引。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
用户可以结合cusolverDnXgetrf和cusolverDnXgetrs来完成线性求解器。
目前,cusolverDnXgetrs仅支持默认算法。
请访问cuSOLVER库示例 - Xgetrf查看代码示例。
cusolverDnXgetrs 支持的算法
|
默认算法。 |
cusolverDnXgetrs函数的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
操作 |
|
|
|
矩阵 |
|
|
|
右侧的数量。 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
大小至少为 |
|
|
|
数组 |
|
|
|
<type> 维度为 |
|
|
|
用于存储矩阵 |
|
|
|
如果 |
通用API有两种不同类型:dataTypeA是矩阵A的数据类型,dataTypeB是矩阵B的数据类型。cusolverDnXgetrs仅支持以下四种组合:
数据类型与计算类型的有效组合
数据类型A |
数据类型B |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0或lda<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 是一个 \(m \times n\) 矩阵,Q 是一个 \(m \times n\) 矩阵,而 R 是一个通过通用API接口生成的 \(n \times n\) 上三角矩阵。
用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgeqrf_bufferSize()返回。
矩阵 R 会被覆盖写入 A 的上三角部分,包括对角线元素。
矩阵 Q 不会显式生成,而是将一系列豪斯霍尔德向量存储在 A 的下三角部分。假设豪斯霍尔德向量的前导非零元素为1,因此输出参数 TAU 包含缩放因子 τ。如果 v 是原始豪斯霍尔德向量,q 是对应于 τ 的新豪斯霍尔德向量,满足以下关系
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnXgeqrf仅支持默认算法。
请访问cuSOLVER库示例 - Xgeqrf查看代码示例。
cusolverDnXgeqrf 支持的算法
|
默认算法。 |
cusolverDnXgeqrf_bufferSize 和 cusolverDnXgeqrf 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度至少为 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API有两种不同类型,dataTypeA是矩阵A的数据类型,dataTypeTau是数组tau的数据类型,computeType是运算的计算类型。cusolverDnXgeqrf仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
计算类型 |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
m,n<0或lda<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() 的因式分解结果,只有下三角或上三角部分有意义,另一部分未被修改。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_LOWER,则分解的详细信息存储为:
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则分解的详细信息存储为:
用户需要提供可通过cusolverDnXsytrf()获取的主元索引,以及由输入参数bufferOnDevice和bufferOnHost指向的设备和主机工作空间。输入参数workspaceInBytesOnDevice和workspaceInBytesOnHost分别表示设备和主机工作空间的字节大小,这些值由cusolverDnXsytrs_bufferSize()返回。
若要在不使用主元旋转的情况下分解和求解对称系统,用户在调用cusolverDnXsytrf和cusolverDnXsytrs时应设置devIpiv = NULL。
如果输出参数 devInfo = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
cusolverDnXsytrs_bufferSize 和 cusolverDnXsytrs 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
右侧的数量。 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
大小至少为 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API有两种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeB表示矩阵A的数据类型。cusolverDnXsytrs仅支持以下四种组合:
数据类型与计算类型的有效组合
数据类型A |
数据类型B |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
n<0或lda<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 表示使用矩阵的哪一部分。该函数会保持其他部分不变。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角逆矩阵。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角逆矩阵。
用户需要提供由输入参数bufferOnDevice和bufferOnHost指向的设备端和主机端工作空间。输入参数workspaceInBytesOnDevice和workspaceInBytesOnHost分别表示设备端和主机端工作空间的字节大小,这些值由cusolverDnXtrtri_bufferSize()函数返回。
如果矩阵求逆失败,输出参数 info = i 表示 A(i,i) = 0。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
请访问cuSOLVER库示例 - Xtrtri查看代码示例。
cusolverDnXtrtri_bufferSize 和 cusolverDnXtrtri 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
枚举的单位对角类型。 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
有效数据类型
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_NOT_SUPPORTED-
不支持的数据类型。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
n<0或lda<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}\))。
用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXlarft_bufferSize()返回。
目前仅支持n >= k的场景。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定基本反射器相乘形成块反射器的顺序。 |
|
|
|
指定定义基本反射器的向量如何存储。 |
|
|
|
块反射器 |
|
|
|
三角因子 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
数组 |
|
|
|
数组 |
|
|
|
维度 |
|
|
|
数组 |
|
|
|
维度 |
|
|
|
数组 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
通用API包含四种不同类型:
dataTypeV是数组V的数据类型
dataTypeTau是数组tau的数据类型
dataTypeT是数组T的数据类型
computeType是运算的计算类型
cusolverDnXlarft 仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型V |
数据类型Tau |
数据类型T |
计算类型 |
含义 |
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
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分解公式表示为
其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负,并按降序排列。U 和 V 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。
用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgesvd_bufferSize()返回。
如果输出参数 info = -i(小于零),表示第 i-th 个参数有误(不包含句柄)。如果 bdsqr 未收敛,info 会指明中间双对角形式中有多少条超对角线未能收敛到零。
目前,cusolverDnXgesvd仅支持默认算法。
cusolverDnXgesvd 支持的算法
|
默认算法。 |
请访问cuSOLVER库示例 - Xgesvd查看代码示例。
备注1: gesvd 仅支持 m>=n。
备注2:该例程返回\(V^H\),而非V。
cusolverDnXgesvd_bufferSize 和 cusolverDnXgesvd 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算矩阵 |
|
|
|
指定计算矩阵V**T全部或部分内容的选项:= 'A':在数组VT中返回V**T的所有N行;= 'S':在数组VT中返回V**T的前min(m,n)行(右奇异向量);= 'O':将V**T的前min(m,n)行(右奇异向量)覆盖写入数组A;= 'N':不计算V**T的任何行(不计算右奇异向量)。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API包含三种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeVT表示矩阵VT的数据类型,computeType表示运算的计算类型。cusolverDnXgesvd仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
数据类型S |
数据类型U |
数据类型VT |
计算类型 |
含义 |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或lda或ldu或ldvt)。 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分解公式表示为
其中 Σ 是一个 \(m \times n\) 矩阵,除了其 min(m,n) 个对角线元素外其余均为零,U 是一个 \(m \times m\) 酉矩阵,V 是一个 \(n \times n\) 酉矩阵。Σ 的对角线元素是 A 的奇异值;它们是实数且非负,并按降序排列。U 和 V 的前 min(m,n) 列分别是 A 的左奇异向量和右奇异向量。
cusolverDnXgesvdp 结合了文献[14]中的极分解和cusolverDnXsyevd来计算SVD。它比基于QR算法的cusolverDnXgesvd快得多。然而,当矩阵A具有接近零的奇异值时,文献[14]中的极分解可能无法提供完整的酉矩阵。为了解决奇异值接近零时的问题,我们添加了一个小的扰动,使极分解能够提供正确的结果。这样做的后果是奇异值会因这个扰动而产生偏移而不准确。输出参数h_err_sigma就是这个扰动的大小。换句话说,h_err_sigma显示了SVD的准确性。
用户需要提供设备和主机的工作空间,这些空间由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgesvdp_bufferSize()返回。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnXgesvdp仅支持默认算法。
cusolverDnXgesvdp 支持的算法
|
默认算法。 |
请访问cuSOLVER库示例 - Xgesvdp查看代码示例。
备注1: gesvdp 也支持 n>=m。
备注2:该例程返回V,而非\(V^{H}\)
cusolverDnXgesvdp_bufferSize 和 cusolverDnXgesvdp 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定选项以仅计算奇异值或同时计算奇异向量:
|
|
|
|
|
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
|
|
|
扰动幅度,显示SVD的准确性。 |
通用API包含三种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeV表示矩阵V的数据类型,computeType表示运算的计算类型。cusolverDnXgesvdp仅支持以下四种组合:
数据类型与计算类型的有效组合
数据类型A |
数据类型S |
数据类型U |
数据类型V |
计算类型 |
含义 |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
m,n<0或lda或ldu或ldv)。 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可表示为
其中Σ是一个\(k \times k\)矩阵,除对角线元素外其余均为零,U是一个\(m \times k\)正交矩阵,V是一个\(k \times n\)正交矩阵。Σ的对角线元素是A的近似奇异值,这些值为实数且非负,并按降序排列。U和V的列向量分别是A的前k个左右奇异向量。
cusolverDnXgesvdr 实现了文献[15]中描述的随机化方法来计算k-SVD,当满足[15]所述条件时,该方法能以高概率保证计算精度。cusolverDnXgesvdr 专用于快速高质量地计算矩阵A的极小部分谱(即k远小于min(m,n)),尤其适用于大维度矩阵的情况。
该方法的精度取决于矩阵A的谱特性、幂迭代次数niters、过采样参数p以及p与矩阵A维度之间的比率。较大的过采样值p或更多的迭代次数niters可能会产生更精确的近似结果,但也会增加cusolverDnXgesvdr的运行时间。
我们建议使用两次迭代,并将过采样设置为至少2k。一旦求解器提供足够的精度,可以调整k和niters的值以获得更好的性能。
用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXgesvdr_bufferSize()函数返回。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
目前,cusolverDnXgesvdr仅支持默认算法。
cusolverDnXgesvdr 支持的算法
|
默认算法。 |
请访问cuSOLVER库示例 - Xgesvdr查看代码示例。
备注1: gesvdr 也支持 n>=m。
备注2:该例程返回V,而非\(V^{H}\)
cusolverDnXgesvdr_bufferSize 和 cusolverDnXgesvdr 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算矩阵 |
|
|
|
指定计算矩阵V全部或部分内容的选项:= 'S':将V的前k行(右奇异向量)返回到数组V中;= 'N':不计算V的任何行(不计算右奇异向量)。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
过采样。子空间的大小将为 |
|
|
|
幂方法的迭代次数。 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API包含五种不同类型,dataTypeA表示矩阵A的数据类型,dataTypeS表示向量S的数据类型,dataTypeU表示矩阵U的数据类型,dataTypeV表示矩阵V的数据类型,computeType表示运算的计算类型。cusolverDnXgesvdr仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
数据类型S |
数据类型U |
数据类型V |
计算类型 |
含义 |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
m,n<0或lda或ldu或ldv)。 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的特征值和特征向量。标准对称特征值问题为
其中 Λ 是一个实数的 \(n \times n\) 对角矩阵。V 是一个 \(n \times n\) 酉矩阵。Λ 的对角线元素是 A 的特征值,按升序排列。
用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXsyevd_bufferSize()返回。
如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。
如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。
请访问cuSOLVER库示例 - Xsyevd查看代码示例。
目前,cusolverDnXsyevd仅支持默认算法。
cusolverDnXsyevd支持的算法
|
默认算法。 |
cusolverDnXsyevd_bufferSize 和 cusolverDnXsyevd 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
一个维度为 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,computeType表示运算的计算类型。cusolverDnXsyevd仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
数据类型W |
计算类型 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda<max(1,n),或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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的全部或部分特征值,并可选择计算特征向量。标准对称特征值问题为
其中Λ是一个实数的n×h_meig对角矩阵。V是一个n×h_meig酉矩阵。h_meig是该例程计算得到的特征值/特征向量数量,当请求整个频谱时(例如range = CUSOLVER_EIG_RANGE_ALL),h_meig等于n。Λ的对角线元素是A按升序排列的特征值。
用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice(以及workspaceInBytesOnHost)表示设备(和主机)工作空间的字节大小,该值由cusolverDnXsyevdx_bufferSize()返回。
如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。如果 info = i(大于零),表示中间三对角形式的 i 个非对角元素未能收敛到零。
如果 jobz = CUSOLVER_EIG_MODE_VECTOR,A 包含矩阵 A 的正交特征向量。这些特征向量是通过分治算法计算得出的。
目前,cusolverDnXsyevdx仅支持默认算法。
请访问cuSOLVER库示例 - Xsyevdx查看代码示例。
cusolverDnXsyevdx 支持的算法
|
默认算法。 |
cusolverDnXsyevdx_bufferSize 和 cusolverDnXsyevdx 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定需要计算的特征值及可选特征向量的选择选项: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
如果 |
|
|
|
整数。如果 |
|
|
|
整数。找到的特征值总数。0 <= h_meig <= n。如果 |
|
|
|
数组 |
|
|
|
一个维度为 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示矩阵W的数据类型,而computeType表示运算的计算类型。cusolverDnXsyevdx仅支持以下四种组合:
数据类型与计算类型的有效组合
数据类型A |
数据类型W |
计算类型 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda<max(1,n),或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或range不是CUSOLVER_EIG_RANGE_ALL或CUSOLVER_EIG_RANGE_V或CUSOLVER_EIG_RANGE_I,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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\)矩阵的特征值和特征向量
其中\(\Lambda_j\)是一个实数的\(n \times n\)对角矩阵。\(V_j\)是一个\(n \times n\)酉矩阵。\(\Lambda_j\)的对角线元素是\(A_j\)按升序排列的特征值。
syevBatched 对每个矩阵执行特征分解。它要求所有矩阵具有相同的大小 n 并且以连续方式打包。
每个矩阵都是列优先存储,其前导维度为lda,因此随机访问的公式为\(A_{k}\operatorname{(i,j)} = {A\lbrack\ i\ +\ lda*j\ +\ lda*n*k\rbrack}\)。
参数 W 还以连续方式包含每个矩阵的特征值,
W随机访问的公式为\(W_{k}\operatorname{(j)} = {W\lbrack\ j\ +\ n*k\rbrack}\)。
用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice和workspaceInBytesOnHost表示设备和主机工作空间的字节大小,这些值由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支持的算法
|
默认算法。 |
cusolverDnXsyevBatched_bufferSize 和 cusolverDnXsyevBatched 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定计算选项:仅计算特征值或计算特征对: |
|
|
|
指定 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
一个维度为 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
一个维度为 |
|
|
|
矩阵数量。 |
通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示数组W的数据类型,computeType表示运算的计算类型。cusolverDnXsyevBatched仅支持以下四种组合:
数据类型与计算类型的有效组合
数据类型A |
数据类型W |
计算类型 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
n<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER或CUBLAS_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)满足
其中 w(j) 是其特征值。矩阵 A 的左特征向量 u(j) 满足
其中 \(u(j)^{H}\) 表示 u(j) 的共轭转置。
计算得到的特征向量经过归一化处理,使其欧几里得范数等于1,且最大分量为实数。
如果A是实数值,有两种方式可以在W中返回特征值。第一种选项将所有数据类型设置为实数值类型。此时W包含2*n个条目,前n个条目存储实部,后n个条目存储虚部。通过设置指针WR = W和WI = W+n,可以恢复使用独立数组WR和WI分别存储实部和虚部的LAPACK接口。第二种选项对W使用复数数据类型。此时W长度为n个条目;每个实特征值存储为复数,对于每个共轭复数对,两个特征值都会被返回。计算过程仍然完全以实数运算执行。
用户需要提供设备和主机的工作空间,分别由输入参数bufferOnDevice和bufferOnHost指向。输入参数workspaceInBytesOnDevice和workspaceInBytesOnHost表示设备和主机工作空间的字节大小,这些值由cusolverDnXsyevBatched_bufferSize()返回。
如果输出参数 info = -i(小于零),表示第 i 个参数有误(不包含句柄)。若 info = 0,则 QR 算法收敛且 W 包含计算得到的 A 的特征值;若请求,则已计算对应的左和/或右特征向量。若 info = i(大于零),则 QR 算法未能计算所有特征值且未计算任何特征向量。W 的 i+1:n 元素包含已收敛的特征值。
备注1: geev 仅支持计算右特征向量。因此,必须设置 jobvl = CUSOLVER_EIG_MODE_NOVECTOR。
备注2:geev 使用平衡技术来改善特征值和特征向量的条件数。
备注3: geev 是一种混合CPU-GPU算法。使用固定主机内存可获得最佳性能。
目前,cusolverDnXgeev仅支持默认算法。
cusolverDnXgeev 支持的算法
|
默认算法。 |
cusolverDnXgeev_bufferSize 和 cusolverDnXgeev 的输入参数列表:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverDN库上下文的句柄。 |
|
|
|
包含由 |
|
|
|
指定是否计算左特征向量。 |
|
|
|
指定是否计算右特征向量。 |
|
|
|
矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
存储计算得到的 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
数组 |
|
|
|
维度为 |
|
|
|
用于存储矩阵 |
|
|
|
计算的数据类型。 |
|
|
|
设备工作空间。一个类型为 |
|
|
|
|
|
|
|
主机工作区。大小为 |
|
|
|
|
|
|
|
如果 |
通用API包含五种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示数组W的数据类型,dataTypeVL表示矩阵VL的数据类型,dataTypeVR表示矩阵VR的数据类型,而computeType表示运算的计算类型。cusolverDnXgeev仅支持以下四种组合:
数据类型与计算类型的有效组合
DataTypeA |
DataTypeW |
DataTypeVL |
DataTypeVR |
ComputeType |
含义 |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
32位混合实数-复数 |
|
|
|
|
|
|
|
|
|
|
|
64位混合实数-复数 |
|
|
|
|
|
|
|
|
|
|
|
|
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
jobvl不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或jobvr不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,n<0,或lda < max(1,n),或当jobvl为CUSOLVER_EIG_MODE_VECTOR时ldvl < n,或当jobvr为CUSOLVER_EIG_MODE_VECTOR时ldvr < 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所需的硬件资源。
输出
|
指向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端资源。
输入
|
cuSolverSP上下文的句柄。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
关闭成功。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.5.1.3. cusolverSpSetStream()
cusolverStatus_t
cusolverSpSetStream(cusolverSpHandle_t handle, cudaStream_t streamId)
此函数设置cuSolverSP库用于执行其例程的流。
输入
|
cuSolverSP上下文的句柄。 |
|
该库要使用的流。 |
返回状态
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\) 稀疏矩阵,由四个数组 csrValA、csrRowPtrA、csrEndPtrA 和 csrColIndA 以 CSR 存储格式定义。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。
csrlsvlu 和 csrlsvqr 不接受非通用矩阵。用户需要将矩阵扩展至其缺失的上/下三角部分,否则结果将不符合预期。用户可以使用 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.
输入
参数 |
内存空间 |
描述 |
|---|---|---|
|
|
cuSolverSP库上下文的句柄。 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
包含每行起始位置的 |
|
|
包含最后一行末尾加1的 |
|
|
矩阵 |
输出
参数 |
内存空间 |
描述 |
|---|---|---|
|
|
1 如果 |
返回状态
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 是一个 \(n \times n\) 稀疏矩阵,由三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。b 是大小为 n 的右侧向量,x 是大小为 n 的解向量。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果矩阵A是对称/厄米特矩阵且仅使用或需要下/上三角部分,用户必须将矩阵扩展至缺失的上/下三角部分,否则结果将出错。
该线性系统通过带部分主元消去的稀疏LU分解求解:
cusolver库提供了三种重排序方案:symrcm、symamd和csrmetisnd,用于减少零填充,这会显著影响LU分解的性能。当输入参数reorder为1(2或3)时,可启用symrcm(symamd或csrmetisnd),否则不执行重排序。
如果 reorder 非零,csrlsvlu 会执行
其中 \(Q = {symrcm}(A + A^{T})\) 。
如果 A 在给定容差 (max(tol,0)) 下是奇异的,那么 U 的某些对角线元素为零,即
输出参数 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将增量式重新分配内存以存储L和U。此特性可避免QR分解时的内存高估。在某些情况下,QR分解的零填充量可能比LU分解高出一个数量级。
备注2:仅提供CPU(主机)路径。
输入
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
cuSolverSP库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
|
|
|
|
一个包含每行起始位置及最后一行末尾加1的 |
|
|
|
整数数组,长度为 |
|
|
|
右侧向量,大小为 |
|
|
|
用于判断是否为奇异值的容差。 |
|
|
|
如果 |
输出
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
大小为 |
|
|
|
如果 |
返回状态
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 是一个 \(m \times m\) 的稀疏矩阵,由三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。b 是大小为 m 的右侧向量,x 是大小为 m 的解向量。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果矩阵A是对称/厄米特矩阵且仅使用或需要下/上三角部分,用户必须将矩阵扩展至缺失的上/下三角部分,否则结果将出错。
线性系统通过稀疏QR分解求解,
如果 A 在给定容差 (max(tol,0)) 下是奇异的,那么 R 的某些对角元素为零,即
输出参数 singularity 是此类 j 的最小索引。如果 A 是非奇异的,则 singularity 为 -1。singularity 采用基0计数,与 A 的基索引无关。例如,如果 A 的第二列与第一列相同,则 A 是奇异的且 singularity = 1,这意味着 R(1,1)≈0。
cusolver库提供了三种重排序方案:symrcm、symamd和csrmetisnd,用于减少零填充现象,这对QR分解的性能有显著影响。当输入参数reorder为1(2或3)时,可启用symrcm(symamd或csrmetisnd)方案,否则不执行重排序。
输入
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
cuSolverSP库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 矩阵 |
|
|
|
一个包含每行起始位置及最后一行末尾加1的 |
|
|
|
矩阵 |
|
|
|
右侧向量,大小为 |
|
|
|
用于判断是否为奇异值的容差。 |
|
|
|
如果 |
输出
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
大小为 |
|
|
|
如果 |
返回状态
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 是一个 \(m \times m\) 对称正定稀疏矩阵,由三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 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分解求解,
其中 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库提供了三种重排序方案:symrcm、symamd和csrmetisnd,用于减少零填充,这会显著影响Cholesky分解的性能。输入参数reorder可以启用symrcm(当reorder为1时)、symamd(为2时)或csrmetisnd(为3时),否则不执行重排序。
备注1:该函数支持原地操作(x和b指向同一内存块)和非原地操作。
备注2:该函数仅适用于32位索引,如果矩阵G存在大量零填充导致非零元素数量超过\(2^{31}\),则会返回CUSOLVER_STATUS_ALLOC_FAILED。
输入
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
cuSolverSP库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 矩阵 |
|
|
|
一个包含每行起始位置及最后一行末尾加1的 |
|
|
|
矩阵 |
|
|
|
右侧向量,大小为 |
|
|
|
用于判断奇异性的容差。 |
|
|
|
如果 |
输出
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
大小为 |
|
|
|
如果 |
返回状态
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);
该函数解决以下最小二乘问题:
A 是一个 \(m \times n\) 稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。b 是大小为 m 的右侧向量,x 是大小为 n 的最小二乘解向量。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果A是方阵、对称/厄米特矩阵且仅使用或需要下/上三角部分,用户必须将矩阵扩展至其缺失的上/下三角部分,否则结果将出错。
该函数仅在m大于或等于n时有效,换句话说,A是一个高矩阵。
最小二乘问题通过带列主元的稀疏QR分解求解,
如果A是满秩的(即A的所有列线性无关),那么矩阵P是一个单位矩阵。假设A的秩为k,小于n,置换矩阵P会以如下方式对A的列进行重新排序:
其中 \(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\) ,最小二乘问题可以重新表述为
或以矩阵形式
输出参数 min_norm 是 \(\left. \|c_{2} \right.\|\),这是最小二乘问题的最小值。
如果A不是满秩矩阵,上述方程没有唯一解。最小二乘问题等价于
或者等价地表示为另一个最小二乘问题
输出参数 x 是 \(P^{T}*y\),即最小二乘问题的解。
输出参数 p 是一个大小为 n 的向量。它对应一个置换矩阵 P。p(i)=j 表示 (P*x)(i) = x(j)。如果 A 是满秩的,则 p=0:n-1。
备注1: p始终基于0,与A的基础索引无关。
备注2:仅提供CPU(主机)路径。
输入
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
cuSolver库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 矩阵 |
|
|
|
一个包含每行起始位置及最后一行末尾加1的 |
|
|
|
矩阵 |
|
|
|
右侧向量,大小为 |
|
|
|
用于决定 |
输出
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
|
|
|
|
大小为 |
|
|
|
一个大小为 |
|
|
|
|
返回状态
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\) 的稀疏矩阵,由三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。输出参数 x 是大小为 m 的近似特征向量,
以下移位逆方法逐步修正特征对直至收敛。
它接受以下参数:
mu0 是特征值的初始猜测值。如果 mu 是单根,则移位逆方法将收敛到最接近 mu0 的特征值 mu。否则,移位逆方法可能不会收敛。
x0 是初始特征向量。如果用户没有偏好,可以随机选择 x0。x0 必须是非零向量,可以是非单位长度。
tol 是用于判断收敛的容差值。如果 tol 小于零,将被视为零。
maxite 是最大迭代次数。当逆位移法因容差过小或所需特征值非单重而导致不收敛时,该参数非常有用。
移位逆方法
给定特征值μ0的初始猜测和初始向量x0
支持的矩阵类型是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 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
cuSolver库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 矩阵 |
|
|
|
一个包含每行起始位置及最后一行末尾加1的 |
|
|
|
矩阵 |
|
|
|
特征值的初始猜测。 |
|
|
|
特征向量的初始猜测,一个大小为 |
|
|
|
移位逆方法中的最大迭代次数。 |
|
|
|
收敛容差。 |
输出
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
在容忍度范围内最接近 |
|
|
|
大小为 |
返回状态
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内的代数特征值数量
其中闭合线C是盒子B的边界,该盒子是由两个点指定的矩形:一个是左下角(输入参数left_bottom_corner),另一个是右上角(输入参数right_upper_corner)。P(z)=det(A - z*I)是A的特征多项式。
A 是一个 \(m \times m\) 的稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。
输出参数 num_eigs 表示在区域 B 内的代数特征值数量。由于多种原因,该数值可能不准确:
轮廓线
C接近某些特征值,甚至穿过某些特征值。由于网格尺寸较粗,数值积分不够精确。默认分辨率是沿轮廓
C均匀分布的1200个网格。
尽管csreigs可能不够精确,但它仍能让用户大致了解在圆盘定理分辨率较差的区域中有多少特征值。例如,拉普拉斯算子的标准三点有限差分格式是一个三对角矩阵,圆盘定理会显示"所有特征值都在区间[0, 4*N^2]内",其中N是网格数量。在这种情况下,csreigs对于[0, 4*N^2]内的任何区间都很有用。
备注1:如果A在实数情况下对称或在复数情况下为厄米特矩阵,则所有特征值均为实数。用户仍需指定一个矩形区域而非区间,该矩形的高度可以远小于其宽度。
备注2:仅提供CPU(主机)路径。
输入
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
cuSolverSP库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
<type> 矩阵 |
|
|
|
一个包含每行起始位置及最后一行末尾加1的 |
|
|
|
矩阵 |
|
|
|
方框的左下角。 |
|
|
|
方框的右上角。 |
输出
参数 |
cusolverSp 内存空间 |
*主机内存空间 |
描述 |
|---|---|---|---|
|
|
|
盒子中的代数特征值数量。 |
返回状态
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 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部rcm算法作用于\(A + A^{T}\),如果矩阵不对称,用户无需扩展该矩阵。
备注1:仅提供CPU(主机)路径。
输入
参数 |
*主机内存空间 |
描述 |
|---|---|---|
|
|
cuSolverSP库上下文的句柄。 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
一个包含每行起始位置及最后一行末尾加一的 |
|
|
矩阵 |
输出
参数 |
hsolver |
描述 |
|---|---|---|
|
|
大小为 |
返回状态
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 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部mdq会处理\(A + A^{T}\),如果矩阵不对称,用户无需扩展该矩阵。
备注1:仅提供CPU(主机)路径。
输入
参数 |
*主机内存空间 |
描述 |
|---|---|---|
|
|
cuSolverSP库上下文的句柄。 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
包含每行起始位置及最后一行末尾加1的 |
|
|
矩阵 |
输出
参数 |
hsolver |
描述 |
|---|---|---|
|
|
大小为 |
返回状态
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 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部,amd作用于\(A + A^{T}\),如果矩阵不对称,用户不需要扩展矩阵。
备注1:仅提供CPU(主机)路径。
输入
参数 |
*主机内存空间 |
描述 |
|---|---|---|
|
|
cuSolverSP库上下文的句柄。 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
一个包含每行起始位置及最后一行末尾加一的 |
|
|
矩阵 |
输出
参数 |
hsolver |
描述 |
|---|---|---|
|
|
大小为 |
返回状态
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版本。
参数 options 是 metis 的配置项。对于没有 metis 使用经验的用户,可以设置 options = NULL 来使用默认配置。
输出参数 p 是一个包含 n 个元素的整数数组。它表示一个基于0索引的置换数组。置换数组 p 对应一个置换矩阵 P,并满足以下关系:
A 是一个 \(n \times n\) 稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。在内部csrmetisnd会处理\(A + A^{T}\),如果矩阵不对称,用户无需自行扩展矩阵。
备注1:仅提供CPU(主机)路径。
输入
参数 |
*主机内存空间 |
描述 |
|---|---|---|
|
|
cuSolverSP库上下文的句柄。 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
一个包含每行起始位置及最后一行末尾加一的 |
|
|
矩阵 |
|
|
用于配置 |
输出
参数 |
*主机内存空间 |
描述 |
|---|---|---|
|
|
大小为 |
返回状态
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\) 稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。支持的矩阵类型为 CUSPARSE_MATRIX_TYPE_GENERAL。
输出参数 p 是一个包含 n 个元素的整数数组。它表示一个基于0索引的置换数组。置换数组 p 对应一个置换矩阵 P,并满足以下关系:
输出参数 numnz 描述了置换矩阵 A(p,:) 中非零对角元的数量。如果 numnz 小于 n,则矩阵 A 存在结构奇异性。
备注1:仅提供CPU(主机)路径。
备注2:此例程不会最大化置换矩阵的对角线值。用户不应期望此例程能使"无主元LU分解"变得稳定。
输入
参数 |
*主机内存空间 |
描述 |
|---|---|---|
|
|
cuSolverSP库上下文的句柄。 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
<type> 数组,包含矩阵 |
|
|
一个包含每行起始位置及最后一行末尾加一的 |
|
|
矩阵 |
输出
参数 |
*主机内存空间 |
描述 |
|---|---|---|
|
|
大小为 |
|
|
置换矩阵对角线上非零元素的数量。 |
返回状态
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的置换:
A 是一个 \(m \times n\) 稀疏矩阵,通过三个数组 csrValA、csrRowPtrA 和 csrColIndA 以 CSR 存储格式定义。
该操作是原地进行的,即矩阵 A 会被 B 覆盖。
置换向量p和q是基于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 是
以及左置换向量 p=(0,2,1),右置换向量 q=(2,1,0),那么 \(P*A*Q^{T}\) 的结果为
备注1:仅提供CPU(主机)路径。
备注2:用户可以结合csrsymrcm和csrperm来获得\(P*A*P^{T}\),该矩阵在QR分解过程中具有更少的零填充。
输入
参数 |
cusolverSp 内存空间 |
描述 |
|---|---|---|
|
|
cuSolver库上下文的句柄。 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
矩阵 |
|
|
整数数组,包含矩阵 |
|
|
矩阵 |
|
|
大小为 |
|
|
大小为 |
|
|
长度为 |
|
|
用户分配的缓冲区,其大小由 |
输出
参数 |
hsolver |
描述 |
|---|---|---|
|
|
整数数组,包含 |
|
|
矩阵 |
|
|
长度为 |
|
|
缓冲区的字节数。 |
返回状态
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分解用于解决一组最小二乘问题
或一组线性系统
其中每个\(A_{j}\)是一个\(m \times n\)稀疏矩阵,通过四个数组csrValA、csrRowPtrA和csrColIndA以CSR存储格式定义。
支持的矩阵类型是CUSPARSE_MATRIX_TYPE_GENERAL。如果A是对称矩阵且仅提供下/上三角部分,用户需要将\(A + A^{H}\)传入此函数。
使用批量稀疏QR分解的前提条件有两个方面。首先,所有矩阵\(A_{j}\)必须具有相同的稀疏模式。其次,在最小二乘问题中不使用列主元交换,因此只有当\(A_{j}\)对所有j = 1,2,..., batchSize都是满秩时,解才有效。由于所有矩阵具有相同的稀疏模式,因此只需要使用一份csrRowPtrA和csrColIndA的副本。但数组csrValA会依次存储所有\(A_{j}\)的系数值。换句话说,csrValA[k*nnzA : (k+1)*nnzA]表示矩阵\(A_{k}\)的数值。
批处理QR使用不透明的数据结构csrqrInfo来保存中间数据,例如QR分解中的矩阵Q和矩阵R。用户需要在执行批处理QR操作中的任何函数之前,先通过cusolverSpCreateCsrqrInfo创建csrqrInfo。在调用cusolverSpDestroyCsrqrInfo之前,csrqrInfo不会释放内部数据。
批处理稀疏QR分解包含三个例程:cusolverSpXcsrqrAnalysisBatched、cusolverSp[S|D|C|Z]csrqrBufferInfoBatched 和 cusolverSp[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,直到internalDataInBytes和workspaceInBytes的总和超过可用设备内存的大小。
假设用户需要执行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 内存空间 |
描述 |
|---|---|---|
|
|
cuSolverSP库上下文的句柄。 |
|
|
每个矩阵 |
|
|
每个矩阵 |
|
|
每个矩阵 |
|
|
每个矩阵 |
|
|
|
|
|
包含每行起始位置及最后一行末尾加1的 |
|
|
每个矩阵 |
|
|
|
|
|
需要求解的系统数量。 |
|
|
用于QR分解的不透明结构体。 |
|
|
由用户分配的缓冲区,其大小由 |
输出
参数 |
cusolverSp 内存空间 |
描述 |
|---|---|---|
|
|
|
|
|
内部数据的字节数。 |
|
|
数值分解中缓冲区的字节数。 |
返回状态
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()来生成这些三角因子。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
对应矩阵 |
|
|
|
对应于矩阵 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
CUSOLVER_STATUS_EXECUTION_FAILED-
内核无法在GPU上启动。
2.6.2. cusolverRfAnalyze()
cusolverStatus_t
cusolverRfAnalyze(cusolverRfHandle_t handle);
该例程根据用户选择的算法,对LU重分解中可用的并行性进行适当分析。
假设之前已经调用了cusolverRfSetup[Host|Device]()来创建分析所需的内部数据结构。
对于单个线性系统,此例程只需调用一次
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
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)
排列 P 和 Q 分别表示应用于原始矩阵 A 的所有左右重排序操作的最终组合。不过,这些排列通常分别与部分主元选取和用于最小化填充量的重排序相关联。
对于单个线性系统,此例程只需调用一次
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
对应于矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
对应于矩阵 |
|
|
|
对应矩阵 |
|
|
|
矩阵 |
|
|
|
该偏移量数组对应于 |
|
|
|
与矩阵 |
|
|
|
对应矩阵 |
|
|
|
左侧排列(通常与主元选择相关)。数组的大小为 |
|
|
|
正确的排列(通常与重新排序相关)。数组的大小为 |
|
|
|
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)
排列 P 和 Q 分别表示应用于原始矩阵 A 的所有左右重排序操作的最终组合。不过,这些排列通常分别与部分主元选取和用于最小化填充量的重排序相关联。
对于单个线性系统,此例程只需调用一次
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
该偏移量数组对应于 |
|
|
|
与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
对应于矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
矩阵 |
|
|
|
该偏移量数组对应于 |
|
|
|
对应于矩阵 |
|
|
|
对应矩阵 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
与矩阵 |
|
|
|
对应矩阵 |
|
|
|
左侧排列(通常与主元选择相关)。数组的大小为 |
|
|
|
正确的排列(通常与重新排序相关)。数组的大小为 |
|
|
|
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库例程之前执行。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向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()来生成这些三角因子。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
对应矩阵中非零元素的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
对应矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
返回状态
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()函数来生成这些三角因子。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
对应于矩阵 |
|
|
|
对应矩阵 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
对应矩阵 |
|
|
|
对应于矩阵 |
返回状态
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库例程后执行。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
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()例程中使用的矩阵格式。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
枚举矩阵格式类型。 |
|
|
|
枚举的单位对角类型。 |
返回状态
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时才会使用数值提升。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
标记为零主元的下限值。 |
|
|
|
用于替换零主元(如果后者被标记)的值。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.6.11. cusolverRfGetNumericBoostReport()
cusolverStatus_t
cusolverRfGetNumericBoostReport(cusolverRfHandle_t handle,
cusolverRfNumericBoostReport_t *report);
该例程用于获取报告,判断在cusolverRfRefactor()和cusolverRfSolve()例程中是否使用了数值提升技术。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
枚举的增强报告类型。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.6.12. cusolverRfGetResetValuesFastMode()
cusolverStatus_t
cusolverRfGetResetValuesFastMode(cusolverRfHandle_t handle,
cusolverRfResetValuesFastMode_t *fastMode);
此例程获取在cusolverRfResetValues例程中使用的模式。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
枚举的模式类型。 |
返回状态
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()中三角求解的算法。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
枚举算法类型。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.6.14. cusolverRfRefactor()
cusolverStatus_t cusolverRfRefactor(cusolverRfHandle_t handle);
该例程执行LU重新分解:
探索GPU上的可用并行性。假设之前已调用cusolverRfAnalyze()以发现可用并行性。
该例程可能会被多次调用,每次对应一个线性方程组:
用于重分解和求解例程的算法组合存在一些限制条件,cusolverRfRefactor()和cusolverRfSolve()。错误的组合会产生错误代码CUSOLVER_STATUS_INVALID_VALUE。下表总结了支持的算法组合:
用于求解和重构例程的兼容算法。
因式分解 |
求解 |
|---|---|
|
|
|
|
|
|
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
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]例程以来,数组csrRowPtrA、csrColIndA、P和Q未发生变化。这一假设反映了以下事实:在方程组集合中,系数矩阵的稀疏模式以及用于最小化填充和旋转的重新排序保持不变:
该例程可能会被多次调用,每次对应一个线性方程组:
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
对应于矩阵中非零元素的数值数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
左侧排列(通常与主元选择相关)。数组的大小为 |
|
|
|
正确的排列(通常与重新排序相关)。数组的大小为 |
|
|
|
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()例程之前调用一次。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
枚举矩阵格式类型。 |
|
|
|
枚举的单位对角类型。 |
返回状态
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时才会使用数值提升功能。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
标记为零主元的下限值。 |
|
|
|
用于替换零主元(如果后者被标记)的值。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_NOT_INITIALIZED-
库未初始化。
2.6.18. cusolverRfSetResetValuesFastMode()
cusolverStatus_t
cusolverRfSetResetValuesFastMode(cusolverRfHandle_t handle,
cusolverRfResetValuesFastMode_t fastMode);
此例程设置cusolverRfResetValues例程中使用的模式。快速模式需要额外内存,仅当需要非常快速地调用cusolverRfResetValues()时才推荐使用。可以在调用cusolverRfAnalyze()例程之前调用一次。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
枚举的模式类型。 |
返回状态
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()例程之前调用一次。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
枚举算法类型。 |
返回状态
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}\)执行前向和后向求解:
假设该结果已通过先前调用cusolverRfRefactor()例程计算得出。
该例程可以求解具有多个右端项(RHS)的线性系统:
尽管目前仅支持单个右侧表达式(RHS)。
该例程可能会被多次调用,每次对应一个线性方程组:
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
左侧排列(通常与主元选择相关)。数组的大小为 |
|
|
|
正确的排列(通常与重新排序相关)。数组的大小为 |
|
|
|
需要求解的右侧项数量。 |
|
|
|
包含临时工作空间的稠密矩阵(大小为 |
|
|
|
稠密矩阵Temp的前导维度( |
|
|
|
包含右侧项 |
|
|
|
稠密矩阵 |
返回状态
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}\}\)都具有相同的稀疏模式,并且非常相似,因此可以通过相同的置换P和Q进行分解。换句话说,\(A_{j}{,\ j>1}\)是\(A_{1}\)的一个小扰动。
该例程接受主机端输入的原始矩阵A(稀疏模式及批量值)、下三角矩阵(L)和上三角矩阵(U),以及第一个线性系统(i=1)完全LU分解生成的左置换矩阵(P)和右置换矩阵(Q):
排列 P 和 Q 分别表示应用于原始矩阵 A 的所有左右重排序操作的最终组合。不过,这些排列通常分别与部分主元选取和用于最小化填充量的重排序相关联。
备注1:矩阵 A、L 和 U 必须采用 CSR 格式且基于0索引。
备注2:为了获得最佳性能,batchSize应为32的倍数且不小于32。该算法受内存带宽限制,一旦达到带宽上限,通过增大batchSize来提升性能的空间将非常有限。实际应用中,32-128的batchSize通常足以获得良好性能,但在某些情况下更大的batchSize可能更有优势。
以下例程对于单个线性系统只需调用一次:
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
批处理模式中的矩阵数量。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
该偏移量数组对应于 |
|
|
|
与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
大小为 |
|
|
|
矩阵 |
|
|
|
该偏移量数组对应于 |
|
|
|
对应于矩阵 |
|
|
|
对应矩阵 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
与矩阵 |
|
|
|
对应矩阵 |
|
|
|
左侧排列(通常与主元选择相关)。数组的大小为 |
|
|
|
正确的排列(通常与重新排序相关)。数组的大小为 |
|
|
|
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]()函数,以便创建分析所需的内部数据结构。
以下例程对于单个线性系统只需调用一次:
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
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例程以来,数组csrRowPtrA、csrColIndA、P和Q未发生变化。
这一假设反映了以下事实:系数矩阵的稀疏模式以及为最小化填充和旋转而进行的重排序在方程组集合中保持不变:
输入参数 csrValA_array 是设备内存上的指针数组。csrValA_array(j) 指向同样位于设备内存上的矩阵:\(A_{j}\)。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
批处理模式中的矩阵数量。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
对应于数组 |
|
|
|
与矩阵中非零元素对应的列索引数组。假设该数组按行排序,且每行内按列排序。数组大小为 |
|
|
|
大小为 |
|
|
|
左侧排列(通常与主元选择相关)。数组的大小为 |
|
|
|
正确的排列(通常与重新排序相关)。数组的大小为 |
|
|
|
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重新分解:
探索GPU上的可用并行性。假设之前已调用cusolverRfBatchAnalyze()以查找可用并行性。
备注:cusolverRfBatchRefactor()不会报告LU重分解的任何失败情况。用户需要调用cusolverRfBatchZeroPivot()来了解哪个矩阵的LU重分解失败了。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
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来检查重构是否成功。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
左侧排列(通常与主元选择相关)。数组的大小为 |
|
|
|
正确的排列(通常与重新排序相关)。数组的大小为 |
|
|
|
需要求解的右侧项数量。 |
|
|
|
包含临时工作空间的稠密矩阵(大小为 |
|
|
|
稠密矩阵Temp的前导维度( |
|
|
|
大小为 |
|
|
|
稠密矩阵 |
返回状态
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分解以获得新的置换矩阵P和Q。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverRF库的句柄。 |
|
|
|
大小为 |
返回状态
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的配置。
针对3个GPU的cuSolverMG分块示例
cuSolverMG中的处理网格是一个GPU ID列表,类似于ScaLAPACK中的进程ID。cuSolverMG仅支持一维列块循环,因此也只支持一维网格。假设deviceId是一个GPU ID列表,那么deviceId=1,1,1和deviceId=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引入了两个参数IA和JA来定位子矩阵。图2展示了维度为M_A乘以N_A的(全局)矩阵A。sub(A)是A的一个M乘以N的子矩阵,起始于IA和JA。请注意IA和JA是基于1的索引。
给定一个分布式矩阵A,用户可以通过调用syevd(A, IA, JA)或者将sub(A)收集到另一个分布式矩阵B并调用syevd(B, IB=1, JB=1)来计算子矩阵sub(A)的特征值。
全局矩阵与局部矩阵
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.1.8. NVLINK
通过NVLINK的点对点通信可以显著降低GPU之间数据交换的开销。cuSolverMG不会隐式启用NVLINK,而是将这个选项交给用户控制,以避免干扰其他库。示例代码H.1展示了如何启用点对点通信。
3.2. cuSolverMG 类型参考
3.2.1. cuSolverMG 类型
支持float、double、cuComplex和cuDoubleComplex数据类型。前两种是标准C语言数据类型,后两种是从cuComplex.h导出的。此外,cuSolverMG还使用了cuBLAS中的一些常见类型。
3.2.2. cusolverMgHandle_t
这是一个指向不透明cuSolverMG上下文的指针类型,用户必须在调用任何其他库函数之前通过调用cusolverMgCreate()来初始化它。未初始化的句柄对象将导致意外行为,包括cuSolverMG崩溃。由cusolverMgCreate()创建并返回的句柄必须传递给每个cuSolverMG函数。
3.2.3. cusolverMgGridMapping_t
该类型表示网格的布局。
值 |
含义 |
|---|---|
|
行优先排序。 |
|
列主序排列。 |
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所需的硬件资源。
输出
|
指向cuSolverMG上下文句柄的指针。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
初始化成功。
CUSOLVER_STATUS_ALLOC_FAILED-
资源无法分配。
3.3.2. cusolverMgDestroy()
cusolverStatus_t
cusolverMgDestroy( cusolverMgHandle_t handle)
该函数释放由cuSolverMG库使用的CPU端资源。
输入
|
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个逻辑设备。
输入
|
指向cuSolverMG上下文句柄的指针。 |
|
逻辑设备的数量。 |
|
一个大小为 |
返回状态
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。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向不透明结构的指针。 |
|
|
|
行中的设备数量。 |
|
|
|
列中的设备数量。 |
|
|
|
大小为 |
|
|
|
行优先或列优先排序。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_INVALID_VALUE-
numColDevices不大于0。numRowDevices不是1。
3.3.5. cusolverMgDestroyGrid()
cusolverStatus_t
cusolverMgDestroyGrid(
cusolverMgGrid_t grid)
该函数释放网格的资源。
参数 |
内存空间 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
指向不透明结构的指针。 |
返回状态
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。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
矩阵描述符。 |
|
|
|
全局A的行数。 |
|
|
|
全局A的列数。 |
|
|
|
每个图块的行数。 |
|
|
|
每个图块的列数。 |
|
|
|
矩阵的数据类型。 |
|
|
|
指向网格结构的指针。 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_INVALID_VALUE-
numRows、numCols、rowBlockSize或colBlockSize小于0。numRows不等于rowBlockSize。
3.3.7. cusolverMgDestroyMatrixDesc()
cusolverStatus_t
cusolverMgDestroyMatrixDesc(
cusolverMgMatrixDesc_t desc)
该函数释放矩阵描述符 desc。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
矩阵描述符。 |
返回状态
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 指示使用矩阵的哪一部分。该函数将保持其他部分不变。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_LOWER,则仅处理 A 的下三角部分,并替换为下三角 Cholesky 因子 L:
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则仅处理 A 的上三角部分,并替换为上三角 Cholesky 因子 U:
用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备上设备内存的设备指针。array_d_work[j]的数据类型为computeType。其大小为lwork,即每个设备的元素数量,该值由cusolverMgPotrf_bufferSize()返回。
如果Cholesky分解失败,即A的某个前导子矩阵不是正定的,或者等价地说L或U的某些对角线元素不是实数。输出参数info将指示A中不是正定的最小前导子矩阵。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
通用API包含两种不同类型:dataTypeA表示矩阵A的数据类型,而computeType表示运算的计算类型及工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。cusolverMgPotrf仅支持以下四种组合。
请访问cuSOLVER库示例 - MgPotrf查看代码示例。
数据类型与计算类型的有效组合
数据类型A |
计算类型 |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverMg库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
一个维度为 |
|
|
|
全局数组A中的行索引,表示 |
|
|
|
全局数组A中的列索引,表示 |
|
|
|
分布式矩阵A的矩阵描述符。 |
|
|
|
用于计算的数据类型。 |
|
|
|
一个维度为 |
|
|
|
|
|
|
|
如果 如果 如果 |
返回状态
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是一个\(n \times n\)埃尔米特矩阵,使用通用API接口时仅需关注下三角或上三角部分。输入参数uplo用于指定矩阵的哪一部分将被使用。该函数会保持矩阵其他部分不变。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_LOWER,则矩阵 A 应包含先前由 cusolverMgPotrf 例程计算的 Cholesky 分解的下三角因子。
如果输入参数 uplo 是 CUBLAS_FILL_MODE_UPPER,则矩阵 A 应包含先前由 cusolverMgPotrf 例程计算的Cholesky分解的上三角因子。
该操作是原地进行的,即矩阵 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包含dataTypeA,descrB包含dataTypeB,因此没有显式的dataTypeA和dataTypeB参数。cusolverMgPotrs仅支持以下四种组合。
请访问cuSOLVER库示例 - MgPotrf查看代码示例。
数据类型与计算类型的有效组合
数据类型A |
数据类型B |
计算类型 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverMg库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
一个维度为 |
|
|
|
全局数组A中的行索引,表示 |
|
|
|
全局数组A中表示 |
|
|
|
分布式矩阵A的矩阵描述符。 |
|
|
|
一个维度为 |
|
|
|
全局数组B中表示 |
|
|
|
全局数组B中表示 |
|
|
|
分布式矩阵B的矩阵描述符。 |
|
|
|
用于计算的数据类型。 |
|
|
|
一个维度为 |
|
|
|
|
|
|
|
如果 如果 |
返回状态
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的逆矩阵
由cusolverMgPotrf()计算得出。
如果输入参数 uplo 为 CUBLAS_FILL_MODE_LOWER,则输入时矩阵 A 包含由 cusolverMgPotrf 计算得出的 A 的下三角因子。仅处理 A 的下三角部分,并将其替换为 A 逆矩阵的下三角部分。
如果输入参数 uplo 为 CUBLAS_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()返回。
如果逆矩阵计算失败,即L或U的某个前导子矩阵为空,输出参数info将指示L或U中不是正定的最小前导子矩阵。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
通用API有两种不同类型,dataTypeA表示矩阵A的数据类型,computeType表示运算的计算类型和工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。cusolverMgPotri仅支持以下四种组合。
请访问cuSOLVER库示例 - MgPotrf查看代码示例。
数据类型与计算类型的有效组合
数据类型A |
计算类型 |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverMg库上下文的句柄。 |
|
|
|
指示矩阵 |
|
|
|
矩阵 |
|
|
|
一个维度为 |
|
|
|
全局数组A中的行索引,表示 |
|
|
|
全局数组A中表示 |
|
|
|
分布式矩阵A的矩阵描述符。 |
|
|
|
用于计算的数据类型。 |
|
|
|
一个维度为 |
|
|
|
|
|
|
|
如果 如果 如果 |
返回状态
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分解
其中 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 保持一致,即 JA 是 sub(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 |
计算类型 |
含义 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
备注1: 分块大小 TA 必须小于或等于512。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverMg库上下文的句柄。 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
一个维度为 |
|
|
|
全局数组A中的行索引,表示 |
|
|
|
全局数组A中表示 |
|
|
|
分布式矩阵A的矩阵描述符。 |
|
|
|
一个维度为 |
|
|
|
用于计算的数据类型。 |
|
|
|
一个维度为 |
|
|
|
|
|
|
|
如果 如果 如果 |
返回状态
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 );
该函数用于求解具有多个右端项的线性方程组
其中A是一个\(N \times N\)矩阵,并且已经通过getrf进行了LU分解,即A的下三角部分是L,而A的上三角部分(包括对角元素)是U。B是一个\(N \times {NRHS}\)的右侧矩阵。解矩阵X会覆盖右侧矩阵B。
输入参数 TRANS 的定义如下

用户需要在array_d_work中提供设备工作空间。array_d_work是一个维度为G的主机指针数组,其中G表示设备数量。array_d_work[j]是指向第j个设备上设备内存的设备指针。array_d_work[j]的数据类型为computeType。array_d_work[j]的大小为lwork,即每个设备的元素数量,该值由cusolverMgGetrs_bufferSize()返回。
如果array_d_IPIV为空,则不执行主元置换。否则,array_d_IPIV是getrf的输出结果。它包含用于置换右侧项的主元索引。
如果输出参数 info = -i (小于零),表示第 i-th 个参数有误(不包含句柄参数)。
通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeB表示矩阵B的数据类型,而computeType表示运算的计算类型及工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。descrB已包含dataTypeB信息,因此无需显式传递dataTypeB参数。cusolverMgGetrs仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
数据类型B |
计算类型 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
备注1: 分块大小 TA 必须小于或等于512。
备注2:仅支持 TRANS=CUBLAS_OP_N。
请访问cuSOLVER库示例 - MgGetrf查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverMG库上下文的句柄。 |
|
|
|
操作 |
|
|
|
矩阵 |
|
|
|
矩阵 |
|
|
|
一个维度为 |
|
|
|
全局数组A中的行索引,表示 |
|
|
|
全局数组A中表示 |
|
|
|
分布式矩阵A的矩阵描述符。 |
|
|
|
一个维度为 |
|
|
|
一个维度为 |
|
|
|
全局数组B中表示 |
|
|
|
全局数组B中表示 |
|
|
|
分布式矩阵B的矩阵描述符。 |
|
|
|
用于计算的数据类型。 |
|
|
|
一个维度为 |
|
|
|
|
|
|
|
如果 如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数 (
N<0或NRHS<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的特征值和特征向量。标准对称特征值问题为:
其中 Λ 是一个实数的 \(N \times N\) 对角矩阵。V 是一个 \(N \times N\) 酉矩阵。Λ 的对角线元素是 A 的特征值,按升序排列。
cusolverMgSyevd 返回特征值到 W 中,并将特征向量覆盖写入 A。W 是一个主机端的 \(1 \times N\) 向量。
通用API包含三种不同类型:dataTypeA表示矩阵A的数据类型,dataTypeW表示向量W的数据类型,computeType表示运算的计算类型和工作空间(array_d_work)的数据类型。descrA已包含dataTypeA信息,因此无需显式传递dataTypeA参数。cusolverMgSyevd仅支持以下四种组合。
数据类型与计算类型的有效组合
数据类型A |
数据类型W |
计算类型 |
含义 |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
用户需要在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] 的数据类型为 dataTypeA。array_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=1 和 JA=1。
备注3:瓦片大小 TA 必须小于或等于1024。为了获得最佳性能,TA 应设为256或512。
请访问cuSOLVER库示例 - MgSyevd查看代码示例。
参数 |
内存 |
输入/输出 |
含义 |
|---|---|---|---|
|
|
|
cuSolverMG库上下文的句柄。 |
|
|
|
指定选项以仅计算特征值或计算特征对:
|
|
|
|
指定
仅支持 |
|
|
|
矩阵 |
|
|
|
一个维度为 如果 如果 如果 |
|
|
|
全局数组A中的行索引,表示 |
|
|
|
全局数组A中表示 |
|
|
|
分布式矩阵A的矩阵描述符。 |
|
|
|
一个维度为 |
|
|
|
向量W的数据类型。 |
|
|
|
用于计算的数据类型。 |
|
|
|
一个维度为 |
|
|
|
|
|
|
|
如果 如果 如果 |
返回状态
CUSOLVER_STATUS_SUCCESS-
操作成功完成。
CUSOLVER_STATUS_INVALID_VALUE-
传递了无效参数(
N<0,或lda,或jobz不是CUSOLVER_EIG_MODE_NOVECTOR或CUSOLVER_EIG_MODE_VECTOR,或uplo不是CUBLAS_FILL_MODE_LOWER,或IA和JA不为1,或N大于全局A的维度,或dataType与computeType的组合无效)。 CUSOLVER_STATUS_INTERNAL_ERROR-
内部操作失败。
4. 致谢
NVIDIA 谨此感谢以下个人和机构所作出的贡献:
来自netlib的CPU LAPACK例程,CLAPACK-3.2.1 (http://www.netlib.org/clapack/)
以下是CLAPACK-3.2.1的许可证。
版权所有 (c) 1992-2008 田纳西大学。保留所有权利。
在满足以下条件的前提下,允许以源代码和二进制形式进行再分发和使用,无论是否经过修改:
源代码的再分发必须保留上述版权声明、本条件列表以及以下免责声明。
以二进制形式重新分发时,必须在随分发提供的文档和/或其他材料中复制上述版权声明、本条件列表以及本许可证中列出的以下免责声明。
未经事先书面许可,不得使用版权持有者的名称或其贡献者的名称来认可或推广基于此软件衍生的产品。
本软件按"原样"提供,版权持有人和贡献者不承担任何明示或默示的担保责任,包括但不限于对适销性和特定用途适用性的默示担保。在任何情况下,无论基于何种法律理论(无论是合同责任、严格责任还是侵权责任,包括疏忽或其他原因),版权所有者或贡献者均不对因使用本软件而导致的任何直接、间接、附带、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购成本、使用损失、数据丢失或利润损失,或业务中断)承担责任,即使已被告知可能发生此类损害。
METIS-5.1.0 (http://glaros.dtc.umn.edu/gkhome/metis/metis/overview)
以下是METIS的许可证(Apache 2.0许可证)。
版权所有 1995-2013,明尼苏达大学董事会
根据Apache许可证2.0版("许可证")授权;除非符合许可证要求,否则不得使用此文件。您可以在以下网址获取许可证副本:
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,依据许可证分发的软件均按"原样"提供,不附带任何明示或暗示的担保或条件。有关许可证下管理权限和限制的具体条款,请参阅许可证内容。
QD (一个C++/Fortran-90的双双精度和四双精度计算包) (http://crd-legacy.lbl.gov/~dhbailey/mpdist/)
以下是QD的许可证(修改后的BSD许可证)。
版权所有 (c) 2003-2009,加利福尼亚大学董事会,经由劳伦斯伯克利国家实验室(需获得美国能源部任何必要批准)保留所有权利。
允许以源代码和二进制形式进行再分发和使用,无论是否修改,只要满足以下条件:
源代码的再分发必须保留版权声明、本条件列表以及以下免责声明。
以二进制形式重新分发时,必须在随附的文档和/或其他材料中复制版权声明、本条件列表以及以下免责声明。
未经事先书面许可,不得使用加州大学、劳伦斯伯克利国家实验室或美国能源部的名称,或其贡献者的名称,来认可或推广由本软件衍生的产品。
本软件按"原样"提供,版权持有人和贡献者不承担任何明示或默示的担保责任,包括但不限于对适销性和特定用途适用性的默示担保。在任何情况下,无论基于何种法律理论(无论是合同责任、严格责任还是侵权责任,包括疏忽或其他原因),版权所有者或贡献者均不对因使用本软件而导致的任何直接、间接、附带、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购成本、使用损失、数据丢失或利润损失、业务中断)承担责任,即使已被告知可能发生此类损害。
您没有任何义务必须向任何人提供源代码功能、性能方面的错误修复、补丁或升级(统称"增强功能");但如果您选择公开或直接向劳伦斯伯克利国家实验室提供您的增强功能,且未对这些增强功能另行施加书面许可协议,则您特此授予以下许可:非排他性、免版税的永久许可,允许以二进制和源代码形式安装、使用、修改、准备衍生作品、整合到其他计算机软件中、分发及再许可此类增强功能或其衍生作品。
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公司的商标或注册商标。其他公司及产品名称可能是其各自关联公司的商标。