1*330d8983SJohannes Doerfert // RUN: %libomptarget-compilexx-generic && %libomptarget-run-generic
2*330d8983SJohannes Doerfert // RUN: %libomptarget-compilexx-generic -O3 && %libomptarget-run-generic
3*330d8983SJohannes Doerfert // RUN: %libomptarget-compilexx-generic -O3 -ffast-math && \
4*330d8983SJohannes Doerfert // RUN: %libomptarget-run-generic
5*330d8983SJohannes Doerfert
6*330d8983SJohannes Doerfert // FIXME: This fails to link due to missing math symbols. We should provide the
7*330d8983SJohannes Doerfert // needed math functions in the GPU `libm` and require the GPU C library.
8*330d8983SJohannes Doerfert // UNSUPPORTED: amdgcn-amd-amdhsa
9*330d8983SJohannes Doerfert // UNSUPPORTED: nvptx64-nvidia-cuda-LTO
10*330d8983SJohannes Doerfert
11*330d8983SJohannes Doerfert #include <cassert>
12*330d8983SJohannes Doerfert #include <complex>
13*330d8983SJohannes Doerfert #include <iostream>
14*330d8983SJohannes Doerfert
test_map()15*330d8983SJohannes Doerfert template <typename T> void test_map() {
16*330d8983SJohannes Doerfert std::complex<T> a(0.2, 1), a_check;
17*330d8983SJohannes Doerfert #pragma omp target map(from : a_check)
18*330d8983SJohannes Doerfert { a_check = a; }
19*330d8983SJohannes Doerfert
20*330d8983SJohannes Doerfert assert(std::abs(a - a_check) < 1e-6);
21*330d8983SJohannes Doerfert }
22*330d8983SJohannes Doerfert
test_plus(AT a,BT b)23*330d8983SJohannes Doerfert template <typename RT, typename AT, typename BT> void test_plus(AT a, BT b) {
24*330d8983SJohannes Doerfert std::complex<RT> c, c_host;
25*330d8983SJohannes Doerfert
26*330d8983SJohannes Doerfert c_host = a + b;
27*330d8983SJohannes Doerfert #pragma omp target map(from : c)
28*330d8983SJohannes Doerfert { c = a + b; }
29*330d8983SJohannes Doerfert
30*330d8983SJohannes Doerfert assert(std::abs(c - c_host) < 1e-6);
31*330d8983SJohannes Doerfert }
32*330d8983SJohannes Doerfert
test_minus(AT a,BT b)33*330d8983SJohannes Doerfert template <typename RT, typename AT, typename BT> void test_minus(AT a, BT b) {
34*330d8983SJohannes Doerfert std::complex<RT> c, c_host;
35*330d8983SJohannes Doerfert
36*330d8983SJohannes Doerfert c_host = a - b;
37*330d8983SJohannes Doerfert #pragma omp target map(from : c)
38*330d8983SJohannes Doerfert { c = a - b; }
39*330d8983SJohannes Doerfert
40*330d8983SJohannes Doerfert assert(std::abs(c - c_host) < 1e-6);
41*330d8983SJohannes Doerfert }
42*330d8983SJohannes Doerfert
test_mul(AT a,BT b)43*330d8983SJohannes Doerfert template <typename RT, typename AT, typename BT> void test_mul(AT a, BT b) {
44*330d8983SJohannes Doerfert std::complex<RT> c, c_host;
45*330d8983SJohannes Doerfert
46*330d8983SJohannes Doerfert c_host = a * b;
47*330d8983SJohannes Doerfert #pragma omp target map(from : c)
48*330d8983SJohannes Doerfert { c = a * b; }
49*330d8983SJohannes Doerfert
50*330d8983SJohannes Doerfert assert(std::abs(c - c_host) < 1e-6);
51*330d8983SJohannes Doerfert }
52*330d8983SJohannes Doerfert
test_div(AT a,BT b)53*330d8983SJohannes Doerfert template <typename RT, typename AT, typename BT> void test_div(AT a, BT b) {
54*330d8983SJohannes Doerfert std::complex<RT> c, c_host;
55*330d8983SJohannes Doerfert
56*330d8983SJohannes Doerfert c_host = a / b;
57*330d8983SJohannes Doerfert #pragma omp target map(from : c)
58*330d8983SJohannes Doerfert { c = a / b; }
59*330d8983SJohannes Doerfert
60*330d8983SJohannes Doerfert assert(std::abs(c - c_host) < 1e-6);
61*330d8983SJohannes Doerfert }
62*330d8983SJohannes Doerfert
test_complex()63*330d8983SJohannes Doerfert template <typename T> void test_complex() {
64*330d8983SJohannes Doerfert test_map<T>();
65*330d8983SJohannes Doerfert
66*330d8983SJohannes Doerfert test_plus<T>(std::complex<T>(0, 1), std::complex<T>(0.5, 0.3));
67*330d8983SJohannes Doerfert test_plus<T>(std::complex<T>(0, 1), T(0.5));
68*330d8983SJohannes Doerfert test_plus<T>(T(0.5), std::complex<T>(0, 1));
69*330d8983SJohannes Doerfert
70*330d8983SJohannes Doerfert test_minus<T>(std::complex<T>(0, 1), std::complex<T>(0.5, 0.3));
71*330d8983SJohannes Doerfert test_minus<T>(std::complex<T>(0, 1), T(0.5));
72*330d8983SJohannes Doerfert test_minus<T>(T(0.5), std::complex<T>(0, 1));
73*330d8983SJohannes Doerfert
74*330d8983SJohannes Doerfert test_mul<T>(std::complex<T>(0, 1), std::complex<T>(0.5, 0.3));
75*330d8983SJohannes Doerfert test_mul<T>(std::complex<T>(0, 1), T(0.5));
76*330d8983SJohannes Doerfert test_mul<T>(T(0.5), std::complex<T>(0, 1));
77*330d8983SJohannes Doerfert
78*330d8983SJohannes Doerfert test_div<T>(std::complex<T>(0, 1), std::complex<T>(0.5, 0.3));
79*330d8983SJohannes Doerfert test_div<T>(std::complex<T>(0, 1), T(0.5));
80*330d8983SJohannes Doerfert test_div<T>(T(0.5), std::complex<T>(0, 1));
81*330d8983SJohannes Doerfert }
82*330d8983SJohannes Doerfert
main()83*330d8983SJohannes Doerfert int main() {
84*330d8983SJohannes Doerfert std::cout << "Testing float" << std::endl;
85*330d8983SJohannes Doerfert test_complex<float>();
86*330d8983SJohannes Doerfert std::cout << "Testing double" << std::endl;
87*330d8983SJohannes Doerfert test_complex<double>();
88*330d8983SJohannes Doerfert return 0;
89*330d8983SJohannes Doerfert }
90