1c4762a1bSJed Brown static char help[] = "Tests the use of MatTranspose_Nest and MatMatMult_Nest_Dense\n"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown #include <petscmat.h> 4c4762a1bSJed Brown 5c4762a1bSJed Brown PetscErrorCode TestInitialMatrix(void) 6c4762a1bSJed Brown { 7c4762a1bSJed Brown const PetscInt nr = 2,nc = 3,nk = 10; 8c4762a1bSJed Brown PetscInt n,N,m,M; 9c4762a1bSJed Brown const PetscInt arow[2*3] = { 2,2,2,3,3,3 }; 10c4762a1bSJed Brown const PetscInt acol[2*3] = { 3,2,4,3,2,4 }; 11c4762a1bSJed Brown Mat A,Atranspose,B,C; 12c4762a1bSJed Brown Mat subs[2*3],**block; 13c4762a1bSJed Brown Vec x,y,Ax,ATy; 14c4762a1bSJed Brown PetscInt i,j; 15c20d7725SJed Brown PetscScalar dot1,dot2,zero = 0.0,one = 1.0,*valsB,*valsC; 16c4762a1bSJed Brown PetscReal norm; 17c4762a1bSJed Brown PetscRandom rctx; 18c20d7725SJed Brown PetscBool equal; 19c4762a1bSJed Brown 20c4762a1bSJed Brown PetscFunctionBegin; 215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomCreate(PETSC_COMM_WORLD,&rctx)); 22c4762a1bSJed Brown /* Force the random numbers to have imaginary part 0 so printed results are the same for --with-scalar-type=real or --with-scalar-type=complex */ 235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomSetInterval(rctx,zero,one)); 245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomSetFromOptions(rctx)); 25c4762a1bSJed Brown for (i=0; i<(nr * nc); i++) { 265f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateSeqDense(PETSC_COMM_WORLD,arow[i],acol[i],NULL,&subs[i])); 27c4762a1bSJed Brown } 285f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateNest(PETSC_COMM_WORLD,nr,NULL,nc,NULL,subs,&A)); 295f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateVecs(A, &x, NULL)); 305f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateVecs(A, NULL, &y)); 315f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(x, &ATy)); 325f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(y, &Ax)); 335f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetRandom(A,rctx)); 345f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(A, MAT_INITIAL_MATRIX, &Atranspose)); 35c4762a1bSJed Brown 365f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(A, PETSC_VIEWER_STDOUT_WORLD)); 375f80ce2aSJacob Faibussowitsch CHKERRQ(MatNestGetSubMats(A, NULL, NULL, &block)); 38c4762a1bSJed Brown for (i=0; i<nr; i++) { 39c4762a1bSJed Brown for (j=0; j<nc; j++) { 405f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(block[i][j], PETSC_VIEWER_STDOUT_WORLD)); 41c4762a1bSJed Brown } 42c4762a1bSJed Brown } 43c4762a1bSJed Brown 445f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(Atranspose, PETSC_VIEWER_STDOUT_WORLD)); 455f80ce2aSJacob Faibussowitsch CHKERRQ(MatNestGetSubMats(Atranspose, NULL, NULL, &block)); 46c4762a1bSJed Brown for (i=0; i<nc; i++) { 47c4762a1bSJed Brown for (j=0; j<nr; j++) { 485f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(block[i][j], PETSC_VIEWER_STDOUT_WORLD)); 49c4762a1bSJed Brown } 50c4762a1bSJed Brown } 51c4762a1bSJed Brown 52c4762a1bSJed Brown /* Check <Ax, y> = <x, A^Ty> */ 53c4762a1bSJed Brown for (i=0; i<10; i++) { 545f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetRandom(x,rctx)); 555f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetRandom(y,rctx)); 56c4762a1bSJed Brown 575f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(A, x, Ax)); 585f80ce2aSJacob Faibussowitsch CHKERRQ(VecDot(Ax, y, &dot1)); 595f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(Atranspose, y, ATy)); 605f80ce2aSJacob Faibussowitsch CHKERRQ(VecDot(ATy, x, &dot2)); 61c4762a1bSJed Brown 625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "<Ax, y> = %g\n", (double)PetscRealPart(dot1))); 635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "<x, A^Ty> = %g\n",(double)PetscRealPart(dot2))); 64c4762a1bSJed Brown } 655f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x)); 665f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&y)); 675f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&Ax)); 68c4762a1bSJed Brown 695f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateSeqDense(PETSC_COMM_WORLD,acol[0]+acol[nr]+acol[2*nr],nk,NULL,&B)); 705f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetRandom(B,rctx)); 715f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C)); 725f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C)); 735f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMultEqual(A,B,C,10,&equal)); 7428b400f6SJacob Faibussowitsch PetscCheck(equal,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in C != A*B"); 75c20d7725SJed Brown 765f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(A,&M,&N)); 775f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetLocalSize(A,&m,&n)); 78c4762a1bSJed Brown for (i=0; i<nk; i++) { 795f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseGetColumn(B,i,&valsB)); 805f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,N,valsB,&x)); 815f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateVecs(A,NULL,&Ax)); 825f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult(A,x,Ax)); 835f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x)); 845f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseGetColumn(C,i,&valsC)); 855f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreateMPIWithArray(PETSC_COMM_WORLD,1,m,M,valsC,&y)); 865f80ce2aSJacob Faibussowitsch CHKERRQ(VecAXPY(y,-1.0,Ax)); 875f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&Ax)); 885f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&y)); 895f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseRestoreColumn(C,&valsC)); 905f80ce2aSJacob Faibussowitsch CHKERRQ(MatDenseRestoreColumn(B,&valsB)); 91c4762a1bSJed Brown } 925f80ce2aSJacob Faibussowitsch CHKERRQ(MatNorm(C,NORM_INFINITY,&norm)); 932c71b3e2SJacob Faibussowitsch PetscCheckFalse(norm > PETSC_SMALL,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatMult(): %g",(double)norm); 945f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&C)); 955f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&B)); 96c4762a1bSJed Brown 97c4762a1bSJed Brown for (i=0; i<(nr * nc); i++) { 985f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&subs[i])); 99c4762a1bSJed Brown } 1005f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&A)); 1015f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&Atranspose)); 1025f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&ATy)); 1035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomDestroy(&rctx)); 104c4762a1bSJed Brown PetscFunctionReturn(0); 105c4762a1bSJed Brown } 106c4762a1bSJed Brown 107c4762a1bSJed Brown PetscErrorCode TestReuseMatrix(void) 108c4762a1bSJed Brown { 109c4762a1bSJed Brown const PetscInt n = 2; 110c4762a1bSJed Brown Mat A; 111c4762a1bSJed Brown Mat subs[2*2],**block; 112c4762a1bSJed Brown PetscInt i,j; 113c4762a1bSJed Brown PetscRandom rctx; 114c4762a1bSJed Brown PetscScalar zero = 0.0, one = 1.0; 115c4762a1bSJed Brown 116c4762a1bSJed Brown PetscFunctionBegin; 1175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomCreate(PETSC_COMM_WORLD,&rctx)); 1185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomSetInterval(rctx,zero,one)); 1195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomSetFromOptions(rctx)); 120c4762a1bSJed Brown for (i=0; i<(n * n); i++) { 1215f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateSeqDense(PETSC_COMM_WORLD,n,n,NULL,&subs[i])); 122c4762a1bSJed Brown } 1235f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateNest(PETSC_COMM_WORLD,n,NULL,n,NULL,subs,&A)); 1245f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetRandom(A,rctx)); 125c4762a1bSJed Brown 1265f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(A, PETSC_VIEWER_STDOUT_WORLD)); 1275f80ce2aSJacob Faibussowitsch CHKERRQ(MatNestGetSubMats(A, NULL, NULL, &block)); 128c4762a1bSJed Brown for (i=0; i<n; i++) { 129c4762a1bSJed Brown for (j=0; j<n; j++) { 1305f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(block[i][j], PETSC_VIEWER_STDOUT_WORLD)); 131c4762a1bSJed Brown } 132c4762a1bSJed Brown } 1335f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(A,MAT_INPLACE_MATRIX,&A)); 1345f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(A, PETSC_VIEWER_STDOUT_WORLD)); 1355f80ce2aSJacob Faibussowitsch CHKERRQ(MatNestGetSubMats(A, NULL, NULL, &block)); 136c4762a1bSJed Brown for (i=0; i<n; i++) { 137c4762a1bSJed Brown for (j=0; j<n; j++) { 1385f80ce2aSJacob Faibussowitsch CHKERRQ(MatView(block[i][j], PETSC_VIEWER_STDOUT_WORLD)); 139c4762a1bSJed Brown } 140c4762a1bSJed Brown } 141c4762a1bSJed Brown 142c4762a1bSJed Brown for (i=0; i<(n * n); i++) { 1435f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&subs[i])); 144c4762a1bSJed Brown } 1455f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&A)); 1465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomDestroy(&rctx)); 147c4762a1bSJed Brown PetscFunctionReturn(0); 148c4762a1bSJed Brown } 149c4762a1bSJed Brown 150c4762a1bSJed Brown int main(int argc,char **args) 151c4762a1bSJed Brown { 152c4762a1bSJed Brown 153*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscInitialize(&argc,&args,(char*)0,help)); 1545f80ce2aSJacob Faibussowitsch CHKERRQ(TestInitialMatrix()); 1555f80ce2aSJacob Faibussowitsch CHKERRQ(TestReuseMatrix()); 156*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscFinalize()); 157*b122ec5aSJacob Faibussowitsch return 0; 158c4762a1bSJed Brown } 159c4762a1bSJed Brown 160c4762a1bSJed Brown /*TEST 161c4762a1bSJed Brown 162c4762a1bSJed Brown test: 163c4762a1bSJed Brown args: -malloc_dump 164c4762a1bSJed Brown 165c4762a1bSJed Brown TEST*/ 166