1 static char help[] = "Tests repeated VecDotBegin()/VecDotEnd().\n\n";
2
3 #include <petscvec.h>
4 #define CheckError(a, b, tol) \
5 do { \
6 if (!PetscIsCloseAtTol(a, b, 0, tol)) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Real error at line %d, tol %g: %s %g %s %g diff %g\n", __LINE__, (double)tol, #a, (double)(a), #b, (double)(b), (double)((a) - (b)))); \
7 } while (0)
8
9 #define CheckErrorScalar(a, b, tol) \
10 do { \
11 if (!PetscIsCloseAtTol(PetscRealPart(a), PetscRealPart(b), 0, tol)) { \
12 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Real error at line %d, tol %g: %s %g %s %g diff %g\n", __LINE__, (double)tol, #a, (double)PetscRealPart(a), #b, (double)PetscRealPart(b), (double)PetscRealPart((a) - (b)))); \
13 } \
14 if (!PetscIsCloseAtTol(PetscImaginaryPart(a), PetscImaginaryPart(b), 0, PETSC_SMALL)) { \
15 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Imag error at line %d, tol %g: %s %g %s %g diff %g\n", __LINE__, (double)tol, #a, (double)PetscImaginaryPart(a), #b, (double)PetscImaginaryPart(b), (double)PetscImaginaryPart((a) - (b)))); \
16 } \
17 } while (0)
18
main(int argc,char ** argv)19 int main(int argc, char **argv)
20 {
21 PetscInt n = 25, i, row0 = 0;
22 PetscScalar two = 2.0, result1, result2, results[40], value, ten = 10.0;
23 PetscScalar result1a, result2a;
24 PetscReal result3, result4, result[2], result3a, result4a, resulta[2];
25 Vec x, y, vecs[40];
26 PetscReal tol = PETSC_SMALL;
27
28 PetscFunctionBeginUser;
29 PetscCall(PetscInitialize(&argc, &argv, NULL, help));
30
31 /* create vectors */
32 PetscCall(VecCreate(PETSC_COMM_WORLD, &x));
33 PetscCall(VecSetSizes(x, n, PETSC_DECIDE));
34 PetscCall(VecSetFromOptions(x));
35 PetscCall(VecDuplicate(x, &y));
36 PetscCall(VecSetRandom(x, NULL));
37 PetscCall(VecViewFromOptions(x, NULL, "-x_view"));
38 PetscCall(VecSet(y, two));
39
40 /*
41 Test mixing dot products and norms that require sums
42 */
43 result1 = result2 = 0.0;
44 result3 = result4 = 0.0;
45 PetscCall(VecDotBegin(x, y, &result1));
46 PetscCall(VecDotBegin(y, x, &result2));
47 PetscCall(VecNormBegin(y, NORM_2, &result3));
48 PetscCall(VecNormBegin(x, NORM_1, &result4));
49 PetscCall(PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)x)));
50 PetscCall(VecDotEnd(x, y, &result1));
51 PetscCall(VecDotEnd(y, x, &result2));
52 PetscCall(VecNormEnd(y, NORM_2, &result3));
53 PetscCall(VecNormEnd(x, NORM_1, &result4));
54
55 PetscCall(VecDot(x, y, &result1a));
56 PetscCall(VecDot(y, x, &result2a));
57 PetscCall(VecNorm(y, NORM_2, &result3a));
58 PetscCall(VecNorm(x, NORM_1, &result4a));
59
60 CheckErrorScalar(result1, result1a, tol);
61 CheckErrorScalar(result2, result2a, tol);
62 CheckError(result3, result3a, tol);
63 CheckError(result4, result4a, tol);
64
65 /*
66 Test norms that only require abs
67 */
68 result1 = result2 = 0.0;
69 result3 = result4 = 0.0;
70 PetscCall(VecNormBegin(y, NORM_MAX, &result3));
71 PetscCall(VecNormBegin(x, NORM_MAX, &result4));
72 PetscCall(VecNormEnd(y, NORM_MAX, &result3));
73 PetscCall(VecNormEnd(x, NORM_MAX, &result4));
74
75 PetscCall(VecNorm(x, NORM_MAX, &result4a));
76 PetscCall(VecNorm(y, NORM_MAX, &result3a));
77 CheckError(result3, result3a, tol);
78 CheckError(result4, result4a, tol);
79
80 /*
81 Tests dot, max, 1, norm
82 */
83 result1 = result2 = 0.0;
84 result3 = result4 = 0.0;
85 PetscCall(VecSetValues(x, 1, &row0, &ten, INSERT_VALUES));
86 PetscCall(VecAssemblyBegin(x));
87 PetscCall(VecAssemblyEnd(x));
88
89 PetscCall(VecDotBegin(x, y, &result1));
90 PetscCall(VecDotBegin(y, x, &result2));
91 PetscCall(VecNormBegin(x, NORM_MAX, &result3));
92 PetscCall(VecNormBegin(x, NORM_1, &result4));
93 PetscCall(VecDotEnd(x, y, &result1));
94 PetscCall(VecDotEnd(y, x, &result2));
95 PetscCall(VecNormEnd(x, NORM_MAX, &result3));
96 PetscCall(VecNormEnd(x, NORM_1, &result4));
97
98 PetscCall(VecDot(x, y, &result1a));
99 PetscCall(VecDot(y, x, &result2a));
100 PetscCall(VecNorm(x, NORM_MAX, &result3a));
101 PetscCall(VecNorm(x, NORM_1, &result4a));
102
103 CheckErrorScalar(result1, result1a, tol);
104 CheckErrorScalar(result2, result2a, tol);
105 CheckError(result3, result3a, tol);
106 CheckError(result4, result4a, tol);
107
108 /*
109 tests 1_and_2 norm
110 */
111 PetscCall(VecNormBegin(x, NORM_MAX, &result3));
112 PetscCall(VecNormBegin(x, NORM_1_AND_2, result));
113 PetscCall(VecNormBegin(y, NORM_MAX, &result4));
114 PetscCall(VecNormEnd(x, NORM_MAX, &result3));
115 PetscCall(VecNormEnd(x, NORM_1_AND_2, result));
116 PetscCall(VecNormEnd(y, NORM_MAX, &result4));
117
118 PetscCall(VecNorm(x, NORM_MAX, &result3a));
119 PetscCall(VecNorm(x, NORM_1_AND_2, resulta));
120 PetscCall(VecNorm(y, NORM_MAX, &result4a));
121
122 CheckError(result3, result3a, tol);
123 CheckError(result4, result4a, tol);
124 CheckError(result[0], resulta[0], tol);
125 CheckError(result[1], resulta[1], tol);
126
127 PetscCall(VecDestroy(&x));
128 PetscCall(VecDestroy(&y));
129
130 /*
131 Tests computing a large number of operations that require
132 allocating a larger data structure internally
133 */
134 for (i = 0; i < 40; i++) {
135 PetscCall(VecCreate(PETSC_COMM_WORLD, vecs + i));
136 PetscCall(VecSetSizes(vecs[i], PETSC_DECIDE, n));
137 PetscCall(VecSetFromOptions(vecs[i]));
138 value = (PetscReal)i;
139 PetscCall(VecSet(vecs[i], value));
140 }
141 for (i = 0; i < 39; i++) PetscCall(VecDotBegin(vecs[i], vecs[i + 1], results + i));
142 for (i = 0; i < 39; i++) {
143 PetscScalar expected = 25.0 * i * (i + 1);
144 PetscCall(VecDotEnd(vecs[i], vecs[i + 1], results + i));
145 CheckErrorScalar(results[i], expected, tol);
146 }
147 for (i = 0; i < 40; i++) PetscCall(VecDestroy(&vecs[i]));
148
149 PetscCall(PetscFinalize());
150 return 0;
151 }
152
153 /*TEST
154
155 test:
156 nsize: 3
157 output_file: output/empty.out
158
159 testset:
160 nsize: 3
161 output_file: output/empty.out
162
163 test:
164 suffix: 2
165 args: -splitreduction_async -options_left no
166
167 test:
168 suffix: 2_cuda
169 args: -splitreduction_async -vec_type cuda
170 requires: cuda
171
172 test:
173 suffix: cuda
174 args: -vec_type cuda
175 requires: cuda
176
177 test:
178 suffix: 2_hip
179 args: -splitreduction_async -vec_type hip
180 requires: hip
181
182 test:
183 suffix: hip
184 args: -vec_type hip
185 requires: hip
186
187 test:
188 suffix: 2_kokkos
189 args: -splitreduction_async -vec_type kokkos -options_left no
190 requires: kokkos_kernels
191
192 test:
193 suffix: kokkos
194 args: -vec_type kokkos
195 requires: kokkos_kernels
196 TEST*/
197