Actual source code: ex104.c

petsc-3.7.3 2016-08-01
Report Typos and Errors
  1: static char help[] = "Test MatMatMult(), MatTranspose(), MatTransposeMatMult() for Dense and Elemental matrices.\n\n";
  2: /*
  3:  Example:
  4:    mpiexec -n <np> ./ex104 -mat_type elemental
  5: */

  7: #include <petscmat.h>

 11: int main(int argc,char **argv)
 12: {
 13:   Mat            A,B,C,D;
 14:   PetscInt       i,M=10,N=5,j,nrows,ncols,am,an,rstart,rend;
 16:   PetscRandom    r;
 17:   PetscBool      equal,iselemental;
 18:   PetscReal      fill = 1.0;
 19:   IS             isrows,iscols;
 20:   const PetscInt *rows,*cols;
 21:   PetscScalar    *v,rval;
 22: #if defined(PETSC_HAVE_ELEMENTAL)
 23:   PetscBool      Test_MatMatMult=PETSC_TRUE;
 24: #else
 25:   PetscBool      Test_MatMatMult=PETSC_FALSE;
 26: #endif
 27:   PetscMPIInt    size;

 29:   PetscInitialize(&argc,&argv,(char*)0,help);
 30:   MPI_Comm_size(PETSC_COMM_WORLD,&size);

 32:   PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);
 33:   PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);
 34:   MatCreate(PETSC_COMM_WORLD,&A);
 35:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);
 36:   MatSetType(A,MATDENSE);
 37:   MatSetFromOptions(A);
 38:   MatSetUp(A);
 39:   PetscRandomCreate(PETSC_COMM_WORLD,&r);
 40:   PetscRandomSetFromOptions(r);

 42:   /* Set local matrix entries */
 43:   MatGetOwnershipIS(A,&isrows,&iscols);
 44:   ISGetLocalSize(isrows,&nrows);
 45:   ISGetIndices(isrows,&rows);
 46:   ISGetLocalSize(iscols,&ncols);
 47:   ISGetIndices(iscols,&cols);
 48:   PetscMalloc1(nrows*ncols,&v);
 49:   for (i=0; i<nrows; i++) {
 50:     for (j=0; j<ncols; j++) {
 51:       PetscRandomGetValue(r,&rval);
 52:       v[i*ncols+j] = rval;
 53:     }
 54:   }
 55:   MatSetValues(A,nrows,rows,ncols,cols,v,INSERT_VALUES);
 56:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
 57:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
 58:   ISRestoreIndices(isrows,&rows);
 59:   ISRestoreIndices(iscols,&cols);
 60:   ISDestroy(&isrows);
 61:   ISDestroy(&iscols);
 62:   PetscRandomDestroy(&r);

 64:   /* Test MatMatMult() */
 65:   if (Test_MatMatMult) {
 66: #if !defined(PETSC_HAVE_ELEMENTAL)
 67:     if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This test requires ELEMENTAL");
 68: #endif
 69:     MatTranspose(A,MAT_INITIAL_MATRIX,&B); /* B = A^T */
 70:     MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C); /* C = B*A = A^T*A */
 71:     MatMatMult(B,A,MAT_REUSE_MATRIX,fill,&C);

 73:     /* Test B*A*x = C*x for n random vector x */
 74:     MatMatMultEqual(B,A,C,10,&equal);
 75:     if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"B*A*x != C*x");
 76:     MatDestroy(&C);

 78:     MatMatMultSymbolic(B,A,fill,&C);
 79:     for (i=0; i<2; i++) {
 80:       /* Repeat the numeric product to test reuse of the previous symbolic product */
 81:       MatMatMultNumeric(B,A,C);
 82: 
 83:       MatMatMultEqual(B,A,C,10,&equal);
 84:       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"B*A*x != C*x");
 85:     }
 86:     MatDestroy(&C);
 87:     MatDestroy(&B);
 88:   }

 90:   /* Test MatTransposeMatMult() */
 91:   PetscObjectTypeCompare((PetscObject)A,MATELEMENTAL,&iselemental);
 92:   if (!iselemental) {
 93:     MatTransposeMatMult(A,A,MAT_INITIAL_MATRIX,fill,&D); /* D = A^T*A */
 94:     MatTransposeMatMult(A,A,MAT_REUSE_MATRIX,fill,&D);
 95:     /* MatView(D,PETSC_VIEWER_STDOUT_WORLD); */
 96:     MatTransposeMatMultEqual(A,A,D,10,&equal);
 97:     if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"D*x != A^T*A*x");
 98:     MatDestroy(&D);

100:     /* Test D*x = A^T*C*A*x, where C is in AIJ format */
101:     MatGetLocalSize(A,&am,&an);
102:     MatCreate(PETSC_COMM_WORLD,&C);
103:     if (size == 1) {
104:       MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,am,am);
105:     } else {
106:       MatSetSizes(C,am,am,PETSC_DECIDE,PETSC_DECIDE);
107:     }
108:     MatSetFromOptions(C);
109:     MatSetUp(C);
110:     MatGetOwnershipRange(C,&rstart,&rend);
111:     v[0] = 1.0;
112:     for (i=rstart; i<rend; i++) {
113:       MatSetValues(C,1,&i,1,&i,v,INSERT_VALUES);
114:     }
115:     MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
116:     MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);

118:     /* B = C*A, D = A^T*B */
119:     MatMatMult(C,A,MAT_INITIAL_MATRIX,1.0,&B);
120:     MatTransposeMatMult(A,B,MAT_INITIAL_MATRIX,fill,&D);
121:     MatTransposeMatMultEqual(A,B,D,10,&equal);
122:     if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"D*x != A^T*B*x");

124:     MatDestroy(&D);
125:     MatDestroy(&C);
126:     MatDestroy(&B);
127:   }

129:   MatDestroy(&A);
130:   PetscFree(v);
131:   PetscFinalize();
132:   return(0);
133: }