1c4762a1bSJed Brown static char help[] = "Test MatMatMult() and MatPtAP() for AIJ matrices.\n\n"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown #include <petscmat.h> 4c4762a1bSJed Brown 5c4762a1bSJed Brown extern PetscErrorCode testPTAPRectangular(void); 6c4762a1bSJed Brown 7d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 8d71ae5a4SJacob Faibussowitsch { 9c4762a1bSJed Brown Mat A, B, C, D; 10c4762a1bSJed Brown PetscScalar a[] = {1., 1., 0., 0., 1., 1., 0., 0., 1.}; 11c4762a1bSJed Brown PetscInt ij[] = {0, 1, 2}; 12c20d7725SJed Brown PetscReal fill = 4.0; 13c4762a1bSJed Brown PetscMPIInt size, rank; 14c20d7725SJed Brown PetscBool isequal; 15c20d7725SJed Brown #if defined(PETSC_HAVE_HYPRE) 16c4762a1bSJed Brown PetscBool test_hypre = PETSC_FALSE; 17c20d7725SJed Brown #endif 18c4762a1bSJed Brown 19327415f7SBarry Smith PetscFunctionBeginUser; 209566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, (char *)0, help)); 21c4762a1bSJed Brown #if defined(PETSC_HAVE_HYPRE) 229566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_hypre", &test_hypre, NULL)); 23c4762a1bSJed Brown #endif 249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 259566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 26c4762a1bSJed Brown 279566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 289566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, 3, 3)); 299566063dSJacob Faibussowitsch PetscCall(MatSetType(A, MATAIJ)); 309566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 319566063dSJacob Faibussowitsch PetscCall(MatSetUp(A)); 329566063dSJacob Faibussowitsch PetscCall(MatSetOption(A, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE)); 33c4762a1bSJed Brown 3448a46eb9SPierre Jolivet if (rank == 0) PetscCall(MatSetValues(A, 3, ij, 3, ij, a, ADD_VALUES)); 359566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 369566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 37c4762a1bSJed Brown 38c4762a1bSJed Brown /* Test MatMatMult() */ 399566063dSJacob Faibussowitsch PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &B)); /* B = A^T */ 409566063dSJacob Faibussowitsch PetscCall(MatMatMult(B, A, MAT_INITIAL_MATRIX, fill, &C)); /* C = B*A */ 419566063dSJacob Faibussowitsch PetscCall(MatMatMult(B, A, MAT_REUSE_MATRIX, fill, &C)); /* recompute C=B*A */ 429566063dSJacob Faibussowitsch PetscCall(MatSetOptionsPrefix(C, "C_")); 439566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(B, A, C, 10, &isequal)); 4428b400f6SJacob Faibussowitsch PetscCheck(isequal, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MatMatMult: C != B*A"); 45c4762a1bSJed Brown 469566063dSJacob Faibussowitsch PetscCall(MatMatMult(C, A, MAT_INITIAL_MATRIX, fill, &D)); /* D = C*A = (A^T*A)*A */ 479566063dSJacob Faibussowitsch PetscCall(MatMatMult(C, A, MAT_REUSE_MATRIX, fill, &D)); 489566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(C, A, D, 10, &isequal)); 4928b400f6SJacob Faibussowitsch PetscCheck(isequal, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MatMatMult: D != C*A"); 50c4762a1bSJed Brown 519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 54c4762a1bSJed Brown 55c20d7725SJed Brown /* Test MatPtAP */ 569566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B)); /* B = A */ 579566063dSJacob Faibussowitsch PetscCall(MatPtAP(A, B, MAT_INITIAL_MATRIX, fill, &C)); /* C = B^T*A*B */ 589566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A, B, C, 10, &isequal)); 5928b400f6SJacob Faibussowitsch PetscCheck(isequal, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MatPtAP: C != B^T*A*B"); 60c4762a1bSJed Brown 61c20d7725SJed Brown /* Repeat MatPtAP to test symbolic/numeric separation for reuse of the symbolic product */ 629566063dSJacob Faibussowitsch PetscCall(MatPtAP(A, B, MAT_REUSE_MATRIX, fill, &C)); 639566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A, B, C, 10, &isequal)); 6428b400f6SJacob Faibussowitsch PetscCheck(isequal, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MatPtAP(reuse): C != B^T*A*B"); 65c4762a1bSJed Brown 669566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 67c1995e1cSHong Zhang 68c1995e1cSHong Zhang /* Test MatPtAP with A as a dense matrix */ 69c1995e1cSHong Zhang { 70c1995e1cSHong Zhang Mat Adense; 719566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATDENSE, MAT_INITIAL_MATRIX, &Adense)); 729566063dSJacob Faibussowitsch PetscCall(MatPtAP(Adense, B, MAT_INITIAL_MATRIX, fill, &C)); 73c1995e1cSHong Zhang 749566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(Adense, B, C, 10, &isequal)); 75c1995e1cSHong Zhang PetscCheck(isequal, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MatPtAP(reuse): C != B^T*Adense*B"); 769566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Adense)); 77c1995e1cSHong Zhang } 78c4762a1bSJed Brown 79c4762a1bSJed Brown if (size == 1) { 80c4762a1bSJed Brown /* A test contributed by Tobias Neckel <neckel@in.tum.de> */ 819566063dSJacob Faibussowitsch PetscCall(testPTAPRectangular()); 82c4762a1bSJed Brown 83c4762a1bSJed Brown /* test MatMatTransposeMult(): A*B^T */ 849566063dSJacob Faibussowitsch PetscCall(MatMatTransposeMult(A, A, MAT_INITIAL_MATRIX, fill, &D)); /* D = A*A^T */ 859566063dSJacob Faibussowitsch PetscCall(MatScale(A, 2.0)); 869566063dSJacob Faibussowitsch PetscCall(MatMatTransposeMult(A, A, MAT_REUSE_MATRIX, fill, &D)); 879566063dSJacob Faibussowitsch PetscCall(MatMatTransposeMultEqual(A, A, D, 10, &isequal)); 8828b400f6SJacob Faibussowitsch PetscCheck(isequal, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "MatMatTranspose: D != A*A^T"); 89c4762a1bSJed Brown } 90c4762a1bSJed Brown 919566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 929566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 939566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 959566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 96b122ec5aSJacob Faibussowitsch return 0; 97c4762a1bSJed Brown } 98c4762a1bSJed Brown 99c4762a1bSJed Brown /* a test contributed by Tobias Neckel <neckel@in.tum.de>, 02 Jul 2008 */ 100d71ae5a4SJacob Faibussowitsch PetscErrorCode testPTAPRectangular(void) 101d71ae5a4SJacob Faibussowitsch { 102c20d7725SJed Brown const int rows = 3, cols = 5; 103c4762a1bSJed Brown int i; 104c20d7725SJed Brown Mat A, P, C; 105c4762a1bSJed Brown 106c4762a1bSJed Brown PetscFunctionBegin; 107c4762a1bSJed Brown /* set up A */ 1089566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJ(PETSC_COMM_WORLD, rows, rows, 1, NULL, &A)); 10948a46eb9SPierre Jolivet for (i = 0; i < rows; i++) PetscCall(MatSetValue(A, i, i, 1.0, INSERT_VALUES)); 1109566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1119566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 112c4762a1bSJed Brown 113c4762a1bSJed Brown /* set up P */ 1149566063dSJacob Faibussowitsch PetscCall(MatCreateSeqAIJ(PETSC_COMM_WORLD, rows, cols, 5, NULL, &P)); 1159566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 0, 0, 1.0, INSERT_VALUES)); 1169566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 0, 1, 2.0, INSERT_VALUES)); 1179566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 0, 2, 0.0, INSERT_VALUES)); 118c4762a1bSJed Brown 1199566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 0, 3, -1.0, INSERT_VALUES)); 120c4762a1bSJed Brown 1219566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 1, 0, 0.0, INSERT_VALUES)); 1229566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 1, 1, -1.0, INSERT_VALUES)); 1239566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 1, 2, 1.0, INSERT_VALUES)); 124c4762a1bSJed Brown 1259566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 2, 0, 3.0, INSERT_VALUES)); 1269566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 2, 1, 0.0, INSERT_VALUES)); 1279566063dSJacob Faibussowitsch PetscCall(MatSetValue(P, 2, 2, -3.0, INSERT_VALUES)); 128c4762a1bSJed Brown 1299566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY)); 1309566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY)); 131c4762a1bSJed Brown 132c4762a1bSJed Brown /* compute C */ 1339566063dSJacob Faibussowitsch PetscCall(MatPtAP(A, P, MAT_INITIAL_MATRIX, 1.0, &C)); 134c4762a1bSJed Brown 1359566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 1369566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 137c4762a1bSJed Brown 138c4762a1bSJed Brown /* compare results */ 139c4762a1bSJed Brown /* 140c4762a1bSJed Brown printf("C:\n"); 1419566063dSJacob Faibussowitsch PetscCall(MatView(C,PETSC_VIEWER_STDOUT_WORLD)); 142c4762a1bSJed Brown 143c4762a1bSJed Brown blitz::Array<double,2> actualC(cols, cols); 144c4762a1bSJed Brown actualC = 0.0; 145c4762a1bSJed Brown for (int i=0; i<cols; i++) { 146c4762a1bSJed Brown for (int j=0; j<cols; j++) { 1479566063dSJacob Faibussowitsch PetscCall(MatGetValues(C, 1, &i, 1, &j, &actualC(i,j))); 148c4762a1bSJed Brown } 149c4762a1bSJed Brown } 150c4762a1bSJed Brown blitz::Array<double,2> expectedC(cols, cols); 151c4762a1bSJed Brown expectedC = 0.0; 152c4762a1bSJed Brown 153c4762a1bSJed Brown expectedC(0,0) = 10.0; 154c4762a1bSJed Brown expectedC(0,1) = 2.0; 155c4762a1bSJed Brown expectedC(0,2) = -9.0; 156c4762a1bSJed Brown expectedC(0,3) = -1.0; 157c4762a1bSJed Brown expectedC(1,0) = 2.0; 158c4762a1bSJed Brown expectedC(1,1) = 5.0; 159c4762a1bSJed Brown expectedC(1,2) = -1.0; 160c4762a1bSJed Brown expectedC(1,3) = -2.0; 161c4762a1bSJed Brown expectedC(2,0) = -9.0; 162c4762a1bSJed Brown expectedC(2,1) = -1.0; 163c4762a1bSJed Brown expectedC(2,2) = 10.0; 164c4762a1bSJed Brown expectedC(2,3) = 0.0; 165c4762a1bSJed Brown expectedC(3,0) = -1.0; 166c4762a1bSJed Brown expectedC(3,1) = -2.0; 167c4762a1bSJed Brown expectedC(3,2) = 0.0; 168c4762a1bSJed Brown expectedC(3,3) = 1.0; 169c4762a1bSJed Brown 170c4762a1bSJed Brown int check = areBlitzArrays2NumericallyEqual(actualC,expectedC); 171c4762a1bSJed Brown validateEqualsWithParams3(check, -1 , "testPTAPRectangular()", check, actualC(check), expectedC(check)); 172c4762a1bSJed Brown */ 173c4762a1bSJed Brown 1749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 1759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&P)); 1769566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 177*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 178c4762a1bSJed Brown } 179c4762a1bSJed Brown 180c4762a1bSJed Brown /*TEST 181c4762a1bSJed Brown 182c4762a1bSJed Brown test: 183c4762a1bSJed Brown 184c4762a1bSJed Brown test: 185c4762a1bSJed Brown suffix: 2 186c4762a1bSJed Brown nsize: 2 187c20d7725SJed Brown args: -matmatmult_via nonscalable 188c20d7725SJed Brown output_file: output/ex93_1.out 189c4762a1bSJed Brown 190c4762a1bSJed Brown test: 191c4762a1bSJed Brown suffix: 3 192c4762a1bSJed Brown nsize: 2 193c20d7725SJed Brown output_file: output/ex93_1.out 194c4762a1bSJed Brown 195c4762a1bSJed Brown test: 196c4762a1bSJed Brown suffix: 4 197c4762a1bSJed Brown nsize: 2 198c20d7725SJed Brown args: -matptap_via scalable 199c20d7725SJed Brown output_file: output/ex93_1.out 200c4762a1bSJed Brown 201c4762a1bSJed Brown test: 202c4762a1bSJed Brown suffix: btheap 203c20d7725SJed Brown args: -matmatmult_via btheap -matmattransmult_via color 204c4762a1bSJed Brown output_file: output/ex93_1.out 205c4762a1bSJed Brown 206c4762a1bSJed Brown test: 207c4762a1bSJed Brown suffix: heap 208c20d7725SJed Brown args: -matmatmult_via heap 209c4762a1bSJed Brown output_file: output/ex93_1.out 210c4762a1bSJed Brown 211c4762a1bSJed Brown #HYPRE PtAP is broken for complex numbers 212c4762a1bSJed Brown test: 213c4762a1bSJed Brown suffix: hypre 214c4762a1bSJed Brown nsize: 3 215c4762a1bSJed Brown requires: hypre !complex 216c20d7725SJed Brown args: -matmatmult_via hypre -matptap_via hypre -test_hypre 217c20d7725SJed Brown output_file: output/ex93_hypre.out 218c4762a1bSJed Brown 219c4762a1bSJed Brown test: 220c4762a1bSJed Brown suffix: llcondensed 221c20d7725SJed Brown args: -matmatmult_via llcondensed 222c4762a1bSJed Brown output_file: output/ex93_1.out 223c4762a1bSJed Brown 224c4762a1bSJed Brown test: 225c4762a1bSJed Brown suffix: scalable 226c20d7725SJed Brown args: -matmatmult_via scalable 227c4762a1bSJed Brown output_file: output/ex93_1.out 228c4762a1bSJed Brown 229c4762a1bSJed Brown test: 230c4762a1bSJed Brown suffix: scalable_fast 231c20d7725SJed Brown args: -matmatmult_via scalable_fast 232c4762a1bSJed Brown output_file: output/ex93_1.out 233c4762a1bSJed Brown 234c4762a1bSJed Brown TEST*/ 235