1c4762a1bSJed Brown 2c4762a1bSJed Brown static char help[] = "Tests MatHYPRE\n"; 3c4762a1bSJed Brown 4c4762a1bSJed Brown #include <petscmathypre.h> 5c4762a1bSJed Brown 6d71ae5a4SJacob Faibussowitsch int main(int argc, char **args) 7d71ae5a4SJacob Faibussowitsch { 8c4762a1bSJed Brown Mat A, B, C, D; 9*40018c87Sstefanozampini Mat pAB, CD; 10c4762a1bSJed Brown hypre_ParCSRMatrix *parcsr; 11c4762a1bSJed Brown PetscReal err; 12c4762a1bSJed Brown PetscInt i, j, N = 6, M = 6; 13c4762a1bSJed Brown PetscBool flg, testptap = PETSC_TRUE, testmatmatmult = PETSC_TRUE; 14c4762a1bSJed Brown PetscReal norm; 15c4762a1bSJed Brown char file[256]; 16*40018c87Sstefanozampini MatType mtype = MATAIJ; 17c4762a1bSJed Brown 18327415f7SBarry Smith PetscFunctionBeginUser; 199566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 209566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL, NULL, "-f", file, sizeof(file), &flg)); 21c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 22c4762a1bSJed Brown testptap = PETSC_FALSE; 23c4762a1bSJed Brown testmatmatmult = PETSC_FALSE; 249566063dSJacob Faibussowitsch PetscCall(PetscOptionsInsertString(NULL, "-options_left 0")); 25c4762a1bSJed Brown #endif 269566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-ptap", &testptap, NULL)); 279566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-matmatmult", &testmatmatmult, NULL)); 289566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 29*40018c87Sstefanozampini #if PetscDefined(HAVE_HYPRE_DEVICE) 30*40018c87Sstefanozampini #if PetscDefined(HAVE_HIP) 31*40018c87Sstefanozampini mtype = MATAIJHIPSPARSE; 32*40018c87Sstefanozampini #elif PetscDefined(HAVE_CUDA) 33*40018c87Sstefanozampini mtype = MATAIJCUSPARSE; 34*40018c87Sstefanozampini #endif 35*40018c87Sstefanozampini #endif 36*40018c87Sstefanozampini 37c4762a1bSJed Brown if (!flg) { /* Create a matrix and test MatSetValues */ 38c4762a1bSJed Brown PetscMPIInt size; 39c4762a1bSJed Brown 409566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 419566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-M", &M, NULL)); 429566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-N", &N, NULL)); 439566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, M, N)); 44*40018c87Sstefanozampini PetscCall(MatSetType(A, mtype)); 459566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 9, NULL)); 469566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 9, NULL, 9, NULL)); 479566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &B)); 489566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, M, N)); 49*40018c87Sstefanozampini #if PetscDefined(HAVE_HYPRE_DEVICE) 50*40018c87Sstefanozampini PetscCall(MatSetType(B, mtype)); 51*40018c87Sstefanozampini #else 529566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATHYPRE)); 53*40018c87Sstefanozampini #endif 54*40018c87Sstefanozampini PetscCall(MatSeqAIJSetPreallocation(B, 9, NULL)); 55*40018c87Sstefanozampini PetscCall(MatMPIAIJSetPreallocation(B, 9, NULL, 9, NULL)); 56c4762a1bSJed Brown if (M == N) { 579566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(B, 9, NULL, 9, NULL)); 58c4762a1bSJed Brown } else { 599566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(B, 6, NULL, 6, NULL)); 60c4762a1bSJed Brown } 61c4762a1bSJed Brown if (M == N) { 62c4762a1bSJed Brown for (i = 0; i < M; i++) { 63c4762a1bSJed Brown PetscInt cols[] = {0, 1, 2, 3, 4, 5}; 64c4762a1bSJed Brown PetscScalar vals[] = {0, 1. / size, 2. / size, 3. / size, 4. / size, 5. / size}; 65c4762a1bSJed Brown for (j = i - 2; j < i + 1; j++) { 66c4762a1bSJed Brown if (j >= N) { 679566063dSJacob Faibussowitsch PetscCall(MatSetValue(A, i, N - 1, (1. * j * N + i) / (3. * N * size), ADD_VALUES)); 689566063dSJacob Faibussowitsch PetscCall(MatSetValue(B, i, N - 1, (1. * j * N + i) / (3. * N * size), ADD_VALUES)); 69c4762a1bSJed Brown } else if (i > j) { 709566063dSJacob Faibussowitsch PetscCall(MatSetValue(A, i, PetscMin(j, N - 1), (1. * j * N + i) / (2. * N * size), ADD_VALUES)); 719566063dSJacob Faibussowitsch PetscCall(MatSetValue(B, i, PetscMin(j, N - 1), (1. * j * N + i) / (2. * N * size), ADD_VALUES)); 72c4762a1bSJed Brown } else { 739566063dSJacob Faibussowitsch PetscCall(MatSetValue(A, i, PetscMin(j, N - 1), -1. - (1. * j * N + i) / (4. * N * size), ADD_VALUES)); 749566063dSJacob Faibussowitsch PetscCall(MatSetValue(B, i, PetscMin(j, N - 1), -1. - (1. * j * N + i) / (4. * N * size), ADD_VALUES)); 75c4762a1bSJed Brown } 76c4762a1bSJed Brown } 779566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, PetscMin(6, N), cols, vals, ADD_VALUES)); 789566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, 1, &i, PetscMin(6, N), cols, vals, ADD_VALUES)); 79c4762a1bSJed Brown } 80c4762a1bSJed Brown } else { 81c4762a1bSJed Brown PetscInt rows[2]; 82c4762a1bSJed Brown PetscBool test_offproc = PETSC_FALSE; 83c4762a1bSJed Brown 849566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_offproc", &test_offproc, NULL)); 85c4762a1bSJed Brown if (test_offproc) { 86c4762a1bSJed Brown const PetscInt *ranges; 87c4762a1bSJed Brown PetscMPIInt rank; 88c4762a1bSJed Brown 899566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 909566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRanges(A, &ranges)); 91c4762a1bSJed Brown rows[0] = ranges[(rank + 1) % size]; 92c4762a1bSJed Brown rows[1] = ranges[(rank + 1) % size + 1]; 93c4762a1bSJed Brown } else { 949566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rows[0], &rows[1])); 95c4762a1bSJed Brown } 96c4762a1bSJed Brown for (i = rows[0]; i < rows[1]; i++) { 97c4762a1bSJed Brown PetscInt cols[] = {0, 1, 2, 3, 4, 5}; 98c4762a1bSJed Brown PetscScalar vals[] = {-1, 1, -2, 2, -3, 3}; 99c4762a1bSJed Brown 1009566063dSJacob Faibussowitsch PetscCall(MatSetValues(A, 1, &i, PetscMin(6, N), cols, vals, INSERT_VALUES)); 1019566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, 1, &i, PetscMin(6, N), cols, vals, INSERT_VALUES)); 102c4762a1bSJed Brown } 103c4762a1bSJed Brown } 104c4762a1bSJed Brown /* MAT_FLUSH_ASSEMBLY currently not supported */ 1059566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1069566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 1079566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 1089566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 109*40018c87Sstefanozampini #if PetscDefined(HAVE_HYPRE_DEVICE) 110*40018c87Sstefanozampini PetscCall(MatConvert(B, MATHYPRE, MAT_INPLACE_MATRIX, &B)); 111*40018c87Sstefanozampini #endif 112c4762a1bSJed Brown 113c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 114c4762a1bSJed Brown /* make the matrix imaginary */ 1159566063dSJacob Faibussowitsch PetscCall(MatScale(A, PETSC_i)); 1169566063dSJacob Faibussowitsch PetscCall(MatScale(B, PETSC_i)); 117c4762a1bSJed Brown #endif 118c4762a1bSJed Brown 119*40018c87Sstefanozampini #if !PetscDefined(HAVE_HYPRE_DEVICE) 120c4762a1bSJed Brown /* MatAXPY further exercises MatSetValues_HYPRE */ 1219566063dSJacob Faibussowitsch PetscCall(MatAXPY(B, -1., A, DIFFERENT_NONZERO_PATTERN)); 1229566063dSJacob Faibussowitsch PetscCall(MatConvert(B, MATMPIAIJ, MAT_INITIAL_MATRIX, &C)); 1239566063dSJacob Faibussowitsch PetscCall(MatNorm(C, NORM_INFINITY, &err)); 12454c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatSetValues %g", err); 1259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 126*40018c87Sstefanozampini #endif 127*40018c87Sstefanozampini PetscCall(MatDestroy(&B)); 128c4762a1bSJed Brown } else { 129c4762a1bSJed Brown PetscViewer viewer; 130c4762a1bSJed Brown 1319566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file, FILE_MODE_READ, &viewer)); 1329566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 1339566063dSJacob Faibussowitsch PetscCall(MatLoad(A, viewer)); 134*40018c87Sstefanozampini PetscCall(MatSetType(A, mtype)); 1359566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 1369566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 137c4762a1bSJed Brown } 138c4762a1bSJed Brown 139c4762a1bSJed Brown /* check conversion routines */ 140f9dc6c1fSStefano Zampini PetscCall(MatViewFromOptions(A, NULL, "-view_A")); 1419566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &B)); 142f9dc6c1fSStefano Zampini PetscCall(MatViewFromOptions(B, NULL, "-view_convert")); 1439566063dSJacob Faibussowitsch PetscCall(MatMultEqual(B, A, 4, &flg)); 144f9dc6c1fSStefano Zampini PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat HYPRE init"); 145f9dc6c1fSStefano Zampini PetscCall(MatConvert(A, MATHYPRE, MAT_REUSE_MATRIX, &B)); 146f9dc6c1fSStefano Zampini PetscCall(MatViewFromOptions(B, NULL, "-view_convert")); 147f9dc6c1fSStefano Zampini PetscCall(MatMultEqual(B, A, 4, &flg)); 148f9dc6c1fSStefano Zampini PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat HYPRE reuse"); 1499566063dSJacob Faibussowitsch PetscCall(MatConvert(B, MATIS, MAT_INITIAL_MATRIX, &D)); 1509566063dSJacob Faibussowitsch PetscCall(MatConvert(B, MATIS, MAT_REUSE_MATRIX, &D)); 1519566063dSJacob Faibussowitsch PetscCall(MatMultEqual(D, A, 4, &flg)); 15254c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat IS"); 1539566063dSJacob Faibussowitsch PetscCall(MatConvert(B, MATAIJ, MAT_INITIAL_MATRIX, &C)); 1549566063dSJacob Faibussowitsch PetscCall(MatConvert(B, MATAIJ, MAT_REUSE_MATRIX, &C)); 1559566063dSJacob Faibussowitsch PetscCall(MatMultEqual(C, A, 4, &flg)); 15654c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat AIJ"); 1579566063dSJacob Faibussowitsch PetscCall(MatAXPY(C, -1., A, SAME_NONZERO_PATTERN)); 1589566063dSJacob Faibussowitsch PetscCall(MatNorm(C, NORM_INFINITY, &err)); 15954c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat AIJ %g", err); 1609566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 1619566063dSJacob Faibussowitsch PetscCall(MatConvert(D, MATAIJ, MAT_INITIAL_MATRIX, &C)); 1629566063dSJacob Faibussowitsch PetscCall(MatAXPY(C, -1., A, SAME_NONZERO_PATTERN)); 1639566063dSJacob Faibussowitsch PetscCall(MatNorm(C, NORM_INFINITY, &err)); 16454c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat IS %g", err); 1659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 1669566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 167c4762a1bSJed Brown 168c4762a1bSJed Brown /* check MatCreateFromParCSR */ 1699566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(B, &parcsr)); 1709566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr, MATAIJ, PETSC_COPY_VALUES, &D)); 1719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 1729566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr, MATHYPRE, PETSC_USE_POINTER, &C)); 173c4762a1bSJed Brown 174c4762a1bSJed Brown /* check MatMult operations */ 1759566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A, B, 4, &flg)); 17654c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMult B"); 1779566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A, C, 4, &flg)); 17854c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMult C"); 1799566063dSJacob Faibussowitsch PetscCall(MatMultAddEqual(A, B, 4, &flg)); 18054c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultAdd B"); 1819566063dSJacob Faibussowitsch PetscCall(MatMultAddEqual(A, C, 4, &flg)); 18254c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultAdd C"); 1839566063dSJacob Faibussowitsch PetscCall(MatMultTransposeEqual(A, B, 4, &flg)); 18454c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTranspose B"); 1859566063dSJacob Faibussowitsch PetscCall(MatMultTransposeEqual(A, C, 4, &flg)); 18654c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTranspose C"); 1879566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAddEqual(A, B, 4, &flg)); 18854c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTransposeAdd B"); 1899566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAddEqual(A, C, 4, &flg)); 19054c59aa7SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTransposeAdd C"); 191c4762a1bSJed Brown 192c4762a1bSJed Brown /* check PtAP */ 193c4762a1bSJed Brown if (testptap && M == N) { 194c4762a1bSJed Brown Mat pP, hP; 195c4762a1bSJed Brown 196c4762a1bSJed Brown /* PETSc MatPtAP -> output is a MatAIJ 197c4762a1bSJed Brown It uses HYPRE functions when -matptap_via hypre is specified at command line */ 1989566063dSJacob Faibussowitsch PetscCall(MatPtAP(A, A, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &pP)); 1999566063dSJacob Faibussowitsch PetscCall(MatPtAP(A, A, MAT_REUSE_MATRIX, PETSC_DEFAULT, &pP)); 2009566063dSJacob Faibussowitsch PetscCall(MatNorm(pP, NORM_INFINITY, &norm)); 2019566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A, A, pP, 10, &flg)); 20254c59aa7SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP_MatAIJ"); 203c4762a1bSJed Brown 204c4762a1bSJed Brown /* MatPtAP_HYPRE_HYPRE -> output is a MatHYPRE */ 2059566063dSJacob Faibussowitsch PetscCall(MatPtAP(C, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &hP)); 2069566063dSJacob Faibussowitsch PetscCall(MatPtAP(C, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &hP)); 2079566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(C, B, hP, 10, &flg)); 20854c59aa7SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP_HYPRE_HYPRE"); 209c20d7725SJed Brown 210c20d7725SJed Brown /* Test MatAXPY_Basic() */ 211*40018c87Sstefanozampini #if !PetscDefined(HAVE_HYPRE_DEVICE) 2129566063dSJacob Faibussowitsch PetscCall(MatAXPY(hP, -1., pP, DIFFERENT_NONZERO_PATTERN)); 2139566063dSJacob Faibussowitsch PetscCall(MatHasOperation(hP, MATOP_NORM, &flg)); 214c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 2159566063dSJacob Faibussowitsch PetscCall(MatConvert(hP, MATAIJ, MAT_INPLACE_MATRIX, &hP)); 216c4762a1bSJed Brown } 2179566063dSJacob Faibussowitsch PetscCall(MatNorm(hP, NORM_INFINITY, &err)); 218e00437b9SBarry Smith PetscCheck(err / norm <= PETSC_SMALL, PetscObjectComm((PetscObject)hP), PETSC_ERR_PLIB, "Error MatPtAP %g %g", err, norm); 219*40018c87Sstefanozampini #endif 2209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&pP)); 2219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&hP)); 222c4762a1bSJed Brown 223c4762a1bSJed Brown /* MatPtAP_AIJ_HYPRE -> output can be decided at runtime with -matptap_hypre_outtype */ 224*40018c87Sstefanozampini #if !PetscDefined(HAVE_HYPRE_DEVICE) 2259566063dSJacob Faibussowitsch PetscCall(MatPtAP(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &hP)); 2269566063dSJacob Faibussowitsch PetscCall(MatPtAP(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &hP)); 2279566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A, B, hP, 10, &flg)); 22854c59aa7SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP_AIJ_HYPRE"); 2299566063dSJacob Faibussowitsch PetscCall(MatDestroy(&hP)); 230*40018c87Sstefanozampini #endif 231c4762a1bSJed Brown } 2329566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2339566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 234c4762a1bSJed Brown 235c4762a1bSJed Brown /* check MatMatMult */ 236c4762a1bSJed Brown if (testmatmatmult) { 2379566063dSJacob Faibussowitsch PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &B)); 2389566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &C)); 2399566063dSJacob Faibussowitsch PetscCall(MatConvert(B, MATHYPRE, MAT_INITIAL_MATRIX, &D)); 240c4762a1bSJed Brown 241c4762a1bSJed Brown /* PETSc MatMatMult -> output is a MatAIJ 242c4762a1bSJed Brown It uses HYPRE functions when -matmatmult_via hypre is specified at command line */ 2439566063dSJacob Faibussowitsch PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &pAB)); 2449566063dSJacob Faibussowitsch PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &pAB)); 2459566063dSJacob Faibussowitsch PetscCall(MatNorm(pAB, NORM_INFINITY, &norm)); 2469566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(A, B, pAB, 10, &flg)); 24754c59aa7SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatMatMult_AIJ_AIJ"); 248c4762a1bSJed Brown 249c4762a1bSJed Brown /* MatMatMult_HYPRE_HYPRE -> output is a MatHYPRE */ 2509566063dSJacob Faibussowitsch PetscCall(MatMatMult(C, D, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &CD)); 2519566063dSJacob Faibussowitsch PetscCall(MatMatMult(C, D, MAT_REUSE_MATRIX, PETSC_DEFAULT, &CD)); 2529566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(C, D, CD, 10, &flg)); 25354c59aa7SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatMatMult_HYPRE_HYPRE"); 254c20d7725SJed Brown 255c20d7725SJed Brown /* Test MatAXPY_Basic() */ 256*40018c87Sstefanozampini #if !PetscDefined(HAVE_HYPRE_DEVICE) 2579566063dSJacob Faibussowitsch PetscCall(MatAXPY(CD, -1., pAB, DIFFERENT_NONZERO_PATTERN)); 258c20d7725SJed Brown 2599566063dSJacob Faibussowitsch PetscCall(MatHasOperation(CD, MATOP_NORM, &flg)); 260c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 2619566063dSJacob Faibussowitsch PetscCall(MatConvert(CD, MATAIJ, MAT_INPLACE_MATRIX, &CD)); 262c4762a1bSJed Brown } 2639566063dSJacob Faibussowitsch PetscCall(MatNorm(CD, NORM_INFINITY, &err)); 26454c59aa7SJacob Faibussowitsch PetscCheck((err / norm) <= PETSC_SMALL, PetscObjectComm((PetscObject)CD), PETSC_ERR_PLIB, "Error MatMatMult %g %g", err, norm); 265*40018c87Sstefanozampini #endif 266c20d7725SJed Brown 2679566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 2699566063dSJacob Faibussowitsch PetscCall(MatDestroy(&pAB)); 2709566063dSJacob Faibussowitsch PetscCall(MatDestroy(&CD)); 271c4762a1bSJed Brown 272c4762a1bSJed Brown /* When configured with HYPRE, MatMatMatMult is available for the triplet transpose(aij)-aij-aij */ 273*40018c87Sstefanozampini #if !PetscDefined(HAVE_HYPRE_DEVICE) 274*40018c87Sstefanozampini Mat CAB; 2759566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(A, &C)); 2769566063dSJacob Faibussowitsch PetscCall(MatMatMatMult(C, A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &CAB)); 2779566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2789566063dSJacob Faibussowitsch PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &C)); 2799566063dSJacob Faibussowitsch PetscCall(MatMatMult(C, A, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &D)); 2809566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2819566063dSJacob Faibussowitsch PetscCall(MatMatMult(D, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &C)); 2829566063dSJacob Faibussowitsch PetscCall(MatNorm(C, NORM_INFINITY, &norm)); 2839566063dSJacob Faibussowitsch PetscCall(MatAXPY(C, -1., CAB, DIFFERENT_NONZERO_PATTERN)); 2849566063dSJacob Faibussowitsch PetscCall(MatNorm(C, NORM_INFINITY, &err)); 28554c59aa7SJacob Faibussowitsch PetscCheck((err / norm) <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMatMatMult %g %g", err, norm); 2869566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2879566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 2889566063dSJacob Faibussowitsch PetscCall(MatDestroy(&CAB)); 289*40018c87Sstefanozampini #endif 2909566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 291c4762a1bSJed Brown } 292c4762a1bSJed Brown 293c4762a1bSJed Brown /* Check MatView */ 2949566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &B)); 2959566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B, NULL, "-view_B")); 296c4762a1bSJed Brown 297c4762a1bSJed Brown /* Check MatDuplicate/MatCopy */ 298c4762a1bSJed Brown for (j = 0; j < 3; j++) { 299c4762a1bSJed Brown MatDuplicateOption dop; 300c4762a1bSJed Brown 301c4762a1bSJed Brown dop = MAT_COPY_VALUES; 302c4762a1bSJed Brown if (j == 1) dop = MAT_DO_NOT_COPY_VALUES; 303c4762a1bSJed Brown if (j == 2) dop = MAT_SHARE_NONZERO_PATTERN; 304c4762a1bSJed Brown 305c4762a1bSJed Brown for (i = 0; i < 3; i++) { 306c4762a1bSJed Brown MatStructure str; 307c4762a1bSJed Brown 3089566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Dup/Copy tests: %" PetscInt_FMT " %" PetscInt_FMT "\n", j, i)); 309c4762a1bSJed Brown 310c4762a1bSJed Brown str = DIFFERENT_NONZERO_PATTERN; 311c4762a1bSJed Brown if (i == 1) str = SAME_NONZERO_PATTERN; 312c4762a1bSJed Brown if (i == 2) str = SUBSET_NONZERO_PATTERN; 313c4762a1bSJed Brown 3149566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, dop, &C)); 3159566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, dop, &D)); 316c4762a1bSJed Brown if (dop != MAT_COPY_VALUES) { 3179566063dSJacob Faibussowitsch PetscCall(MatCopy(A, C, str)); 3189566063dSJacob Faibussowitsch PetscCall(MatCopy(B, D, str)); 319c4762a1bSJed Brown } 320c4762a1bSJed Brown /* AXPY with AIJ and HYPRE */ 321*40018c87Sstefanozampini #if !PetscDefined(HAVE_HYPRE_DEVICE) 3229566063dSJacob Faibussowitsch PetscCall(MatAXPY(C, -1.0, D, str)); 3239566063dSJacob Faibussowitsch PetscCall(MatNorm(C, NORM_INFINITY, &err)); 324*40018c87Sstefanozampini #else 325*40018c87Sstefanozampini err = 0.0; 326*40018c87Sstefanozampini #endif 327c4762a1bSJed Brown if (err > PETSC_SMALL) { 3289566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-view_duplicate_diff")); 3299566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B, NULL, "-view_duplicate_diff")); 3309566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(C, NULL, "-view_duplicate_diff")); 331f9dc6c1fSStefano Zampini PetscCall(MatViewFromOptions(D, NULL, "-view_duplicate_diff")); 33298921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error test 1 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")", err, j, i); 333c4762a1bSJed Brown } 334c4762a1bSJed Brown /* AXPY with HYPRE and HYPRE */ 3359566063dSJacob Faibussowitsch PetscCall(MatAXPY(D, -1.0, B, str)); 336c4762a1bSJed Brown if (err > PETSC_SMALL) { 3379566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-view_duplicate_diff")); 3389566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B, NULL, "-view_duplicate_diff")); 3399566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(D, NULL, "-view_duplicate_diff")); 34098921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error test 2 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")", err, j, i); 341c4762a1bSJed Brown } 342*40018c87Sstefanozampini #if !PetscDefined(HAVE_HYPRE_DEVICE) 343c4762a1bSJed Brown /* Copy from HYPRE to AIJ */ 3449566063dSJacob Faibussowitsch PetscCall(MatCopy(B, C, str)); 345c4762a1bSJed Brown /* Copy from AIJ to HYPRE */ 3469566063dSJacob Faibussowitsch PetscCall(MatCopy(A, D, str)); 347c4762a1bSJed Brown /* AXPY with HYPRE and AIJ */ 3489566063dSJacob Faibussowitsch PetscCall(MatAXPY(D, -1.0, C, str)); 3499566063dSJacob Faibussowitsch PetscCall(MatHasOperation(D, MATOP_NORM, &flg)); 350c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 3519566063dSJacob Faibussowitsch PetscCall(MatConvert(D, MATAIJ, MAT_INPLACE_MATRIX, &D)); 352c4762a1bSJed Brown } 3539566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_INFINITY, &err)); 354c4762a1bSJed Brown if (err > PETSC_SMALL) { 3559566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-view_duplicate_diff")); 3569566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(C, NULL, "-view_duplicate_diff")); 3579566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(D, NULL, "-view_duplicate_diff")); 35898921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error test 3 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")", err, j, i); 359c4762a1bSJed Brown } 360*40018c87Sstefanozampini #endif 3619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 3629566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 363c4762a1bSJed Brown } 364c4762a1bSJed Brown } 3659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 366c4762a1bSJed Brown 3679566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(A, &flg)); 368c4762a1bSJed Brown if (flg) { 369c4762a1bSJed Brown Vec y, y2; 370c4762a1bSJed Brown 3719566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &B)); 3729566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, NULL, &y)); 3739566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(B, NULL, &y2)); 3749566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(A, y)); 3759566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(B, y2)); 3769566063dSJacob Faibussowitsch PetscCall(VecAXPY(y2, -1.0, y)); 3779566063dSJacob Faibussowitsch PetscCall(VecNorm(y2, NORM_INFINITY, &err)); 378c4762a1bSJed Brown if (err > PETSC_SMALL) { 3799566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(y, NULL, "-view_diagonal_diff")); 3809566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(y2, NULL, "-view_diagonal_diff")); 38198921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatGetDiagonal %g", err); 382c4762a1bSJed Brown } 3839566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 3849566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y)); 3859566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y2)); 386c4762a1bSJed Brown } 387c4762a1bSJed Brown 3889566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 389c4762a1bSJed Brown 3909566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 391b122ec5aSJacob Faibussowitsch return 0; 392c4762a1bSJed Brown } 393c4762a1bSJed Brown 394c4762a1bSJed Brown /*TEST 395c4762a1bSJed Brown 396c4762a1bSJed Brown build: 397c4762a1bSJed Brown requires: hypre 398c4762a1bSJed Brown 399c4762a1bSJed Brown test: 400c4762a1bSJed Brown suffix: 1 401c4762a1bSJed Brown args: -N 11 -M 11 402c4762a1bSJed Brown output_file: output/ex115_1.out 403c4762a1bSJed Brown 404c4762a1bSJed Brown test: 405c4762a1bSJed Brown suffix: 2 406c4762a1bSJed Brown nsize: 3 407*40018c87Sstefanozampini args: -N 13 -M 13 -matmatmult_via hypre -options_left 0 408c4762a1bSJed Brown output_file: output/ex115_1.out 409c4762a1bSJed Brown 410c4762a1bSJed Brown test: 411c4762a1bSJed Brown suffix: 3 412c4762a1bSJed Brown nsize: 4 413*40018c87Sstefanozampini args: -M 13 -N 7 -matmatmult_via hypre -options_left 0 414c4762a1bSJed Brown output_file: output/ex115_1.out 415c4762a1bSJed Brown 416c4762a1bSJed Brown test: 417c4762a1bSJed Brown suffix: 4 418c4762a1bSJed Brown nsize: 2 419c4762a1bSJed Brown args: -M 12 -N 19 420c4762a1bSJed Brown output_file: output/ex115_1.out 421c4762a1bSJed Brown 422c4762a1bSJed Brown test: 423c4762a1bSJed Brown suffix: 5 424c4762a1bSJed Brown nsize: 3 425*40018c87Sstefanozampini args: -M 13 -N 13 -options_left 0 -matptap_via hypre -matptap_hypre_outtype hypre 426c4762a1bSJed Brown output_file: output/ex115_1.out 427c4762a1bSJed Brown 428c4762a1bSJed Brown test: 429263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 430c4762a1bSJed Brown suffix: 6 431c4762a1bSJed Brown nsize: 3 432c4762a1bSJed Brown args: -M 12 -N 19 -test_offproc 433c4762a1bSJed Brown output_file: output/ex115_1.out 434c4762a1bSJed Brown 435c4762a1bSJed Brown test: 436263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 437c4762a1bSJed Brown suffix: 7 438c4762a1bSJed Brown nsize: 3 439c4762a1bSJed Brown args: -M 19 -N 12 -test_offproc -view_B ::ascii_info_detail 440c4762a1bSJed Brown output_file: output/ex115_7.out 441c4762a1bSJed Brown 442c4762a1bSJed Brown test: 443263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 444c4762a1bSJed Brown suffix: 8 445c4762a1bSJed Brown nsize: 3 446c4762a1bSJed Brown args: -M 1 -N 12 -test_offproc 447c4762a1bSJed Brown output_file: output/ex115_1.out 448c4762a1bSJed Brown 449c4762a1bSJed Brown test: 450263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 451c4762a1bSJed Brown suffix: 9 452c4762a1bSJed Brown nsize: 3 453c4762a1bSJed Brown args: -M 1 -N 2 -test_offproc 454c4762a1bSJed Brown output_file: output/ex115_1.out 455c4762a1bSJed Brown 456c4762a1bSJed Brown TEST*/ 457