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 179566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc,&args,(char*)0,help)); 189566063dSJacob 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; 229566063dSJacob Faibussowitsch PetscCall(PetscOptionsInsertString(NULL,"-options_left 0")); 23c4762a1bSJed Brown #endif 249566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL,NULL,"-ptap",&testptap,NULL)); 259566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL,NULL,"-matmatmult",&testmatmatmult,NULL)); 269566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); 27c4762a1bSJed Brown if (!flg) { /* Create a matrix and test MatSetValues */ 28c4762a1bSJed Brown PetscMPIInt size; 29c4762a1bSJed Brown 309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size)); 319566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL)); 329566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL)); 339566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N)); 349566063dSJacob Faibussowitsch PetscCall(MatSetType(A,MATAIJ)); 359566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A,9,NULL)); 369566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A,9,NULL,9,NULL)); 379566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD,&B)); 389566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N)); 399566063dSJacob Faibussowitsch PetscCall(MatSetType(B,MATHYPRE)); 40c4762a1bSJed Brown if (M == N) { 419566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(B,9,NULL,9,NULL)); 42c4762a1bSJed Brown } else { 439566063dSJacob 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) { 519566063dSJacob Faibussowitsch PetscCall(MatSetValue(A,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES)); 529566063dSJacob Faibussowitsch PetscCall(MatSetValue(B,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES)); 53c4762a1bSJed Brown } else if (i > j) { 549566063dSJacob Faibussowitsch PetscCall(MatSetValue(A,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES)); 559566063dSJacob Faibussowitsch PetscCall(MatSetValue(B,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES)); 56c4762a1bSJed Brown } else { 579566063dSJacob Faibussowitsch PetscCall(MatSetValue(A,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES)); 589566063dSJacob Faibussowitsch PetscCall(MatSetValue(B,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES)); 59c4762a1bSJed Brown } 60c4762a1bSJed Brown } 619566063dSJacob Faibussowitsch PetscCall(MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,ADD_VALUES)); 629566063dSJacob 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 689566063dSJacob 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 739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 749566063dSJacob 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 { 789566063dSJacob 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 849566063dSJacob Faibussowitsch PetscCall(MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,INSERT_VALUES)); 859566063dSJacob 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 */ 899566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 909566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 919566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 929566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 93c4762a1bSJed Brown 94c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX) 95c4762a1bSJed Brown /* make the matrix imaginary */ 969566063dSJacob Faibussowitsch PetscCall(MatScale(A,PETSC_i)); 979566063dSJacob Faibussowitsch PetscCall(MatScale(B,PETSC_i)); 98c4762a1bSJed Brown #endif 99c4762a1bSJed Brown 100c4762a1bSJed Brown /* MatAXPY further exercises MatSetValues_HYPRE */ 1019566063dSJacob Faibussowitsch PetscCall(MatAXPY(B,-1.,A,DIFFERENT_NONZERO_PATTERN)); 1029566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATMPIAIJ,MAT_INITIAL_MATRIX,&C)); 1039566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 10454c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatSetValues %g",err); 1059566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 1069566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 107c4762a1bSJed Brown } else { 108c4762a1bSJed Brown PetscViewer viewer; 109c4762a1bSJed Brown 1109566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&viewer)); 1119566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 1129566063dSJacob Faibussowitsch PetscCall(MatLoad(A,viewer)); 1139566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 1149566063dSJacob Faibussowitsch PetscCall(MatGetSize(A,&M,&N)); 115c4762a1bSJed Brown } 116c4762a1bSJed Brown 117c4762a1bSJed Brown /* check conversion routines */ 1189566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B)); 1199566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_REUSE_MATRIX,&B)); 1209566063dSJacob Faibussowitsch PetscCall(MatMultEqual(B,A,4,&flg)); 12154c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat HYPRE"); 1229566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATIS,MAT_INITIAL_MATRIX,&D)); 1239566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATIS,MAT_REUSE_MATRIX,&D)); 1249566063dSJacob Faibussowitsch PetscCall(MatMultEqual(D,A,4,&flg)); 12554c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat IS"); 1269566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,&C)); 1279566063dSJacob Faibussowitsch PetscCall(MatConvert(B,MATAIJ,MAT_REUSE_MATRIX,&C)); 1289566063dSJacob Faibussowitsch PetscCall(MatMultEqual(C,A,4,&flg)); 12954c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat AIJ"); 1309566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN)); 1319566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 13254c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat AIJ %g",err); 1339566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 1349566063dSJacob Faibussowitsch PetscCall(MatConvert(D,MATAIJ,MAT_INITIAL_MATRIX,&C)); 1359566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN)); 1369566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 13754c59aa7SJacob Faibussowitsch PetscCheck(err <= PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat IS %g",err); 1389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 1399566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 140c4762a1bSJed Brown 141c4762a1bSJed Brown /* check MatCreateFromParCSR */ 1429566063dSJacob Faibussowitsch PetscCall(MatHYPREGetParCSR(B,&parcsr)); 1439566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr,MATAIJ,PETSC_COPY_VALUES,&D)); 1449566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 1459566063dSJacob Faibussowitsch PetscCall(MatCreateFromParCSR(parcsr,MATHYPRE,PETSC_USE_POINTER,&C)); 146c4762a1bSJed Brown 147c4762a1bSJed Brown /* check MatMult operations */ 1489566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A,B,4,&flg)); 14954c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult B"); 1509566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A,C,4,&flg)); 15154c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult C"); 1529566063dSJacob Faibussowitsch PetscCall(MatMultAddEqual(A,B,4,&flg)); 15354c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd B"); 1549566063dSJacob Faibussowitsch PetscCall(MatMultAddEqual(A,C,4,&flg)); 15554c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd C"); 1569566063dSJacob Faibussowitsch PetscCall(MatMultTransposeEqual(A,B,4,&flg)); 15754c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose B"); 1589566063dSJacob Faibussowitsch PetscCall(MatMultTransposeEqual(A,C,4,&flg)); 15954c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose C"); 1609566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAddEqual(A,B,4,&flg)); 16154c59aa7SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTransposeAdd B"); 1629566063dSJacob 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 */ 1719566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pP)); 1729566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,A,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pP)); 1739566063dSJacob Faibussowitsch PetscCall(MatNorm(pP,NORM_INFINITY,&norm)); 1749566063dSJacob 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 */ 1789566063dSJacob Faibussowitsch PetscCall(MatPtAP(C,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP)); 1799566063dSJacob Faibussowitsch PetscCall(MatPtAP(C,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP)); 1809566063dSJacob 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() */ 1849566063dSJacob Faibussowitsch PetscCall(MatAXPY(hP,-1.,pP,DIFFERENT_NONZERO_PATTERN)); 1859566063dSJacob Faibussowitsch PetscCall(MatHasOperation(hP,MATOP_NORM,&flg)); 186c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 1879566063dSJacob Faibussowitsch PetscCall(MatConvert(hP,MATAIJ,MAT_INPLACE_MATRIX,&hP)); 188c4762a1bSJed Brown } 1899566063dSJacob Faibussowitsch PetscCall(MatNorm(hP,NORM_INFINITY,&err)); 190*e00437b9SBarry Smith PetscCheck(err/norm <= PETSC_SMALL,PetscObjectComm((PetscObject)hP),PETSC_ERR_PLIB,"Error MatPtAP %g %g",err,norm); 1919566063dSJacob Faibussowitsch PetscCall(MatDestroy(&pP)); 1929566063dSJacob Faibussowitsch PetscCall(MatDestroy(&hP)); 193c4762a1bSJed Brown 194c4762a1bSJed Brown /* MatPtAP_AIJ_HYPRE -> output can be decided at runtime with -matptap_hypre_outtype */ 1959566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP)); 1969566063dSJacob Faibussowitsch PetscCall(MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP)); 1979566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A,B,hP,10,&flg)); 19854c59aa7SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_AIJ_HYPRE"); 1999566063dSJacob Faibussowitsch PetscCall(MatDestroy(&hP)); 200c4762a1bSJed Brown } 2019566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2029566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 203c4762a1bSJed Brown 204c4762a1bSJed Brown /* check MatMatMult */ 205c4762a1bSJed Brown if (testmatmatmult) { 2069566063dSJacob Faibussowitsch PetscCall(MatTranspose(A,MAT_INITIAL_MATRIX,&B)); 2079566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&C)); 2089566063dSJacob 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 */ 2129566063dSJacob Faibussowitsch PetscCall(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pAB)); 2139566063dSJacob Faibussowitsch PetscCall(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pAB)); 2149566063dSJacob Faibussowitsch PetscCall(MatNorm(pAB,NORM_INFINITY,&norm)); 2159566063dSJacob 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 */ 2199566063dSJacob Faibussowitsch PetscCall(MatMatMult(C,D,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CD)); 2209566063dSJacob Faibussowitsch PetscCall(MatMatMult(C,D,MAT_REUSE_MATRIX,PETSC_DEFAULT,&CD)); 2219566063dSJacob 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() */ 2259566063dSJacob Faibussowitsch PetscCall(MatAXPY(CD,-1.,pAB,DIFFERENT_NONZERO_PATTERN)); 226c20d7725SJed Brown 2279566063dSJacob Faibussowitsch PetscCall(MatHasOperation(CD,MATOP_NORM,&flg)); 228c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 2299566063dSJacob Faibussowitsch PetscCall(MatConvert(CD,MATAIJ,MAT_INPLACE_MATRIX,&CD)); 230c4762a1bSJed Brown } 2319566063dSJacob 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 2349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 2369566063dSJacob Faibussowitsch PetscCall(MatDestroy(&pAB)); 2379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&CD)); 238c4762a1bSJed Brown 239c4762a1bSJed Brown /* When configured with HYPRE, MatMatMatMult is available for the triplet transpose(aij)-aij-aij */ 2409566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(A,&C)); 2419566063dSJacob Faibussowitsch PetscCall(MatMatMatMult(C,A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CAB)); 2429566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2439566063dSJacob Faibussowitsch PetscCall(MatTranspose(A,MAT_INITIAL_MATRIX,&C)); 2449566063dSJacob Faibussowitsch PetscCall(MatMatMult(C,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D)); 2459566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2469566063dSJacob Faibussowitsch PetscCall(MatMatMult(D,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C)); 2479566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&norm)); 2489566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.,CAB,DIFFERENT_NONZERO_PATTERN)); 2499566063dSJacob 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); 2519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 2539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&CAB)); 2549566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 255c4762a1bSJed Brown } 256c4762a1bSJed Brown 257c4762a1bSJed Brown /* Check MatView */ 2589566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_A")); 2599566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B)); 2609566063dSJacob 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 2739566063dSJacob 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 2799566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A,dop,&C)); 2809566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B,dop,&D)); 281c4762a1bSJed Brown if (dop != MAT_COPY_VALUES) { 2829566063dSJacob Faibussowitsch PetscCall(MatCopy(A,C,str)); 2839566063dSJacob Faibussowitsch PetscCall(MatCopy(B,D,str)); 284c4762a1bSJed Brown } 285c4762a1bSJed Brown /* AXPY with AIJ and HYPRE */ 2869566063dSJacob Faibussowitsch PetscCall(MatAXPY(C,-1.0,D,str)); 2879566063dSJacob Faibussowitsch PetscCall(MatNorm(C,NORM_INFINITY,&err)); 288c4762a1bSJed Brown if (err > PETSC_SMALL) { 2899566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_duplicate_diff")); 2909566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B,NULL,"-view_duplicate_diff")); 2919566063dSJacob 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 */ 2959566063dSJacob Faibussowitsch PetscCall(MatAXPY(D,-1.0,B,str)); 296c4762a1bSJed Brown if (err > PETSC_SMALL) { 2979566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_duplicate_diff")); 2989566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(B,NULL,"-view_duplicate_diff")); 2999566063dSJacob 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 */ 3039566063dSJacob Faibussowitsch PetscCall(MatCopy(B,C,str)); 304c4762a1bSJed Brown /* Copy from AIJ to HYPRE */ 3059566063dSJacob Faibussowitsch PetscCall(MatCopy(A,D,str)); 306c4762a1bSJed Brown /* AXPY with HYPRE and AIJ */ 3079566063dSJacob Faibussowitsch PetscCall(MatAXPY(D,-1.0,C,str)); 3089566063dSJacob Faibussowitsch PetscCall(MatHasOperation(D,MATOP_NORM,&flg)); 309c4762a1bSJed Brown if (!flg) { /* TODO add MatNorm_HYPRE */ 3109566063dSJacob Faibussowitsch PetscCall(MatConvert(D,MATAIJ,MAT_INPLACE_MATRIX,&D)); 311c4762a1bSJed Brown } 3129566063dSJacob Faibussowitsch PetscCall(MatNorm(D,NORM_INFINITY,&err)); 313c4762a1bSJed Brown if (err > PETSC_SMALL) { 3149566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A,NULL,"-view_duplicate_diff")); 3159566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(C,NULL,"-view_duplicate_diff")); 3169566063dSJacob 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 } 3199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 3209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 321c4762a1bSJed Brown } 322c4762a1bSJed Brown } 3239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 324c4762a1bSJed Brown 3259566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(A,&flg)); 326c4762a1bSJed Brown if (flg) { 327c4762a1bSJed Brown Vec y,y2; 328c4762a1bSJed Brown 3299566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B)); 3309566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A,NULL,&y)); 3319566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(B,NULL,&y2)); 3329566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(A,y)); 3339566063dSJacob Faibussowitsch PetscCall(MatGetDiagonal(B,y2)); 3349566063dSJacob Faibussowitsch PetscCall(VecAXPY(y2,-1.0,y)); 3359566063dSJacob Faibussowitsch PetscCall(VecNorm(y2,NORM_INFINITY,&err)); 336c4762a1bSJed Brown if (err > PETSC_SMALL) { 3379566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(y,NULL,"-view_diagonal_diff")); 3389566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(y2,NULL,"-view_diagonal_diff")); 33998921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatGetDiagonal %g",err); 340c4762a1bSJed Brown } 3419566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 3429566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y)); 3439566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y2)); 344c4762a1bSJed Brown } 345c4762a1bSJed Brown 3469566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 347c4762a1bSJed Brown 3489566063dSJacob 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