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