2
0
mirror of https://github.com/boostorg/compute.git synced 2026-01-28 19:12:15 +00:00
Files
compute/test/test_complex.cpp
Kyle Lutz 4ab37ada07 Add system-wide default command queue
This adds a system-wide default command queue. This queue is
accessible via the new static system::default_queue() method.
The default command queue is created for the default compute
device in the default context and is analogous to the default
stream in CUDA.

This changes how algorithms operate when invoked without an
explicit command queue. Previously, each algorithm had two
overloads, the first expected a command queue to be explicitly
passed and the second would create and use a temporary command
queue. Now, all algorithms take a command queue argument which
has a default value equal to system::default_queue().

This fixes a number of race-conditions and performance issues
througout the library associated with create, using, and
destroying many separate command queues.
2013-05-15 20:59:56 -04:00

169 lines
6.3 KiB
C++

//---------------------------------------------------------------------------//
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://kylelutz.github.com/compute for more information.
//---------------------------------------------------------------------------//
#define BOOST_TEST_MODULE TestComplex
#include <boost/test/unit_test.hpp>
#include <boost/compute/complex.hpp>
#include <boost/compute/algorithm/copy.hpp>
#include <boost/compute/algorithm/fill.hpp>
#include <boost/compute/algorithm/transform.hpp>
#include <boost/compute/container/vector.hpp>
#include <boost/compute/type_traits/type_name.hpp>
#include "context_setup.hpp"
// copies a vector of complex<float>'s on the host to the device
BOOST_AUTO_TEST_CASE(copy_complex_vector)
{
std::vector<std::complex<float> > host_vector;
host_vector.push_back(std::complex<float>(1.0f, 2.0f));
host_vector.push_back(std::complex<float>(-2.0f, 1.0f));
host_vector.push_back(std::complex<float>(1.0f, -2.0f));
host_vector.push_back(std::complex<float>(-2.0f, -1.0f));
boost::compute::vector<std::complex<float> > device_vector;
boost::compute::copy(
host_vector.begin(),
host_vector.end(),
device_vector.begin()
);
boost::compute::system::finish();
BOOST_CHECK_EQUAL(std::complex<float>(device_vector[0]), std::complex<float>(1.0f, 2.0f));
BOOST_CHECK_EQUAL(std::complex<float>(device_vector[1]), std::complex<float>(-2.0f, 1.0f));
BOOST_CHECK_EQUAL(std::complex<float>(device_vector[2]), std::complex<float>(1.0f, -2.0f));
BOOST_CHECK_EQUAL(std::complex<float>(device_vector[3]), std::complex<float>(-2.0f, -1.0f));
}
// fills a vector of complex<float>'s on the device with a constant value
BOOST_AUTO_TEST_CASE(fill_complex_vector)
{
boost::compute::vector<std::complex<float> > vector(6);
boost::compute::fill(
vector.begin(),
vector.end(),
std::complex<float>(2.0f, 5.0f)
);
boost::compute::system::finish();
BOOST_CHECK_EQUAL(std::complex<float>(vector[0]), std::complex<float>(2.0f, 5.0f));
BOOST_CHECK_EQUAL(std::complex<float>(vector[1]), std::complex<float>(2.0f, 5.0f));
BOOST_CHECK_EQUAL(std::complex<float>(vector[2]), std::complex<float>(2.0f, 5.0f));
BOOST_CHECK_EQUAL(std::complex<float>(vector[3]), std::complex<float>(2.0f, 5.0f));
BOOST_CHECK_EQUAL(std::complex<float>(vector[4]), std::complex<float>(2.0f, 5.0f));
BOOST_CHECK_EQUAL(std::complex<float>(vector[5]), std::complex<float>(2.0f, 5.0f));
}
// extracts the real and imag components of a vector of complex<float>'s using
// transform with the real() and imag() functions
BOOST_AUTO_TEST_CASE(extract_real_and_imag)
{
boost::compute::vector<std::complex<float> > vector;
vector.push_back(std::complex<float>(1.0f, 3.0f));
vector.push_back(std::complex<float>(3.0f, 1.0f));
vector.push_back(std::complex<float>(5.0f, -1.0f));
vector.push_back(std::complex<float>(7.0f, -3.0f));
vector.push_back(std::complex<float>(9.0f, -5.0f));
BOOST_CHECK_EQUAL(vector.size(), size_t(5));
boost::compute::vector<float> reals(5);
boost::compute::transform(
vector.begin(),
vector.end(),
reals.begin(),
boost::compute::real<float>()
);
boost::compute::system::finish();
BOOST_CHECK_EQUAL(float(reals[0]), float(1.0f));
BOOST_CHECK_EQUAL(float(reals[1]), float(3.0f));
BOOST_CHECK_EQUAL(float(reals[2]), float(5.0f));
BOOST_CHECK_EQUAL(float(reals[3]), float(7.0f));
BOOST_CHECK_EQUAL(float(reals[4]), float(9.0f));
boost::compute::vector<float> imags(5);
boost::compute::transform(
vector.begin(),
vector.end(),
imags.begin(),
boost::compute::imag<float>()
);
boost::compute::system::finish();
BOOST_CHECK_EQUAL(float(imags[0]), float(3.0f));
BOOST_CHECK_EQUAL(float(imags[1]), float(1.0f));
BOOST_CHECK_EQUAL(float(imags[2]), float(-1.0f));
BOOST_CHECK_EQUAL(float(imags[3]), float(-3.0f));
BOOST_CHECK_EQUAL(float(imags[4]), float(-5.0f));
}
// compute the complex conjugate of a vector of complex<float>'s
BOOST_AUTO_TEST_CASE(complex_conj)
{
boost::compute::vector<std::complex<float> > input;
input.push_back(std::complex<float>(1.0f, 3.0f));
input.push_back(std::complex<float>(3.0f, 1.0f));
input.push_back(std::complex<float>(5.0f, -1.0f));
input.push_back(std::complex<float>(7.0f, -3.0f));
input.push_back(std::complex<float>(9.0f, -5.0f));
BOOST_CHECK_EQUAL(input.size(), size_t(5));
boost::compute::vector<std::complex<float> > output(5);
boost::compute::transform(
input.begin(),
input.end(),
output.begin(),
boost::compute::conj<float>()
);
boost::compute::system::finish();
BOOST_CHECK_EQUAL(std::complex<float>(output[0]), std::complex<float>(1.0f, -3.0f));
BOOST_CHECK_EQUAL(std::complex<float>(output[1]), std::complex<float>(3.0f, -1.0f));
BOOST_CHECK_EQUAL(std::complex<float>(output[2]), std::complex<float>(5.0f, 1.0f));
BOOST_CHECK_EQUAL(std::complex<float>(output[3]), std::complex<float>(7.0f, 3.0f));
BOOST_CHECK_EQUAL(std::complex<float>(output[4]), std::complex<float>(9.0f, 5.0f));
}
// check type_name() for std::complex
BOOST_AUTO_TEST_CASE(complex_type_name)
{
BOOST_CHECK(
std::strcmp(
boost::compute::type_name<std::complex<float> >(),
"float2"
) == 0
);
}
BOOST_AUTO_TEST_CASE(transform_multiply)
{
boost::compute::vector<std::complex<float> > x(context);
x.push_back(std::complex<float>(1.0f, 2.0f));
x.push_back(std::complex<float>(-2.0f, 5.0f));
boost::compute::vector<std::complex<float> > y(context);
y.push_back(std::complex<float>(3.0f, 4.0f));
y.push_back(std::complex<float>(2.0f, -1.0f));
boost::compute::vector<std::complex<float> > z(2, context);
// z = x * y
boost::compute::transform(
x.begin(),
x.end(),
y.begin(),
z.begin(),
boost::compute::multiplies<std::complex<float> >(),
queue
);
queue.finish();
BOOST_CHECK_EQUAL(std::complex<float>(z[0]), std::complex<float>(-5.0f, 10.0f));
BOOST_CHECK_EQUAL(std::complex<float>(z[1]), std::complex<float>(1.0f, 12.0f));
}
BOOST_AUTO_TEST_SUITE_END()