1 // RUN: %libomptarget-compilexx-generic -O3 && %libomptarget-run-generic
2 
3 #include <iostream>
4 
5 template <typename T> int test_map() {
6   std::cout << "map(complex<>)" << std::endl;
7   T a(0.2), a_check;
8 #pragma omp target map(from : a_check)
9   { a_check = a; }
10 
11   if (a_check != a) {
12     std::cout << " wrong results";
13     return 1;
14   }
15 
16   return 0;
17 }
18 
19 template <typename T> int test_reduction() {
20   std::cout << "flat parallelism" << std::endl;
21   T sum(0), sum_host(0);
22   const int size = 100;
23   T array[size];
24   for (int i = 0; i < size; i++) {
25     array[i] = i;
26     sum_host += array[i];
27   }
28 
29 #pragma omp target teams distribute parallel for map(to: array[:size])         \
30                                                  reduction(+ : sum)
31   for (int i = 0; i < size; i++)
32     sum += array[i];
33 
34   if (sum != sum_host)
35     std::cout << " wrong results " << sum << " host " << sum_host << std::endl;
36 
37   std::cout << "hierarchical parallelism" << std::endl;
38   const int nblock(10), block_size(10);
39   T block_sum[nblock];
40 #pragma omp target teams distribute map(to                                     \
41                                         : array[:size])                        \
42     map(from                                                                   \
43         : block_sum[:nblock])
44   for (int ib = 0; ib < nblock; ib++) {
45     T partial_sum = 0;
46     const int istart = ib * block_size;
47     const int iend = (ib + 1) * block_size;
48 #pragma omp parallel for reduction(+ : partial_sum)
49     for (int i = istart; i < iend; i++)
50       partial_sum += array[i];
51     block_sum[ib] = partial_sum;
52   }
53 
54   sum = 0;
55   for (int ib = 0; ib < nblock; ib++) {
56     sum += block_sum[ib];
57   }
58 
59   if (sum != sum_host) {
60     std::cout << " wrong results " << sum << " host " << sum_host << std::endl;
61     return 1;
62   }
63 
64   return 0;
65 }
66 
67 template <typename T> int test_complex() {
68   int ret = 0;
69   ret |= test_map<T>();
70   ret |= test_reduction<T>();
71   return ret;
72 }
73 
74 int main() {
75   int ret = 0;
76   std::cout << "Testing float" << std::endl;
77   ret |= test_complex<float>();
78   std::cout << "Testing double" << std::endl;
79   ret |= test_complex<double>();
80   return ret;
81 }
82