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