Actual source code: ex104.c
petsc-3.10.5 2019-03-28
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*/