C++ 带有ScaLAPACK的Cholesky

C++ 带有ScaLAPACK的Cholesky,c++,distributed-computing,blas,intel-mkl,scalapack,C++,Distributed Computing,Blas,Intel Mkl,Scalapack,我正在尝试通过MKL Intel的库进行Cholesky分解,该库使用ScaLAPACK。我在主节点中读取整个矩阵,然后像这样分发它。当SPD矩阵的尺寸为偶数时,一切正常。然而,当它是奇数时,pdpotrf()认为矩阵不是正定的 可能是因为子矩阵不是SPD吗?我正在使用此矩阵: 子矩阵为(4个进程和块大小为2x2): 在这里,每个子矩阵不是SPD,但是,整个矩阵是SPD(已通过运行1个进程进行检查)。我该怎么办?或者我无能为力,pdpotrf()无法处理奇数大小的矩阵 以下是我如何称呼例行程序

我正在尝试通过MKL Intel的库进行Cholesky分解,该库使用ScaLAPACK。我在主节点中读取整个矩阵,然后像这样分发它。当SPD矩阵的尺寸为偶数时,一切正常。然而,当它是奇数时,
pdpotrf()
认为矩阵不是正定的

可能是因为子矩阵不是SPD吗?我正在使用此矩阵:

子矩阵为(4个进程和块大小为2x2):

在这里,每个子矩阵不是SPD,但是,整个矩阵是SPD(已通过运行1个进程进行检查)。我该怎么办?或者我无能为力,
pdpotrf()
无法处理奇数大小的矩阵


以下是我如何称呼例行程序:

int iZERO = 0;
int descA[9];
// N, M dimensions of matrix. lda = N
// Nb, Mb dimensions of block
descinit_(descA, &N, &M, &Nb, &Mb, &iZERO, &iZERO, &ctxt, &lda, &info);
...
pdpotrf((char*)"L", &ord, A_loc, &IA, &JA, descA, &info);
我也试过:

// nrows/ncols is the number of rows/columns a submatrix has
descinit_(descA, &N, &M, &nrows, &ncols, &iZERO, &iZERO, &ctxt, &lda, &info);
但我有一个错误:

{0,0}:在{0,1}的条目上:在PDPOTR{1的条目上, 0}:在PDPOTRF参数编号605的条目上,有一个非法值{ 1,1}:在输入PDPOTRF参数编号605时,有一个非法的 参数编号605的值具有非法值

PDPOTRF参数编号605具有非法值info<0:如果 第i个参数是一个数组,并且j项有一个非法值,那么 INFO=-(i*100+j),如果第i个参数是标量且具有非法 值,然后INFO=-i。信息=-605

从我的示例中,您可以看到函数的参数的含义


代码基于此。输出:


问题可能来自:

MPI_Bcast(&lda, 1, MPI_INT, 0, MPI_COMM_WORLD);
在这一行之前,如果矩阵的维数为奇数,则每个进程的lda是不同的。两个进程处理2行,两个进程处理3行。但是在
MPI_Bcast()
之后,
lda
在任何地方都是相同的(3)

问题是子例程的参数
lda
必须是本地数组的前导维度,即2或3

通过评论MPI\u Bcast(),我得到了:

Description init sucesss!
SUCCESS
Matrix A result:
2   1   2 0.5   2 
0.5 0.5   0   0   0 
1  -1   1   0   0 
0.25 -0.25 -0.5 0.5   0 
1  -1  -2  -3   1 

最后,它将解释该程序在偶数维上运行良好,而在奇数维上运行失败

您可以尝试LAPACK版本(dpotrf)…这不是@Jeff发布的。我也用
dpotrf()
检查了这一点,它可以正常工作。然而,我只对分布式解决方案感兴趣。我知道这一点。重点是获得调试洞察力。看起来你已经做到了。你也可以试试Elemental,它有一个更友好的API,对Cholesky执行相同或更好的操作,并且支持的不仅仅是密集矩阵。哦,好的@Jeff,是的,我已经说过了,应该提到,抱歉,将进行编辑。我知道Elemental,项目负责人Jack Poulson非常友好、善良。然而,出于各种原因,我不得不使用ScaLAPACK。所以,现在我必须看看
pdpotrf()
发生了什么。你认为它不能处理奇数维吗?哦,我想到了全局矩阵,干得好。很好的顶部答案顺便说一句。Dacor:P还有这个链接:
MPI_Bcast(&lda, 1, MPI_INT, 0, MPI_COMM_WORLD);
Description init sucesss!
SUCCESS
Matrix A result:
2   1   2 0.5   2 
0.5 0.5   0   0   0 
1  -1   1   0   0 
0.25 -0.25 -0.5 0.5   0 
1  -1  -2  -3   1