Actual source code: ex28.c
1: static char help[] = "Tests vector norms and repeated VecDotBegin()/VecDotEnd().\n\n";
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)
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)
19: int main(int argc, char **argv)
20: {
21: PetscInt n = 25, i, rows[] = {0, 1};
22: PetscScalar two = 2.0, result1, result2, results[40], value, values[] = {10.0, 11.0};
23: PetscScalar result1a, result2a;
24: PetscReal result3, result4, result[2], result3a, result4a, resulta[2];
25: Vec x, y, x_ref, y_ref, vecs[40];
26: PetscReal tol = PETSC_SMALL;
28: PetscFunctionBeginUser;
29: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
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(VecCreate(PETSC_COMM_WORLD, &x_ref));
37: PetscCall(VecSetSizes(x_ref, n, PETSC_DECIDE));
38: PetscCall(VecSetType(x_ref, VECSTANDARD));
39: PetscCall(VecDuplicate(x_ref, &y_ref));
40: PetscCall(VecSetRandom(x, NULL));
41: PetscCall(VecCopy(x, x_ref));
42: PetscCall(VecViewFromOptions(x, NULL, "-x_view"));
43: PetscCall(VecSet(y, two));
44: PetscCall(VecSet(y_ref, two));
46: /*
47: Test mixing dot products and norms that require sums
48: */
49: result1 = result2 = 0.0;
50: result3 = result4 = 0.0;
51: PetscCall(VecDotBegin(x, y, &result1));
52: PetscCall(VecDotBegin(y, x, &result2));
53: PetscCall(VecNormBegin(y, NORM_2, &result3));
54: PetscCall(VecNormBegin(x, NORM_1, &result4));
55: PetscCall(PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)x)));
56: PetscCall(VecDotEnd(x, y, &result1));
57: PetscCall(VecDotEnd(y, x, &result2));
58: PetscCall(VecNormEnd(y, NORM_2, &result3));
59: PetscCall(VecNormEnd(x, NORM_1, &result4));
61: PetscCall(VecDot(x, y, &result1a));
62: PetscCall(VecDot(y, x, &result2a));
63: PetscCall(VecNorm(y, NORM_2, &result3a));
64: PetscCall(VecNorm(x, NORM_1, &result4a));
66: CheckErrorScalar(result1, result1a, tol);
67: CheckErrorScalar(result2, result2a, tol);
68: CheckError(result3, result3a, tol);
69: CheckError(result4, result4a, tol);
70: PetscCall(VecNorm(y_ref, NORM_2, &result3a));
71: PetscCall(VecNorm(x_ref, NORM_1, &result4a));
72: CheckError(result3, result3a, tol);
73: CheckError(result4, result4a, tol);
75: /*
76: Test norms that only require abs
77: */
78: result1 = result2 = 0.0;
79: result3 = result4 = 0.0;
80: PetscCall(VecNormBegin(y, NORM_MAX, &result3));
81: PetscCall(VecNormBegin(x, NORM_MAX, &result4));
82: PetscCall(VecNormEnd(y, NORM_MAX, &result3));
83: PetscCall(VecNormEnd(x, NORM_MAX, &result4));
85: PetscCall(VecNorm(x, NORM_MAX, &result4a));
86: PetscCall(VecNorm(y, NORM_MAX, &result3a));
87: CheckError(result3, result3a, tol);
88: CheckError(result4, result4a, tol);
89: PetscCall(VecNorm(x_ref, NORM_MAX, &result4a));
90: PetscCall(VecNorm(y_ref, NORM_MAX, &result3a));
91: CheckError(result3, result3a, tol);
92: CheckError(result4, result4a, tol);
94: /*
95: Tests dot, max, 1, norm
96: */
97: result1 = result2 = 0.0;
98: result3 = result4 = 0.0;
99: #if PetscDefined(USE_COMPLEX)
100: // The entries 6+8i and 11 have opposite order under |z| and |Re(z)| + |Im(z)|.
101: values[0] = PetscCMPLX(6, 8);
102: #endif
103: PetscCall(VecSetValues(x, 2, rows, values, INSERT_VALUES));
104: PetscCall(VecAssemblyBegin(x));
105: PetscCall(VecAssemblyEnd(x));
106: PetscCall(VecSetValues(x_ref, 2, rows, values, INSERT_VALUES));
107: PetscCall(VecAssemblyBegin(x_ref));
108: PetscCall(VecAssemblyEnd(x_ref));
110: PetscCall(VecDotBegin(x, y, &result1));
111: PetscCall(VecDotBegin(y, x, &result2));
112: PetscCall(VecNormBegin(x, NORM_MAX, &result3));
113: PetscCall(VecNormBegin(x, NORM_1, &result4));
114: PetscCall(VecDotEnd(x, y, &result1));
115: PetscCall(VecDotEnd(y, x, &result2));
116: PetscCall(VecNormEnd(x, NORM_MAX, &result3));
117: PetscCall(VecNormEnd(x, NORM_1, &result4));
119: PetscCall(VecDot(x, y, &result1a));
120: PetscCall(VecDot(y, x, &result2a));
121: PetscCall(VecNorm(x, NORM_MAX, &result3a));
122: PetscCall(VecNorm(x, NORM_1, &result4a));
124: CheckErrorScalar(result1, result1a, tol);
125: CheckErrorScalar(result2, result2a, tol);
126: CheckError(result3, result3a, tol);
127: CheckError(result4, result4a, tol);
128: PetscCall(VecNorm(x_ref, NORM_MAX, &result3a));
129: PetscCall(VecNorm(x_ref, NORM_1, &result4a));
130: CheckError(result3, result3a, tol);
131: CheckError(result4, result4a, tol);
133: /*
134: tests 1_and_2 norm
135: */
136: PetscCall(VecNormBegin(x, NORM_MAX, &result3));
137: PetscCall(VecNormBegin(x, NORM_1_AND_2, result));
138: PetscCall(VecNormBegin(y, NORM_MAX, &result4));
139: PetscCall(VecNormEnd(x, NORM_MAX, &result3));
140: PetscCall(VecNormEnd(x, NORM_1_AND_2, result));
141: PetscCall(VecNormEnd(y, NORM_MAX, &result4));
143: PetscCall(VecNorm(x, NORM_MAX, &result3a));
144: PetscCall(VecNorm(x, NORM_1_AND_2, resulta));
145: PetscCall(VecNorm(y, NORM_MAX, &result4a));
147: CheckError(result3, result3a, tol);
148: CheckError(result4, result4a, tol);
149: CheckError(result[0], resulta[0], tol);
150: CheckError(result[1], resulta[1], tol);
151: PetscCall(VecNorm(x_ref, NORM_MAX, &result3a));
152: PetscCall(VecNorm(x_ref, NORM_1_AND_2, resulta));
153: PetscCall(VecNorm(y_ref, NORM_MAX, &result4a));
154: CheckError(result3, result3a, tol);
155: CheckError(result4, result4a, tol);
156: CheckError(result[0], resulta[0], tol);
157: CheckError(result[1], resulta[1], tol);
159: PetscCall(VecDestroy(&x));
160: PetscCall(VecDestroy(&y));
161: PetscCall(VecDestroy(&x_ref));
162: PetscCall(VecDestroy(&y_ref));
164: /*
165: Tests computing a large number of operations that require
166: allocating a larger data structure internally
167: */
168: for (i = 0; i < 40; i++) {
169: PetscCall(VecCreate(PETSC_COMM_WORLD, vecs + i));
170: PetscCall(VecSetSizes(vecs[i], PETSC_DECIDE, n));
171: PetscCall(VecSetFromOptions(vecs[i]));
172: value = (PetscReal)i;
173: PetscCall(VecSet(vecs[i], value));
174: }
175: for (i = 0; i < 39; i++) PetscCall(VecDotBegin(vecs[i], vecs[i + 1], results + i));
176: for (i = 0; i < 39; i++) {
177: PetscScalar expected = 25.0 * i * (i + 1);
178: PetscCall(VecDotEnd(vecs[i], vecs[i + 1], results + i));
179: CheckErrorScalar(results[i], expected, tol);
180: }
181: for (i = 0; i < 40; i++) PetscCall(VecDestroy(&vecs[i]));
183: PetscCall(PetscFinalize());
184: return 0;
185: }
187: /*TEST
189: testset:
190: requires: complex
191: output_file: output/empty.out
193: test:
194: suffix: complex_norms
196: test:
197: suffix: complex_norms_cuda
198: args: -vec_type cuda
199: requires: cuda
201: test:
202: suffix: complex_norms_hip
203: args: -vec_type hip
204: requires: hip
206: test:
207: suffix: complex_norms_kokkos
208: args: -vec_type kokkos
209: requires: kokkos_kernels
211: test:
212: nsize: 3
213: output_file: output/empty.out
215: testset:
216: nsize: 3
217: output_file: output/empty.out
219: test:
220: suffix: 2
221: args: -splitreduction_async -options_left no
223: test:
224: suffix: 2_cuda
225: args: -splitreduction_async -vec_type cuda
226: requires: cuda
228: test:
229: suffix: cuda
230: args: -vec_type cuda
231: requires: cuda
233: test:
234: suffix: 2_hip
235: args: -splitreduction_async -vec_type hip
236: requires: hip
238: test:
239: suffix: hip
240: args: -vec_type hip
241: requires: hip
243: test:
244: suffix: 2_kokkos
245: args: -splitreduction_async -vec_type kokkos -options_left no
246: requires: kokkos_kernels
248: test:
249: suffix: kokkos
250: args: -vec_type kokkos
251: requires: kokkos_kernels
252: TEST*/