xref: /petsc/src/mat/tests/ex132.c (revision 030f984af8d8bb4c203755d35bded3c05b3d83ce)
1 
2 static char help[] = "Test MatAXPY()\n\n";
3 
4 #include <petscmat.h>
5 
6 int main(int argc,char **args)
7 {
8   Mat            C,C1,C2,CU;
9   PetscScalar    v;
10   PetscInt       Ii,J,Istart,Iend;
11   PetscErrorCode ierr;
12   PetscInt       i,j,m = 3,n;
13   PetscMPIInt    size;
14   PetscBool      mat_nonsymmetric = PETSC_FALSE,flg;
15   MatInfo        info;
16 
17   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
18   ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr);
19   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr);
20   n    = 2*size;
21 
22   /* Set flag if we are doing a nonsymmetric problem; the default is symmetric. */
23   ierr = PetscOptionsGetBool(NULL,NULL,"-mat_nonsym",&mat_nonsymmetric,NULL);CHKERRQ(ierr);
24 
25   ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr);
26   ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr);
27   ierr = MatSetFromOptions(C);CHKERRQ(ierr);
28   ierr = MatSeqAIJSetPreallocation(C,5,NULL);CHKERRQ(ierr);
29   ierr = MatMPIAIJSetPreallocation(C,5,NULL,5,NULL);CHKERRQ(ierr);
30 
31   ierr = MatGetOwnershipRange(C,&Istart,&Iend);CHKERRQ(ierr);
32   for (Ii=Istart; Ii<Iend; Ii++) {
33     v = -1.0; i = Ii/n; j = Ii - i*n;
34     if (i>0)   {J = Ii - n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);}
35     if (i<m-1) {J = Ii + n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);}
36     if (j>0)   {J = Ii - 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);}
37     if (j<n-1) {J = Ii + 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);}
38     v = 4.0; ierr = MatSetValues(C,1,&Ii,1,&Ii,&v,ADD_VALUES);CHKERRQ(ierr);
39   }
40 
41   /* Make the matrix nonsymmetric if desired */
42   if (mat_nonsymmetric) {
43     for (Ii=Istart; Ii<Iend; Ii++) {
44       v = -1.5; i = Ii/n;
45       if (i>1) {J = Ii-n-1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,ADD_VALUES);CHKERRQ(ierr);}
46     }
47   } else {
48     ierr = MatSetOption(C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
49     ierr = MatSetOption(C,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
50   }
51   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
52   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
53   ierr = PetscObjectSetName((PetscObject)C,"C");CHKERRQ(ierr);
54   ierr = MatViewFromOptions(C,NULL,"-view");CHKERRQ(ierr);
55 
56   /* C1 = 2.0*C1 + C, C1 is anti-diagonal and has different non-zeros than C */
57   ierr = MatCreate(PETSC_COMM_WORLD,&C1);CHKERRQ(ierr);
58   ierr = MatSetSizes(C1,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr);
59   ierr = MatSetFromOptions(C1);CHKERRQ(ierr);
60   ierr = MatSeqAIJSetPreallocation(C1,1,NULL);CHKERRQ(ierr);
61   ierr = MatMPIAIJSetPreallocation(C1,1,NULL,1,NULL);CHKERRQ(ierr);
62   for (Ii=Istart; Ii<Iend; Ii++) {
63     v = 1.0;
64     i = m*n - Ii -1;
65     j = Ii;
66     ierr = MatSetValues(C1,1,&i,1,&j,&v,ADD_VALUES);CHKERRQ(ierr);
67   }
68   ierr = MatAssemblyBegin(C1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
69   ierr = MatAssemblyEnd(C1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
70   ierr = PetscObjectSetName((PetscObject)C1,"C1");CHKERRQ(ierr);
71   ierr = MatViewFromOptions(C1,NULL,"-view");CHKERRQ(ierr);
72   ierr = MatDuplicate(C1,MAT_COPY_VALUES,&CU);CHKERRQ(ierr);
73 
74   ierr = PetscPrintf(PETSC_COMM_WORLD," MatAXPY(C1,2.0,C,DIFFERENT_NONZERO_PATTERN)...\n");CHKERRQ(ierr);
75   ierr = MatAXPY(C1,2.0,C,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
76   ierr = MatAXPY(CU,2.0,C,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr);
77   ierr = MatGetInfo(C1,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
78   ierr = PetscPrintf(PETSC_COMM_WORLD," C1: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n",info.nz_allocated,info.nz_used, info.nz_unneeded);CHKERRQ(ierr);
79   ierr = MatViewFromOptions(C1,NULL,"-view");CHKERRQ(ierr);
80   ierr = MatMultEqual(CU,C1,10,&flg);CHKERRQ(ierr);
81   if (!flg) {
82     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error UNKNOWN_NONZERO_PATTERN (supposedly DIFFERENT_NONZERO_PATTERN)\n");CHKERRQ(ierr);
83     ierr = MatViewFromOptions(CU,NULL,"-view");CHKERRQ(ierr);
84   }
85   ierr = MatDestroy(&CU);CHKERRQ(ierr);
86 
87   /* Secondly, compute C1 = 2.0*C2 + C1, C2 has non-zero pattern of C */
88   ierr = MatDuplicate(C,MAT_DO_NOT_COPY_VALUES,&C2);CHKERRQ(ierr);
89   ierr = MatDuplicate(C1,MAT_COPY_VALUES,&CU);CHKERRQ(ierr);
90 
91   for (Ii=Istart; Ii<Iend; Ii++) {
92     v    = 1.0;
93     ierr = MatSetValues(C2,1,&Ii,1,&Ii,&v,ADD_VALUES);CHKERRQ(ierr);
94   }
95   ierr = MatAssemblyBegin(C2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
96   ierr = MatAssemblyEnd(C2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
97   ierr = PetscObjectSetName((PetscObject)C2,"C2");CHKERRQ(ierr);
98   ierr = MatViewFromOptions(C2,NULL,"-view");CHKERRQ(ierr);
99   ierr = PetscPrintf(PETSC_COMM_WORLD," MatAXPY(C1,2.0,C2,SUBSET_NONZERO_PATTERN)...\n");CHKERRQ(ierr);
100   ierr = MatAXPY(C1,2.0,C2,SUBSET_NONZERO_PATTERN);CHKERRQ(ierr);
101   ierr = MatAXPY(CU,2.0,C2,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr);
102   ierr = MatGetInfo(C1,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
103   ierr = PetscPrintf(PETSC_COMM_WORLD," C1: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n",info.nz_allocated,info.nz_used, info.nz_unneeded);CHKERRQ(ierr);
104   ierr = MatViewFromOptions(C1,NULL,"-view");CHKERRQ(ierr);
105   ierr = MatMultEqual(CU,C1,10,&flg);CHKERRQ(ierr);
106   if (!flg) {
107     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error UNKNOWN_NONZERO_PATTERN (supposedly SUBSET_NONZERO_PATTERN)\n");CHKERRQ(ierr);
108     ierr = MatViewFromOptions(CU,NULL,"-view");CHKERRQ(ierr);
109   }
110   ierr = MatDestroy(&CU);CHKERRQ(ierr);
111 
112   /* Test SAME_NONZERO_PATTERN computing C2 = C2 + 2.0 * C */
113   ierr = MatDuplicate(C2,MAT_COPY_VALUES,&CU);CHKERRQ(ierr);
114   ierr = PetscPrintf(PETSC_COMM_WORLD," MatAXPY(C2,2.0,C,SAME_NONZERO_PATTERN)...\n");CHKERRQ(ierr);
115   ierr = MatAXPY(C2,2.0,C,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
116   ierr = MatAXPY(CU,2.0,C,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr);
117   ierr = MatGetInfo(C2,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
118   ierr = PetscPrintf(PETSC_COMM_WORLD," C2: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n",info.nz_allocated,info.nz_used, info.nz_unneeded);CHKERRQ(ierr);
119   ierr = MatViewFromOptions(C2,NULL,"-view");CHKERRQ(ierr);
120   ierr = MatMultEqual(CU,C2,10,&flg);CHKERRQ(ierr);
121   if (!flg) {
122     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error UNKNOWN_NONZERO_PATTERN (supposedly SUBSET_NONZERO_PATTERN)\n");CHKERRQ(ierr);
123     ierr = MatViewFromOptions(CU,NULL,"-view");CHKERRQ(ierr);
124   }
125   ierr = MatDestroy(&CU);CHKERRQ(ierr);
126 
127   ierr = MatDestroy(&C1);CHKERRQ(ierr);
128   ierr = MatDestroy(&C2);CHKERRQ(ierr);
129   ierr = MatDestroy(&C);CHKERRQ(ierr);
130 
131   ierr = PetscFinalize();
132   return ierr;
133 }
134 
135 /*TEST
136 
137    test:
138      suffix: 1
139      filter: grep -v " type:" | grep -v "Mat Object"
140      args: -view
141      diff_args: -j
142 
143    test:
144      output_file: output/ex132_1.out
145      requires: cuda
146      suffix: 1_cuda
147      filter: grep -v " type:" | grep -v "Mat Object"
148      args: -view -mat_type aijcusparse
149      diff_args: -j
150 
151    test:
152      output_file: output/ex132_1.out
153      requires: kokkos_kernels
154      suffix: 1_kokkos
155      filter: grep -v " type:" | grep -v "Mat Object"
156      args: -view -mat_type aijkokkos
157      diff_args: -j
158 
159    test:
160      suffix: 2
161      filter: grep -v " type:" | grep -v "Mat Object"
162      args: -view -mat_nonsym
163      diff_args: -j
164 
165    test:
166      output_file: output/ex132_2.out
167      requires: cuda
168      suffix: 2_cuda
169      filter: grep -v " type:" | grep -v "Mat Object"
170      args: -view -mat_type aijcusparse -mat_nonsym
171      diff_args: -j
172 
173    test:
174      output_file: output/ex132_2.out
175      requires: kokkos_kernels
176      suffix: 2_kokkos
177      filter: grep -v " type:" | grep -v "Mat Object"
178      args: -view -mat_type aijkokkos -mat_nonsym
179      diff_args: -j
180 
181    test:
182      nsize: 2
183      suffix: 1_par
184      filter: grep -v " type:" | grep -v "Mat Object"
185      args: -view
186      diff_args: -j
187 
188    test:
189      nsize: 2
190      output_file: output/ex132_1_par.out
191      requires: cuda
192      suffix: 1_par_cuda
193      filter: grep -v " type:" | grep -v "Mat Object"
194      args: -view -mat_type aijcusparse
195      diff_args: -j
196 
197    test:
198      nsize: 2
199      output_file: output/ex132_1_par.out
200      requires: kokkos_kernels
201      suffix: 1_par_kokkos
202      filter: grep -v " type:" | grep -v "Mat Object"
203      args: -view -mat_type aijkokkos
204      diff_args: -j
205 
206    test:
207      nsize: 2
208      suffix: 2_par
209      filter: grep -v " type:" | grep -v "Mat Object"
210      args: -view -mat_nonsym
211      diff_args: -j
212 
213    test:
214      nsize: 2
215      output_file: output/ex132_2_par.out
216      requires: cuda
217      suffix: 2_par_cuda
218      filter: grep -v " type:" | grep -v "Mat Object"
219      args: -view -mat_type aijcusparse -mat_nonsym
220      diff_args: -j
221 
222    test:
223      nsize: 2
224      output_file: output/ex132_2_par.out
225      requires: kokkos_kernels
226      suffix: 2_par_kokkos
227      filter: grep -v " type:" | grep -v "Mat Object"
228      args: -view -mat_type aijkokkos -mat_nonsym -use_gpu_aware_mpi {{0 1}}
229      diff_args: -j
230 
231 TEST*/
232