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; }
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; }
/* Solve Mx = b */ DATA* yohan::matrix::solveLinearEquation(SquareSparseMatrix* M, DATA* b) { //for SymmetricUpperSquareSparseMatrix, using MUMPS if (M->getType() == SquareSparseMatrix::TYPE_SymmetricMumpsSquareSparse) { /* Platform MUMPS relatives*/ DMUMPS_STRUC_C id; /* JOB_INIT */ id.job = -1; // step: JOB_INIT id.par = 1; // the host will participate the factorisation/solve phase, in SEQ version, 1 is better id.sym = 0; // 2 - general symmetric; 1 - symmetric positive definite; 0 - unsymmetric //id.comm_fortran = -987654; dmumps_c(&id); /* Define the problem on the host */ SymmetricMumpsSquareSparseMatrix* A = (SymmetricMumpsSquareSparseMatrix*)M; id.n = A->order; //order id.nz = A->size; //count of non-element id.irn = A->rows; id.jcn = A->columns; id.a = A->values; id.rhs = b; /* Configuration of the solver */ //id.ICNTL(5) = 0; // the matrix is defined in an "assembled format", (i, j, val) id.ICNTL(1) = -1; id.ICNTL(2) = -1; id.ICNTL(3) = -1; id.ICNTL(4) = 0; // all these are for the dignostic display, put on -1 if not necessary /* Call the solver */ id.job = 6; dmumps_c(&id); /* We should consider here whether we desallocate the M and the b */ /* JOB_END */ id.job=-2; dmumps_c(&id); /* Return */ return b; } else if (M->getType() == SquareSparseMatrix::TYPE_SymmetricMumpsSquareSparse2) { /* Platform MUMPS relatives*/ DMUMPS_STRUC_C id; /* JOB_INIT */ id.job = -1; // step: JOB_INIT id.par = 1; // the host will participate the factorisation/solve phase, in SEQ version, 1 is better id.sym = 0; // 2 - general symmetric; 1 - symmetric positive definite; 0 - unsymmetric //id.comm_fortran = -987654; dmumps_c(&id); /* Define the problem on the host */ SymmetricMumpsSquareSparseMatrix2* A = (SymmetricMumpsSquareSparseMatrix2*)M; id.n = A->order; //order id.nz = A->size; //count of non-element id.irn = A->rows; id.jcn = A->columns; id.a = A->values; id.rhs = b; /* Configuration of the solver */ //id.ICNTL(5) = 0; // the matrix is defined in an "assembled format", (i, j, val) id.ICNTL(1) = -1; id.ICNTL(2) = -1; id.ICNTL(3) = -1; id.ICNTL(4) = 0; // all these are for the dignostic display, put on -1 if not necessary /* Call the solver */ id.job = 6; dmumps_c(&id); /* We should consider here whether we desallocate the M and the b */ /* JOB_END */ id.job=-2; dmumps_c(&id); /* Return */ return b; } else return NULL; //if (A->getType() == SquareSparseMatrix::TYPE_SymmetricIntelSquareSparse) }
//----------------------------------------------------------------------------- std::size_t MUMPSLUSolver::solve(GenericVector& x, const GenericVector& b) { dolfin_assert(_matA); DMUMPS_STRUC_C data; data.comm_fortran = -987654; // Initialise data.job = -1; // Host participates in solve data.par = 1; // Output related parameters //data.ICNTL(1) = 6; // error messages //data.ICNTL(2) = 0; //data.ICNTL(3) = 6; // Global information //data.ICNTL(3) = 6; // Global information if (parameters["verbose"]) data.ICNTL(4) = 2; else data.ICNTL(4) = 1; // Matrix symmetry (0=non-symmetric, 2=symmetric positive defn, 2=symmetric) data.sym = 0; if (parameters["symmetric"]) data.sym = 2; // Initialise MUMPS dmumps_c(&data); // Related to use of ScaLAPACK (+/-. Negative is faster?) //data.ICNTL(13) = -1; // Solve transpose (1: A x = b, otherwise A^T x = b) data.ICNTL(9) = 1; // FIXME (20=default) data.ICNTL(14) = 20; // Reordering (7=automatic) data.ICNTL(7) = 7; // Control solution vector (0=solution on root, 1=solution distributed) data.ICNTL(21) = 1; // Distributed matrix data.ICNTL(18) = 3; // Parallel/serial analysis (0=auto, 1=serial, 2=parallel) if (MPI::size(_matA->mpi_comm()) > 1) data.ICNTL(28) = 2; else data.ICNTL(28) = 0; // Parallel graph partitioning library (0=auto, 1=pt-scotch, 2=parmetis) data.ICNTL(29) = 0; // Global size dolfin_assert(_matA->size(0) == _matA->size(1)); data.n = _matA->size(0); if (!_matA->base_one()) dolfin_error("MUMPSLUSolver.cpp", "initialize solver", "MUMPS requires a CoordinateMatrix with Fortran-style " "base 1 indexing"); // Get matrix coordinate and value data const std::vector<std::size_t>& rows = _matA->rows(); const std::vector<std::size_t>& cols = _matA->columns(); const std::vector<double>& vals = _matA->values(); // Number of non-zero entries on this process data.nz_loc = rows.size(); // Pass matrix data to MUMPS. Trust MUMPS not to change it data.irn_loc = const_cast<int*>(reinterpret_cast<const int*>(rows.data())); data.jcn_loc = const_cast<int*>(reinterpret_cast<const int*>(cols.data())); data.a_loc = const_cast<double*>(vals.data()); // Analyse and factorize data.job = 4; dmumps_c(&data); if (data.INFOG(1) < 0) dolfin_error("MUMPSLUSolver.cpp", "compute matrix factors", "MUMPS reported an error during the analysis and " "factorisation"); cout << "Factorisation finished" << endl; // Gather RHS on root process and attach std::vector<double> _b; b.gather_on_zero(_b); data.rhs = _b.data(); // Scaling strategy (77 is default) data.ICNTL(8) = 77; // Get size of local solution vector x and create objects to hold solution const std::size_t local_x_size = data.INFO(23); std::vector<int> x_local_indices(local_x_size); std::vector<double> x_local_vals(local_x_size); // Attach solution data to MUMPS object data.lsol_loc = local_x_size; data.sol_loc = x_local_vals.data(); data.isol_loc = x_local_indices.data(); // Solve problem data.job = 3; dmumps_c(&data); if (data.INFOG(1) < 0) dolfin_error("MUMPSLUSolver.cpp", "compute matrix factors", "MUMPS reported an error during the solve"); // Shift indices by -1 for (std::size_t i = 0; i < local_x_size ; ++i) x_local_indices[i]--; // Set x values #if defined(PETSC_USE_64BIT_INDICES) // Cast indices to 64 bit std::vector<dolfin::la_index> _x_local_indices(x_local_indices.begin(), x_local_indices.end()); x.set_local(x_local_vals.data(), x_local_indices.size(), _x_local_indices.data()); #else x.set_local(x_local_vals.data(), x_local_indices.size(), x_local_indices.data()); #endif x.apply("insert"); // Clean up data.job = -2; dmumps_c(&data); return 1; }