Actual source code: ex104.c

petsc-3.9.4 2018-09-11
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>

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

 27:   PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
 28:   MPI_Comm_size(PETSC_COMM_WORLD,&size);

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

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

 62:   /* Test MatTranspose() */
 63:   MatCreateTranspose(A,&C);
 64:   MatTranspose(A,MAT_INITIAL_MATRIX,&B); /* B = A^T */
 65:   MatMultEqual(C,B,10,&equal);
 66:   if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"A^T*x != (x^T*A)^T");
 67:   MatTranspose(A,MAT_REUSE_MATRIX,&B); /* B = A^T */
 68:   MatMultEqual(C,B,10,&equal);
 69:   if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"A^T*x != (x^T*A)^T");
 70:   MatDestroy(&B);
 71:   MatDuplicate(A,MAT_COPY_VALUES,&B);
 72:   MatTranspose(B,MAT_INPLACE_MATRIX,&B);
 73:   MatMultEqual(C,B,10,&equal);
 74:   if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"A^T*x != (x^T*A)^T");
 75:   MatDestroy(&B);
 76:   MatDestroy(&C);

 78:   /* Test MatMatMult() */
 79:   if (Test_MatMatMult) {
 80: #if !defined(PETSC_HAVE_ELEMENTAL)
 81:     if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This test requires ELEMENTAL");
 82: #endif
 83:     MatTranspose(A,MAT_INITIAL_MATRIX,&B); /* B = A^T */
 84:     MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C); /* C = B*A = A^T*A */
 85:     MatMatMult(B,A,MAT_REUSE_MATRIX,fill,&C);

 87:     /* Test B*A*x = C*x for n random vector x */
 88:     MatMatMultEqual(B,A,C,10,&equal);
 89:     if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"B*A*x != C*x");
 90:     MatDestroy(&C);

 92:     MatMatMultSymbolic(B,A,fill,&C);
 93:     for (i=0; i<2; i++) {
 94:       /* Repeat the numeric product to test reuse of the previous symbolic product */
 95:       MatMatMultNumeric(B,A,C);
 96: 
 97:       MatMatMultEqual(B,A,C,10,&equal);
 98:       if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"B*A*x != C*x");
 99:     }
100:     MatDestroy(&C);
101:     MatDestroy(&B);
102:   }

104:   /* Test MatTransposeMatMult() */
105:   PetscObjectTypeCompare((PetscObject)A,MATELEMENTAL,&iselemental);
106:   if (!iselemental) {
107:     MatTransposeMatMult(A,A,MAT_INITIAL_MATRIX,fill,&D); /* D = A^T*A */
108:     MatTransposeMatMult(A,A,MAT_REUSE_MATRIX,fill,&D);
109:     /* MatView(D,PETSC_VIEWER_STDOUT_WORLD); */
110:     MatTransposeMatMultEqual(A,A,D,10,&equal);
111:     if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"D*x != A^T*A*x");
112:     MatDestroy(&D);

114:     /* Test D*x = A^T*C*A*x, where C is in AIJ format */
115:     MatGetLocalSize(A,&am,&an);
116:     MatCreate(PETSC_COMM_WORLD,&C);
117:     if (size == 1) {
118:       MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,am,am);
119:     } else {
120:       MatSetSizes(C,am,am,PETSC_DECIDE,PETSC_DECIDE);
121:     }
122:     MatSetFromOptions(C);
123:     MatSetUp(C);
124:     MatGetOwnershipRange(C,&rstart,&rend);
125:     v[0] = 1.0;
126:     for (i=rstart; i<rend; i++) {
127:       MatSetValues(C,1,&i,1,&i,v,INSERT_VALUES);
128:     }
129:     MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
130:     MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);

132:     /* B = C*A, D = A^T*B */
133:     MatMatMult(C,A,MAT_INITIAL_MATRIX,1.0,&B);
134:     MatTransposeMatMult(A,B,MAT_INITIAL_MATRIX,fill,&D);
135:     MatTransposeMatMultEqual(A,B,D,10,&equal);
136:     if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"D*x != A^T*B*x");

138:     MatDestroy(&D);
139:     MatDestroy(&C);
140:     MatDestroy(&B);
141:   }

143:   MatDestroy(&A);
144:   PetscFree(v);
145:   PetscFinalize();
146:   return ierr;
147: }

149: /*TEST

151:     test:
152:       output_file: output/ex104.out

154:     test:
155:       suffix: 2
156:       nsize: 2
157:       output_file: output/ex104.out

159: TEST*/