YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_openmp.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <math.h>
8
9#include "tests.h"
10#include "utils_common.h"
11
17int main (int argc, char** argv) {
18
19 if (argc != 2) PUT_ERR("wrong number of arguments");
20
21 enum {
22 SRC_COUNT = 10,
23 TGT_COUNT = 5,
24 };
25 double weights[TGT_COUNT][SRC_COUNT] =
26 {{0.0,0.1,0.0,0.3,0.0,0.0,0.2,0.0,0.4,0.0},
27 {0.0,0.0,0.0,0.0,0.5,0.5,0.0,0.0,0.0,0.0},
28 {0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1},
29 {0.2,0.0,0.2,0.0,0.2,0.0,0.2,0.0,0.2,0.0},
30 {0.0,0.3,0.0,0.0,0.3,0.0,0.0,0.4,0.0,0.0}};
31
32 // generate source field
33 double src_field[SRC_COUNT];
34 for (size_t i = 0; i < SRC_COUNT; ++i) src_field[i] = (double)(i+1);
35
36 // compute reference target field
37 double ref_tgt_field[TGT_COUNT];
38 for (size_t i = 0; i < TGT_COUNT; ++i) {
39 double tgt_value = 0.0;
40 for (size_t j = 0; j < SRC_COUNT; ++j)
41 tgt_value += src_field[j] * weights[i][j];
42 ref_tgt_field[i] = tgt_value;
43 }
44
45#ifdef YAC_OPENMP_ENABLED
46 int ref_num_threads = atoi(argv[1]);
47#else
48 UNUSED(argv);
49#endif
50
51 size_t prefix_num_src_per_tgt[TGT_COUNT + 1];
52 size_t src_idx[SRC_COUNT * TGT_COUNT];
53 double compact_weights[SRC_COUNT * TGT_COUNT];
54
55 // generate sparse weight matrix
56 prefix_num_src_per_tgt[0] = 0;
57 for (size_t i = 0, k = 0; i < TGT_COUNT; ++i) {
58 for (size_t j = 0; j < SRC_COUNT; ++j) {
59 if (weights[i][j] != 0.0) {
60 src_idx[k] = j;
61 compact_weights[k] = weights[i][j];
62 ++k;
63 }
64 }
65 prefix_num_src_per_tgt[i+1] = k;
66 }
67
68 // compute target field using sparse weight matrix and OpenMP (if available)
69 double tgt_field[TGT_COUNT];
71 {
73 for (size_t i = 0; i < TGT_COUNT; ++i) {
74#ifdef YAC_OPENMP_ENABLED
75 if (omp_get_num_threads() != ref_num_threads)
76 PUT_ERR("wrong number of threads");
77#endif
78 double tgt_value = 0.0;
79 size_t const j_bound = prefix_num_src_per_tgt[i+1];
80 for (size_t j = prefix_num_src_per_tgt[i]; j < j_bound; ++j) {
81 tgt_value += src_field[src_idx[j]] * compact_weights[j];
82 }
83 tgt_field[i] = tgt_value;
84 }
85 }
86
87 // check results
88 for (size_t i = 0; i < TGT_COUNT; ++i)
89 if (fabs(ref_tgt_field[i] - tgt_field[i]) > 1.0e-6)
90 PUT_ERR("wrong tgt_field value");
91
92 return TEST_EXIT_CODE;
93}
#define UNUSED(x)
Definition core.h:72
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
#define YAC_OMP_PARALLEL
#define YAC_OMP_FOR