예제 #1
0
MKL_INT PardisoSolver::FactorMatrix(const SparseMatrix * A)
{
  if (directIterative)
    return 0;

  mkl_set_num_threads(numThreads);

  // compute the factorization
  if (verbose >= 1)
    printf("Factoring the %d x %d matrix (%d threads)...\n", n, n, numThreads);

  int upperTriangleOnly = 1;
  int oneIndexed = 1;

  if ((mtype == REAL_SPD) || (mtype == REAL_SYM_INDEFINITE))  // matrix is symmetric
    upperTriangleOnly = 1;    // symmetric matrix can only be represented by its upper triangle elements
  else  // structural symmetric or unsymmetric
    upperTriangleOnly = 0;    // unsymmetric matrix must store all its elements
  A->GenerateCompressedRowMajorFormat(a, NULL, NULL, upperTriangleOnly, oneIndexed);

  // factor 
  phase = 22;
  PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL,  &error);

  if (error != 0)
    printf("Error: Pardiso Cholesky decomposition returned non-zero exit code %d.\n", error);

  if (verbose >= 1)
    printf("Factorization completed.\n");

  return error;
}
예제 #2
0
MKL_INT PardisoSolver::SolveLinearSystemDirectIterative(const SparseMatrix * A, double * x, const double * rhs)
{
  if (directIterative != 1)
  {
    printf("Error: direct-iterative flag was not specified in the constructor.\n");
    return 102;
  }

  mkl_set_num_threads(numThreads); 

  if (verbose >= 2)
    printf("Solving linear system...(%d threads, direct-iterative)\n", numThreads);

  int upperTriangleOnly = 1;
  int oneIndexed = 1;
  A->GenerateCompressedRowMajorFormat(a, NULL, NULL, upperTriangleOnly, oneIndexed);

  phase = 23;
  PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)rhs, x, &error);

  if (error != 0)
    printf("Error: Pardiso solve returned non-zero exit code %d.\n", error);

  if (verbose >= 2)
    printf("Solve completed.\n"); 

  return error;
}
예제 #3
0
MKL_INT PardisoSolver::BackwardSubstitution(double * x, const double * y)
{
  if (directIterative != 0)
  {
    printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n");
    return 101;
  }

  mkl_set_num_threads(numThreads); 

  if (verbose >= 2)
    printf("Performing forward substitution...(%d threads)\n", numThreads);

  int maxIterRefinementSteps = iparm[7];
  iparm[7] = 0;

  phase = 333;
  PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)y, x, &error);

  iparm[7] = maxIterRefinementSteps;

  if (error != 0)
    printf("Error: Pardiso solve returned non-zero exit code %d.\n", error);

  if (verbose >= 2)
    printf("Solve completed.\n"); 

  return error;
}
예제 #4
0
MKL_INT PardisoSolver::ComputeCholeskyDecomposition(const SparseMatrix * A)
{
  if (directIterative)
    return 0;

  // compute the factorization
  if (verbose >= 1)
    printf("Factoring the %d x %d matrix (%d threads)...\n",n,n, numThreads);

  int upperTriangleOnly = 1;
  int oneIndexed = 1;
  A->GenerateCompressedRowMajorFormat(a, NULL, NULL, upperTriangleOnly, oneIndexed);

  // factor 
  phase = 22;
  PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL,  &error);

  if (error != 0)
    printf("Error: Pardiso Cholesky decomposition returned non-zero exit code %d.\n", error);

  if (verbose >= 1)
    printf("Factorization completed.\n");

  return error;
}
예제 #5
0
MKL_INT PardisoSolver::DiagonalSubstitution(double * v, const double * y)
{
  if (directIterative != 0)
  {
    printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n");
    return 101;
  }

  if (positiveDefinite == 1)
  {
    printf("Error: diagonal substitution should not be used for positive-definite matrices.\n");
    return 102;
  }

  if (verbose >= 2)
    printf("Performing forward substitution...(%d threads, using previously computed LU)\n", numThreads);

  int maxIterRefinementSteps = iparm[7];
  iparm[7] = 0;

  phase = 332;
  PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)y, v, &error);

  iparm[7] = maxIterRefinementSteps;

  if (error != 0)
    printf("Error: Pardiso solve returned non-zero exit code %d.\n", error);

  if (verbose >= 2)
    printf("Solve completed.\n"); 

  return error;
}
예제 #6
0
PardisoSolver::~PardisoSolver()
{
  phase = -1;
  PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL, &error);

  if (error != 0)
    printf("Error: Pardiso Cholesky dealloacation returned non-zero exit code %d.\n", error);

  free(a);
  free(ia);
  free(ja);
}
예제 #7
0
int PardisoSolver::SolveLinearSystem(double * x, const double * rhs)
{
  if (directIterative != 0)
  {
    printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n");
    return 101;
  }

  if (verbose >= 2)
    printf("Solving linear system...(%d threads, using previously computed LU)\n", numThreads);

  phase = 33;
  PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)rhs, x, &error);

  if (error != 0)
    printf("Error: Pardiso solve returned non-zero exit code %d.\n", error);

  if (verbose >= 2)
    printf("Solve completed.\n"); 

  return (int)error;
}
예제 #8
0
MKL_INT PardisoSolver::SolveLinearSystemMultipleRHS(double * x, const double * rhs, int numRHS)
{
  if (directIterative != 0)
  {
    printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n");
    return 101;
  }

  if (verbose >= 2)
    printf("Solving linear system...(%d threads)\n", numThreads);

  mkl_set_num_threads(numThreads); 

  phase = 33;
  PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &numRHS, iparm, &msglvl, (double*)rhs, x, &error);

  if (error != 0)
    printf("Error: Pardiso solve returned non-zero exit code %d.\n", error);

  if (verbose >= 2)
    printf("Solve completed.\n");

  return error;
}
예제 #9
0
	int LinearSparseSolver( static_sparse_CSR_Matrix<double, std::int32_t, M_PROP::SYM>& A,
							Matrix<double, M_PROP::GE, M_SHAPE::RE, M_ORD::COL>& B,
							Matrix<double, M_PROP::GE, M_SHAPE::RE, M_ORD::COL>& X,
							std::ostream& log,
							int threads)
{

		typedef MML3_INT_TYPE  int_t;
		
		int len=100;
		char buf[100];
		//MKLGetVersionString(buf, len);
		 mkl_get_version_string(buf, len);

		log	<< "Solutore lineare per matrici sparse basato su:\n"
			<< "\tMKL-PARDISO: " << std::string(buf,len);
		
		

		log << "\nCaratteristiche del sistema:"
			<< "\n\t    N   =" << A.nrows()
			<< "\n\t    NNZ =" << A.nonzeros()
			<< "\n\t    NRHS=" << B.ncols() << std::endl;
			
	// pardiso parameters
	MML3::Vector<int_t>	pardiso_pt(64);
	pardiso_pt=0;
	int_t				pardiso_maxfct = 1;	// una sola matrice da fattorizzare
	int_t				pardiso_mnum = 1;	// la matrice numero 1
	int_t				pardiso_mtype = 2;	// matrici simmetriche definite positive
	int_t				pardiso_phase = 0;
	int_t				pardiso_n = A.nrows();
	double*				pardiso_a=A.column_value();
	int_t*				pardiso_ia = A.row_pos();
	int_t*				pardiso_ja = A.column_index();
	MML3::Vector<int_t>	pardiso_perm(pardiso_n);
	int_t				pardiso_nrhs = 0;
	MML3::Vector<int_t>	pardiso_iparam(64); 
	pardiso_iparam = 0;
	int_t				pardiso_msglvl = 0;	// 1=messaggi a run time, 0=no messaggi
	double*				pardiso_b=0;
	double*				pardiso_x=0;
	int_t				pardiso_error=0;



	
	pardiso_iparam(1)  = 1; /* No solver default*/
	pardiso_iparam(2)  = 2; /* Fill-in reordering from METIS, 1 for AMD */
	pardiso_iparam(3)  = threads; /* Numbers of thread processors */
	pardiso_iparam(4)  = 0; /* No iterative-direct algorithm */
	pardiso_iparam(5)  = 0; /* No user fill-in reducing permutation */
	pardiso_iparam(6)  = 0; /* Write solution into x */
	pardiso_iparam(7)  = 16; /* Default logical fortran unit number for output */
	pardiso_iparam(8)  = 0; /* Max numbers of iterative refinement steps */
	pardiso_iparam(9)  = 0; /* Not in use*/
	pardiso_iparam(10) = 13; /* Perturb the pivot elements with 1E-13 */
	pardiso_iparam(11) = 0; /* Use nonsymmetric permutation and scaling MPS */
	pardiso_iparam(12) = 0; /* Not in use*/
	pardiso_iparam(13) = 0; /* Not in use*/
	pardiso_iparam(14) = 0; /* Output: Number of perturbed pivots */
	pardiso_iparam(15) = 0; /* Not in use*/
	pardiso_iparam(16) = 0; /* Not in use*/
	pardiso_iparam(17) = 0; /* Not in use*/
	pardiso_iparam(18) = -1; /* Output: Number of nonzeros in the factor LU */
	pardiso_iparam(19) = -1; /* Output: Mflops for LU factorization */
	pardiso_iparam(20) = 0;  /* Output: Numbers of CG Iterations */




	
	// --------------------------------------------------------------------
	// Reordering and Symbolic Factorization. This step also allocates 
	// all memory that is necessary for the factorization. 
	// --------------------------------------------------------------------
	pardiso_phase = 11;
	PARDISO(	pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, 
				&pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, 
				pardiso_iparam.begin(), &pardiso_msglvl, 0, 0, &pardiso_error);

	if (pardiso_error != 0) 
	{
		log << "riordino e fattorizzazione simbolica falliti, codice: " << pardiso_error << "\n";
		return -1;
	}
	log <<	"\tRiordino e fattorizzazione simbolica completata" 
		<<	"\n\t\tFactor NNZ=" <<  pardiso_iparam(18) 
		<<	"\n\t\tMFLOPS    ="	<<  pardiso_iparam(19);


	// --------------------------------------------------------------------
	// Numerical factorization.
	// --------------------------------------------------------------------
	pardiso_phase = 22;
	PARDISO(	pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, 
				&pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, 
				pardiso_iparam.begin(), &pardiso_msglvl, 0, 0, &pardiso_error);

	if (pardiso_error != 0) 
	{
		log << " fattorizzazione numerica fallita, codice pardiso=" << pardiso_error << "\n";
		return -1;
	}
		

	// --------------------------------------------------------------------*/
	//  Back substitution and iterative refinement. */
	// --------------------------------------------------------------------*/
	pardiso_phase = 33;
	pardiso_nrhs=B.nrows();
	pardiso_iparam(6)  = 0;  // Write solution into x. Attenzione, anche se lo pongo ad 1 in modo che la soluzione sovrascriva F, X viene comunque usato
	
	
	PARDISO(	pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, 
				&pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, 
				pardiso_iparam.begin(), &pardiso_msglvl, B.begin(), X.begin(), &pardiso_error);

	if (pardiso_error != 0) 
	{
		log << "Errore nella fase  di sostituzione all'indietro e rifinitura iteritava, codice: " << pardiso_error << "\n";
		return -1;
	}
	

	// --------------------------------------------------------------------
	// Termination and release of memory. 
	// --------------------------------------------------------------------
	pardiso_phase = -1; /* Release internal memory. */
	PARDISO(	pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, 
				&pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, 
				pardiso_iparam.begin(), &pardiso_msglvl, 0, 0, &pardiso_error);


	return 1;
		
}
예제 #10
0
int main (int argc, char **argv) 
{
    /* Matrix data. */

   CRS_MATRIX *M1, *M2;
   double *b1, *x1, *b2, *x2, *r;
   int n;
   int nvals;

   FILE *fp;

   if (argc == 1) {
     fp = stdin;
   }
   else if (argc == 2) {
     fp = fopen (*argv, "r");
   }
   else {
     fprintf (stderr, "Usage: pardisoTestExample [<fileName>]\n");
     exit (1);
   }

   M1 = readCRSMatrix (fp, /*symmetric=*/1);
   n = M1->nrows;
   b1 = readVector (fp, n);
   x1 = (double*)malloc(n*sizeof(double));
   r = (double*)malloc(n*sizeof(double));

   // ja -> M1->colIdxs;
   // a -> M1->vals;
   // ia -> M1->rowOffs

   int      mtype = -2;        /* Real symmetric matrix */
   int      nrhs = 1;          /* Number of right hand sides. */

   /* Internal solver memory pointer pt,                  */
   /* 32-bit: int pt[64]; 64-bit: long int pt[64]         */
   /* or void *pt[64] should be OK on both architectures  */ 
   void    *pt[64]; 

   /* Pardiso control parameters. */
   int      iparm[64];
   int      maxfct, mnum, phase, error, msglvl;

   /* Number of processors. */
   int      num_procs;

   /* Auxiliary variables. */
   char    *var;
   int      i;

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

   double t0, t1;
   
/* -------------------------------------------------------------------- */
/* ..  Setup Pardiso control parameters.                                */
/* -------------------------------------------------------------------- */

   error = 0;
   //solver = 0; /* use sparse direct solver */
   // do we need this, or will init take care of it?
   for (i=0; i<64; i++) {
     pt[i] = (void*)0;
   }
   for (i=0; i<64; i++) {
     iparm[i] = 0;
   }
   iparm[0] = 1; /* Don't use solver default values */
   iparm[1] = 3; /* Fill-in reordering from OpenMP METIS */
   /* Numbers of processors; if 0, defaults to max number or MKL_NUM_THREADS */
   iparm[2] = 0;
   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] = 1; /* Use nonsymmetric permutation and scaling MPS */
   iparm[11] = 0; /* Not in use */
   iparm[12] = 0; /* Maximum weighted matching algorithm is switched-off (default for symmetric). Try iparm[12] = 1 in case of inappropriate accuracy */
   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[20] = 1; /* use 1x1 and 2x2 pivoting

   //F77_FUNC(pardisoinit) (pt,  &mtype, &solver, iparm, &error); 

   if (error != 0) 
    {
      if (error == -10 )
	 printf("No license file found \n");
      if (error == -11 )
	 printf("License is expired \n");
      if (error == -12 )
	 printf("Wrong username or hostname \n");
      return 1; 
    }
   else
    { printf("PARDISO license check was successful ... \n");
    }

   /* Numbers of processors, value of OMP_NUM_THREADS */
   var = getenv("OMP_NUM_THREADS");
   if(var != NULL)
      sscanf( var, "%d", &num_procs );
   else {
     printf("Set environment OMP_NUM_THREADS to 1");
     exit(1);
   }
   iparm[2]  = num_procs;
   
   // other special settings
   iparm[1] = 3; // 2 for metis, 0 for AMD
   iparm[9] = 12;
   iparm[10] = 1;
   iparm[12] = 1; // setting this to 2 can cause errors sometimes
   
   maxfct = 1;		/* Maximum number of numerical factorizations.  */
   mnum   = 1;         /* Which factorization to use. */
    
   msglvl = 0;         /* Print statistical information  */
   error  = 0;         /* Initialize error flag */

/* -------------------------------------------------------------------- */
/* ..  Reordering and Symbolic Factorization.  This step also allocates */
/*     all memory that is necessary for the factorization.              */
/* -------------------------------------------------------------------- */
   phase = 11; 

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, &ddum, &ddum, &error);
   t1 = currentTimeUsec();
    
   if (error != 0) {
     printf("ERROR during symbolic factorization: %d\n", error);
     exit(1);
   }
   printf("Analyze: msec=%8.1f\n", (t1-t0)/1000.0);
   printf("Number of nonzeros in factors  = %d\n", iparm[17]);
   printf("Number of factorization MFLOPS = %d\n", iparm[18]);
   
/* -------------------------------------------------------------------- */
/* ..  Numerical factorization.                                         */
/* -------------------------------------------------------------------- */    
   phase = 22;

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, &ddum, &ddum, &error);
   t1 = currentTimeUsec();   

   if (error != 0) {
     printf("ERROR during numerical factorization: %d\n", error);
     exit(2);
   }
   printf("Factor:  msec=%8.1f\n", (t1-t0)/1000.0);

/* -------------------------------------------------------------------- */    
/* ..  Back substitution and iterative refinement.                      */
/* -------------------------------------------------------------------- */    
   phase = 33;

   iparm[7] = 1;       /* Max numbers of iterative refinement steps. */

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, b1, x1, &error);
   t1 = currentTimeUsec();   
   if (error != 0) {
     printf("ERROR during solution: %d\n", error);
     exit(3);
   }

   mulVector (r, M1, x1);
   subVector (r, r, b1, n);
   printf("Solve:   msec=%8.1f\n\n", (t1-t0)/1000.0);
   /* for (i=0; i<n; i++) { */
   /*   printf ("%g ", x1[i]); */
   /* } */
   /* printf ("\n"); */
   printf("residual=%g\n", normVector(r, n));

#if 0
   M2 = readCRSMatrix (fp, /*symmetric=*/1);
   n = M2->nrows;
   b2 = readVector (fp, n);
   x2 = (double*)malloc(n*sizeof(double));

   setVector (x2, x1, n);

   iparm[7] = 1;       /* Max numbers of iterative refinement steps. */
   iparm[3] = 102;

   printf ("maxfct=%d\n", maxfct);
   printf ("mnum=%d\n", mnum);
   printf ("mtype=%d\n", mtype);
   printf ("phase=%d\n", phase);
   printf ("idum=%d\n", idum);
   for (i=0; i<64; i++) {
     printf ("%d ", iparm[i]);
   }
   printf ("\n");

   t0 = currentTimeUsec();
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, M2->vals, M2->rowOffs, M2->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, b2, x2, &error);
   t1 = currentTimeUsec();   
   if (error != 0) {
     printf("ERROR during solution: %d\n", error);
     exit(3);
   }
   printf ("num iterations=%d\n", iparm[19]);

   for (i=0; i<n; i++) {
     printf ("%g ", x2[i]);
   }
   printf ("\n");
   printf("Solve:   msec=%8.1f\n\n", (t1-t0)/1000.0);

   mulVector (r, M2, x2);
   subVector (r, r, b2, n);
   printf("residual=%g\n", normVector(r, n));
#endif

/* -------------------------------------------------------------------- */    
/* ..  Termination and release of memory.                               */
/* -------------------------------------------------------------------- */    
   phase = -1;                 /* Release internal memory. */
    
   PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
		      &n, &ddum, M1->rowOffs, M1->colIdxs, &idum, &nrhs,
		      iparm, &msglvl, &ddum, &ddum, &error);

   return 0;
} 
예제 #11
0
PardisoSolver::PardisoSolver(const SparseMatrix * A, int numThreads_, matrixType mtype_, reorderingType rtype_, int directIterative_, int verbose_): numThreads(numThreads_), mtype(mtype_), rtype(rtype_), directIterative(directIterative_), verbose(verbose_)
{
  mkl_set_num_threads(numThreads);

  n = A->Getn();

  if (verbose >= 1)
    printf("Converting matrix to Pardiso format...\n");

  int numEntries;
  int upperTriangleOnly;  
  if ((mtype == REAL_SPD) || (mtype == REAL_SYM_INDEFINITE))  // matrix is symmetric
  {
    numEntries = A->GetNumUpperTriangleEntries();
    upperTriangleOnly = 1;
  }
  else  
  {
    // structural symmetric or unsymmetric
    numEntries = A->GetNumEntries();
    upperTriangleOnly = 0;
  }
  a = (double*) malloc (sizeof(double) * numEntries);  
  ia = (int*) malloc (sizeof(int) * (A->GetNumRows() + 1));  
  ja = (int*) malloc (sizeof(int) * numEntries);  
  int oneIndexed = 1;
  A->GenerateCompressedRowMajorFormat(a, ia, ja, upperTriangleOnly, oneIndexed);

  if (verbose >= 2)
    printf("numEntries: %d\n", numEntries);

  // permute & do symbolic factorization

  nrhs = 1; // Number of right hand sides.
  maxfct = 1; // Maximum number of numerical factorizations.
  mnum = 1; // Which factorization to use.
  msglvl = verbose >= 1 ? verbose - 1 : 0; // Print statistical information to the output file
  error = 0; // Initialize error flag

  for (int i = 0; i < 64; i++) 
    iparm[i] = 0;

  iparm[0] = 1; // Do not use the solver default values (use custom values, provided below)
  iparm[1] = rtype; // matrix re-ordering algorithm
  iparm[2] = 0; // unused 

  // use iterative-direct algorithm if requested
  if (directIterative)
  {
    if (mtype == REAL_SPD)  
      iparm[3] = 62; // matrix is symmetric positive-definite; use CGS iteration for symmetric positive-definite matrices
    else
      iparm[3] = 61; // use CGS iteration
  }
  else
    iparm[3] = 0; 

  iparm[4] = 0; // No user fill-in reducing permutation
  iparm[5] = 0; // Write solution into x
  iparm[6] = 0; // Output: number of iterative refinement steps performed
  iparm[7] = 0; // Max numbers of iterative refinement steps (used during the solving stage). Value of 0 (default) means: The solver automatically performs two steps of iterative refinement when perturbed pivots are obtained during the numerical factorization.
  iparm[8] = 0; // Reserved. Must set to 0.

  // Pivoting perturbation; the values below are Pardiso's default values
  // Pivoting only applies to REAL_UNSYM and REAL_SYM_INDEFINITE
  if (mtype == REAL_UNSYM)
    iparm[9] = 13; // For non-symmetric matrices, perturb the pivot elements with 1E-13
  else 
    iparm[9] = 8; // Use 1.0E-8 for symmetric indefinite matrices
  
  // Scaling and matching. The following below are the Pardiso defaults.
  if (mtype == REAL_UNSYM)  // unsymmetric matrices
  {
    iparm[10] = 1; // enable scaling
    iparm[12] = 1; // enable matching
  }
  else
  {
    iparm[10] = 0; // disable scaling
    iparm[12] = 0; // disable matching
  }

  iparm[11] = 0; // Solve with transposed or conjugate transposed matrix A. Not in use here.

  iparm[13] = 0; // Output: Number of perturbed pivots
  iparm[14] = 0; // Output: Peak memory on symbolic factorization (in KB)
  iparm[15] = 0; // Output: Permanent memory on symbolic factorization (in KB)
  iparm[16] = 0; // Output: Size of factors/Peak memory on numerical factorization and solution (in KB)
  
  iparm[17] = -1; // Output: Report the number of non-zero elements in the factors.
  iparm[18] = 0; // Report number of floating point operations (in 10^6 floating point operations) that are necessary to factor the matrix A. Disabled.
  iparm[19] = 0; // Output: Report CG/CGS diagnostics.
  iparm[20] = 1; // Pivoting for symmetric indefinite matrices: Apply 1x1 and 2x2 Bunch-Kaufman pivoting during the factorization process.
  iparm[21] = 0; // Output: Inertia: number of positive eigenvalues.
  iparm[22] = 0; // Output: Inertia: number of negative eigenvalues.

  iparm[23] = 0; // Parallel factorization control. Use default.
  iparm[24] = 0; // Parallel forward/backward solve control. Intel MKL PARDISO uses a parallel algorithm for the solve step.

  // the other iparms (above 24) are left at 0

  /* -------------------------------------------------------------------- *\
     .. 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[i] = 0;

  if (verbose >= 1)
    printf("Reordering and symbolically factorizing the matrix...\n");

  /* -------------------------------------------------------------------- *\
     .. Reordering and Symbolic Factorization. This step also allocates 
     all memory that is necessary for the factorization.
  \* -------------------------------------------------------------------- */
  phase = 11;
  PARDISO (pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase,
    &n, a, ia, ja, NULL, &nrhs,
    iparm, &msglvl, NULL, NULL, &error);

  if (error != 0)
  {
    printf("Error: Pardiso matrix re-ordering/symbolic factorization returned non-zero exit code %d.\n", error);
    throw error;
  }

  if (verbose >= 2)
  {
    printf("\nReordering and symbolic factorization completed...\n");
    printf("Number of nonzeros in factors = %d\n", iparm[17]);
    printf("Number of factorization MFLOPS = %d\n", iparm[18]);
  }
}
예제 #12
0
PardisoSolver::PardisoSolver(const SparseMatrix * A, int numThreads_, int positiveDefinite_, int directIterative_, int verbose_) : numThreads(numThreads_), positiveDefinite(positiveDefinite_), directIterative(directIterative_), verbose(verbose_)
{
  mkl_set_num_threads(numThreads);

  n = A->Getn();

  if (verbose >= 1)
    printf("Converting matrix to Pardiso format...\n");

  int numUpperTriangleEntries = A->GetNumUpperTriangleEntries();

  a = (double*) malloc (sizeof(double) * numUpperTriangleEntries);  
  ia = (int*) malloc (sizeof(int) * (A->GetNumRows() + 1));  
  ja = (int*) malloc (sizeof(int) * numUpperTriangleEntries);  

  int upperTriangleOnly = 1;
  int oneIndexed = 1;
  A->GenerateCompressedRowMajorFormat(a, ia, ja, upperTriangleOnly, oneIndexed);

  if (verbose >= 2)
    printf("numUpperTriEntries: %d\n", numUpperTriangleEntries);

  // permute & do symbolic factorization

  mtype = positiveDefinite ? 2 : -2;
  nrhs = 1; /* Number of right hand sides. */
  maxfct = 1; /* Maximum number of numerical factorizations. */
  mnum = 1; /* Which factorization to use. */
  msglvl = verbose >= 1 ? verbose-1 : 0; /* Print statistical information in file */
  error = 0; /* Initialize error flag */

  for (int i = 0; i < 64; i++) 
    iparm[i] = 0;
  iparm[0] = 1; // No solver default
  iparm[1] = 2; // 0=minimum degree ordering, 2=Fill-in reordering from METIS
  iparm[2] = numThreads; // Numbers of processors, value of OMP_NUM_THREADS
  iparm[3] = directIterative ? 62 : 0; //62; // 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] = 2; // Max numbers of iterative refinement steps
  iparm[8] = 0; // Not in use
  iparm[9] = 8; //13; // Perturb the pivot elements with 1E-13
  iparm[10] = 0; //1; // Use nonsymmetric permutation and scaling MPS
  iparm[11] = 0; // Not in use
  iparm[12] = 0; // matchings for highly indefinite symmetric matrices
  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] = 0; // no Output: Mflops for LU factorization
  iparm[19] = 0; // Output: Numbers of CG Iterations
  iparm[20] = 1; // pivoting method

/*
  iparm[0] = 0;
  iparm[2] = numThreads;
*/

  /* -------------------------------------------------------------------- */
  /* .. 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[i] = 0;

  if (verbose >= 1)
    printf("Reordering matrix...\n");

  /* -------------------------------------------------------------------- */
  /* .. Reordering and Symbolic Factorization. This step also allocates */
  /* all memory that is necessary for the factorization. */
  /* -------------------------------------------------------------------- */
  phase = 11;
  PARDISO (pt, &maxfct, &mnum, &mtype, &phase,
           &n, a, ia, ja, NULL, &nrhs,
          iparm, &msglvl, NULL, NULL, &error);

  if (error != 0)
  {
    printf("Error: Pardiso matrix re-ordering returned non-zero exit code %d.\n", error);
    throw error;
  }

  if (verbose >= 2)
  {
    printf("\nReordering completed ...\n");
    printf("Number of nonzeros in factors = %d\n", iparm[17]);
    printf("Number of factorization MFLOPS = %d\n", iparm[18]);
  }
}