Я пытаюсь сделать разложение Холецкого через 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
Проблема может исходить от:
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
Наконец, это объясняет, что программа хорошо работает для четных измерений и не работает для нечетных измерений!