Холецкий со Скалапаком

Я пытаюсь сделать разложение Холецкого через pdpotrf () библиотеки MKL-Intel, которая использует ScaLAPACK. Я читаю всю матрицу в главном узле, а затем распространяю ее, как в этом пример. Все работает нормально, когда размер матрицы SPD четный. Однако, когда это странно, pdpotrf() считает, что матрица не является положительно определенной.

Может быть потому, что подматрицы не SPD? Я работаю с этой матрицей: введите описание изображения здесь

и подматрицы (с 4 процессами и блоками размером 2×2):

A_loc on node 0
4   1   2
1 0.5   0
2   0  16

nrows = 3, ncols = 2
A_loc on node 1
2 0.5
0   0
0   0

nrows = 2, ncols = 3
A_loc on node 2
2   0   0
0.5   0   0

nrows = 2, ncols = 2
A_loc on node 3
3   0
0 0.625

Здесь каждая подматрица не является 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 имел недопустимый
значение F параметра 605 имело недопустимое значение

Параметр PDPOTRF номер 605 имел недопустимую информацию о значении < 0: если
i-й аргумент — это массив, а j-запись имеет недопустимое значение, тогда
INFO = — (i * 100 + j), если i-й аргумент является скаляром и имеет недопустимый
значение, то INFO = -i. информация = -605

От моего ответ, Вы можете видеть, что означают аргументы функции.


Код основан на этом вопрос. Выход:

gsamaras@pythagoras:~/konstantis/check_examples$ ../../mpich-install/bin/mpic++ -o test minor.cpp -I../../intel/mkl/include ../../intel/mkl/lib/intel64/libmkl_scalapack_lp64.a       -Wl,--start-group       ../../intel/mkl/lib/intel64/libmkl_intel_lp64.a ../../intel/mkl/lib/intel64/libmkl_core.a  ../../intel/mkl/lib/intel64/libmkl_sequential.a    -Wl,--end-group ../../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_lp64.a -lpthread       -lm     -ldl
gsamaras@pythagoras:~/konstantis/check_examples$ mpiexec -n 4 ./test
Processes grid pattern:
0 1
2 3
nrows = 3, ncols = 3
A_loc on node 0
4   1   2
1 0.5   0
2   0  16

nrows = 3, ncols = 2
A_loc on node 1
2 0.5
0   0
0   0

nrows = 2, ncols = 3
A_loc on node 2
2   0   0
0.5   0   0

nrows = 2, ncols = 2
A_loc on node 3
3   0
0 0.625

Description init sucesss!
matrix is not positive definte
Matrix A result:
2   1   2 0.5   2
0.5 0.5   0   0   0
1   0   1   0 -0.25
0.25  -1 -0.5 0.625   0
1  -1  -2 -0.5  14

2

Решение

Проблема может исходить от:

MPI_Bcast(&lda, 1, MPI_INT, 0, MPI_COMM_WORLD);

До этой строки, lda отличается в каждом процессе, если размер матрицы нечетен. Два процесса обрабатывают 2 строки, а два процесса обрабатывают 3 строки. Но после MPI_Bcast(), lda везде одинаково (3).

Проблема в том, что аргумент lda подпрограммы DESCINIT должен быть ведущим измерением локального массива, то есть 2 или 3.

Комментируя MPI_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

Наконец, это объясняет, что программа хорошо работает для четных измерений и не работает для нечетных измерений!

2

Другие решения


По вопросам рекламы [email protected]