Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.

pardiso_getdiag problem

Oleg_S_
Beginner
739 Views

Hello everyone!

I am using pardiso to solve nonsymmetric system, but i don't get result that i expect. Today i tried pardiso_getdiag to understand what is going on with diagonal after factorization and i noticed that pardiso thinks that i have zero elements on diagonal which is not true. And if size of the matrix rises i get more zeros. Matrix_checkers returns MKL_SPARSE_CHECKER_SUCCESS. How can i solve this problem? I attached my matrix in csr format. Indexing starts from zero.

Thank you.

0 Kudos
6 Replies
mecej4
Honored Contributor III
739 Views

Your matrix is fine, and I was able to obtain a solution of A x = b with b = 1 (all elements). I used the pardiso_unsym_f.f example code from the MKL distribution, modified to read your data files.

Perhaps if you post your code one could spot problems with the Pardiso calls and arguments.

0 Kudos
Oleg_S_
Beginner
739 Views

Thanks for quick response. Here is my code:

	*msglvl = 0;		//	Не выводить полезную информацию
	*mtype = 11;		//	Не симметричная реальная матрица
	for (int i = 0; i < 64; i++)
	{
		iparm = 0;
	}
	iparm[0] = 1;         /* No solver default */
	iparm[1] = 0;         /* Fill-in reordering from METIS */
	iparm[2] = 2;
	iparm[3] = 0;         /* No iterative-direct algorithm */
	iparm[4] = 0;         /* No user fill-in reducing permutation */
	iparm[5] = 0;         /* Write solution into x */
	iparm[6] = 0;         /* Not in use */
	iparm[7] = 0;         /* Max numbers of iterative refinement steps */
	iparm[8] = 0;         /* Not in use */
	iparm[9] = 13;        /* Perturb the pivot elements with 1E-13 */
	iparm[10] = 0;        /* Use nonsymmetric permutation and scaling MPS */
	iparm[11] = 0;        /* Conjugate transposed/transpose solve */
	iparm[12] = 1;        /* Maximum weighted matching algorithm is switched-on (default for non-symmetric) */
	iparm[13] = 0;        /* Output: Number of perturbed pivots */
	iparm[14] = 0;        /* Not in use */
	iparm[15] = 0;        /* Not in use */
	iparm[16] = 0;        /* Not in use */
	iparm[17] = -1;       /* Output: Number of nonzeros in the factor LU */
	iparm[18] = -1;       /* Output: Mflops for LU factorization */
	iparm[19] = 0;        /* Output: Numbers of CG Iterations */
	iparm[26] = 1;
	iparm[34] = 1;
	iparm[55] = 1;

	MKL_INT nrhs = 1;     /* Number of right hand sides. */
	MKL_INT maxfct, mnum, phase, error;
	/* Auxiliary variables. */


	double ddum;          /* Double dummy */
	MKL_INT idum;         /* Integer dummy. */


	maxfct = 1;           /* Maximum number of numerical factorizations. */
	mnum = 1;         /* Which factorization to use. */
	//	msglvl = 1;           /* Print statistical information in file */
	error = 0;            /* Initialize error flag */
	/* -------------------------------------------------------------------- */
	/* .. Initialize the internal solver memory pointer. This is only */
	/* necessary for the FIRST call of the PARDISO solver. */
	/* -------------------------------------------------------------------- */
	for (int i = 0; i < 64; i++)
	{
		pt = 0;
	}

	

	sparse_checker_error_values check_err_val;
	sparse_struct pt1;


	sparse_matrix_checker_init(&pt1);
	pt1.n = n;
	pt1.csr_ia = ia;
	pt1.csr_ja = ja;
	pt1.indexing = MKL_ZERO_BASED;
	pt1.matrix_structure = MKL_GENERAL_STRUCTURE;
	pt1.print_style = MKL_C_STYLE;
	pt1.message_level = MKL_PRINT;

	check_err_val = sparse_matrix_checker(&pt1);

	printf("Matrix check details: (%d, %d, %d)\n", pt1.check_result[0], pt1.check_result[1], pt1.check_result[2]);

	if (check_err_val == MKL_SPARSE_CHECKER_NONTRIANGULAR) {
		printf("Matrix check result: MKL_SPARSE_CHECKER_NONTRIANGULAR\n");
		error = 0;
	}
	else {
		if (check_err_val == MKL_SPARSE_CHECKER_SUCCESS) { printf("Matrix check result: MKL_SPARSE_CHECKER_SUCCESS\n"); }
		if (check_err_val == MKL_SPARSE_CHECKER_NON_MONOTONIC) { printf("Matrix check result: MKL_SPARSE_CHECKER_NON_MONOTONIC\n"); }
		if (check_err_val == MKL_SPARSE_CHECKER_OUT_OF_RANGE) { printf("Matrix check result: MKL_SPARSE_CHECKER_OUT_OF_RANGE\n"); }
		if (check_err_val == MKL_SPARSE_CHECKER_NONORDERED) { printf("Matrix check result: MKL_SPARSE_CHECKER_NONORDERED\n"); }
		error = 1;
	}

	
	phase = 11;
	PARDISO(pt, &maxfct, &mnum, &mtype, &phase,
		&n, a, ia, ja, &idum, &nrhs, iparm, &msglvl, &ddum, &ddum, &error);

	if (error != 0)
	{
		printf("\nERROR during symbolic factorization: %d", error);
		exit(1);
	}
	printf("\nReordering completed ... ");
	printf("\nNumber of nonzeros in factors = %d", iparm[17]);
	printf("\nNumber of factorization MFLOPS = %d", iparm[18]); fflush(0);
	/* -------------------------------------------------------------------- */
	/* .. Numerical factorization. */
	/* -------------------------------------------------------------------- */

	phase = 22;
	PARDISO(pt, &maxfct, &mnum, &mtype, &phase,
		&n, a, ia, ja, &idum, &nrhs, iparm, &msglvl, &ddum, &ddum, &error);
	if (error != 0)
	{
		system("pause");
		printf("\nERROR during numerical factorization: %d", error);
		exit(2);
	}
	
	double *df = NULL;
	double *da = NULL;
	MKL_INT er_d = 0;

	df = (double*)mkl_malloc(n * sizeof(double), 64);

	da = (double*)mkl_malloc(n * sizeof(double), 64);



	pardiso_getdiag(pt, df, da, &mnum, &er_d);
	printf("\nFirst\n");
	for (int i = 0; i < n; i++)
	{
		printf("d_fact[%d]= %lf d_a=%lf \n", i, df, da);
	}

	phase = 33;
	PARDISO(pt, &maxfct, &mnum, &mtype, &phase,
		&n, a, ia, ja, &idum, &nrhs, iparm, &msglvl, b, X, &error);
	if (error != 0)
	{
			printf("\nERROR during solution: %d", error);
			exit(3);
	}
	phase = -1;           /* Release internal memory. */
	PARDISO(pt, &maxfct, &mnum, &mtype, &phase,
		&n, &ddum, ia, ja, &idum, &nrhs,
		iparm, &msglvl, &ddum, &ddum, &error);

 

After pardiso_getdiag i see this: d_fact[41]= 4.269444 d_a=4.625000 d_fact[42]= 4.269444 d_a=4.625000 d_fact[43]= 37.925772 d_a=-0.000000 d_fact[44]= 37.924292 d_a=-0.000000 d_fact[45]= 8.519367 d_a=-0.000000 d_fact[46]= 4.189655 d_a=-0.000000 d_fact[47]= 2.036909 d_a=-0.000000 d_fact[48]= 0.412003 d_a=-0.000000 d_fact[49]= 0.402489 d_a=-0.000000

I also attached my b vector. Maybe it would help.

0 Kudos
mecej4
Honored Contributor III
739 Views

Since you posted only a part of the code, it is difficult to comment. Similarly, when you simply say "i don't get result that i expect" we are not told what you expect.

When you report problems with code, it is usually necessary for you to give details of MKL and compiler version, OS, CPU model, etc.

0 Kudos
Oleg_S_
Beginner
739 Views

I'm running visual studio on win 7. I have MKL 2017 Update 2. I have intel compiler 2017.1.143. My cpu model is i7-3615QM

0 Kudos
Oleg_S_
Beginner
739 Views

Can someone tell why pardiso_getdiag thinks that i have zeros on a diagonal?

0 Kudos
mecej4
Honored Contributor III
739 Views

I had not used pardiso_getdiag() before you brought it to my attention. The MKL document page contains the following contradictory statements:

da: Array with a dimension of n. Contains diagonal elements of the initial matrix

and

Elements of da correspond to diagonal elements of matrix L computed during phase 22

It cannot be both (initial matrix A and L factor). So, MKL group, which is it? If the latter, how is da different from df ?

Oleg: The solution of your equation set given by the dense Lapack solver DGESV agrees with the solution given by MKL-Pardiso, as well as Pardiso-5 from www.pardiso-project.org . If you maintain that the results are incorrect you should  provide supporting arguments. Until I learn more about pardiso_getdiag() I would not not depend entirely on it to decide whether a solution is correct or not.

0 Kudos
Reply