• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10 
11 #define BOOST_TEST_MODULE TestComplex
12 #include <boost/test/unit_test.hpp>
13 
14 #include <boost/compute/algorithm/copy.hpp>
15 #include <boost/compute/algorithm/fill.hpp>
16 #include <boost/compute/algorithm/transform.hpp>
17 #include <boost/compute/container/vector.hpp>
18 #include <boost/compute/types/complex.hpp>
19 #include <boost/compute/type_traits/type_name.hpp>
20 
21 #include "context_setup.hpp"
22 
23 // copies a vector of complex<float>'s on the host to the device
BOOST_AUTO_TEST_CASE(copy_complex_vector)24 BOOST_AUTO_TEST_CASE(copy_complex_vector)
25 {
26     std::vector<std::complex<float> > host_vector;
27     host_vector.push_back(std::complex<float>(1.0f, 2.0f));
28     host_vector.push_back(std::complex<float>(-2.0f, 1.0f));
29     host_vector.push_back(std::complex<float>(1.0f, -2.0f));
30     host_vector.push_back(std::complex<float>(-2.0f, -1.0f));
31 
32     boost::compute::vector<std::complex<float> > device_vector(context);
33     boost::compute::copy(
34         host_vector.begin(),
35         host_vector.end(),
36         device_vector.begin(),
37         queue
38     );
39     queue.finish();
40     BOOST_CHECK_EQUAL(std::complex<float>(device_vector[0]), std::complex<float>(1.0f, 2.0f));
41     BOOST_CHECK_EQUAL(std::complex<float>(device_vector[1]), std::complex<float>(-2.0f, 1.0f));
42     BOOST_CHECK_EQUAL(std::complex<float>(device_vector[2]), std::complex<float>(1.0f, -2.0f));
43     BOOST_CHECK_EQUAL(std::complex<float>(device_vector[3]), std::complex<float>(-2.0f, -1.0f));
44 }
45 
46 // fills a vector of complex<float>'s on the device with a constant value
BOOST_AUTO_TEST_CASE(fill_complex_vector)47 BOOST_AUTO_TEST_CASE(fill_complex_vector)
48 {
49     boost::compute::vector<std::complex<float> > vector(6, context);
50     boost::compute::fill(
51         vector.begin(),
52         vector.end(),
53         std::complex<float>(2.0f, 5.0f),
54         queue
55     );
56     queue.finish();
57     BOOST_CHECK_EQUAL(std::complex<float>(vector[0]), std::complex<float>(2.0f, 5.0f));
58     BOOST_CHECK_EQUAL(std::complex<float>(vector[1]), std::complex<float>(2.0f, 5.0f));
59     BOOST_CHECK_EQUAL(std::complex<float>(vector[2]), std::complex<float>(2.0f, 5.0f));
60     BOOST_CHECK_EQUAL(std::complex<float>(vector[3]), std::complex<float>(2.0f, 5.0f));
61     BOOST_CHECK_EQUAL(std::complex<float>(vector[4]), std::complex<float>(2.0f, 5.0f));
62     BOOST_CHECK_EQUAL(std::complex<float>(vector[5]), std::complex<float>(2.0f, 5.0f));
63 }
64 
65 // extracts the real and imag components of a vector of complex<float>'s using
66 // transform with the real() and imag() functions
BOOST_AUTO_TEST_CASE(extract_real_and_imag)67 BOOST_AUTO_TEST_CASE(extract_real_and_imag)
68 {
69     boost::compute::vector<std::complex<float> > vector(context);
70     vector.push_back(std::complex<float>(1.0f, 3.0f), queue);
71     vector.push_back(std::complex<float>(3.0f, 1.0f), queue);
72     vector.push_back(std::complex<float>(5.0f, -1.0f), queue);
73     vector.push_back(std::complex<float>(7.0f, -3.0f), queue);
74     vector.push_back(std::complex<float>(9.0f, -5.0f), queue);
75     BOOST_CHECK_EQUAL(vector.size(), size_t(5));
76 
77     boost::compute::vector<float> reals(5, context);
78     boost::compute::transform(
79         vector.begin(),
80         vector.end(),
81         reals.begin(),
82         boost::compute::real<float>(),
83         queue
84     );
85     queue.finish();
86     BOOST_CHECK_EQUAL(float(reals[0]), float(1.0f));
87     BOOST_CHECK_EQUAL(float(reals[1]), float(3.0f));
88     BOOST_CHECK_EQUAL(float(reals[2]), float(5.0f));
89     BOOST_CHECK_EQUAL(float(reals[3]), float(7.0f));
90     BOOST_CHECK_EQUAL(float(reals[4]), float(9.0f));
91 
92     boost::compute::vector<float> imags(5, context);
93     boost::compute::transform(
94         vector.begin(),
95         vector.end(),
96         imags.begin(),
97         boost::compute::imag<float>(),
98         queue
99     );
100     queue.finish();
101     BOOST_CHECK_EQUAL(float(imags[0]), float(3.0f));
102     BOOST_CHECK_EQUAL(float(imags[1]), float(1.0f));
103     BOOST_CHECK_EQUAL(float(imags[2]), float(-1.0f));
104     BOOST_CHECK_EQUAL(float(imags[3]), float(-3.0f));
105     BOOST_CHECK_EQUAL(float(imags[4]), float(-5.0f));
106 }
107 
108 // compute the complex conjugate of a vector of complex<float>'s
BOOST_AUTO_TEST_CASE(complex_conj)109 BOOST_AUTO_TEST_CASE(complex_conj)
110 {
111     boost::compute::vector<std::complex<float> > input(context);
112     input.push_back(std::complex<float>(1.0f, 3.0f), queue);
113     input.push_back(std::complex<float>(3.0f, 1.0f), queue);
114     input.push_back(std::complex<float>(5.0f, -1.0f), queue);
115     input.push_back(std::complex<float>(7.0f, -3.0f), queue);
116     input.push_back(std::complex<float>(9.0f, -5.0f), queue);
117     BOOST_CHECK_EQUAL(input.size(), size_t(5));
118 
119     boost::compute::vector<std::complex<float> > output(5, context);
120     boost::compute::transform(
121         input.begin(),
122         input.end(),
123         output.begin(),
124         boost::compute::conj<float>(),
125         queue
126     );
127     queue.finish();
128     BOOST_CHECK_EQUAL(std::complex<float>(output[0]), std::complex<float>(1.0f, -3.0f));
129     BOOST_CHECK_EQUAL(std::complex<float>(output[1]), std::complex<float>(3.0f, -1.0f));
130     BOOST_CHECK_EQUAL(std::complex<float>(output[2]), std::complex<float>(5.0f, 1.0f));
131     BOOST_CHECK_EQUAL(std::complex<float>(output[3]), std::complex<float>(7.0f, 3.0f));
132     BOOST_CHECK_EQUAL(std::complex<float>(output[4]), std::complex<float>(9.0f, 5.0f));
133 }
134 
135 // check type_name() for std::complex
BOOST_AUTO_TEST_CASE(complex_type_name)136 BOOST_AUTO_TEST_CASE(complex_type_name)
137 {
138     BOOST_CHECK(
139         std::strcmp(
140             boost::compute::type_name<std::complex<float> >(),
141             "float2"
142         ) == 0
143     );
144 }
145 
BOOST_AUTO_TEST_CASE(transform_multiply)146 BOOST_AUTO_TEST_CASE(transform_multiply)
147 {
148     boost::compute::vector<std::complex<float> > x(context);
149     x.push_back(std::complex<float>(1.0f, 2.0f), queue);
150     x.push_back(std::complex<float>(-2.0f, 5.0f), queue);
151 
152     boost::compute::vector<std::complex<float> > y(context);
153     y.push_back(std::complex<float>(3.0f, 4.0f), queue);
154     y.push_back(std::complex<float>(2.0f, -1.0f), queue);
155 
156     boost::compute::vector<std::complex<float> > z(2, context);
157 
158     // z = x * y
159     boost::compute::transform(
160         x.begin(),
161         x.end(),
162         y.begin(),
163         z.begin(),
164         boost::compute::multiplies<std::complex<float> >(),
165         queue
166     );
167     queue.finish();
168 
169     BOOST_CHECK_EQUAL(std::complex<float>(z[0]), std::complex<float>(-5.0f, 10.0f));
170     BOOST_CHECK_EQUAL(std::complex<float>(z[1]), std::complex<float>(1.0f, 12.0f));
171 }
172 
173 BOOST_AUTO_TEST_SUITE_END()
174