1c4762a1bSJed Brown 2c4762a1bSJed Brown static char help[] = "Tests MatHYPRE\n"; 3c4762a1bSJed Brown 4c4762a1bSJed Brown #include <petscmathypre.h> 5c4762a1bSJed Brown 6c4762a1bSJed Brown int main(int argc,char **args) 7c4762a1bSJed Brown { 8c4762a1bSJed Brown Mat A,B,C,D; 9c4762a1bSJed Brown Mat pAB,CD,CAB; 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]; 16c4762a1bSJed Brown 17*9566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc,&args,(char*)0,help)); 18*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL,NULL,"-f",file,sizeof(file),&flg)); 19c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 20c4762a1bSJed Brown testptap = PETSC_FALSE; 21c4762a1bSJed Brown testmatmatmult = PETSC_FALSE; 22*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsInsertString(NULL,"-options_left 0")); 23c4762a1bSJed Brown #endif 24*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL,NULL,"-ptap",&testptap,NULL)); 25*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL,NULL,"-matmatmult",&testmatmatmult,NULL)); 26*9566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); 27c4762a1bSJed Brown if (!flg) { /* Create a matrix and test MatSetValues */ 28c4762a1bSJed Brown PetscMPIInt size; 29c4762a1bSJed Brown 30*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); 31*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL)); 32*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL)); 33*9566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N)); 34*9566063dSJacob Faibussowitsch PetscCall(MatSetType(A,MATAIJ)); 35*9566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A,9,NULL)); 36*9566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A,9,NULL,9,NULL)); 37*9566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD,&B)); 38*9566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N)); 39*9566063dSJacob Faibussowitsch PetscCall(MatSetType(B,MATHYPRE)); 40c4762a1bSJed Brown if (M == N) { 41*9566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(B,9,NULL,9,NULL)); 42c4762a1bSJed Brown } else { 43*9566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(B,6,NULL,6,NULL)); 44c4762a1bSJed Brown } 45c4762a1bSJed Brown if (M == N) { 46c4762a1bSJed Brown for (i=0; i<M; i++) { 47c4762a1bSJed Brown PetscInt cols[] = {0,1,2,3,4,5}; 48c4762a1bSJed Brown PetscScalar vals[] = {0,1./size,2./size,3./size,4./size,5./size}; 49c4762a1bSJed Brown for (j=i-2; j<i+1; j++) { 50c4762a1bSJed Brown if (j >= N) { 51*9566063dSJacob Faibussowitsch PetscCall(MatSetValue(A,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES)); 52*9566063dSJacob Faibussowitsch PetscCall(MatSetValue(B,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES)); 53c4762a1bSJed Brown } else if (i > j) { 54*9566063dSJacob Faibussowitsch PetscCall(MatSetValue(A,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES)); 55*9566063dSJacob Faibussowitsch PetscCall(MatSetValue(B,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES)); 56c4762a1bSJed Brown } else { 57*9566063dSJacob Faibussowitsch PetscCall(MatSetValue(A,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES)); 58*9566063dSJacob Faibussowitsch PetscCall(MatSetValue(B,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES)); 59c4762a1bSJed Brown } 60c4762a1bSJed Brown } 61*9566063dSJacob Faibussowitsch PetscCall(MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,ADD_VALUES)); 62*9566063dSJacob Faibussowitsch PetscCall(MatSetValues(B,1,&i,PetscMin(6,N),cols,vals,ADD_VALUES)); 63c4762a1bSJed Brown } 64c4762a1bSJed Brown } else { 65c4762a1bSJed Brown PetscInt rows[2]; 66c4762a1bSJed Brown PetscBool test_offproc = PETSC_FALSE; 67c4762a1bSJed Brown 68*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL,NULL,"-test_offproc",&test_offproc,NULL)); 69c4762a1bSJed Brown if (test_offproc) { 70c4762a1bSJed Brown const PetscInt *ranges; 71c4762a1bSJed Brown PetscMPIInt rank; 72c4762a1bSJed Brown 73*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 74*9566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRanges(A,&ranges)); 75c4762a1bSJed Brown rows[0] = ranges[(rank+1)%size]; 76c4762a1bSJed Brown rows[1] = ranges[(rank+1)%size + 1]; 77c4762a1bSJed Brown } else { 78*9566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A,&rows[0],&rows[1])); 79c4762a1bSJed Brown } 80c4762a1bSJed Brown for (i=rows[0];i<rows[1];i++) { 81c4762a1bSJed Brown PetscInt cols[] = {0,1,2,3,4,5}; 82c4762a1bSJed Brown PetscScalar vals[] = {-1,1,-2,2,-3,3}; 83c4762a1bSJed Brown 84*9566063dSJacob Faibussowitsch PetscCall(MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,INSERT_VALUES)); 85*9566063dSJacob Faibussowitsch PetscCall(MatSetValues(B,1,&i,PetscMin(6,N),cols,vals,INSERT_VALUES)); 86c4762a1bSJed Brown } 87c4762a1bSJed Brown } 88c4762a1bSJed Brown /* MAT_FLUSH_ASSEMBLY currently not supported */ 89*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 90*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 91*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 92*9566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 93c4762a1bSJed Brown 94c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 95c4762a1bSJed Brown /* make the matrix imaginary */ 96*9566063dSJacob Faibussowitsch PetscCall(MatScale(A,PETSC_i)); 97*9566063dSJacob Faibussowitsch PetscCall(MatScale(B,PETSC_i)); 98c4762a1bSJed Brown #endif 99c4762a1bSJed Brown 100c4762a1bSJed Brown /* MatAXPY further exercises MatSetValues_HYPRE */ 101*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(B,-1.,A,DIFFERENT_NONZERO_PATTERN)); 102*9566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATMPIAIJ,MAT_INITIAL_MATRIX,&C)); 103*9566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 10454c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatSetValues %g",err); 105*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 106*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 107c4762a1bSJed Brown } else { 108c4762a1bSJed Brown PetscViewer viewer; 109c4762a1bSJed Brown 110*9566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&viewer)); 111*9566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 112*9566063dSJacob Faibussowitsch PetscCall(MatLoad(A,viewer)); 113*9566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 114*9566063dSJacob Faibussowitsch PetscCall(MatGetSize(A,&M,&N)); 115c4762a1bSJed Brown } 116c4762a1bSJed Brown 117c4762a1bSJed Brown /* check conversion routines */ 118*9566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B)); 119*9566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_REUSE_MATRIX,&B)); 120*9566063dSJacob Faibussowitsch PetscCall(MatMultEqual(B,A,4,&flg)); 12154c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat HYPRE"); 122*9566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATIS,MAT_INITIAL_MATRIX,&D)); 123*9566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATIS,MAT_REUSE_MATRIX,&D)); 124*9566063dSJacob Faibussowitsch PetscCall(MatMultEqual(D,A,4,&flg)); 12554c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat IS"); 126*9566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,&C)); 127*9566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATAIJ,MAT_REUSE_MATRIX,&C)); 128*9566063dSJacob Faibussowitsch PetscCall(MatMultEqual(C,A,4,&flg)); 12954c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat AIJ"); 130*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN)); 131*9566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 13254c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat AIJ %g",err); 133*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 134*9566063dSJacob Faibussowitsch PetscCall(MatConvert(D,MATAIJ,MAT_INITIAL_MATRIX,&C)); 135*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN)); 136*9566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 13754c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat IS %g",err); 138*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 139*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 140c4762a1bSJed Brown 141c4762a1bSJed Brown /* check MatCreateFromParCSR */ 142*9566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(B,&parcsr)); 143*9566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr,MATAIJ,PETSC_COPY_VALUES,&D)); 144*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 145*9566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr,MATHYPRE,PETSC_USE_POINTER,&C)); 146c4762a1bSJed Brown 147c4762a1bSJed Brown /* check MatMult operations */ 148*9566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A,B,4,&flg)); 14954c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult B"); 150*9566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A,C,4,&flg)); 15154c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult C"); 152*9566063dSJacob Faibussowitsch PetscCall(MatMultAddEqual(A,B,4,&flg)); 15354c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd B"); 154*9566063dSJacob Faibussowitsch PetscCall(MatMultAddEqual(A,C,4,&flg)); 15554c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd C"); 156*9566063dSJacob Faibussowitsch PetscCall(MatMultTransposeEqual(A,B,4,&flg)); 15754c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose B"); 158*9566063dSJacob Faibussowitsch PetscCall(MatMultTransposeEqual(A,C,4,&flg)); 15954c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose C"); 160*9566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAddEqual(A,B,4,&flg)); 16154c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTransposeAdd B"); 162*9566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAddEqual(A,C,4,&flg)); 16354c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTransposeAdd C"); 164c4762a1bSJed Brown 165c4762a1bSJed Brown /* check PtAP */ 166c4762a1bSJed Brown if (testptap && M == N) { 167c4762a1bSJed Brown Mat pP,hP; 168c4762a1bSJed Brown 169c4762a1bSJed Brown /* PETSc MatPtAP -> output is a MatAIJ 170c4762a1bSJed Brown It uses HYPRE functions when -matptap_via hypre is specified at command line */ 171*9566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pP)); 172*9566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,A,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pP)); 173*9566063dSJacob Faibussowitsch PetscCall(MatNorm(pP,NORM_INFINITY,&norm)); 174*9566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A,A,pP,10,&flg)); 17554c59aa7SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_MatAIJ"); 176c4762a1bSJed Brown 177c4762a1bSJed Brown /* MatPtAP_HYPRE_HYPRE -> output is a MatHYPRE */ 178*9566063dSJacob Faibussowitsch PetscCall(MatPtAP(C,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP)); 179*9566063dSJacob Faibussowitsch PetscCall(MatPtAP(C,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP)); 180*9566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(C,B,hP,10,&flg)); 18154c59aa7SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_HYPRE_HYPRE"); 182c20d7725SJed Brown 183c20d7725SJed Brown /* Test MatAXPY_Basic() */ 184*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(hP,-1.,pP,DIFFERENT_NONZERO_PATTERN)); 185*9566063dSJacob Faibussowitsch PetscCall(MatHasOperation(hP,MATOP_NORM,&flg)); 186c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 187*9566063dSJacob Faibussowitsch PetscCall(MatConvert(hP,MATAIJ,MAT_INPLACE_MATRIX,&hP)); 188c4762a1bSJed Brown } 189*9566063dSJacob Faibussowitsch PetscCall(MatNorm(hP,NORM_INFINITY,&err)); 1902c71b3e2SJacob Faibussowitsch PetscCheckFalse(err/norm > PETSC_SMALL,PetscObjectComm((PetscObject)hP),PETSC_ERR_PLIB,"Error MatPtAP %g %g",err,norm); 191*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&pP)); 192*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&hP)); 193c4762a1bSJed Brown 194c4762a1bSJed Brown /* MatPtAP_AIJ_HYPRE -> output can be decided at runtime with -matptap_hypre_outtype */ 195*9566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP)); 196*9566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP)); 197*9566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A,B,hP,10,&flg)); 19854c59aa7SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_AIJ_HYPRE"); 199*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&hP)); 200c4762a1bSJed Brown } 201*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 202*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 203c4762a1bSJed Brown 204c4762a1bSJed Brown /* check MatMatMult */ 205c4762a1bSJed Brown if (testmatmatmult) { 206*9566063dSJacob Faibussowitsch PetscCall(MatTranspose(A,MAT_INITIAL_MATRIX,&B)); 207*9566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&C)); 208*9566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATHYPRE,MAT_INITIAL_MATRIX,&D)); 209c4762a1bSJed Brown 210c4762a1bSJed Brown /* PETSc MatMatMult -> output is a MatAIJ 211c4762a1bSJed Brown It uses HYPRE functions when -matmatmult_via hypre is specified at command line */ 212*9566063dSJacob Faibussowitsch PetscCall(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pAB)); 213*9566063dSJacob Faibussowitsch PetscCall(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pAB)); 214*9566063dSJacob Faibussowitsch PetscCall(MatNorm(pAB,NORM_INFINITY,&norm)); 215*9566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(A,B,pAB,10,&flg)); 21654c59aa7SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatMult_AIJ_AIJ"); 217c4762a1bSJed Brown 218c4762a1bSJed Brown /* MatMatMult_HYPRE_HYPRE -> output is a MatHYPRE */ 219*9566063dSJacob Faibussowitsch PetscCall(MatMatMult(C,D,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CD)); 220*9566063dSJacob Faibussowitsch PetscCall(MatMatMult(C,D,MAT_REUSE_MATRIX,PETSC_DEFAULT,&CD)); 221*9566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(C,D,CD,10,&flg)); 22254c59aa7SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatMult_HYPRE_HYPRE"); 223c20d7725SJed Brown 224c20d7725SJed Brown /* Test MatAXPY_Basic() */ 225*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(CD,-1.,pAB,DIFFERENT_NONZERO_PATTERN)); 226c20d7725SJed Brown 227*9566063dSJacob Faibussowitsch PetscCall(MatHasOperation(CD,MATOP_NORM,&flg)); 228c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 229*9566063dSJacob Faibussowitsch PetscCall(MatConvert(CD,MATAIJ,MAT_INPLACE_MATRIX,&CD)); 230c4762a1bSJed Brown } 231*9566063dSJacob Faibussowitsch PetscCall(MatNorm(CD,NORM_INFINITY,&err)); 23254c59aa7SJacob Faibussowitsch PetscCheck((err/norm) <= PETSC_SMALL,PetscObjectComm((PetscObject)CD),PETSC_ERR_PLIB,"Error MatMatMult %g %g",err,norm); 233c20d7725SJed Brown 234*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 235*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 236*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&pAB)); 237*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&CD)); 238c4762a1bSJed Brown 239c4762a1bSJed Brown /* When configured with HYPRE, MatMatMatMult is available for the triplet transpose(aij)-aij-aij */ 240*9566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(A,&C)); 241*9566063dSJacob Faibussowitsch PetscCall(MatMatMatMult(C,A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CAB)); 242*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 243*9566063dSJacob Faibussowitsch PetscCall(MatTranspose(A,MAT_INITIAL_MATRIX,&C)); 244*9566063dSJacob Faibussowitsch PetscCall(MatMatMult(C,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D)); 245*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 246*9566063dSJacob Faibussowitsch PetscCall(MatMatMult(D,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C)); 247*9566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&norm)); 248*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.,CAB,DIFFERENT_NONZERO_PATTERN)); 249*9566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 25054c59aa7SJacob Faibussowitsch PetscCheck((err/norm) <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMatMatMult %g %g",err,norm); 251*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 252*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 253*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&CAB)); 254*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 255c4762a1bSJed Brown } 256c4762a1bSJed Brown 257c4762a1bSJed Brown /* Check MatView */ 258*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_A")); 259*9566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B)); 260*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B,NULL,"-view_B")); 261c4762a1bSJed Brown 262c4762a1bSJed Brown /* Check MatDuplicate/MatCopy */ 263c4762a1bSJed Brown for (j=0;j<3;j++) { 264c4762a1bSJed Brown MatDuplicateOption dop; 265c4762a1bSJed Brown 266c4762a1bSJed Brown dop = MAT_COPY_VALUES; 267c4762a1bSJed Brown if (j==1) dop = MAT_DO_NOT_COPY_VALUES; 268c4762a1bSJed Brown if (j==2) dop = MAT_SHARE_NONZERO_PATTERN; 269c4762a1bSJed Brown 270c4762a1bSJed Brown for (i=0;i<3;i++) { 271c4762a1bSJed Brown MatStructure str; 272c4762a1bSJed Brown 273*9566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Dup/Copy tests: %" PetscInt_FMT " %" PetscInt_FMT "\n",j,i)); 274c4762a1bSJed Brown 275c4762a1bSJed Brown str = DIFFERENT_NONZERO_PATTERN; 276c4762a1bSJed Brown if (i==1) str = SAME_NONZERO_PATTERN; 277c4762a1bSJed Brown if (i==2) str = SUBSET_NONZERO_PATTERN; 278c4762a1bSJed Brown 279*9566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A,dop,&C)); 280*9566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B,dop,&D)); 281c4762a1bSJed Brown if (dop != MAT_COPY_VALUES) { 282*9566063dSJacob Faibussowitsch PetscCall(MatCopy(A,C,str)); 283*9566063dSJacob Faibussowitsch PetscCall(MatCopy(B,D,str)); 284c4762a1bSJed Brown } 285c4762a1bSJed Brown /* AXPY with AIJ and HYPRE */ 286*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.0,D,str)); 287*9566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 288c4762a1bSJed Brown if (err > PETSC_SMALL) { 289*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_duplicate_diff")); 290*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B,NULL,"-view_duplicate_diff")); 291*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(C,NULL,"-view_duplicate_diff")); 29298921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 1 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i); 293c4762a1bSJed Brown } 294c4762a1bSJed Brown /* AXPY with HYPRE and HYPRE */ 295*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(D,-1.0,B,str)); 296c4762a1bSJed Brown if (err > PETSC_SMALL) { 297*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_duplicate_diff")); 298*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B,NULL,"-view_duplicate_diff")); 299*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(D,NULL,"-view_duplicate_diff")); 30098921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 2 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i); 301c4762a1bSJed Brown } 302c4762a1bSJed Brown /* Copy from HYPRE to AIJ */ 303*9566063dSJacob Faibussowitsch PetscCall(MatCopy(B,C,str)); 304c4762a1bSJed Brown /* Copy from AIJ to HYPRE */ 305*9566063dSJacob Faibussowitsch PetscCall(MatCopy(A,D,str)); 306c4762a1bSJed Brown /* AXPY with HYPRE and AIJ */ 307*9566063dSJacob Faibussowitsch PetscCall(MatAXPY(D,-1.0,C,str)); 308*9566063dSJacob Faibussowitsch PetscCall(MatHasOperation(D,MATOP_NORM,&flg)); 309c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 310*9566063dSJacob Faibussowitsch PetscCall(MatConvert(D,MATAIJ,MAT_INPLACE_MATRIX,&D)); 311c4762a1bSJed Brown } 312*9566063dSJacob Faibussowitsch PetscCall(MatNorm(D,NORM_INFINITY,&err)); 313c4762a1bSJed Brown if (err > PETSC_SMALL) { 314*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_duplicate_diff")); 315*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(C,NULL,"-view_duplicate_diff")); 316*9566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(D,NULL,"-view_duplicate_diff")); 31798921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 3 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i); 318c4762a1bSJed Brown } 319*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 320*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 321c4762a1bSJed Brown } 322c4762a1bSJed Brown } 323*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 324c4762a1bSJed Brown 325*9566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(A,&flg)); 326c4762a1bSJed Brown if (flg) { 327c4762a1bSJed Brown Vec y,y2; 328c4762a1bSJed Brown 329*9566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B)); 330*9566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A,NULL,&y)); 331*9566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(B,NULL,&y2)); 332*9566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(A,y)); 333*9566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(B,y2)); 334*9566063dSJacob Faibussowitsch PetscCall(VecAXPY(y2,-1.0,y)); 335*9566063dSJacob Faibussowitsch PetscCall(VecNorm(y2,NORM_INFINITY,&err)); 336c4762a1bSJed Brown if (err > PETSC_SMALL) { 337*9566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(y,NULL,"-view_diagonal_diff")); 338*9566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(y2,NULL,"-view_diagonal_diff")); 33998921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatGetDiagonal %g",err); 340c4762a1bSJed Brown } 341*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 342*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y)); 343*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y2)); 344c4762a1bSJed Brown } 345c4762a1bSJed Brown 346*9566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 347c4762a1bSJed Brown 348*9566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 349b122ec5aSJacob Faibussowitsch return 0; 350c4762a1bSJed Brown } 351c4762a1bSJed Brown 352c4762a1bSJed Brown /*TEST 353c4762a1bSJed Brown 354c4762a1bSJed Brown build: 355c4762a1bSJed Brown requires: hypre 356c4762a1bSJed Brown 357c4762a1bSJed Brown test: 358263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 359c4762a1bSJed Brown suffix: 1 360c4762a1bSJed Brown args: -N 11 -M 11 361c4762a1bSJed Brown output_file: output/ex115_1.out 362c4762a1bSJed Brown 363c4762a1bSJed Brown test: 364263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 365c4762a1bSJed Brown suffix: 2 366c4762a1bSJed Brown nsize: 3 367c4762a1bSJed Brown args: -N 13 -M 13 -matmatmult_via hypre 368c4762a1bSJed Brown output_file: output/ex115_1.out 369c4762a1bSJed Brown 370c4762a1bSJed Brown test: 371263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 372c4762a1bSJed Brown suffix: 3 373c4762a1bSJed Brown nsize: 4 374c4762a1bSJed Brown args: -M 13 -N 7 -matmatmult_via hypre 375c4762a1bSJed Brown output_file: output/ex115_1.out 376c4762a1bSJed Brown 377c4762a1bSJed Brown test: 378263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 379c4762a1bSJed Brown suffix: 4 380c4762a1bSJed Brown nsize: 2 381c4762a1bSJed Brown args: -M 12 -N 19 382c4762a1bSJed Brown output_file: output/ex115_1.out 383c4762a1bSJed Brown 384c4762a1bSJed Brown test: 385263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 386c4762a1bSJed Brown suffix: 5 387c4762a1bSJed Brown nsize: 3 388c4762a1bSJed Brown args: -M 13 -N 13 -matptap_via hypre -matptap_hypre_outtype hypre 389c4762a1bSJed Brown output_file: output/ex115_1.out 390c4762a1bSJed Brown 391c4762a1bSJed Brown test: 392263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 393c4762a1bSJed Brown suffix: 6 394c4762a1bSJed Brown nsize: 3 395c4762a1bSJed Brown args: -M 12 -N 19 -test_offproc 396c4762a1bSJed Brown output_file: output/ex115_1.out 397c4762a1bSJed Brown 398c4762a1bSJed Brown test: 399263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 400c4762a1bSJed Brown suffix: 7 401c4762a1bSJed Brown nsize: 3 402c4762a1bSJed Brown args: -M 19 -N 12 -test_offproc -view_B ::ascii_info_detail 403c4762a1bSJed Brown output_file: output/ex115_7.out 404c4762a1bSJed Brown 405c4762a1bSJed Brown test: 406263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 407c4762a1bSJed Brown suffix: 8 408c4762a1bSJed Brown nsize: 3 409c4762a1bSJed Brown args: -M 1 -N 12 -test_offproc 410c4762a1bSJed Brown output_file: output/ex115_1.out 411c4762a1bSJed Brown 412c4762a1bSJed Brown test: 413263f2b91SStefano Zampini requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 414c4762a1bSJed Brown suffix: 9 415c4762a1bSJed Brown nsize: 3 416c4762a1bSJed Brown args: -M 1 -N 2 -test_offproc 417c4762a1bSJed Brown output_file: output/ex115_1.out 418c4762a1bSJed Brown 419c4762a1bSJed Brown TEST*/ 420