调用magma_dpotrf_gpu与magma_dpotri_gpu实现Cholesky矩阵求逆出错
问题描述
- 已实现基于
magma_dgetrf_gpu、magma_dgetri_gpu的LU分解GPU矩阵求逆功能,运行正常 - 当前需适配对称正定矩阵场景,改用Cholesky分解实现求逆,将核心接口替换为
magma_dpotrf_gpu和magma_dpotri_gpu后,输出的逆矩阵结果错误 - 怀疑代码中
ldwork变量使用magma_get_dgetri_nb获取块大小的逻辑存在问题 - 已附上三类参考代码:自行编写的MAGMA Cholesky求逆完整代码、可正常运行的LAPACKE LU分解求逆代码、可正常运行的MAGMA LU分解求逆代码
- 实现参考了MAGMA官方文档第4.4.21节的
magma_dpotri接口说明,需排查magma_dpotrf_gpu和magma_dpotri_gpu的调用逻辑错误点,同时需要了解基于LAPACKE的dpotrf、dpotri实现对称矩阵求逆的正确方案
问题排查与解决方案
MAGMA Cholesky求逆调用错误点排查
- 块大小获取逻辑错误:
magma_get_dgetri_nb是LU求逆(dgetri)专属的块大小查询接口,Cholesky求逆必须调用magma_get_dpotri_nb获取适配的块大小,两者的最优块大小不通用,这是你当前场景下最可能的核心错误点 - uplo参数与矩阵存储不匹配:
magma_dpotrf_gpu仅处理对称矩阵的单侧三角区域,需要显式指定uplo参数为MagmaUpper(使用上三角)或MagmaLower(使用下三角),输入矩阵仅需填充对应三角区域的数值,若传入全矩阵、或uplo参数与实际填充的三角区域不匹配,会直接导致分解错误 - 显存空间与leading dimension配置错误:
magma_dpotri_gpu要求输入的分解后矩阵在显存上连续存储,leading dimension(lda)取值不能小于矩阵阶数n,dwork显存空间大小需要满足ldwork >= n * nb(nb为magma_get_dpotri_nb返回的块大小),空间不足会触发未定义行为 - 返回值校验缺失:每次调用
magma_dpotrf_gpu、magma_dpotri_gpu后都需要校验返回值:返回值为0表示调用正常;返回值小于0表示第|返回值|个参数非法;返回值大于0表示矩阵非正定,分解失败
LAPACKE对称正定矩阵Cholesky求逆正确实现方案
以下为列优先存储场景的标准实现流程:
- 调用
LAPACKE_dpotrf完成Cholesky分解:// 参数说明:存储布局、三角区域标识('L'为下三角/'U'为上三角)、矩阵阶数n、矩阵指针A、leading dimension lda lapack_int info = LAPACKE_dpotrf(LAPACK_COL_MAJOR, 'L', n, A, lda); // 需先判断info是否为0,非0则说明参数非法或矩阵非正定,终止后续流程 - 调用
LAPACKE_dpotri基于分解结果求逆:// 参数与dpotrf一致,调用完成后A中指定的三角区域会被替换为逆矩阵的对应三角部分 info = LAPACKE_dpotri(LAPACK_COL_MAJOR, 'L', n, A, lda); - 补全对称逆矩阵:dpotri仅返回逆矩阵的单侧三角区域,需要手动补全另一侧的数值:
// 下三角场景的补全逻辑,上三角场景交换i、j赋值顺序即可 for(int i = 0; i < n; i++){ for(int j = i + 1; j < n; j++){ A[j * lda + i] = A[i * lda + j]; } }
内容的提问来源于stack exchange,提问作者user1773603
相关产品推荐
相关产品推荐

