1c4762a1bSJed Brown static char help[] = "Tests MatSolve() and MatMatSolve() (interface to superlu_dist, mumps and mkl_pardiso).\n\ 278bc9606SHong Zhang Example: mpiexec -n <np> ./ex125 -f <matrix binary file> -nrhs 4 -mat_solver_type <>\n\n"; 378bc9606SHong Zhang 478bc9606SHong Zhang /* 578bc9606SHong Zhang -mat_solver_type: 678bc9606SHong Zhang superlu 778bc9606SHong Zhang superlu_dist 878bc9606SHong Zhang mumps 978bc9606SHong Zhang mkl_pardiso 1078bc9606SHong Zhang cusparse 1178bc9606SHong Zhang petsc 1278bc9606SHong Zhang */ 13c4762a1bSJed Brown 14c4762a1bSJed Brown #include <petscmat.h> 15c4762a1bSJed Brown 16d71ae5a4SJacob Faibussowitsch int main(int argc, char **args) 17d71ae5a4SJacob Faibussowitsch { 18b18964edSHong Zhang Mat A, RHS = NULL, RHS1 = NULL, C, F, X; 19c4762a1bSJed Brown Vec u, x, b; 20c4762a1bSJed Brown PetscMPIInt size; 2178bc9606SHong Zhang PetscInt m, n, nfact, nsolve, nrhs, ipack = 5; 22c4762a1bSJed Brown PetscReal norm, tol = 1.e-10; 23*62671d91SStefano Zampini IS perm = NULL, iperm = NULL; 24c4762a1bSJed Brown MatFactorInfo info; 25c4762a1bSJed Brown PetscRandom rand; 2678bc9606SHong Zhang PetscBool flg, symm, testMatSolve = PETSC_TRUE, testMatMatSolve = PETSC_TRUE, testMatMatSolveTranspose = PETSC_TRUE, testMatSolveTranspose = PETSC_TRUE, match = PETSC_FALSE; 27c4762a1bSJed Brown PetscBool chol = PETSC_FALSE, view = PETSC_FALSE, matsolvexx = PETSC_FALSE; 28c4762a1bSJed Brown #if defined(PETSC_HAVE_MUMPS) 29c4762a1bSJed Brown PetscBool test_mumps_opts = PETSC_FALSE; 30c4762a1bSJed Brown #endif 31c4762a1bSJed Brown PetscViewer fd; /* viewer */ 32c4762a1bSJed Brown char file[PETSC_MAX_PATH_LEN]; /* input file name */ 3378bc9606SHong Zhang char pack[PETSC_MAX_PATH_LEN]; 34c4762a1bSJed Brown 35327415f7SBarry Smith PetscFunctionBeginUser; 369566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 379566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 38c4762a1bSJed Brown 39c4762a1bSJed Brown /* Determine file from which we read the matrix A */ 409566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, NULL, "-f", file, sizeof(file), &flg)); 419a14fc28SStefano Zampini if (flg) { /* Load matrix A */ 429566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file, FILE_MODE_READ, &fd)); 439566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 449566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 459566063dSJacob Faibussowitsch PetscCall(MatLoad(A, fd)); 469566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&fd)); 479a14fc28SStefano Zampini } else { 489a14fc28SStefano Zampini n = 13; 499566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL)); 509566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 519566063dSJacob Faibussowitsch PetscCall(MatSetType(A, MATAIJ)); 529566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 539566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n)); 549566063dSJacob Faibussowitsch PetscCall(MatSetUp(A)); 559566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 569566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 579566063dSJacob Faibussowitsch PetscCall(MatShift(A, 1.0)); 589a14fc28SStefano Zampini } 59c4762a1bSJed Brown 60c4762a1bSJed Brown /* if A is symmetric, set its flag -- required by MatGetInertia() */ 6178bc9606SHong Zhang PetscCall(MatIsSymmetric(A, 0.0, &symm)); 6278bc9606SHong Zhang PetscCall(MatSetOption(A, MAT_SYMMETRIC, symm)); 63c4762a1bSJed Brown 64*62671d91SStefano Zampini /* test MATNEST support */ 65*62671d91SStefano Zampini flg = PETSC_FALSE; 66*62671d91SStefano Zampini PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_nest", &flg, NULL)); 67*62671d91SStefano Zampini if (flg) { 68*62671d91SStefano Zampini /* Create a nested matrix representing 69*62671d91SStefano Zampini 70*62671d91SStefano Zampini | 0 0 A | 71*62671d91SStefano Zampini | 0 A 0 | 72*62671d91SStefano Zampini | A 0 0 | 73*62671d91SStefano Zampini 74*62671d91SStefano Zampini */ 75*62671d91SStefano Zampini Mat B, mats[9] = {NULL, NULL, A, NULL, A, NULL, A, NULL, NULL}; 76*62671d91SStefano Zampini 77*62671d91SStefano Zampini PetscCall(MatCreateNest(PETSC_COMM_WORLD, 3, NULL, 3, NULL, mats, &B)); 78*62671d91SStefano Zampini PetscCall(MatDestroy(&A)); 79*62671d91SStefano Zampini A = B; 80*62671d91SStefano Zampini PetscCall(MatSetOption(A, MAT_SYMMETRIC, symm)); 81*62671d91SStefano Zampini } 82*62671d91SStefano Zampini PetscCall(MatGetLocalSize(A, &m, &n)); 83*62671d91SStefano Zampini PetscCheck(m == n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "This example is not intended for rectangular matrices (%" PetscInt_FMT ", %" PetscInt_FMT ")", m, n); 84*62671d91SStefano Zampini 859566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-A_view")); 86c4762a1bSJed Brown 87a5b23f4aSJose E. Roman /* Create dense matrix C and X; C holds true solution with identical columns */ 88c4762a1bSJed Brown nrhs = 2; 899566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-nrhs", &nrhs, NULL)); 909566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "ex125: nrhs %" PetscInt_FMT "\n", nrhs)); 919566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &C)); 929566063dSJacob Faibussowitsch PetscCall(MatSetOptionsPrefix(C, "rhs_")); 939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, PETSC_DECIDE, PETSC_DECIDE, nrhs)); 949566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATDENSE)); 959566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(C)); 969566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 97c4762a1bSJed Brown 989566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-view_factor", &view, NULL)); 999566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_matmatsolve", &testMatMatSolve, NULL)); 10078bc9606SHong Zhang PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_matmatsolvetranspose", &testMatMatSolveTranspose, NULL)); 10178bc9606SHong Zhang PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_matsolvetranspose", &testMatSolveTranspose, NULL)); 1029566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-cholesky", &chol, NULL)); 103c4762a1bSJed Brown #if defined(PETSC_HAVE_MUMPS) 1049566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_mumps_opts", &test_mumps_opts, NULL)); 105c4762a1bSJed Brown #endif 106c4762a1bSJed Brown 1079566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PETSC_COMM_WORLD, &rand)); 1089566063dSJacob Faibussowitsch PetscCall(PetscRandomSetFromOptions(rand)); 1099566063dSJacob Faibussowitsch PetscCall(MatSetRandom(C, rand)); 1109566063dSJacob Faibussowitsch PetscCall(MatDuplicate(C, MAT_DO_NOT_COPY_VALUES, &X)); 111c4762a1bSJed Brown 112c4762a1bSJed Brown /* Create vectors */ 1139566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, &x, &b)); 1149566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &u)); /* save the true solution */ 115c4762a1bSJed Brown 116c4762a1bSJed Brown /* Test Factorization */ 1179566063dSJacob Faibussowitsch PetscCall(MatGetOrdering(A, MATORDERINGND, &perm, &iperm)); 118c4762a1bSJed Brown 11978bc9606SHong Zhang PetscCall(PetscOptionsGetString(NULL, NULL, "-mat_solver_type", pack, sizeof(pack), NULL)); 120c4762a1bSJed Brown #if defined(PETSC_HAVE_SUPERLU) 12178bc9606SHong Zhang PetscCall(PetscStrcmp(MATSOLVERSUPERLU, pack, &match)); 12278bc9606SHong Zhang if (match) { 12328b400f6SJacob Faibussowitsch PetscCheck(!chol, PETSC_COMM_WORLD, PETSC_ERR_SUP, "SuperLU does not provide Cholesky!"); 1249566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " SUPERLU LU:\n")); 1259566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERSUPERLU, MAT_FACTOR_LU, &F)); 12678bc9606SHong Zhang matsolvexx = PETSC_FALSE; /* Test MatMatSolve(F,RHS,RHS), RHS is a dense matrix, need further work */ 12778bc9606SHong Zhang ipack = 0; 12878bc9606SHong Zhang goto skipoptions; 12978bc9606SHong Zhang } 130c4762a1bSJed Brown #endif 131c4762a1bSJed Brown #if defined(PETSC_HAVE_SUPERLU_DIST) 13278bc9606SHong Zhang PetscCall(PetscStrcmp(MATSOLVERSUPERLU_DIST, pack, &match)); 13378bc9606SHong Zhang if (match) { 13428b400f6SJacob Faibussowitsch PetscCheck(!chol, PETSC_COMM_WORLD, PETSC_ERR_SUP, "SuperLU does not provide Cholesky!"); 1359566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " SUPERLU_DIST LU:\n")); 1369566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERSUPERLU_DIST, MAT_FACTOR_LU, &F)); 137c4762a1bSJed Brown matsolvexx = PETSC_TRUE; 13878bc9606SHong Zhang if (symm) { /* A is symmetric */ 13978bc9606SHong Zhang testMatMatSolveTranspose = PETSC_TRUE; 14078bc9606SHong Zhang testMatSolveTranspose = PETSC_TRUE; 14178bc9606SHong Zhang } else { /* superlu_dist does not support solving A^t x = rhs yet */ 14278bc9606SHong Zhang testMatMatSolveTranspose = PETSC_FALSE; 14378bc9606SHong Zhang testMatSolveTranspose = PETSC_FALSE; 14478bc9606SHong Zhang } 14578bc9606SHong Zhang ipack = 1; 14678bc9606SHong Zhang goto skipoptions; 14778bc9606SHong Zhang } 148c4762a1bSJed Brown #endif 149c4762a1bSJed Brown #if defined(PETSC_HAVE_MUMPS) 15078bc9606SHong Zhang PetscCall(PetscStrcmp(MATSOLVERMUMPS, pack, &match)); 15178bc9606SHong Zhang if (match) { 152c4762a1bSJed Brown if (chol) { 1539566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " MUMPS CHOLESKY:\n")); 1549566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERMUMPS, MAT_FACTOR_CHOLESKY, &F)); 155c4762a1bSJed Brown } else { 1569566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " MUMPS LU:\n")); 1579566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERMUMPS, MAT_FACTOR_LU, &F)); 158c4762a1bSJed Brown } 159c4762a1bSJed Brown matsolvexx = PETSC_TRUE; 160c4762a1bSJed Brown if (test_mumps_opts) { 161c4762a1bSJed Brown /* test mumps options */ 162c4762a1bSJed Brown PetscInt icntl; 163c4762a1bSJed Brown PetscReal cntl; 164c4762a1bSJed Brown 165c4762a1bSJed Brown icntl = 2; /* sequential matrix ordering */ 1669566063dSJacob Faibussowitsch PetscCall(MatMumpsSetIcntl(F, 7, icntl)); 167c4762a1bSJed Brown 168c4762a1bSJed Brown cntl = 1.e-6; /* threshold for row pivot detection */ 1699566063dSJacob Faibussowitsch PetscCall(MatMumpsSetIcntl(F, 24, 1)); 1709566063dSJacob Faibussowitsch PetscCall(MatMumpsSetCntl(F, 3, cntl)); 171c4762a1bSJed Brown } 17278bc9606SHong Zhang ipack = 2; 17378bc9606SHong Zhang goto skipoptions; 17478bc9606SHong Zhang } 175c4762a1bSJed Brown #endif 176c4762a1bSJed Brown #if defined(PETSC_HAVE_MKL_PARDISO) 17778bc9606SHong Zhang PetscCall(PetscStrcmp(MATSOLVERMKL_PARDISO, pack, &match)); 17878bc9606SHong Zhang if (match) { 179c4762a1bSJed Brown if (chol) { 1809566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " MKL_PARDISO CHOLESKY:\n")); 1819566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERMKL_PARDISO, MAT_FACTOR_CHOLESKY, &F)); 182c4762a1bSJed Brown } else { 1839566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " MKL_PARDISO LU:\n")); 1849566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERMKL_PARDISO, MAT_FACTOR_LU, &F)); 185c4762a1bSJed Brown } 18678bc9606SHong Zhang ipack = 3; 18778bc9606SHong Zhang goto skipoptions; 18878bc9606SHong Zhang } 189c4762a1bSJed Brown #endif 19038a8e8c1SStefano Zampini #if defined(PETSC_HAVE_CUDA) 19178bc9606SHong Zhang PetscCall(PetscStrcmp(MATSOLVERCUSPARSE, pack, &match)); 19278bc9606SHong Zhang if (match) { 19338a8e8c1SStefano Zampini if (chol) { 1949566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " CUSPARSE CHOLESKY:\n")); 1959566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERCUSPARSE, MAT_FACTOR_CHOLESKY, &F)); 19638a8e8c1SStefano Zampini } else { 1979566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " CUSPARSE LU:\n")); 1989566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERCUSPARSE, MAT_FACTOR_LU, &F)); 19938a8e8c1SStefano Zampini } 20078bc9606SHong Zhang testMatSolveTranspose = PETSC_FALSE; 20178bc9606SHong Zhang testMatMatSolveTranspose = PETSC_FALSE; 20278bc9606SHong Zhang ipack = 4; 20378bc9606SHong Zhang goto skipoptions; 20478bc9606SHong Zhang } 20538a8e8c1SStefano Zampini #endif 20678bc9606SHong Zhang /* PETSc */ 20778bc9606SHong Zhang match = PETSC_TRUE; 20878bc9606SHong Zhang if (match) { 209c4762a1bSJed Brown if (chol) { 2109566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " PETSC CHOLESKY:\n")); 2119566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERPETSC, MAT_FACTOR_CHOLESKY, &F)); 212c4762a1bSJed Brown } else { 2139566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " PETSC LU:\n")); 2149566063dSJacob Faibussowitsch PetscCall(MatGetFactor(A, MATSOLVERPETSC, MAT_FACTOR_LU, &F)); 215c4762a1bSJed Brown } 216c4762a1bSJed Brown matsolvexx = PETSC_TRUE; 21778bc9606SHong Zhang ipack = 5; 21878bc9606SHong Zhang goto skipoptions; 219c4762a1bSJed Brown } 220c4762a1bSJed Brown 22178bc9606SHong Zhang skipoptions: 2229566063dSJacob Faibussowitsch PetscCall(MatFactorInfoInitialize(&info)); 223c4762a1bSJed Brown info.fill = 5.0; 224c4762a1bSJed Brown info.shifttype = (PetscReal)MAT_SHIFT_NONE; 225c4762a1bSJed Brown if (chol) { 2269566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorSymbolic(F, A, perm, &info)); 227c4762a1bSJed Brown } else { 2289566063dSJacob Faibussowitsch PetscCall(MatLUFactorSymbolic(F, A, perm, iperm, &info)); 229c4762a1bSJed Brown } 230c4762a1bSJed Brown 231c4762a1bSJed Brown for (nfact = 0; nfact < 2; nfact++) { 232c4762a1bSJed Brown if (chol) { 2339566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " %" PetscInt_FMT "-the CHOLESKY numfactorization \n", nfact)); 2349566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorNumeric(F, A, &info)); 235c4762a1bSJed Brown } else { 2369566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " %" PetscInt_FMT "-the LU numfactorization \n", nfact)); 2379566063dSJacob Faibussowitsch PetscCall(MatLUFactorNumeric(F, A, &info)); 238c4762a1bSJed Brown } 239c4762a1bSJed Brown if (view) { 2409566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_INFO)); 2419566063dSJacob Faibussowitsch PetscCall(MatView(F, PETSC_VIEWER_STDOUT_WORLD)); 2429566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD)); 243c4762a1bSJed Brown view = PETSC_FALSE; 244c4762a1bSJed Brown } 245c4762a1bSJed Brown 246c4762a1bSJed Brown #if defined(PETSC_HAVE_SUPERLU_DIST) 247c4762a1bSJed Brown if (ipack == 1) { /* Test MatSuperluDistGetDiagU() 248c4762a1bSJed Brown -- input: matrix factor F; output: main diagonal of matrix U on all processes */ 249c4762a1bSJed Brown PetscInt M; 250c4762a1bSJed Brown PetscScalar *diag; 251c4762a1bSJed Brown #if !defined(PETSC_USE_COMPLEX) 252c4762a1bSJed Brown PetscInt nneg, nzero, npos; 253c4762a1bSJed Brown #endif 254c4762a1bSJed Brown 2559566063dSJacob Faibussowitsch PetscCall(MatGetSize(F, &M, NULL)); 2569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(M, &diag)); 2579566063dSJacob Faibussowitsch PetscCall(MatSuperluDistGetDiagU(F, diag)); 2589566063dSJacob Faibussowitsch PetscCall(PetscFree(diag)); 259c4762a1bSJed Brown 260c4762a1bSJed Brown #if !defined(PETSC_USE_COMPLEX) 261c4762a1bSJed Brown /* Test MatGetInertia() */ 26278bc9606SHong Zhang if (symm) { /* A is symmetric */ 2639566063dSJacob Faibussowitsch PetscCall(MatGetInertia(F, &nneg, &nzero, &npos)); 2649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, " MatInertia: nneg: %" PetscInt_FMT ", nzero: %" PetscInt_FMT ", npos: %" PetscInt_FMT "\n", nneg, nzero, npos)); 26578bc9606SHong Zhang } 266c4762a1bSJed Brown #endif 267c4762a1bSJed Brown } 268c4762a1bSJed Brown #endif 269c4762a1bSJed Brown 270d47f36abSHong Zhang #if defined(PETSC_HAVE_MUMPS) 271d47f36abSHong Zhang /* mumps interface allows repeated call of MatCholeskyFactorSymbolic(), while the succession calls do nothing */ 272d47f36abSHong Zhang if (ipack == 2) { 273d47f36abSHong Zhang if (chol) { 2749566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorSymbolic(F, A, perm, &info)); 2759566063dSJacob Faibussowitsch PetscCall(MatCholeskyFactorNumeric(F, A, &info)); 276d47f36abSHong Zhang } else { 2779566063dSJacob Faibussowitsch PetscCall(MatLUFactorSymbolic(F, A, perm, iperm, &info)); 2789566063dSJacob Faibussowitsch PetscCall(MatLUFactorNumeric(F, A, &info)); 279d47f36abSHong Zhang } 280d47f36abSHong Zhang } 281d47f36abSHong Zhang #endif 282d47f36abSHong Zhang 283b18964edSHong Zhang /* Test MatMatSolve(), A X = B, where B can be dense or sparse */ 284c4762a1bSJed Brown if (testMatMatSolve) { 285c4762a1bSJed Brown if (!nfact) { 2869566063dSJacob Faibussowitsch PetscCall(MatMatMult(A, C, MAT_INITIAL_MATRIX, 2.0, &RHS)); 287c4762a1bSJed Brown } else { 2889566063dSJacob Faibussowitsch PetscCall(MatMatMult(A, C, MAT_REUSE_MATRIX, 2.0, &RHS)); 289c4762a1bSJed Brown } 290c4762a1bSJed Brown for (nsolve = 0; nsolve < 2; nsolve++) { 2919566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " %" PetscInt_FMT "-the MatMatSolve \n", nsolve)); 2929566063dSJacob Faibussowitsch PetscCall(MatMatSolve(F, RHS, X)); 293c4762a1bSJed Brown 294c4762a1bSJed Brown /* Check the error */ 2959566063dSJacob Faibussowitsch PetscCall(MatAXPY(X, -1.0, C, SAME_NONZERO_PATTERN)); 2969566063dSJacob Faibussowitsch PetscCall(MatNorm(X, NORM_FROBENIUS, &norm)); 297b18964edSHong Zhang if (norm > tol) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT "-the MatMatSolve: Norm of error %g, nsolve %" PetscInt_FMT "\n", nsolve, (double)norm, nsolve)); 298c4762a1bSJed Brown } 299b18964edSHong Zhang 300c4762a1bSJed Brown if (matsolvexx) { 301c4762a1bSJed Brown /* Test MatMatSolve(F,RHS,RHS), RHS is a dense matrix */ 3029566063dSJacob Faibussowitsch PetscCall(MatCopy(RHS, X, SAME_NONZERO_PATTERN)); 3039566063dSJacob Faibussowitsch PetscCall(MatMatSolve(F, X, X)); 304c4762a1bSJed Brown /* Check the error */ 3059566063dSJacob Faibussowitsch PetscCall(MatAXPY(X, -1.0, C, SAME_NONZERO_PATTERN)); 3069566063dSJacob Faibussowitsch PetscCall(MatNorm(X, NORM_FROBENIUS, &norm)); 307b18964edSHong Zhang if (norm > tol) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "MatMatSolve(F,RHS,RHS): Norm of error %g\n", (double)norm)); 308c4762a1bSJed Brown } 309c4762a1bSJed Brown 310c4762a1bSJed Brown if (ipack == 2 && size == 1) { 311c4762a1bSJed Brown Mat spRHS, spRHST, RHST; 312c4762a1bSJed Brown 3139566063dSJacob Faibussowitsch PetscCall(MatTranspose(RHS, MAT_INITIAL_MATRIX, &RHST)); 3149566063dSJacob Faibussowitsch PetscCall(MatConvert(RHST, MATAIJ, MAT_INITIAL_MATRIX, &spRHST)); 3159566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(spRHST, &spRHS)); 316c4762a1bSJed Brown for (nsolve = 0; nsolve < 2; nsolve++) { 3179566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " %" PetscInt_FMT "-the sparse MatMatSolve \n", nsolve)); 3189566063dSJacob Faibussowitsch PetscCall(MatMatSolve(F, spRHS, X)); 319c4762a1bSJed Brown 320c4762a1bSJed Brown /* Check the error */ 3219566063dSJacob Faibussowitsch PetscCall(MatAXPY(X, -1.0, C, SAME_NONZERO_PATTERN)); 3229566063dSJacob Faibussowitsch PetscCall(MatNorm(X, NORM_FROBENIUS, &norm)); 323b18964edSHong Zhang if (norm > tol) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT "-the sparse MatMatSolve: Norm of error %g, nsolve %" PetscInt_FMT "\n", nsolve, (double)norm, nsolve)); 324c4762a1bSJed Brown } 325b18964edSHong Zhang PetscCall(MatDestroy(&spRHST)); 326b18964edSHong Zhang PetscCall(MatDestroy(&spRHS)); 327b18964edSHong Zhang PetscCall(MatDestroy(&RHST)); 328b18964edSHong Zhang } 329b18964edSHong Zhang } 330b18964edSHong Zhang 331b18964edSHong Zhang /* Test testMatMatSolveTranspose(), A^T X = B, where B can be dense or sparse */ 332b18964edSHong Zhang if (testMatMatSolveTranspose) { 333b18964edSHong Zhang if (!nfact) { 334b18964edSHong Zhang PetscCall(MatTransposeMatMult(A, C, MAT_INITIAL_MATRIX, 2.0, &RHS1)); 335b18964edSHong Zhang } else { 336b18964edSHong Zhang PetscCall(MatTransposeMatMult(A, C, MAT_REUSE_MATRIX, 2.0, &RHS1)); 337b18964edSHong Zhang } 338b18964edSHong Zhang 339b18964edSHong Zhang for (nsolve = 0; nsolve < 2; nsolve++) { 34078bc9606SHong Zhang PetscCall(PetscPrintf(PETSC_COMM_WORLD, " %" PetscInt_FMT "-the MatMatSolveTranspose\n", nsolve)); 341b18964edSHong Zhang PetscCall(MatMatSolveTranspose(F, RHS1, X)); 342b18964edSHong Zhang 343b18964edSHong Zhang /* Check the error */ 344b18964edSHong Zhang PetscCall(MatAXPY(X, -1.0, C, SAME_NONZERO_PATTERN)); 345b18964edSHong Zhang PetscCall(MatNorm(X, NORM_FROBENIUS, &norm)); 346b18964edSHong Zhang if (norm > tol) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT "-the MatMatSolveTranspose: Norm of error %g, nsolve %" PetscInt_FMT "\n", nsolve, (double)norm, nsolve)); 347b18964edSHong Zhang } 348b18964edSHong Zhang 349b18964edSHong Zhang if (ipack == 2 && size == 1) { 350b18964edSHong Zhang Mat spRHS, spRHST, RHST; 351b18964edSHong Zhang 352b18964edSHong Zhang PetscCall(MatTranspose(RHS1, MAT_INITIAL_MATRIX, &RHST)); 353b18964edSHong Zhang PetscCall(MatConvert(RHST, MATAIJ, MAT_INITIAL_MATRIX, &spRHST)); 354b18964edSHong Zhang PetscCall(MatCreateTranspose(spRHST, &spRHS)); 355b18964edSHong Zhang for (nsolve = 0; nsolve < 2; nsolve++) { 356b18964edSHong Zhang PetscCall(MatMatSolveTranspose(F, spRHS, X)); 357b18964edSHong Zhang 358b18964edSHong Zhang /* Check the error */ 359b18964edSHong Zhang PetscCall(MatAXPY(X, -1.0, C, SAME_NONZERO_PATTERN)); 360b18964edSHong Zhang PetscCall(MatNorm(X, NORM_FROBENIUS, &norm)); 361b18964edSHong Zhang if (norm > tol) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT "-the sparse MatMatSolveTranspose: Norm of error %g, nsolve %" PetscInt_FMT "\n", nsolve, (double)norm, nsolve)); 362c4762a1bSJed Brown } 3639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&spRHST)); 3649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&spRHS)); 3659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&RHST)); 366c4762a1bSJed Brown } 367c4762a1bSJed Brown } 368c4762a1bSJed Brown 369c4762a1bSJed Brown /* Test MatSolve() */ 370c4762a1bSJed Brown if (testMatSolve) { 371c4762a1bSJed Brown for (nsolve = 0; nsolve < 2; nsolve++) { 3729566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, rand)); 3739566063dSJacob Faibussowitsch PetscCall(VecCopy(x, u)); 3749566063dSJacob Faibussowitsch PetscCall(MatMult(A, x, b)); 375c4762a1bSJed Brown 3769566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, " %" PetscInt_FMT "-the MatSolve \n", nsolve)); 3779566063dSJacob Faibussowitsch PetscCall(MatSolve(F, b, x)); 378c4762a1bSJed Brown 379c4762a1bSJed Brown /* Check the error */ 3809566063dSJacob Faibussowitsch PetscCall(VecAXPY(u, -1.0, x)); /* u <- (-1.0)x + u */ 3819566063dSJacob Faibussowitsch PetscCall(VecNorm(u, NORM_2, &norm)); 382c4762a1bSJed Brown if (norm > tol) { 383c4762a1bSJed Brown PetscReal resi; 3849566063dSJacob Faibussowitsch PetscCall(MatMult(A, x, u)); /* u = A*x */ 3859566063dSJacob Faibussowitsch PetscCall(VecAXPY(u, -1.0, b)); /* u <- (-1.0)b + u */ 3869566063dSJacob Faibussowitsch PetscCall(VecNorm(u, NORM_2, &resi)); 3879566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "MatSolve: Norm of error %g, resi %g, numfact %" PetscInt_FMT "\n", (double)norm, (double)resi, nfact)); 388c4762a1bSJed Brown } 389c4762a1bSJed Brown } 390c4762a1bSJed Brown } 39178bc9606SHong Zhang 39278bc9606SHong Zhang /* Test MatSolveTranspose() */ 39378bc9606SHong Zhang if (testMatSolveTranspose) { 39478bc9606SHong Zhang for (nsolve = 0; nsolve < 2; nsolve++) { 39578bc9606SHong Zhang PetscCall(VecSetRandom(x, rand)); 39678bc9606SHong Zhang PetscCall(VecCopy(x, u)); 39778bc9606SHong Zhang PetscCall(MatMultTranspose(A, x, b)); 39878bc9606SHong Zhang 39978bc9606SHong Zhang PetscCall(PetscPrintf(PETSC_COMM_WORLD, " %" PetscInt_FMT "-the MatSolveTranspose\n", nsolve)); 40078bc9606SHong Zhang PetscCall(MatSolveTranspose(F, b, x)); 40178bc9606SHong Zhang 40278bc9606SHong Zhang /* Check the error */ 40378bc9606SHong Zhang PetscCall(VecAXPY(u, -1.0, x)); /* u <- (-1.0)x + u */ 40478bc9606SHong Zhang PetscCall(VecNorm(u, NORM_2, &norm)); 40578bc9606SHong Zhang if (norm > tol) { 40678bc9606SHong Zhang PetscReal resi; 40778bc9606SHong Zhang PetscCall(VecAXPY(u, -1.0, b)); /* u <- (-1.0)b + u */ 40878bc9606SHong Zhang PetscCall(VecNorm(u, NORM_2, &resi)); 40978bc9606SHong Zhang PetscCall(PetscPrintf(PETSC_COMM_WORLD, "MatSolveTranspose: Norm of error %g, resi %g, numfact %" PetscInt_FMT "\n", (double)norm, (double)resi, nfact)); 41078bc9606SHong Zhang } 41178bc9606SHong Zhang } 41278bc9606SHong Zhang } 413c4762a1bSJed Brown } 414c4762a1bSJed Brown 415c4762a1bSJed Brown /* Free data structures */ 4169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 4179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 4189566063dSJacob Faibussowitsch PetscCall(MatDestroy(&F)); 4199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&X)); 4209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&RHS)); 421b18964edSHong Zhang PetscCall(MatDestroy(&RHS1)); 422c4762a1bSJed Brown 4239566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&rand)); 4249566063dSJacob Faibussowitsch PetscCall(ISDestroy(&perm)); 4259566063dSJacob Faibussowitsch PetscCall(ISDestroy(&iperm)); 4269566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 4279566063dSJacob Faibussowitsch PetscCall(VecDestroy(&b)); 4289566063dSJacob Faibussowitsch PetscCall(VecDestroy(&u)); 4299566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 430b122ec5aSJacob Faibussowitsch return 0; 431c4762a1bSJed Brown } 432c4762a1bSJed Brown 433c4762a1bSJed Brown /*TEST 434c4762a1bSJed Brown 435c4762a1bSJed Brown test: 436dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES) 43778bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/medium -mat_solver_type petsc 438c4762a1bSJed Brown output_file: output/ex125.out 439c4762a1bSJed Brown 440c4762a1bSJed Brown test: 4419a14fc28SStefano Zampini suffix: 2 44278bc9606SHong Zhang args: -mat_solver_type petsc 4439a14fc28SStefano Zampini output_file: output/ex125.out 4449a14fc28SStefano Zampini 4459a14fc28SStefano Zampini test: 446c4762a1bSJed Brown suffix: mkl_pardiso 447dfd57a17SPierre Jolivet requires: mkl_pardiso datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES) 44878bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/small -mat_solver_type mkl_pardiso 449c4762a1bSJed Brown 450c4762a1bSJed Brown test: 4519a14fc28SStefano Zampini suffix: mkl_pardiso_2 4529a14fc28SStefano Zampini requires: mkl_pardiso 45378bc9606SHong Zhang args: -mat_solver_type mkl_pardiso 4549a14fc28SStefano Zampini output_file: output/ex125_mkl_pardiso.out 4559a14fc28SStefano Zampini 4569a14fc28SStefano Zampini test: 457c4762a1bSJed Brown suffix: mumps 458dfd57a17SPierre Jolivet requires: mumps datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES) 45978bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/small -mat_solver_type mumps 460c4762a1bSJed Brown output_file: output/ex125_mumps_seq.out 461c4762a1bSJed Brown 462c4762a1bSJed Brown test: 463*62671d91SStefano Zampini suffix: mumps_nest 464*62671d91SStefano Zampini requires: mumps datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES) 465*62671d91SStefano Zampini args: -f ${DATAFILESPATH}/matrices/small -mat_solver_type mumps -test_nest 466*62671d91SStefano Zampini output_file: output/ex125_mumps_seq.out 467*62671d91SStefano Zampini 468*62671d91SStefano Zampini test: 469c4762a1bSJed Brown suffix: mumps_2 470c4762a1bSJed Brown nsize: 3 471dfd57a17SPierre Jolivet requires: mumps datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES) 47278bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/small -mat_solver_type mumps 473c4762a1bSJed Brown output_file: output/ex125_mumps_par.out 474c4762a1bSJed Brown 475c4762a1bSJed Brown test: 476*62671d91SStefano Zampini suffix: mumps_2_nest 477*62671d91SStefano Zampini nsize: 3 478*62671d91SStefano Zampini requires: mumps datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES) 479*62671d91SStefano Zampini args: -f ${DATAFILESPATH}/matrices/small -mat_solver_type mumps -test_nest 480*62671d91SStefano Zampini output_file: output/ex125_mumps_par.out 481*62671d91SStefano Zampini 482*62671d91SStefano Zampini test: 4839a14fc28SStefano Zampini suffix: mumps_3 4849a14fc28SStefano Zampini requires: mumps 48578bc9606SHong Zhang args: -mat_solver_type mumps 4869a14fc28SStefano Zampini output_file: output/ex125_mumps_seq.out 4879a14fc28SStefano Zampini 4889a14fc28SStefano Zampini test: 489*62671d91SStefano Zampini suffix: mumps_3_nest 490*62671d91SStefano Zampini requires: mumps 491*62671d91SStefano Zampini args: -mat_solver_type mumps -test_nest 492*62671d91SStefano Zampini output_file: output/ex125_mumps_seq.out 493*62671d91SStefano Zampini 494*62671d91SStefano Zampini test: 4959a14fc28SStefano Zampini suffix: mumps_4 4969a14fc28SStefano Zampini nsize: 3 4979a14fc28SStefano Zampini requires: mumps 49878bc9606SHong Zhang args: -mat_solver_type mumps 4999a14fc28SStefano Zampini output_file: output/ex125_mumps_par.out 5009a14fc28SStefano Zampini 5019a14fc28SStefano Zampini test: 502*62671d91SStefano Zampini suffix: mumps_4_nest 503*62671d91SStefano Zampini nsize: 3 504*62671d91SStefano Zampini requires: mumps 505*62671d91SStefano Zampini args: -mat_solver_type mumps -test_nest 506*62671d91SStefano Zampini output_file: output/ex125_mumps_par.out 507*62671d91SStefano Zampini 508*62671d91SStefano Zampini test: 509d47f36abSHong Zhang suffix: mumps_5 510d47f36abSHong Zhang nsize: 3 511d47f36abSHong Zhang requires: mumps 51278bc9606SHong Zhang args: -mat_solver_type mumps -cholesky 513d47f36abSHong Zhang output_file: output/ex125_mumps_par_cholesky.out 514d47f36abSHong Zhang 515d47f36abSHong Zhang test: 516*62671d91SStefano Zampini suffix: mumps_5_nest 517*62671d91SStefano Zampini nsize: 3 518*62671d91SStefano Zampini requires: mumps 519*62671d91SStefano Zampini args: -mat_solver_type mumps -cholesky -test_nest 520*62671d91SStefano Zampini output_file: output/ex125_mumps_par_cholesky.out 521*62671d91SStefano Zampini 522*62671d91SStefano Zampini test: 52378bc9606SHong Zhang suffix: superlu 52478bc9606SHong Zhang requires: datafilespath double !complex !defined(PETSC_USE_64BIT_INDICES) superlu 52578bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/medium -mat_solver_type superlu 52678bc9606SHong Zhang output_file: output/ex125_superlu.out 52778bc9606SHong Zhang 52878bc9606SHong Zhang test: 529c4762a1bSJed Brown suffix: superlu_dist 5309a14fc28SStefano Zampini nsize: {{1 3}} 531d4783600SBarry Smith requires: datafilespath double !complex !defined(PETSC_USE_64BIT_INDICES) superlu_dist 53278bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/small -mat_solver_type superlu_dist -mat_superlu_dist_rowperm NOROWPERM 53378bc9606SHong Zhang output_file: output/ex125_superlu_dist.out 534c4762a1bSJed Brown 535c4762a1bSJed Brown test: 536c4762a1bSJed Brown suffix: superlu_dist_2 5379a14fc28SStefano Zampini nsize: {{1 3}} 5389a14fc28SStefano Zampini requires: superlu_dist !complex 53978bc9606SHong Zhang args: -n 36 -mat_solver_type superlu_dist -mat_superlu_dist_rowperm NOROWPERM 540c4762a1bSJed Brown output_file: output/ex125_superlu_dist.out 541c4762a1bSJed Brown 542c4762a1bSJed Brown test: 54378bc9606SHong Zhang suffix: superlu_dist_3 54478bc9606SHong Zhang nsize: {{1 3}} 54578bc9606SHong Zhang requires: superlu_dist !complex 54678bc9606SHong Zhang requires: datafilespath double !complex !defined(PETSC_USE_64BIT_INDICES) superlu_dist 54778bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/medium -mat_solver_type superlu_dist -mat_superlu_dist_rowperm NOROWPERM 54878bc9606SHong Zhang output_file: output/ex125_superlu_dist_nonsymmetric.out 54978bc9606SHong Zhang 55078bc9606SHong Zhang test: 551c4762a1bSJed Brown suffix: superlu_dist_complex 552c4762a1bSJed Brown nsize: 3 553d4783600SBarry Smith requires: datafilespath double superlu_dist complex !defined(PETSC_USE_64BIT_INDICES) 55478bc9606SHong Zhang args: -f ${DATAFILESPATH}/matrices/farzad_B_rhs -mat_solver_type superlu_dist 555c4762a1bSJed Brown output_file: output/ex125_superlu_dist_complex.out 556c4762a1bSJed Brown 55738a8e8c1SStefano Zampini test: 5589a14fc28SStefano Zampini suffix: superlu_dist_complex_2 5599a14fc28SStefano Zampini nsize: 3 5609a14fc28SStefano Zampini requires: superlu_dist complex 56178bc9606SHong Zhang args: -mat_solver_type superlu_dist 56278bc9606SHong Zhang output_file: output/ex125_superlu_dist_complex_2.out 5639a14fc28SStefano Zampini 5649a14fc28SStefano Zampini test: 56538a8e8c1SStefano Zampini suffix: cusparse 566dfd57a17SPierre Jolivet requires: cuda datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES) 56773ff1584SJunchao Zhang #todo: fix the bug with cholesky 56878bc9606SHong Zhang #args: -mat_type aijcusparse -f ${DATAFILESPATH}/matrices/small -mat_solver_type cusparse -cholesky {{0 1}separate output} 56978bc9606SHong Zhang args: -mat_type aijcusparse -f ${DATAFILESPATH}/matrices/small -mat_solver_type cusparse -cholesky {{0}separate output} 57038a8e8c1SStefano Zampini 5719a14fc28SStefano Zampini test: 5729a14fc28SStefano Zampini suffix: cusparse_2 5739a14fc28SStefano Zampini requires: cuda 57478bc9606SHong Zhang args: -mat_type aijcusparse -mat_solver_type cusparse -cholesky {{0 1}separate output} 5759a14fc28SStefano Zampini 576c4762a1bSJed Brown TEST*/ 577