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*/