xref: /petsc/src/mat/tests/ex55.c (revision dfd57a172ac9fa6c7b5fe6de6ab5df85cefc2996)
1c4762a1bSJed Brown 
2c4762a1bSJed Brown static char help[] = "Tests converting a matrix to another format with MatConvert().\n\n";
3c4762a1bSJed Brown 
4c4762a1bSJed Brown #include <petscmat.h>
5c4762a1bSJed Brown /* Usage: mpiexec -n <np> ex55 -verbose <0 or 1> */
6c4762a1bSJed Brown 
7c4762a1bSJed Brown int main(int argc,char **args)
8c4762a1bSJed Brown {
9c4762a1bSJed Brown   Mat            C,A,B,D;
10c4762a1bSJed Brown   PetscErrorCode ierr;
11c4762a1bSJed Brown   PetscInt       i,j,ntypes,bs,mbs,m,block,d_nz=6, o_nz=3,col[3],row,verbose=0;
12c4762a1bSJed Brown   PetscMPIInt    size,rank;
13c4762a1bSJed Brown   MatType        type[9];
14c4762a1bSJed Brown   char           file[PETSC_MAX_PATH_LEN];
15c4762a1bSJed Brown   PetscViewer    fd;
16c4762a1bSJed Brown   PetscBool      equal,flg_loadmat,flg,issymmetric;
17c4762a1bSJed Brown   PetscScalar    value[3];
18c4762a1bSJed Brown 
19c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
20c4762a1bSJed Brown   ierr = PetscOptionsGetInt(NULL,NULL,"-verbose",&verbose,NULL);CHKERRQ(ierr);
21589a23caSBarry Smith   ierr = PetscOptionsGetString(NULL,NULL,"-f",file,sizeof(file),&flg_loadmat);CHKERRQ(ierr);
22ffc4695bSBarry Smith   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr);
23ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
24c4762a1bSJed Brown 
25c4762a1bSJed Brown   ierr = PetscOptionsHasName(NULL,NULL,"-testseqaij",&flg);CHKERRQ(ierr);
26c4762a1bSJed Brown   if (flg) {
27c4762a1bSJed Brown     if (size == 1) {
28c4762a1bSJed Brown       type[0] = MATSEQAIJ;
29c4762a1bSJed Brown     } else {
30c4762a1bSJed Brown       type[0] = MATMPIAIJ;
31c4762a1bSJed Brown     }
32c4762a1bSJed Brown   } else {
33c4762a1bSJed Brown     type[0] = MATAIJ;
34c4762a1bSJed Brown   }
35c4762a1bSJed Brown   if (size == 1) {
36c4762a1bSJed Brown     ntypes  = 3;
37c4762a1bSJed Brown     type[1] = MATSEQBAIJ;
38c4762a1bSJed Brown     type[2] = MATSEQSBAIJ;
39c4762a1bSJed Brown   } else {
40c4762a1bSJed Brown     ntypes  = 3;
41c4762a1bSJed Brown     type[1] = MATMPIBAIJ;
42c4762a1bSJed Brown     type[2] = MATMPISBAIJ;
43c4762a1bSJed Brown   }
44c4762a1bSJed Brown 
45c4762a1bSJed Brown   /* input matrix C */
46c4762a1bSJed Brown   if (flg_loadmat) {
47c4762a1bSJed Brown     /* Open binary file. */
48c4762a1bSJed Brown     ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr);
49c4762a1bSJed Brown 
50c4762a1bSJed Brown     /* Load a baij matrix, then destroy the viewer. */
51c4762a1bSJed Brown     ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr);
52c4762a1bSJed Brown     if (size == 1) {
53c4762a1bSJed Brown       ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
54c4762a1bSJed Brown     } else {
55c4762a1bSJed Brown       ierr = MatSetType(C,MATMPIBAIJ);CHKERRQ(ierr);
56c4762a1bSJed Brown     }
57c4762a1bSJed Brown     ierr = MatSetFromOptions(C);CHKERRQ(ierr);
58c4762a1bSJed Brown     ierr = MatLoad(C,fd);CHKERRQ(ierr);
59c4762a1bSJed Brown     ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr);
60c4762a1bSJed Brown   } else { /* Create a baij mat with bs>1  */
61c4762a1bSJed Brown     bs   = 2; mbs=8;
62c4762a1bSJed Brown     ierr = PetscOptionsGetInt(NULL,NULL,"-mbs",&mbs,NULL);CHKERRQ(ierr);
63c4762a1bSJed Brown     ierr = PetscOptionsGetInt(NULL,NULL,"-bs",&bs,NULL);CHKERRQ(ierr);
64c4762a1bSJed Brown     if (bs <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG," bs must be >1 in this case");
65c4762a1bSJed Brown     m    = mbs*bs;
66c4762a1bSJed Brown     ierr = MatCreateBAIJ(PETSC_COMM_WORLD,bs,PETSC_DECIDE,PETSC_DECIDE,m,m,d_nz,NULL,o_nz,NULL,&C);CHKERRQ(ierr);
67c4762a1bSJed Brown     for (block=0; block<mbs; block++) {
68c4762a1bSJed Brown       /* diagonal blocks */
69c4762a1bSJed Brown       value[0] = -1.0; value[1] = 4.0; value[2] = -1.0;
70c4762a1bSJed Brown       for (i=1+block*bs; i<bs-1+block*bs; i++) {
71c4762a1bSJed Brown         col[0] = i-1; col[1] = i; col[2] = i+1;
72c4762a1bSJed Brown         ierr   = MatSetValues(C,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr);
73c4762a1bSJed Brown       }
74c4762a1bSJed Brown       i       = bs - 1+block*bs; col[0] = bs - 2+block*bs; col[1] = bs - 1+block*bs;
75c4762a1bSJed Brown       value[0]=-1.0; value[1]=4.0;
76c4762a1bSJed Brown       ierr    = MatSetValues(C,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr);
77c4762a1bSJed Brown 
78c4762a1bSJed Brown       i       = 0+block*bs; col[0] = 0+block*bs; col[1] = 1+block*bs;
79c4762a1bSJed Brown       value[0]=4.0; value[1] = -1.0;
80c4762a1bSJed Brown       ierr    = MatSetValues(C,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr);
81c4762a1bSJed Brown     }
82c4762a1bSJed Brown     /* off-diagonal blocks */
83c4762a1bSJed Brown     value[0]=-1.0;
84c4762a1bSJed Brown     for (i=0; i<(mbs-1)*bs; i++) {
85c4762a1bSJed Brown       col[0]=i+bs;
86c4762a1bSJed Brown       ierr  = MatSetValues(C,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr);
87c4762a1bSJed Brown       col[0]=i; row=i+bs;
88c4762a1bSJed Brown       ierr  = MatSetValues(C,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr);
89c4762a1bSJed Brown     }
90c4762a1bSJed Brown     ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
91c4762a1bSJed Brown     ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
92c4762a1bSJed Brown   }
93c4762a1bSJed Brown   {
94c4762a1bSJed Brown     /* Check the symmetry of C because it will be converted to a sbaij matrix */
95c4762a1bSJed Brown     Mat Ctrans;
96c4762a1bSJed Brown     ierr = MatTranspose(C,MAT_INITIAL_MATRIX,&Ctrans);CHKERRQ(ierr);
97c4762a1bSJed Brown     ierr = MatEqual(C,Ctrans,&flg);CHKERRQ(ierr);
98c4762a1bSJed Brown /*
99c4762a1bSJed Brown     {
100c4762a1bSJed Brown       ierr = MatAXPY(C,1.,Ctrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
101c4762a1bSJed Brown       flg  = PETSC_TRUE;
102c4762a1bSJed Brown     }
103c4762a1bSJed Brown */
104c4762a1bSJed Brown     ierr = MatSetOption(C,MAT_SYMMETRIC,flg);CHKERRQ(ierr);
105c4762a1bSJed Brown     ierr = MatDestroy(&Ctrans);CHKERRQ(ierr);
106c4762a1bSJed Brown   }
107c4762a1bSJed Brown   ierr = MatIsSymmetric(C,0.0,&issymmetric);CHKERRQ(ierr);
108c4762a1bSJed Brown   ierr = MatViewFromOptions(C,NULL,"-view_mat");CHKERRQ(ierr);
109c4762a1bSJed Brown 
110c4762a1bSJed Brown   /* convert C to other formats */
111c4762a1bSJed Brown   for (i=0; i<ntypes; i++) {
112c4762a1bSJed Brown     PetscBool ismpisbaij,isseqsbaij;
113c4762a1bSJed Brown 
114c4762a1bSJed Brown     ierr = PetscStrcmp(type[i],MATMPISBAIJ,&ismpisbaij);CHKERRQ(ierr);
115c4762a1bSJed Brown     ierr = PetscStrcmp(type[i],MATMPISBAIJ,&isseqsbaij);CHKERRQ(ierr);
116c4762a1bSJed Brown     if (!issymmetric && (ismpisbaij || isseqsbaij)) continue;
117c4762a1bSJed Brown     ierr = MatConvert(C,type[i],MAT_INITIAL_MATRIX,&A);CHKERRQ(ierr);
118c4762a1bSJed Brown     ierr = MatMultEqual(A,C,10,&equal);CHKERRQ(ierr);
119c4762a1bSJed Brown     if (!equal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in conversion from BAIJ to %s",type[i]);
120c4762a1bSJed Brown     for (j=i+1; j<ntypes; j++) {
121c4762a1bSJed Brown       ierr = PetscStrcmp(type[j],MATMPISBAIJ,&ismpisbaij);CHKERRQ(ierr);
122c4762a1bSJed Brown       ierr = PetscStrcmp(type[j],MATMPISBAIJ,&isseqsbaij);CHKERRQ(ierr);
123c4762a1bSJed Brown       if (!issymmetric && (ismpisbaij || isseqsbaij)) continue;
124c4762a1bSJed Brown       if (verbose>0) {
125c4762a1bSJed Brown         ierr = PetscPrintf(PETSC_COMM_WORLD," \n[%d] test conversion between %s and %s\n",rank,type[i],type[j]);CHKERRQ(ierr);
126c4762a1bSJed Brown       }
127c4762a1bSJed Brown 
128c4762a1bSJed Brown       if (!rank && verbose) printf("Convert %s A to %s B\n",type[i],type[j]);
129c4762a1bSJed Brown       ierr = MatConvert(A,type[j],MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr);
130c4762a1bSJed Brown       /*
131c4762a1bSJed Brown       if (j == 2) {
132c4762a1bSJed Brown         ierr = PetscPrintf(PETSC_COMM_SELF," A: %s\n",type[i]);CHKERRQ(ierr);
133c4762a1bSJed Brown         ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
134c4762a1bSJed Brown         ierr = PetscPrintf(PETSC_COMM_SELF," B: %s\n",type[j]);CHKERRQ(ierr);
135c4762a1bSJed Brown         ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
136c4762a1bSJed Brown       }
137c4762a1bSJed Brown        */
138c4762a1bSJed Brown       ierr = MatMultEqual(A,B,10,&equal);CHKERRQ(ierr);
139c4762a1bSJed Brown       if (!equal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in conversion from %s to %s",type[i],type[j]);
140c4762a1bSJed Brown 
141c4762a1bSJed Brown       if (size == 1 || j != 2) { /* Matconvert from mpisbaij mat to other formats are not supported */
142c4762a1bSJed Brown         if (!rank && verbose) printf("Convert %s B to %s D\n",type[j],type[i]);
143c4762a1bSJed Brown         ierr = MatConvert(B,type[i],MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr);
144c4762a1bSJed Brown         ierr = MatMultEqual(B,D,10,&equal);CHKERRQ(ierr);
145c4762a1bSJed Brown         if (!equal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Error in conversion from %s to %s",type[j],type[i]);
146c4762a1bSJed Brown 
147c4762a1bSJed Brown         ierr = MatDestroy(&D);CHKERRQ(ierr);
148c4762a1bSJed Brown       }
149c4762a1bSJed Brown       ierr = MatDestroy(&B);CHKERRQ(ierr);
150c4762a1bSJed Brown       ierr = MatDestroy(&D);CHKERRQ(ierr);
151c4762a1bSJed Brown     }
152c4762a1bSJed Brown 
153c4762a1bSJed Brown     /* Test in-place convert */
154c4762a1bSJed Brown     if (size == 1) { /* size > 1 is not working yet! */
155c4762a1bSJed Brown       j = (i+1)%ntypes;
156c4762a1bSJed Brown       ierr = PetscStrcmp(type[j],MATMPISBAIJ,&ismpisbaij);CHKERRQ(ierr);
157c4762a1bSJed Brown       ierr = PetscStrcmp(type[j],MATMPISBAIJ,&isseqsbaij);CHKERRQ(ierr);
158c4762a1bSJed Brown       if (!issymmetric && (ismpisbaij || isseqsbaij)) continue;
159c4762a1bSJed Brown       /* printf("[%d] i: %d, j: %d\n",rank,i,j); */
160c4762a1bSJed Brown       ierr = MatConvert(A,type[j],MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr);
161c4762a1bSJed Brown     }
162c4762a1bSJed Brown 
163c4762a1bSJed Brown     ierr = MatDestroy(&A);CHKERRQ(ierr);
164c4762a1bSJed Brown   }
165c4762a1bSJed Brown 
166c4762a1bSJed Brown   /* test BAIJ to MATIS */
167c4762a1bSJed Brown   if (size > 1) {
168c4762a1bSJed Brown     MatType ctype;
169c4762a1bSJed Brown 
170c4762a1bSJed Brown     ierr = MatGetType(C,&ctype);CHKERRQ(ierr);
171c4762a1bSJed Brown     ierr = MatConvert(C,MATIS,MAT_INITIAL_MATRIX,&A);CHKERRQ(ierr);
172c4762a1bSJed Brown     ierr = MatMultEqual(A,C,10,&equal);CHKERRQ(ierr);
173c4762a1bSJed Brown     ierr = MatViewFromOptions(A,NULL,"-view_conv");CHKERRQ(ierr);
174c4762a1bSJed Brown     if (!equal) {
175c4762a1bSJed Brown       Mat C2;
176c4762a1bSJed Brown 
177c4762a1bSJed Brown       ierr = MatConvert(A,ctype,MAT_INITIAL_MATRIX,&C2);CHKERRQ(ierr);
178c4762a1bSJed Brown       ierr = MatViewFromOptions(C2,NULL,"-view_conv_assembled");CHKERRQ(ierr);
179c4762a1bSJed Brown       ierr = MatAXPY(C2,-1.,C,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
180c4762a1bSJed Brown       ierr = MatChop(C2,PETSC_SMALL);CHKERRQ(ierr);
181c4762a1bSJed Brown       ierr = MatViewFromOptions(C2,NULL,"-view_err");CHKERRQ(ierr);
182c4762a1bSJed Brown       ierr = MatDestroy(&C2);CHKERRQ(ierr);
183c4762a1bSJed Brown       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in conversion from BAIJ to MATIS");
184c4762a1bSJed Brown     }
185c4762a1bSJed Brown     ierr = MatConvert(C,MATIS,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
186c4762a1bSJed Brown     ierr = MatMultEqual(A,C,10,&equal);CHKERRQ(ierr);
187c4762a1bSJed Brown     ierr = MatViewFromOptions(A,NULL,"-view_conv");CHKERRQ(ierr);
188c4762a1bSJed Brown     if (!equal) {
189c4762a1bSJed Brown       Mat C2;
190c4762a1bSJed Brown 
191c4762a1bSJed Brown       ierr = MatConvert(A,ctype,MAT_INITIAL_MATRIX,&C2);CHKERRQ(ierr);
192c4762a1bSJed Brown       ierr = MatViewFromOptions(C2,NULL,"-view_conv_assembled");CHKERRQ(ierr);
193c4762a1bSJed Brown       ierr = MatAXPY(C2,-1.,C,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
194c4762a1bSJed Brown       ierr = MatChop(C2,PETSC_SMALL);CHKERRQ(ierr);
195c4762a1bSJed Brown       ierr = MatViewFromOptions(C2,NULL,"-view_err");CHKERRQ(ierr);
196c4762a1bSJed Brown       ierr = MatDestroy(&C2);CHKERRQ(ierr);
197c4762a1bSJed Brown       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in conversion from BAIJ to MATIS");
198c4762a1bSJed Brown     }
199c4762a1bSJed Brown     ierr = MatDestroy(&A);CHKERRQ(ierr);
200c4762a1bSJed Brown     ierr = MatDuplicate(C,MAT_COPY_VALUES,&A);CHKERRQ(ierr);
201c4762a1bSJed Brown     ierr = MatConvert(A,MATIS,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr);
202c4762a1bSJed Brown     ierr = MatViewFromOptions(A,NULL,"-view_conv");CHKERRQ(ierr);
203c4762a1bSJed Brown     ierr = MatMultEqual(A,C,10,&equal);CHKERRQ(ierr);
204c4762a1bSJed Brown     if (!equal) {
205c4762a1bSJed Brown       Mat C2;
206c4762a1bSJed Brown 
207c4762a1bSJed Brown       ierr = MatViewFromOptions(A,NULL,"-view_conv");CHKERRQ(ierr);
208c4762a1bSJed Brown       ierr = MatConvert(A,ctype,MAT_INITIAL_MATRIX,&C2);CHKERRQ(ierr);
209c4762a1bSJed Brown       ierr = MatViewFromOptions(C2,NULL,"-view_conv_assembled");CHKERRQ(ierr);
210c4762a1bSJed Brown       ierr = MatAXPY(C2,-1.,C,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
211c4762a1bSJed Brown       ierr = MatChop(C2,PETSC_SMALL);CHKERRQ(ierr);
212c4762a1bSJed Brown       ierr = MatViewFromOptions(C2,NULL,"-view_err");CHKERRQ(ierr);
213c4762a1bSJed Brown       ierr = MatDestroy(&C2);CHKERRQ(ierr);
214c4762a1bSJed Brown       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in conversion from BAIJ to MATIS");
215c4762a1bSJed Brown     }
216c4762a1bSJed Brown     ierr = MatDestroy(&A);CHKERRQ(ierr);
217c4762a1bSJed Brown   }
218c4762a1bSJed Brown   ierr = MatDestroy(&C);CHKERRQ(ierr);
219c4762a1bSJed Brown 
220c4762a1bSJed Brown   ierr = PetscFinalize();
221c4762a1bSJed Brown   return ierr;
222c4762a1bSJed Brown }
223c4762a1bSJed Brown 
224c4762a1bSJed Brown /*TEST
225c4762a1bSJed Brown 
226c4762a1bSJed Brown    test:
227c4762a1bSJed Brown 
228c4762a1bSJed Brown    test:
229c4762a1bSJed Brown       suffix: 2
230c4762a1bSJed Brown       nsize: 3
231c4762a1bSJed Brown 
232c4762a1bSJed Brown    testset:
233c4762a1bSJed Brown       requires: parmetis
234c4762a1bSJed Brown       output_file: output/ex55_1.out
235c4762a1bSJed Brown       nsize: 3
236c4762a1bSJed Brown       args: -mat_is_disassemble_l2g_type nd -mat_partitioning_type parmetis
237c4762a1bSJed Brown       test:
238c4762a1bSJed Brown         suffix: matis_baij_parmetis_nd
239c4762a1bSJed Brown       test:
240c4762a1bSJed Brown         suffix: matis_aij_parmetis_nd
241c4762a1bSJed Brown         args: -testseqaij
242c4762a1bSJed Brown       test:
243*dfd57a17SPierre Jolivet         requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
244c4762a1bSJed Brown         suffix: matis_poisson1_parmetis_nd
245c4762a1bSJed Brown         args: -f ${DATAFILESPATH}/matrices/poisson1
246c4762a1bSJed Brown 
247c4762a1bSJed Brown    testset:
248*dfd57a17SPierre Jolivet       requires: ptscotch defined(PETSC_HAVE_SCOTCH_PARMETIS_V3_NODEND)
249c4762a1bSJed Brown       output_file: output/ex55_1.out
250c4762a1bSJed Brown       nsize: 4
251c4762a1bSJed Brown       args: -mat_is_disassemble_l2g_type nd -mat_partitioning_type ptscotch
252c4762a1bSJed Brown       test:
253c4762a1bSJed Brown         suffix: matis_baij_ptscotch_nd
254c4762a1bSJed Brown       test:
255c4762a1bSJed Brown         suffix: matis_aij_ptscotch_nd
256c4762a1bSJed Brown         args: -testseqaij
257c4762a1bSJed Brown       test:
258*dfd57a17SPierre Jolivet         requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
259c4762a1bSJed Brown         suffix: matis_poisson1_ptscotch_nd
260c4762a1bSJed Brown         args: -f ${DATAFILESPATH}/matrices/poisson1
261c4762a1bSJed Brown 
262c4762a1bSJed Brown TEST*/
263