示例#1
0
void MUMPS_solver::get_factorization( Mat<double, Gen<>, SparseLine<> > &mat, bool want_free ) {
    if ( already_factorized ) return;
    else already_factorized = true;

    init_MPI();
    
    /// initialisation de MUMPS pour un seul processeur
    id.par = 1; /// le maître participe à la factorisation
    id.sym = 0; /// matrice générale
    id.comm_fortran = use_comm_word; /// communicator de MPI 
    id.job = job_init;
    dmumps_c( &id );
    id.ICNTL( 1 ) = -1; /*! No outputs */
    id.ICNTL( 2 ) = -1; /*! No outputs */
    id.ICNTL( 3 ) = -1; /*! No outputs */
    id.ICNTL( 4 ) = -1;  /*! No outputs */
    /*! Define the problem on the host */
    if ( myid == 0 ) {
        free();
        /// construction des données nécessaires à la factorisation (excepté a qui peut ne pas être nécessaire )
        load_matrix( mat );
    
        id.job = job_analyse;
        dmumps_c( &id );
        
        id.job = job_factorize;
        dmumps_c( &id );    
        
        if ( want_free )
            mat.free();
        
    }
}
示例#2
0
int MAIN__()
{
	int argc = 1;
	char * name = "c_example";
	char ** argv;
#else
int main(int argc, char ** argv)
{
#endif
	DMUMPS_STRUC_C id;
	MUMPS_INT n = 2;
	MUMPS_INT nz = 2;
	MUMPS_INT irn[] = { 1, 2 };
	MUMPS_INT jcn[] = { 1, 2 };
	double a[2];
	double rhs[2];

	MUMPS_INT myid, ierr;
#if defined(MAIN_COMP)
	argv = &name;
#endif
	ierr = MPI_Init(&argc, &argv);
	ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
	/* Define A and rhs */
	rhs[0] = 1.0; rhs[1] = 4.0;
	a[0] = 1.0; a[1] = 2.0;

	/* Initialize a MUMPS instance. Use MPI_COMM_WORLD */
	id.job = JOB_INIT; id.par = 1; id.sym = 0; id.comm_fortran = USE_COMM_WORLD;
	dmumps_c(&id);
	/* Define the problem on the host */
	if (myid == 0) {
		id.n = n; id.nz = nz; id.irn = irn; id.jcn = jcn;
		id.a = a; id.rhs = rhs;
	}
#define ICNTL(I) icntl[(I)-1] /* macro s.t. indices match documentation */
	/* No outputs */
	id.ICNTL(1) = -1; id.ICNTL(2) = -1; id.ICNTL(3) = -1; id.ICNTL(4) = 0;
	/* Call the MUMPS package. */
	id.job = 6;
	dmumps_c(&id);
	id.job = JOB_END; dmumps_c(&id); /* Terminate instance */
	if (myid == 0) {
		printf("Solution is : (%8.2f  %8.2f)\n", rhs[0], rhs[1]);
	}
	ierr = MPI_Finalize();
	getchar();
	return 0;
}
示例#3
0
//-------------------------------------------------------------------
// Default Constructor
//-------------------------------------------------------------------
ClpCholeskyMumps::ClpCholeskyMumps (int denseThreshold)
     : ClpCholeskyBase(denseThreshold)
{
     mumps_ = (DMUMPS_STRUC_C*)malloc(sizeof(DMUMPS_STRUC_C));
     type_ = 16;
     mumps_->n = 0;
     mumps_->nz = 0;
     mumps_->a = NULL;
     mumps_->jcn = NULL;
     mumps_->irn = NULL;
     mumps_->job = JOB_INIT;//initialize mumps
     mumps_->par = 1;//working host for sequential version
     mumps_->sym = 2;//general symmetric matrix
     mumps_->comm_fortran = USE_COMM_WORLD;
     int myid, ierr;
     int justName;
     ierr = MPI_Init(&justName, NULL);
     ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
     assert (!ierr);
     dmumps_c(mumps_);
#define ICNTL(I) icntl[(I)-1] /* macro s.t. indices match documentation */
#define CNTL(I) cntl[(I)-1] /* macro s.t. indices match documentation */
     mumps_->ICNTL(5) = 1; // say compressed format
     mumps_->ICNTL(4) = 2; // log messages
     mumps_->ICNTL(24) = 1; // Deal with zeros on diagonal
     mumps_->CNTL(3) = 1.0e-20; // drop if diagonal less than this
     // output off
     mumps_->ICNTL(1) = -1;
     mumps_->ICNTL(2) = -1;
     mumps_->ICNTL(3) = -1;
     mumps_->ICNTL(4) = 0;
}
示例#4
0
//=============================================================================
void Amesos_Mumps::Destroy()
{
  if (!NoDestroy_) 
  { 
    // destroy instance of the package
    MDS.job = -2;

    if (Comm().MyPID() < MaxProcs_) dmumps_c(&(MDS));
    
#if 0
    if (IsComputeSchurComplementOK_ && (Comm().MyPID() == 0)
	&& MDS.schur) {
      delete [] MDS.schur;
      MDS.schur = 0;
    }
#endif
    
#ifdef HAVE_MPI
    if (MUMPSComm_) 
    {
      MPI_Comm_free( &MUMPSComm_ );
      MUMPSComm_ = 0;
    }
#endif
    
    if( (verbose_ && PrintTiming_) || verbose_ == 2) PrintTiming();
    if( (verbose_ && PrintStatus_) || verbose_ == 2) PrintStatus();
  }
}
示例#5
0
bool Chordal::solveSchur(Vector& rhs)
{
  mumps_id.job = MUMPS_JOB_SOLVE;
  mumps_id.rhs = rhs.ele;
  dmumps_c(&mumps_id);
  return SDPA_SUCCESS;
}
示例#6
0
/* Uses factorization to solve. */
void
ClpCholeskyMumps::solve (double * region)
{
     mumps_->rhs = region;
     mumps_->job = 3; // solve
     dmumps_c(mumps_);
}
示例#7
0
//-------------------------------------------------------------------
// Destructor
//-------------------------------------------------------------------
ClpCholeskyMumps::~ClpCholeskyMumps ()
{
     mumps_->job = JOB_END;
     dmumps_c(mumps_); /* Terminate instance */
     MPI_Finalize();
     free(mumps_);
}
 ESymSolverStatus MumpsSolverInterface::Solve(Index nrhs, double *rhs_vals)
 {
   DBG_START_METH("MumpsSolverInterface::Solve", dbg_verbosity);
   DMUMPS_STRUC_C* mumps_data = (DMUMPS_STRUC_C*)mumps_ptr_;
   ESymSolverStatus retval = SYMSOLVER_SUCCESS;
   if (HaveIpData()) {
     IpData().TimingStats().LinearSystemBackSolve().Start();
   }
   for (Index i = 0; i < nrhs; i++) {
     Index offset = i * mumps_data->n;
     mumps_data->rhs = &(rhs_vals[offset]);
     mumps_data->job = 3;//solve
     Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                    "Calling MUMPS-3 for solve at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
     dmumps_c(mumps_data);
     Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                    "Done with MUMPS-3 for solve at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
     int error = mumps_data->info[0];
     if (error < 0) {
       Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                      "Error=%d returned from MUMPS in Solve.\n",
                      error);
       retval = SYMSOLVER_FATAL_ERROR;
     }
   }
   if (HaveIpData()) {
     IpData().TimingStats().LinearSystemBackSolve().End();
   }
   return retval;
 }
 MumpsSolverInterface::MumpsSolverInterface()
 {
   DBG_START_METH("MumpsSolverInterface::MumpsSolverInterface()",
                  dbg_verbosity);
   //initialize mumps
   DMUMPS_STRUC_C* mumps_ = new DMUMPS_STRUC_C;
   int argc=1;
   char ** argv = 0;
   int myid;
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &myid);
   mumps_->n = 0;
   mumps_->nz = 0;
   mumps_->a = NULL;
   mumps_->jcn = NULL;
   mumps_->irn = NULL;
   mumps_->job = -1;//initialize mumps
   mumps_->par = 1;//working host for sequential version
   mumps_->sym = 2;//general symetric matrix
   mumps_->comm_fortran = USE_COMM_WORLD;
   dmumps_c(mumps_);
   mumps_->icntl[1] = 0;
   mumps_->icntl[2] = 0;//QUIETLY!
   mumps_->icntl[3] = 0;
   mumps_ptr_ = (void*)mumps_;
 }
示例#10
0
bool Chordal::factorizeSchur(int m, int* diagonalIndex,
			     FILE* Display, FILE* fpOut)
{
  // I need to adjust Schur before factorization
  // to loose Numerical Error Condition
  double adjustSize = PLUS_ADJUST_DIAGONAL;
  for (int i=0; i<m; ++i) {
    sparse_bMat_ptr->sp_ele[diagonalIndex[i]] += adjustSize;
  }
  
  mumps_id.job = MUMPS_JOB_FACTORIZE;
  mumps_id.a   = sparse_bMat_ptr->sp_ele;
  dmumps_c(&mumps_id);
  bool isSuccess = SDPA_SUCCESS;
  while (mumps_id.infog[1-1] == -9) {
    #if 0
    rMessage("mumps icntl(14) = " << mumps_id.icntl[14-1]);
    rMessage("mumps icntl(23) = " << mumps_id.icntl[23-1]);
    #endif
    if (Display) {
      fprintf(Display,"MUMPS needs more memory space. Trying ANALYSIS phase once more\n");
    }
    if (fpOut) {
      fprintf(fpOut,  "MUMPS needs more memory space. Trying ANALYSIS phase once more\n");
    }
    mumps_id.icntl[14-1] += 20; // More 20% working memory space
    analysisAndcountLowerNonZero(m);
    mumps_id.job = MUMPS_JOB_FACTORIZE;
    dmumps_c(&mumps_id);
  }
   if (mumps_id.infog[1-1] < 0) {
    isSuccess = SDPA_FAILURE;
    if (mumps_id.infog[1-1] == -10) {
      rMessage("Cholesky failed by NUMERICAL ERROR");
      rMessage("There are some possibilities.");
      rMessage("1. SDPA terminates due to inaccuracy of numerical error");
      rMessage("2. The input problem may not have (any) interior-points");
      rMessage("3. Input matrices are linearly dependent");
    }
    else {
      rMessage("Cholesky failed with Error Code "
	       << mumps_id.infog[1-1]);
    }
  }
  return isSuccess;
}
示例#11
0
MUMPS_solver::~MUMPS_solver() {
    if ( MPI_is_initialized ) {
        id.job = job_end;
        dmumps_c( &id ); /** Terminate instance */
        ierr = MPI_Finalize();
        //std::cerr << "MPI_Finalize() = " << ierr << std::endl;
    }
}
示例#12
0
void Chordal::terminate()
{
  if (mumps_usage == true) {
    mumps_id.job = MUMPS_JOB_END;
    dmumps_c(&mumps_id);
    mumps_usage = false;
  }
  if (sparse_bMat_ptr) {
    sparse_bMat_ptr->terminate();
  }
  sparse_bMat_ptr = NULL;
}
  MumpsSolverInterface::~MumpsSolverInterface()
  {
    DBG_START_METH("MumpsSolverInterface::~MumpsSolverInterface()",
                   dbg_verbosity);

    DMUMPS_STRUC_C* mumps_ = (DMUMPS_STRUC_C*)mumps_ptr_;
    mumps_->job = -2; //terminate mumps
    dmumps_c(mumps_);
    MPI_Finalize();
    delete [] mumps_->a;
    delete mumps_;
  }
示例#14
0
void Chordal::initialize(SparseMatrix* sparse_bMat_ptr)
{
  // condition of sparse computation
  // m_threshold < mDim, 
  // b_threshold < nBlock, 
  // aggregate_threshold >= aggrigated sparsity ratio
  // extend_threshold    >= extended sparsity ratio
  m_threshold = 100;
  b_threshold = 5;
  aggregate_threshold = 0.70;
  extend_threshold = 0.80;
  
#if FORCE_SCHUR_DENSE // DENSE computation for debugging
  m_threshold = 10000000;
  b_threshold = 1000000; 
  aggregate_threshold = 0.0; 
  extend_threshold = 0.0; 
#endif
#if FORCE_SCHUR_SPARSE // SPARSE computation for debugging
  m_threshold = 0;
  b_threshold = 0; 
  aggregate_threshold = 2.0; 
  extend_threshold = 2.0; 
#endif
  // initialize by assuming Schur would be DENSE
  best = SELECT_DENSE;

  this->sparse_bMat_ptr = sparse_bMat_ptr;

  // initialize MUMPS
  mumps_id.job = MUMPS_JOB_INIT;
  mumps_id.comm_fortran = MUMPS_USE_COMM_WORLD;
  // rank 0 process participates factorizations
  mumps_id.par = 1;
  // Only symmetric positive definite matricies
  mumps_id.sym = 1;
  // No OUTPUTS
  mumps_id.icntl[1-1] = -1;
  mumps_id.icntl[2-1] = -1;
  mumps_id.icntl[3-1] = -1;
  mumps_id.icntl[4-1] =  0;

  // MUMPS selects ordering automatically
  mumps_id.icntl[7-1] =  SELECT_MUMPS_BEST;
  // for Minumum Degree Ordering
  // mumps_id.icntl[7-1] =  0;
  
  dmumps_c(&mumps_id);
  mumps_usage = true;

}
示例#15
0
int Amesos_Mumps::NumericFactorization()
{
  IsNumericFactorizationOK_ = false;
  
  if (IsSymbolicFactorizationOK_ == false)
    AMESOS_CHK_ERR(SymbolicFactorization());

  RedistrMatrix(true);
  AMESOS_CHK_ERR(ConvertToTriplet(true));

  if (Comm().NumProc() != 1) 
  {
    if (Comm().MyPID() < MaxProcs_) 
      MDS.a_loc = &Val[0];
  } 
  else 
    MDS.a = &Val[0];

  // Request numeric factorization 
  MDS.job = 2;
  // Perform numeric factorization
  ResetTimer();

  if (Comm().MyPID() < MaxProcs_) {
    dmumps_c(&(MDS));
  }

  NumFactTime_ = AddTime("Total numeric factorization time", NumFactTime_);
  
  int IntWrong = CheckError()?1:0 ; 
  int AnyWrong;
  Comm().SumAll( &IntWrong, &AnyWrong, 1 ) ; 
  bool Wrong = AnyWrong > 0 ; 


  if ( Wrong ) {
      AMESOS_CHK_ERR( NumericallySingularMatrixError ) ; 
  }

  IsNumericFactorizationOK_ = true;
  NumNumericFact_++;  
  return(0);
}
示例#16
0
double Chordal::analysisAndcountLowerNonZero(int m)
{
  mumps_id.job = MUMPS_JOB_ANALYSIS;
  mumps_id.n   = m;
  mumps_id.nz  = sparse_bMat_ptr->NonZeroCount;
  mumps_id.irn = sparse_bMat_ptr->row_index;
  mumps_id.jcn = sparse_bMat_ptr->column_index;
  mumps_id.a   = sparse_bMat_ptr->sp_ele;
  
  // sparse_bMat_ptr->display();
  // rMessage("m = " << m);
  // rMessage("NonZeroCount = " << sparse_bMat_ptr->NonZeroCount);
  
  // No OUTPUTS for analysis
  mumps_id.icntl[1-1] = -1;
  mumps_id.icntl[2-1] = -1;
  mumps_id.icntl[3-1] = -1;
  mumps_id.icntl[4-1] =  0;
  // strcpy(mumps_id.write_problem,"write_problem");
  dmumps_c(&mumps_id);
  double lower_nonzeros = (double)mumps_id.infog[20-1];
  // if lower_nonzeros  is greater than 1.0e+6,
  // the value infog[20-1] is lower_nonzeros*(-1)/(1.0e+6).
  // we need to adjust the value.
  if (lower_nonzeros < 0) {
    lower_nonzeros *= (-1.0e+6);
  }
  #if 0
  rMessage("lower_nonzeros = " << lower_nonzeros);
  rMessage("Schur density = " << lower_nonzeros/((m+1)*m/2)*100 << "%" );
  #endif

  if (mumps_id.infog[1-1] != 0) {
    rError("MUMPS ERROR " << mumps_id.infog[1-1]);
  }
  return lower_nonzeros;
}
示例#17
0
/* Orders rows and saves pointer to matrix.and model */
int
ClpCholeskyMumps::order(ClpInterior * model)
{
     numberRows_ = model->numberRows();
     if (doKKT_) {
          numberRows_ += numberRows_ + model->numberColumns();
          printf("finish coding MUMPS KKT!\n");
          abort();
     }
     rowsDropped_ = new char [numberRows_];
     memset(rowsDropped_, 0, numberRows_);
     numberRowsDropped_ = 0;
     model_ = model;
     rowCopy_ = model->clpMatrix()->reverseOrderedCopy();
     const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts();
     const int * columnLength = model_->clpMatrix()->getVectorLengths();
     const int * row = model_->clpMatrix()->getIndices();
     const CoinBigIndex * rowStart = rowCopy_->getVectorStarts();
     const int * rowLength = rowCopy_->getVectorLengths();
     const int * column = rowCopy_->getIndices();
     // We need two arrays for counts
     int * which = new int [numberRows_];
     int * used = new int[numberRows_+1];
     CoinZeroN(used, numberRows_);
     int iRow;
     sizeFactor_ = 0;
     for (iRow = 0; iRow < numberRows_; iRow++) {
          int number = 1;
          // make sure diagonal exists
          which[0] = iRow;
          used[iRow] = 1;
          if (!rowsDropped_[iRow]) {
               CoinBigIndex startRow = rowStart[iRow];
               CoinBigIndex endRow = rowStart[iRow] + rowLength[iRow];
               for (CoinBigIndex k = startRow; k < endRow; k++) {
                    int iColumn = column[k];
                    CoinBigIndex start = columnStart[iColumn];
                    CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn];
                    for (CoinBigIndex j = start; j < end; j++) {
                         int jRow = row[j];
                         if (jRow >= iRow && !rowsDropped_[jRow]) {
                              if (!used[jRow]) {
                                   used[jRow] = 1;
                                   which[number++] = jRow;
                              }
                         }
                    }
               }
               sizeFactor_ += number;
               int j;
               for (j = 0; j < number; j++)
                    used[which[j]] = 0;
          }
     }
     delete [] which;
     // NOT COMPRESSED FOR NOW ??? - Space for starts
     mumps_->ICNTL(5) = 0; // say NOT compressed format
     try {
          choleskyStart_ = new CoinBigIndex[numberRows_+1+sizeFactor_];
     } catch (...) {
          // no memory
          return -1;
     }
     // Now we have size - create arrays and fill in
     try {
          choleskyRow_ = new int [sizeFactor_];
     } catch (...) {
          // no memory
          delete [] choleskyStart_;
          choleskyStart_ = NULL;
          return -1;
     }
     try {
          sparseFactor_ = new double[sizeFactor_];
     } catch (...) {
          // no memory
          delete [] choleskyRow_;
          choleskyRow_ = NULL;
          delete [] choleskyStart_;
          choleskyStart_ = NULL;
          return -1;
     }

     sizeFactor_ = 0;
     which = choleskyRow_;
     for (iRow = 0; iRow < numberRows_; iRow++) {
          int number = 1;
          // make sure diagonal exists
          which[0] = iRow;
          used[iRow] = 1;
          choleskyStart_[iRow] = sizeFactor_;
          if (!rowsDropped_[iRow]) {
               CoinBigIndex startRow = rowStart[iRow];
               CoinBigIndex endRow = rowStart[iRow] + rowLength[iRow];
               for (CoinBigIndex k = startRow; k < endRow; k++) {
                    int iColumn = column[k];
                    CoinBigIndex start = columnStart[iColumn];
                    CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn];
                    for (CoinBigIndex j = start; j < end; j++) {
                         int jRow = row[j];
                         if (jRow >= iRow && !rowsDropped_[jRow]) {
                              if (!used[jRow]) {
                                   used[jRow] = 1;
                                   which[number++] = jRow;
                              }
                         }
                    }
               }
               sizeFactor_ += number;
               int j;
               for (j = 0; j < number; j++)
                    used[which[j]] = 0;
               // Sort
               std::sort(which, which + number);
               // move which on
               which += number;
          }
     }
     choleskyStart_[numberRows_] = sizeFactor_;
     delete [] used;
     permuteInverse_ = new int [numberRows_];
     permute_ = new int[numberRows_];
     // To Fortran and fake
     for (iRow = 0; iRow < numberRows_ + 1; iRow++) {
          int k = choleskyStart_[iRow];
          int kEnd = choleskyStart_[iRow+1];
          k += numberRows_ + 1;
          kEnd += numberRows_ + 1;
          for (; k < kEnd; k++)
               choleskyStart_[k] = iRow + 1;
          choleskyStart_[iRow]++;
     }
     mumps_->nz = sizeFactor_;
     mumps_->irn = choleskyStart_ + numberRows_ + 1;
     mumps_->jcn = choleskyRow_;
     mumps_->a = NULL;
     for (CoinBigIndex i = 0; i < sizeFactor_; i++) {
          choleskyRow_[i]++;
#ifndef NDEBUG
          assert (mumps_->irn[i] >= 1 && mumps_->irn[i] <= numberRows_);
          assert (mumps_->jcn[i] >= 1 && mumps_->jcn[i] <= numberRows_);
#endif
     }
     // validate
     //mumps code here
     mumps_->n = numberRows_;
     mumps_->nelt = numberRows_;
     mumps_->eltptr = choleskyStart_;
     mumps_->eltvar = choleskyRow_;
     mumps_->a_elt = NULL;
     mumps_->rhs = NULL;
     mumps_->job = 1; // order
     dmumps_c(mumps_);
     mumps_->a = sparseFactor_;
     if (mumps_->infog[0]) {
          COIN_DETAIL_PRINT(printf("MUMPS ordering failed -error %d %d\n",
				   mumps_->infog[0], mumps_->infog[1]));
          return 1;
     } else {
          double size = mumps_->infog[19];
          if (size < 0)
               size *= -1000000;
          COIN_DETAIL_PRINT(printf("%g nonzeros, flop count %g\n", size, mumps_->rinfog[0]));
     }
     for (iRow = 0; iRow < numberRows_; iRow++) {
          permuteInverse_[iRow] = iRow;
          permute_[iRow] = iRow;
     }
     return 0;
}
  ESymSolverStatus MumpsSolverInterface::
  DetermineDependentRows(const Index* ia, const Index* ja,
                         std::list<Index>& c_deps)
  {
    DBG_START_METH("MumpsSolverInterface::DetermineDependentRows",
                   dbg_verbosity);
    DMUMPS_STRUC_C* mumps_data = (DMUMPS_STRUC_C*)mumps_ptr_;

    c_deps.clear();

    ESymSolverStatus retval;
    // Do the symbolic facotrization if it hasn't been done yet
    if (!have_symbolic_factorization_) {
      const Index mumps_permuting_scaling_orig = mumps_permuting_scaling_;
      const Index mumps_scaling_orig = mumps_scaling_;
      mumps_permuting_scaling_ = 0;
      mumps_scaling_ = 6;
      retval = SymbolicFactorization();
      mumps_permuting_scaling_ = mumps_permuting_scaling_orig;
      mumps_scaling_ = mumps_scaling_orig;
      if (retval != SYMSOLVER_SUCCESS ) {
        return retval;
      }
      have_symbolic_factorization_ = true;
    }
    // perform the factorization, in order to find dependent rows/columns

    //Set flags to ask MUMPS for checking linearly dependent rows
    mumps_data->icntl[23] = 1;
    mumps_data->cntl[2] = mumps_dep_tol_;
    mumps_data->job = 2;//numerical factorization

    dump_matrix(mumps_data);
    dmumps_c(mumps_data);
    int error = mumps_data->info[0];

    //Check for errors
    if (error == -8 || error == -9) {//not enough memory
      const Index trycount_max = 20;
      for (int trycount=0; trycount<trycount_max; trycount++) {
        Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA,
                       "MUMPS returned INFO(1) = %d and requires more memory, reallocating.  Attempt %d\n",
                       error,trycount+1);
        Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA,
                       "  Increasing icntl[13] from %d to ", mumps_data->icntl[13]);
        double mem_percent = mumps_data->icntl[13];
        mumps_data->icntl[13] = (Index)(2.0 * mem_percent);
        Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "%d.\n", mumps_data->icntl[13]);

        dump_matrix(mumps_data);
        dmumps_c(mumps_data);
        error = mumps_data->info[0];
        if (error != -8 && error != -9)
          break;
      }
      if (error == -8 || error == -9) {
        Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                       "MUMPS was not able to obtain enough memory.\n");
        // Reset flags
        mumps_data->icntl[23] = 0;
        return SYMSOLVER_FATAL_ERROR;
      }
    }

    // Reset flags
    mumps_data->icntl[23] = 0;

    if (error < 0) {//some other error
      Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                     "MUMPS returned INFO(1) =%d MUMPS failure.\n",
                     error);
      return SYMSOLVER_FATAL_ERROR;
    }

    const Index n_deps = mumps_data->infog[27];
    for (Index i=0; i<n_deps; i++) {
      c_deps.push_back(mumps_data->pivnul_list[i]-1);
    }

    return SYMSOLVER_SUCCESS;
  }
示例#19
0
DMUMPS_STRUC_C* NM_MUMPS_id(NumericsMatrix* A)
{
    NumericsSparseLinearSolverParams* params = NM_linearSolverParams(A);

    if (!params->solver_data)
    {
        params->solver_data = malloc(sizeof(DMUMPS_STRUC_C));

        DMUMPS_STRUC_C* mumps_id = (DMUMPS_STRUC_C*) params->solver_data;

        // Initialize a MUMPS instance. Use MPI_COMM_WORLD.
        mumps_id->job = JOB_INIT;
        mumps_id->par = 1;
        mumps_id->sym = 0;

        if (NM_MPI_com(A) == MPI_COMM_WORLD)
        {
            mumps_id->comm_fortran = USE_COMM_WORLD;
        }
        else
        {
            mumps_id->comm_fortran = MPI_Comm_c2f(NM_MPI_com(A));
        }

        dmumps_c(mumps_id);

        if (verbose == 1)
        {
            mumps_id->ICNTL(1) = -1; // Error messages, standard output stream.
            mumps_id->ICNTL(2) = -1; // Diagnostics,    standard output stream.
            mumps_id->ICNTL(3) = -1; // Global infos,   standard output stream.

            mumps_id->ICNTL(11) = 1; // Error analysis

        }
        else if (verbose == 2)
        {
            mumps_id->ICNTL(1) = -1; // Error messages, standard output stream.
            mumps_id->ICNTL(2) = -1; // Diagnostics,    standard output stream.
            mumps_id->ICNTL(3) = 6; // Global infos,   standard output stream.

//      mumps_id->ICNTL(4) = 4; // Errors, warnings and information on
            // input, output parameters printed.

//      mumps_id->ICNTL(10) = 1; // One step of iterative refinment
            mumps_id->ICNTL(11) = 1; // Error analysis
        }
        else if (verbose >= 3)
        {
            mumps_id->ICNTL(1) = 6; // Error messages, standard output stream.
            mumps_id->ICNTL(2) = 6; // Diagnostics,    standard output stream.
            mumps_id->ICNTL(3) = 6; // Global infos,   standard output stream.

//      mumps_id->ICNTL(4) = 4; // Errors, warnings and information on
            // input, output parameters printed.

//      mumps_id->ICNTL(10) = 1; // One step of iterative refinment
            mumps_id->ICNTL(11) = 1; // Error analysis
        }
        else
        {
            mumps_id->ICNTL(1) = -1;
            mumps_id->ICNTL(2) = -1;
            mumps_id->ICNTL(3) = -1;
        }

        mumps_id->ICNTL(24) = 1; // Null pivot row detection see also CNTL(3) & CNTL(5)
        // ok for a cube on a plane & four contact points
        // computeAlartCurnierSTD != generated in this case...

        //mumps_id->CNTL(3) = ...;
        //mumps_id->CNTL(5) = ...;

    }
    DMUMPS_STRUC_C* mumps_id = (DMUMPS_STRUC_C*) params->solver_data;
    mumps_id->n = (int) NM_triplet(A)->n;
    mumps_id->irn = NM_MUMPS_irn(A);
    mumps_id->jcn = NM_MUMPS_jcn(A);

    int nz;
    if (NM_sparse(A)->triplet)
    {
        nz = (int) NM_sparse(A)->triplet->nz;
        mumps_id->nz = nz;
        mumps_id->a = NM_sparse(A)->triplet->x;
    }
    else
    {
        nz = NM_linearSolverParams(A)->iWork[2 * NM_csc(A)->nzmax];
        mumps_id->nz = nz;
        mumps_id->a = NM_sparse(A)->csc->x;
    }




    return (DMUMPS_STRUC_C*) params->solver_data;
}
示例#20
0
int NM_gesv(NumericsMatrix* A, double *b)
{
    assert(A->size0 == A->size1);

    int info = 1;

    switch (A->storageType)
    {
    case NM_DENSE:
    {
        assert(A->matrix0);

        DGESV(A->size0, 1, A->matrix0, A->size0, NM_iWork(A, A->size0), b,
              A->size0, &info);
        break;
    }

    case NM_SPARSE_BLOCK: /* sparse block -> triplet -> csc */
    case NM_SPARSE:
    {
        switch (NM_linearSolverParams(A)->solver)
        {
        case NS_CS_LUSOL:
            info = !cs_lusol(1, NM_csc(A), b, DBL_EPSILON);
            break;

#ifdef WITH_MUMPS
        case NS_MUMPS:
        {
            /* the mumps instance is initialized (call with job=-1) */
            DMUMPS_STRUC_C* mumps_id = NM_MUMPS_id(A);

            mumps_id->rhs = b;
            mumps_id->job = 6;

            /* compute the solution */
            dmumps_c(mumps_id);

            /* clean the mumps instance */
            mumps_id->job = -2;
            dmumps_c(mumps_id);
            info = mumps_id->info[0];

            if (info > 0)
            {
                if (verbose > 0)
                {
                    printf("NM_gesv: MUMPS fails : info(1)=%d, info(2)=%d\n", info, mumps_id->info[1]);
                }
            }
            if (verbose > 1)
            {
                printf("MUMPS : condition number %g\n", mumps_id->rinfog[9]);
                printf("MUMPS : component wise scaled residual %g\n", mumps_id->rinfog[6]);
                printf("MUMPS : \n");
            }

            /* Here we free mumps_id ...  */
            free(NM_linearSolverParams(A)->solver_data);
            NM_linearSolverParams(A)->solver_data = NULL;

            break;
        }
#endif
        default:
        {
            fprintf(stderr, "NM_gesv: unknown sparse linearsolver : %d\n", NM_linearSolverParams(A)->solver);
            exit(EXIT_FAILURE);
        }
        }
        break;
    }

    default:
        assert (0 && "NM_gesv unknown storageType");
    }

    /* some time we cannot find a solution to a linear system, and its fine, for
     * instance with the minFBLSA. Therefore, we should not check here for
     * problems, but the calling function has to check the return code.*/
//  CHECK_RETURN(info);
    return info;
}
  ESymSolverStatus MumpsSolverInterface::Factorization(
    bool check_NegEVals, Index numberOfNegEVals)
  {
    DBG_START_METH("MumpsSolverInterface::Factorization", dbg_verbosity);
    DMUMPS_STRUC_C* mumps_data = (DMUMPS_STRUC_C*)mumps_ptr_;

    mumps_data->job = 2;//numerical factorization

    dump_matrix(mumps_data);
    Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                   "Calling MUMPS-2 for numerical factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
    dmumps_c(mumps_data);
    Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                   "Done with MUMPS-2 for numerical factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
    int error = mumps_data->info[0];

    //Check for errors
    if (error == -8 || error == -9) {//not enough memory
      const Index trycount_max = 20;
      for (int trycount=0; trycount<trycount_max; trycount++) {
        Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA,
                       "MUMPS returned INFO(1) = %d and requires more memory, reallocating.  Attempt %d\n",
                       error,trycount+1);
        Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA,
                       "  Increasing icntl[13] from %d to ", mumps_data->icntl[13]);
        double mem_percent = mumps_data->icntl[13];
        mumps_data->icntl[13] = (Index)(2.0 * mem_percent);
        Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "%d.\n", mumps_data->icntl[13]);

        dump_matrix(mumps_data);
        Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                       "Calling MUMPS-2 (repeated) for numerical factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
        dmumps_c(mumps_data);
        Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                       "Done with MUMPS-2 (repeated) for numerical factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
        error = mumps_data->info[0];
        if (error != -8 && error != -9)
          break;
      }
      if (error == -8 || error == -9) {
        Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                       "MUMPS was not able to obtain enough memory.\n");
        return SYMSOLVER_FATAL_ERROR;
      }
    }

    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "Number of doubles for MUMPS to hold factorization (INFO(9)) = %d\n",
                   mumps_data->info[8]);
    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "Number of integers for MUMPS to hold factorization (INFO(10)) = %d\n",
                   mumps_data->info[9]);

    if (error == -10) {//system is singular
      Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                     "MUMPS returned INFO(1) = %d matrix is singular.\n",error);
      return SYMSOLVER_SINGULAR;
    }

    negevals_ = mumps_data->infog[11];

    if (error == -13) {
      Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                     "MUMPS returned INFO(1) =%d - out of memory when trying to allocate %d %s.\nIn some cases it helps to decrease the value of the option \"mumps_mem_percent\".\n",
                     error, mumps_data->info[1] < 0 ? -mumps_data->info[1] : mumps_data->info[1], mumps_data->info[1] < 0 ? "MB" : "bytes");
      return SYMSOLVER_FATAL_ERROR;
    }
    if (error < 0) {//some other error
      Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                     "MUMPS returned INFO(1) =%d MUMPS failure.\n",
                     error);
      return SYMSOLVER_FATAL_ERROR;
    }

    if (check_NegEVals && (numberOfNegEVals!=negevals_)) {
      Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                     "In MumpsSolverInterface::Factorization: negevals_ = %d, but numberOfNegEVals = %d\n",
                     negevals_, numberOfNegEVals);
      return SYMSOLVER_WRONG_INERTIA;
    }

    return SYMSOLVER_SUCCESS;
  }
  ESymSolverStatus MumpsSolverInterface::SymbolicFactorization()
  {
    DBG_START_METH("MumpsSolverInterface::SymbolicFactorization",
                   dbg_verbosity);
    DMUMPS_STRUC_C* mumps_data = (DMUMPS_STRUC_C*)mumps_ptr_;

    if (HaveIpData()) {
      IpData().TimingStats().LinearSystemSymbolicFactorization().Start();
    }

    mumps_data->job = 1;//symbolic ordering pass

    //mumps_data->icntl[1] = 6;
    //mumps_data->icntl[2] = 6;//QUIETLY!
    //mumps_data->icntl[3] = 4;

    mumps_data->icntl[5] = mumps_permuting_scaling_;
    mumps_data->icntl[6] = mumps_pivot_order_;
    mumps_data->icntl[7] = mumps_scaling_;
    mumps_data->icntl[9] = 0;//no iterative refinement iterations


    mumps_data->icntl[12] = 1;//avoid lapack bug, ensures proper inertia
    mumps_data->icntl[13] = mem_percent_; //% memory to allocate over expected
    mumps_data->cntl[0] = pivtol_;  // Set pivot tolerance

    dump_matrix(mumps_data);

    Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                   "Calling MUMPS-1 for symbolic factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
    dmumps_c(mumps_data);
    Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
                   "Done with MUMPS-1 for symbolic factorization at cpu time %10.3f (wall %10.3f).\n", CpuTime(), WallclockTime());
    int error = mumps_data->info[0];
    const int& mumps_permuting_scaling_used = mumps_data->infog[22];
    const int& mumps_pivot_order_used = mumps_data->infog[6];
    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "MUMPS used permuting_scaling %d and pivot_order %d.\n",
                   mumps_permuting_scaling_used, mumps_pivot_order_used);
    Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                   "           scaling will be %d.\n",
                   mumps_data->icntl[7]);

    if (HaveIpData()) {
      IpData().TimingStats().LinearSystemSymbolicFactorization().End();
    }

    //return appropriat value
    if (error == -6) {//system is singular
      Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
                     "MUMPS returned INFO(1) = %d matrix is singular.\n",error);
      return SYMSOLVER_SINGULAR;
    }
    if (error < 0) {
      Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA,
                     "Error=%d returned from MUMPS in Factorization.\n",
                     error);
      return SYMSOLVER_FATAL_ERROR;
    }

    return SYMSOLVER_SUCCESS;
  }
示例#23
0
int MAIN__()
{
  int argc=1;
  char * name = "c_example";
  char ** argv ;
#else
int main(int argc, char ** argv)
{
#endif
  DMUMPS_STRUC_C id;

  int n = 6;
  int nz = 21;
  int irnL[] = {1,2,3,4,5,6,2,3,4,5,6,3,4,5,6,4,5,6,5,6,6};
  int jcnL[] = {1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,5,5,6};
  int irnS[] = {1,2,3,2,3,3};
  int jcnS[] = {1,1,1,2,2,3};

  int *irn = irnL;
  int *jcn = jcnL;

  double a[21];
  double rhs[6];

  int myid, ierr, numP;
#if defined(MAIN_COMP)
  argv = &name;
#endif
  ierr = MPI_Init(&argc, &argv);
  ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  ierr = MPI_Comm_size(MPI_COMM_WORLD, &numP);
  
  double nump = numP * 1.0;

  /* Define A and rhs */
  rhs[0]=2.0;rhs[1]=2.0;rhs[2]=2.0;rhs[3]=2.0;rhs[4]=2.0;rhs[5]=2.0;

  a[0]=4169.95/nump;
  a[1]=0.0;
  a[2]=10075.0/nump;
  a[3]=-4030;
  a[4]=0.0;
  a[5]=0.0;
  a[6]=10084.0/nump;
  a[7]=-1612.0/nump;
  a[8]=0.0;
  a[9]=-8.9556;
  a[10]=-1612;
  a[11]=1354080.0/nump;
  a[12]=0.0;
  a[13]=1612.0;
  a[14]=193440.0;
  a[15]=4169.93;
  a[16]=0.0;
  a[17]=10075;
  a[18]=10084;
  a[19]=1612;
  a[20]=1354000;

  if (myid != 0) {
      nz = 6;

      a[0]=4169.95/nump;
      a[1]=0.0;
      a[2]=10075.0/nump;

      a[3]=10084.0/nump;
      a[4]=-1612.0/nump;

      a[5]=1354080.0/nump;

      irn = irnS;
      jcn = jcnS;
  }

#define ICNTL(I) icntl[(I)-1] /* macro s.t. indices match documentation */

  /* Initialize a MUMPS instance. Use MPI_COMM_WORLD */
  id.job=JOB_INIT; id.par=1; id.sym=2; id.comm_fortran=USE_COMM_WORLD;

  /* parallel solver; distributed i/p matrix A */
  id.ICNTL(5)=0; id.ICNTL(18)=3;  
  dmumps_c(&id);

  /* Define the problem on the host */
  /*
  id.n = n; id.nz =nz; id.irn=irn; id.jcn=jcn;
  id.a = a; id.rhs = rhs;
  */

  /* parallel solver; distributed i/p matrix A */

  id.ICNTL(5)=0; id.ICNTL(18)=3;  

  id.n = n; id.nz_loc =nz; id.irn_loc=irn; id.jcn_loc=jcn;
  id.a_loc = a; id.rhs = rhs;

  /* No outputs */
  id.ICNTL(1)=-1; id.ICNTL(2)=-1; id.ICNTL(3)=-1; id.ICNTL(4)=0; 

  id.job=1;
  dmumps_c(&id);


  id.job=5;
  dmumps_c(&id);

  if (myid == 0) {
    printf("Solution is : (%8.6e %8.6e %8.6e %8.6e %8.6e %8.6e \n", rhs[0],rhs[1], rhs[2], rhs[3], rhs[4], rhs[5]);
  }

  rhs[0]=2.0;rhs[1]=2.0;rhs[2]=2.0;rhs[3]=1.0;rhs[4]=1.0;rhs[5]=1.0;


  id.job=3;
  dmumps_c(&id);

  /* Terminate instance */
  id.job=JOB_END; 
  dmumps_c(&id); 

  if (myid == 0) {
    printf("Solution is : (%8.6e %8.6e %8.6e %8.6e %8.6e %8.6e \n", rhs[0],rhs[1], rhs[2], rhs[3], rhs[4], rhs[5]);
  }

  ierr = MPI_Finalize();
  return 0;
}
 void operator() ( DMUMPS_STRUC_C& struc ) const {
   dmumps_c( &struc ) ;
 }
示例#25
0
文件: mumpsmex.c 项目: geocug/MUMPS
void mexFunction(int nlhs, mxArray *plhs[ ],
                 int nrhs, const mxArray *prhs[ ]) { 
  
  int i,j,pos;
  int *ptr_int;
  double *ptr_matlab;
#if MUMPS_ARITH == MUMPS_ARITH_z
  double *ptri_matlab;
#endif
  mwSize tmp_m,tmp_n;

  /* C pointer for input parameters */
  size_t inst_address;
  mwSize n,m,ne, netrue ;
  int job;
  mwIndex *irn_in,*jcn_in;
  
  /* variable for multiple and sparse rhs */
  int posrhs;
          mwSize  nbrhs,ldrhs, nz_rhs;
  mwIndex *irhs_ptr, *irhs_sparse;
  double *rhs_sparse;
#if MUMPS_ARITH == MUMPS_ARITH_z
  double *im_rhs_sparse;
#endif

  DMUMPS_STRUC_C *dmumps_par;
  int dosolve = 0;
  int donullspace = 0;
  int doanalysis = 0;
  int dofactorize = 0;
  
  
  EXTRACT_FROM_MATLAB_TOVAL(JOB,job);

  doanalysis = (job == 1 || job == 4 || job == 6);
  dofactorize = (job == 2 || job == 4 || job == 5 || job == 6);
  dosolve = (job == 3 || job == 5 || job == 6);

  if(job == -1){
    DMUMPS_alloc(&dmumps_par);
    EXTRACT_FROM_MATLAB_TOVAL(SYM,dmumps_par->sym);
    dmumps_par->job = -1;
    dmumps_par->par = 1;
    dmumps_c(dmumps_par);
    dmumps_par->nz = -1;
    dmumps_par->nz_alloc = -1;
  }else{
    EXTRACT_FROM_MATLAB_TOVAL(INST,inst_address);
    ptr_int = (int *) inst_address;

    dmumps_par = (DMUMPS_STRUC_C *) ptr_int;

    if(job == -2){
      dmumps_par->job = -2;
      dmumps_c(dmumps_par);
      /* If colsca/rowsca were freed by MUMPS,
         dmumps_par->colsca/rowsca are now null.
         Application of MYFREE in call below thus ok */
      DMUMPS_free(&dmumps_par);
    }else{

      /* check of input arguments */
      n = mxGetN(A_IN);
      m = mxGetM(A_IN);

      if (!mxIsSparse(A_IN) || n != m )
          mexErrMsgTxt("Input matrix must be a sparse square matrix");
      
      jcn_in = mxGetJc(A_IN);
      ne = jcn_in[n];
      irn_in = mxGetIr(A_IN);
      dmumps_par->n = (int)n;
      if(dmumps_par->n != n)
          mexErrMsgTxt("Input is too big; will not work...barfing out\n");
      
      if(dmumps_par->sym != 0)
          netrue = (n+ne)/2;
      else
          netrue = ne;
      
      if(dmumps_par->nz_alloc < netrue || dmumps_par->nz_alloc >= 2*netrue){  
        MYFREE(dmumps_par->jcn);
        MYFREE(dmumps_par->irn);
        MYFREE(dmumps_par->a);
        MYMALLOC((dmumps_par->jcn),(int)netrue,int);
        MYMALLOC((dmumps_par->irn),(int)netrue,int);
        MYMALLOC((dmumps_par->a),(int)netrue,double2);
        dmumps_par->nz_alloc = (int)netrue;
    if (dmumps_par->nz_alloc != netrue)
        mexErrMsgTxt("Input is too big; will not work...barfing out\n");
      }


      if(dmumps_par->sym == 0){
        /* if analysis already performed then we only need to read
           numerical values
           Note that we suppose that matlab did not change the internal
           format of the matrix between the 2 calls */
        if(doanalysis){ 
          /* || dmumps_par->info[22] == 0 */
          for(i=0;i<dmumps_par->n;i++){
            for(j=jcn_in[i];j<jcn_in[i+1];j++){
              (dmumps_par->jcn)[j] = i+1;
              (dmumps_par->irn)[j] = ((int)irn_in[j])+1;
            }
          }
        }
    dmumps_par->nz = (int)ne;
    if( dmumps_par->nz != ne)
        mexErrMsgTxt("Input is too big; will not work...barfing out\n");
#if MUMPS_ARITH == MUMPS_ARITH_z
        ptr_matlab = mxGetPr(A_IN);
        for(i=0;i<dmumps_par->nz;i++){                                                   
          ((dmumps_par->a)[i]).r = ptr_matlab[i];
        }
        ptr_matlab = mxGetPi(A_IN);
        if(ptr_matlab){
          for(i=0;i<dmumps_par->nz;i++){                                                   
            ((dmumps_par->a)[i]).i = ptr_matlab[i];
          }
        }else{
          for(i=0;i<dmumps_par->nz;i++){                                                   
             ((dmumps_par->a)[i]).i = 0.0;
             }
        }
#else
        ptr_matlab = mxGetPr(A_IN);
        for(i=0;i<dmumps_par->nz;i++){                                                   
          (dmumps_par->a)[i] = ptr_matlab[i];
        }
#endif
      }else{
        /* in the symmetric case we do not need to check doanalysis */
        pos = 0;
        ptr_matlab = mxGetPr(A_IN);
#if MUMPS_ARITH == MUMPS_ARITH_z
        ptri_matlab = mxGetPi(A_IN);
#endif
        for(i=0;i<dmumps_par->n;i++){
          for(j=jcn_in[i];j<jcn_in[i+1];j++){
            if(irn_in[j] >= i){
              if(pos >= netrue)
              mexErrMsgTxt("Input matrix must be symmetric");
              (dmumps_par->jcn)[pos] = i+1;
              (dmumps_par->irn)[pos] = (int)irn_in[j]+1;
#if MUMPS_ARITH == MUMPS_ARITH_z
              ((dmumps_par->a)[pos]).r = ptr_matlab[j];
              if(ptri_matlab){
                ((dmumps_par->a)[pos]).i = ptri_matlab[j];
              }else{
                ((dmumps_par->a)[pos]).i = 0.0;
              }
#else
              (dmumps_par->a)[pos] = ptr_matlab[j];
#endif
              pos++;
             }
          }
        }
        dmumps_par->nz = pos;
      }
    

      EXTRACT_FROM_MATLAB_TOVAL(JOB,dmumps_par->job);
      EXTRACT_FROM_MATLAB_TOARR(ICNTL_IN,dmumps_par->icntl,int,40);
      EXTRACT_FROM_MATLAB_TOARR(CNTL_IN,dmumps_par->cntl,double,15);
      EXTRACT_FROM_MATLAB_TOPTR(PERM_IN,(dmumps_par->perm_in),int,((int)n));

      /* colsca and rowsca are treated differently: it may happen that
         dmumps_par-> colsca is nonzero because it was set to a nonzero
         value on output (COLSCA_OUT) from MUMPS. Unfortunately if scaling
         was on output, one cannot currently provide scaling on input
         afterwards without reinitializing the instance */

      EXTRACT_SCALING_FROM_MATLAB_TOPTR(COLSCA_IN,(dmumps_par->colsca),(dmumps_par->colsca_from_mumps),((int)n)); /* type always double */
      EXTRACT_SCALING_FROM_MATLAB_TOPTR(ROWSCA_IN,(dmumps_par->rowsca),(dmumps_par->rowsca_from_mumps),((int)n)); /* type always double */

      EXTRACT_FROM_MATLAB_TOARR(KEEP_IN,dmumps_par->keep,int,500);
      EXTRACT_FROM_MATLAB_TOARR(DKEEP_IN,dmumps_par->dkeep,double,230);

      dmumps_par->size_schur = (int)mxGetN(VAR_SCHUR);
      EXTRACT_FROM_MATLAB_TOPTR(VAR_SCHUR,(dmumps_par->listvar_schur),int,dmumps_par->size_schur);
      if(!dmumps_par->listvar_schur) dmumps_par->size_schur = 0;

      ptr_matlab = mxGetPr (RHS_IN);

/*
 * To follow the "spirit" of the Matlab/Scilab interfaces, treat case of null
 * space separately. In that case, we initialize lrhs and nrhs, automatically
 * allocate the space needed, and do not rely on what is provided by the user
 * in component RHS, that is not touched.
 *
 * Note that, at the moment, the user should not call the solution step combined
 * with the factorization step when he/she sets icntl[25-1] to a non-zero value.
 * Hence we suppose in the following that infog[28-1] is available and that we
 * can use it.
 * 
 * For users of scilab/matlab, it would still be nice to be able to set ICNTL(25)=-1,
 * and use JOB=6. If we want to make such a feature available, we should
 * call separately job=2 and job=3 even if job=5 or 6 and set nbrhs (and allocate
 * space correctly) between job=2 and job=3 calls to MUMPS.
 *
 */
      if ( dmumps_par->icntl[25-1] == -1 && dmumps_par->infog[28-1] > 0 ) {
          dmumps_par->nrhs=dmumps_par->infog[28-1];
          donullspace = dosolve;
         }
      else if ( dmumps_par->icntl[25-1] > 0 && dmumps_par->icntl[25-1] <= dmumps_par->infog[28-1] ) {
           dmumps_par->nrhs=1;
           donullspace = dosolve;
         }
      else {
           donullspace=0;
         }
      if (donullspace) {
        nbrhs=dmumps_par->nrhs; ldrhs=n;
        dmumps_par->lrhs=(int)n;
        MYMALLOC((dmumps_par->rhs),((dmumps_par->n)*(dmumps_par->nrhs)),double2);
         }
      else if((!dosolve) || ptr_matlab[0] == -9999 ) { /* rhs not already provided, or not used */
/*     Case where dosolve is true and ptr_matlab[0]=-9999, this could cause problems:
 *        1/ RHS was not initialized while it should have been
 *        2/ RHS was explicitely initialized to -9999 but is not allocated of the right size
 */
        EXTRACT_CMPLX_FROM_MATLAB_TOPTR(RHS_IN,(dmumps_par->rhs),double,1);
      }else{
示例#26
0
//=============================================================================
int Amesos_Mumps::SymbolicFactorization()
{

  // erase data if present. 
  if (IsSymbolicFactorizationOK_ && MDS.job != -777)
   Destroy();

  IsSymbolicFactorizationOK_ = false;
  IsNumericFactorizationOK_ = false;

  CreateTimer(Comm());
  
  CheckParameters();
  AMESOS_CHK_ERR(ConvertToTriplet(false));

#if defined(HAVE_MPI) && defined(HAVE_AMESOS_MPI_C2F)
  if (MaxProcs_ != Comm().NumProc()) 
  {
    if(MUMPSComm_) 
      MPI_Comm_free(&MUMPSComm_);

    std::vector<int> ProcsInGroup(MaxProcs_);
    for (int i = 0 ; i < MaxProcs_ ; ++i) 
      ProcsInGroup[i] = i;

    MPI_Group OrigGroup, MumpsGroup;
    MPI_Comm_group(MPI_COMM_WORLD, &OrigGroup);
    MPI_Group_incl(OrigGroup, MaxProcs_, &ProcsInGroup[0], &MumpsGroup);
    MPI_Comm_create(MPI_COMM_WORLD, MumpsGroup, &MUMPSComm_);

#ifdef MUMPS_4_9
    MDS.comm_fortran = (MUMPS_INT) MPI_Comm_c2f( MUMPSComm_);
#else

#ifndef HAVE_AMESOS_OLD_MUMPS
    MDS.comm_fortran = (DMUMPS_INT) MPI_Comm_c2f( MUMPSComm_);
#else
    MDS.comm_fortran = (F_INT) MPI_Comm_c2f( MUMPSComm_);
#endif

#endif

  } 
  else 
  {
    const Epetra_MpiComm* MpiComm = dynamic_cast<const Epetra_MpiComm*>(&Comm());
    assert (MpiComm != 0);
#ifdef MUMPS_4_9
    MDS.comm_fortran = (MUMPS_INT) MPI_Comm_c2f(MpiComm->GetMpiComm());
#else

#ifndef HAVE_AMESOS_OLD_MUMPS
    MDS.comm_fortran = (DMUMPS_INT) MPI_Comm_c2f(MpiComm->GetMpiComm());
#else
    MDS.comm_fortran = (F_INT) MPI_Comm_c2f(MpiComm->GetMpiComm());
#endif

#endif
  }
#else
  // This next three lines of code were required to make Amesos_Mumps work
  // with Ifpack_SubdomainFilter. They is usefull in all cases
  // when using MUMPS on a subdomain.
  const Epetra_MpiComm* MpiComm = dynamic_cast<const Epetra_MpiComm*>(&Comm());
  assert (MpiComm != 0);
  MDS.comm_fortran = (MUMPS_INT) MPI_Comm_c2f(MpiComm->GetMpiComm());
  // only thing I can do, use MPI_COMM_WORLD. This will work in serial as well
  // Previously, the next line was uncommented, but we don't want MUMPS to work
  // on the global MPI comm, but on the comm associated with the matrix
  //  MDS.comm_fortran = -987654;
#endif
  
  MDS.job = -1  ;     //  Initialization
  MDS.par = 1 ;       //  Host IS involved in computations
//  MDS.sym = MatrixProperty_;
  MDS.sym =  0;       //  MatrixProperty_ is unititalized.  Furthermore MUMPS 
                      //  expects only half of the matrix to be provided for
                      //  symmetric matrices.  Hence setting MDS.sym to be non-zero
                      //  indicating that the matrix is symmetric will only work
                      //  if we change ConvertToTriplet to pass only half of the 
                      //  matrix.  Bug #2331 and Bug #2332 - low priority


  RedistrMatrix(true);

  if (Comm().MyPID() < MaxProcs_) 
  {
    dmumps_c(&(MDS));   //  Initialize MUMPS
    static_cast<void>( CheckError( ) );  
  }

  MDS.n = Matrix().NumGlobalRows();

  // fix pointers for nonzero pattern of A. Numerical values
  // will be entered in PerformNumericalFactorization()
  if (Comm().NumProc() != 1) 
  {
    MDS.nz_loc = RedistrMatrix().NumMyNonzeros();

    if (Comm().MyPID() < MaxProcs_) 
    {
      MDS.irn_loc = &Row[0]; 
      MDS.jcn_loc = &Col[0];
    }
  } 
  else 
  {
    if (Comm().MyPID() == 0) 
    {
      MDS.nz = Matrix().NumMyNonzeros();
      MDS.irn = &Row[0]; 
      MDS.jcn = &Col[0]; 
    }
  }

  // scaling if provided by the user
  if (RowSca_ != 0) 
  {
    MDS.rowsca = RowSca_;
    MDS.colsca = ColSca_;
  }

  // given ordering if provided by the user
  if (PermIn_ != 0) 
  {
    MDS.perm_in = PermIn_;
  }

  MDS.job = 1;     // Request symbolic factorization

  SetICNTLandCNTL();

  // Perform symbolic factorization

  ResetTimer();

  if (Comm().MyPID() < MaxProcs_) 
    dmumps_c(&(MDS));

  SymFactTime_ = AddTime("Total symbolic factorization time", SymFactTime_);

  int IntWrong = CheckError()?1:0 ; 
  int AnyWrong;
  Comm().SumAll( &IntWrong, &AnyWrong, 1 ) ; 
  bool Wrong = AnyWrong > 0 ; 


  if ( Wrong ) {
      AMESOS_CHK_ERR( StructurallySingularMatrixError ) ; 
  }

  IsSymbolicFactorizationOK_ = true ;
  NumSymbolicFact_++;  

  return 0;
}
示例#27
0
/* Factorize - filling in rowsDropped and returning number dropped */
int
ClpCholeskyMumps::factorize(const double * diagonal, int * rowsDropped)
{
     const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts();
     const int * columnLength = model_->clpMatrix()->getVectorLengths();
     const int * row = model_->clpMatrix()->getIndices();
     const double * element = model_->clpMatrix()->getElements();
     const CoinBigIndex * rowStart = rowCopy_->getVectorStarts();
     const int * rowLength = rowCopy_->getVectorLengths();
     const int * column = rowCopy_->getIndices();
     const double * elementByRow = rowCopy_->getElements();
     int numberColumns = model_->clpMatrix()->getNumCols();
     int iRow;
     double * work = new double[numberRows_];
     CoinZeroN(work, numberRows_);
     const double * diagonalSlack = diagonal + numberColumns;
     int newDropped = 0;
     double largest;
     //double smallest;
     //perturbation
     double perturbation = model_->diagonalPerturbation() * model_->diagonalNorm();
     perturbation = 0.0;
     perturbation = perturbation * perturbation;
     if (perturbation > 1.0) {
#ifdef COIN_DEVELOP
          //if (model_->model()->logLevel()&4)
          std::cout << "large perturbation " << perturbation << std::endl;
#endif
          perturbation = sqrt(perturbation);;
          perturbation = 1.0;
     }
     double delta2 = model_->delta(); // add delta*delta to diagonal
     delta2 *= delta2;
     for (iRow = 0; iRow < numberRows_; iRow++) {
          double * put = sparseFactor_ + choleskyStart_[iRow] - 1; // Fortran
          int * which = choleskyRow_ + choleskyStart_[iRow] - 1; // Fortran
          int number = choleskyStart_[iRow+1] - choleskyStart_[iRow];
          if (!rowLength[iRow])
               rowsDropped_[iRow] = 1;
          if (!rowsDropped_[iRow]) {
               CoinBigIndex startRow = rowStart[iRow];
               CoinBigIndex endRow = rowStart[iRow] + rowLength[iRow];
               work[iRow] = diagonalSlack[iRow] + delta2;
               for (CoinBigIndex k = startRow; k < endRow; k++) {
                    int iColumn = column[k];
                    if (!whichDense_ || !whichDense_[iColumn]) {
                         CoinBigIndex start = columnStart[iColumn];
                         CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn];
                         double multiplier = diagonal[iColumn] * elementByRow[k];
                         for (CoinBigIndex j = start; j < end; j++) {
                              int jRow = row[j];
                              if (jRow >= iRow && !rowsDropped_[jRow]) {
                                   double value = element[j] * multiplier;
                                   work[jRow] += value;
                              }
                         }
                    }
               }
               int j;
               for (j = 0; j < number; j++) {
                    int jRow = which[j] - 1; // to Fortran
                    put[j] = work[jRow];
                    work[jRow] = 0.0;
               }
          } else {
               // dropped
               int j;
               for (j = 1; j < number; j++) {
                    put[j] = 0.0;
               }
               put[0] = 1.0;
          }
     }
     //check sizes
     double largest2 = maximumAbsElement(sparseFactor_, sizeFactor_);
     largest2 *= 1.0e-20;
     largest = CoinMin(largest2, 1.0e-11);
     int numberDroppedBefore = 0;
     for (iRow = 0; iRow < numberRows_; iRow++) {
          int dropped = rowsDropped_[iRow];
          // Move to int array
          rowsDropped[iRow] = dropped;
          if (!dropped) {
               CoinBigIndex start = choleskyStart_[iRow] - 1; // to Fortran
               double diagonal = sparseFactor_[start];
               if (diagonal > largest2) {
                    sparseFactor_[start] = CoinMax(diagonal, 1.0e-10);
               } else {
                    sparseFactor_[start] = CoinMax(diagonal, 1.0e-10);
                    rowsDropped[iRow] = 2;
                    numberDroppedBefore++;
               }
          }
     }
     delete [] work;
     // code here
     mumps_->a_elt = sparseFactor_;
     mumps_->rhs = NULL;
     mumps_->job = 2; // factorize
     dmumps_c(mumps_);
     if (mumps_->infog[0]) {
          COIN_DETAIL_PRINT(printf("MUMPS factorization failed -error %d %d\n",
				   mumps_->infog[0], mumps_->infog[1]));
     }
     choleskyCondition_ = 1.0;
     bool cleanCholesky;
     if (model_->numberIterations() < 2000)
          cleanCholesky = true;
     else
          cleanCholesky = false;
     if (cleanCholesky) {
          //drop fresh makes some formADAT easier
          //int oldDropped=numberRowsDropped_;
          if (newDropped || numberRowsDropped_) {
               //std::cout <<"Rank "<<numberRows_-newDropped<<" ( "<<
               //  newDropped<<" dropped)";
               //if (newDropped>oldDropped)
               //std::cout<<" ( "<<newDropped-oldDropped<<" dropped this time)";
               //std::cout<<std::endl;
               newDropped = 0;
               for (int i = 0; i < numberRows_; i++) {
                    int dropped = rowsDropped[i];
                    rowsDropped_[i] = (char)dropped;
                    if (dropped == 2) {
                         //dropped this time
                         rowsDropped[newDropped++] = i;
                         rowsDropped_[i] = 0;
                    }
               }
               numberRowsDropped_ = newDropped;
               newDropped = -(2 + newDropped);
          }
     } else {
          if (newDropped) {
               newDropped = 0;
               for (int i = 0; i < numberRows_; i++) {
                    int dropped = rowsDropped[i];
                    rowsDropped_[i] = (char)dropped;
                    if (dropped == 2) {
                         //dropped this time
                         rowsDropped[newDropped++] = i;
                         rowsDropped_[i] = 1;
                    }
               }
          }
          numberRowsDropped_ += newDropped;
          if (numberRowsDropped_ && 0) {
               std::cout << "Rank " << numberRows_ - numberRowsDropped_ << " ( " <<
                         numberRowsDropped_ << " dropped)";
               if (newDropped) {
                    std::cout << " ( " << newDropped << " dropped this time)";
               }
               std::cout << std::endl;
          }
     }
     status_ = 0;
     return newDropped;
}
示例#28
0
int Amesos_Mumps::Solve()
{ 
  if (IsNumericFactorizationOK_ == false)
    AMESOS_CHK_ERR(NumericFactorization());

  Epetra_MultiVector* vecX = Problem_->GetLHS(); 
  Epetra_MultiVector* vecB = Problem_->GetRHS();
  int NumVectors = vecX->NumVectors();

  if ((vecX == 0) || (vecB == 0))
    AMESOS_CHK_ERR(-1);

  if (NumVectors != vecB->NumVectors())
    AMESOS_CHK_ERR(-1);

  if (Comm().NumProc() == 1) 
  {
    // do not import any data
    for (int j = 0 ; j < NumVectors; j++) 
    {
      ResetTimer();

      MDS.job = 3;     // Request solve

      for (int i = 0 ; i < Matrix().NumMyRows() ; ++i) 
	(*vecX)[j][i] = (*vecB)[j][i];
      MDS.rhs = (*vecX)[j];

      dmumps_c(&(MDS)) ;  // Perform solve
      static_cast<void>( CheckError( ) );   // Can hang 
      SolveTime_ = AddTime("Total solve time", SolveTime_);
    }
  } 
  else 
  {
    Epetra_MultiVector SerialVector(SerialMap(),NumVectors);

    ResetTimer();
    AMESOS_CHK_ERR(SerialVector.Import(*vecB,SerialImporter(),Insert));
    VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_);
    
    for (int j = 0 ; j < NumVectors; j++) 
    {
      if (Comm().MyPID() == 0)
	MDS.rhs = SerialVector[j];

      // solve the linear system and take time
      MDS.job = 3;     
      ResetTimer();
      if (Comm().MyPID() < MaxProcs_) 
	dmumps_c(&(MDS)) ;  // Perform solve
      static_cast<void>( CheckError( ) );   // Can hang 

      SolveTime_ = AddTime("Total solve time", SolveTime_);
    }

    // ship solution back and take timing
    ResetTimer();
    AMESOS_CHK_ERR(vecX->Export(SerialVector,SerialImporter(),Insert));
    VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_);
  }

  if (ComputeTrueResidual_)
    ComputeTrueResidual(Matrix(), *vecX, *vecB, UseTranspose(), "Amesos_Mumps");

  if (ComputeVectorNorms_)
    ComputeVectorNorms(*vecX, *vecB, "Amesos_Mumps");

  NumSolve_++;  
  
  return(0) ; 
}