diff options
Diffstat (limited to 'src/boost/libs/compute/test/test_transform.cpp')
-rw-r--r-- | src/boost/libs/compute/test/test_transform.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/src/boost/libs/compute/test/test_transform.cpp b/src/boost/libs/compute/test/test_transform.cpp new file mode 100644 index 00000000..81b95c0e --- /dev/null +++ b/src/boost/libs/compute/test/test_transform.cpp @@ -0,0 +1,324 @@ +//---------------------------------------------------------------------------// +// 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://boostorg.github.com/compute for more information. +//---------------------------------------------------------------------------// + +#define BOOST_TEST_MODULE TestTransform +#include <boost/test/unit_test.hpp> + +#include <boost/compute/lambda.hpp> +#include <boost/compute/system.hpp> +#include <boost/compute/function.hpp> +#include <boost/compute/functional.hpp> +#include <boost/compute/algorithm/transform.hpp> +#include <boost/compute/container/vector.hpp> +#include <boost/compute/iterator/counting_iterator.hpp> +#include <boost/compute/functional/field.hpp> + +#include "check_macros.hpp" +#include "context_setup.hpp" + +namespace bc = boost::compute; +namespace compute = boost::compute; + +BOOST_AUTO_TEST_CASE(transform_int_abs) +{ + int data[] = { 1, -2, -3, -4, 5 }; + bc::vector<int> vector(data, data + 5, queue); + CHECK_RANGE_EQUAL(int, 5, vector, (1, -2, -3, -4, 5)); + + bc::transform(vector.begin(), + vector.end(), + vector.begin(), + bc::abs<int>(), + queue); + CHECK_RANGE_EQUAL(int, 5, vector, (1, 2, 3, 4, 5)); +} + +BOOST_AUTO_TEST_CASE(transform_float_sqrt) +{ + float data[] = { 1.0f, 4.0f, 9.0f, 16.0f }; + bc::vector<float> vector(data, data + 4, queue); + CHECK_RANGE_EQUAL(float, 4, vector, (1.0f, 4.0f, 9.0f, 16.0f)); + + bc::transform(vector.begin(), + vector.end(), + vector.begin(), + bc::sqrt<float>(), + queue); + queue.finish(); + BOOST_CHECK_CLOSE(float(vector[0]), 1.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(vector[1]), 2.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(vector[2]), 3.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(vector[3]), 4.0f, 1e-4f); +} + +BOOST_AUTO_TEST_CASE(transform_float_clamp) +{ + float data[] = { 10.f, 20.f, 30.f, 40.f, 50.f }; + bc::vector<float> vector(data, data + 5, queue); + CHECK_RANGE_EQUAL(float, 5, vector, (10.0f, 20.0f, 30.0f, 40.0f, 50.0f)); + + bc::transform(vector.begin(), + vector.end(), + vector.begin(), + clamp(bc::_1, 15.f, 45.f), + queue); + CHECK_RANGE_EQUAL(float, 5, vector, (15.0f, 20.0f, 30.0f, 40.0f, 45.0f)); +} + +BOOST_AUTO_TEST_CASE(transform_add_int) +{ + int data1[] = { 1, 2, 3, 4 }; + bc::vector<int> input1(data1, data1 + 4, queue); + + int data2[] = { 10, 20, 30, 40 }; + bc::vector<int> input2(data2, data2 + 4, queue); + + bc::vector<int> output(4, context); + bc::transform(input1.begin(), + input1.end(), + input2.begin(), + output.begin(), + bc::plus<int>(), + queue); + CHECK_RANGE_EQUAL(int, 4, output, (11, 22, 33, 44)); + + bc::transform(input1.begin(), + input1.end(), + input2.begin(), + output.begin(), + bc::multiplies<int>(), + queue); + CHECK_RANGE_EQUAL(int, 4, output, (10, 40, 90, 160)); +} + +BOOST_AUTO_TEST_CASE(transform_pow4) +{ + float data[] = { 1.0f, 2.0f, 3.0f, 4.0f }; + bc::vector<float> vector(data, data + 4, queue); + CHECK_RANGE_EQUAL(float, 4, vector, (1.0f, 2.0f, 3.0f, 4.0f)); + + bc::vector<float> result(4, context); + bc::transform(vector.begin(), + vector.end(), + result.begin(), + pown(bc::_1, 4), + queue); + queue.finish(); + BOOST_CHECK_CLOSE(float(result[0]), 1.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(result[1]), 16.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(result[2]), 81.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(result[3]), 256.0f, 1e-4f); +} + +BOOST_AUTO_TEST_CASE(transform_custom_function) +{ + float data[] = { 9.0f, 7.0f, 5.0f, 3.0f }; + bc::vector<float> vector(data, data + 4, queue); + + BOOST_COMPUTE_FUNCTION(float, pow3add4, (float x), + { + return pow(x, 3.0f) + 4.0f; + }); + + bc::vector<float> result(4, context); + bc::transform(vector.begin(), + vector.end(), + result.begin(), + pow3add4, + queue); + queue.finish(); + BOOST_CHECK_CLOSE(float(result[0]), 733.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(result[1]), 347.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(result[2]), 129.0f, 1e-4f); + BOOST_CHECK_CLOSE(float(result[3]), 31.0f, 1e-4f); +} + +BOOST_AUTO_TEST_CASE(extract_vector_component) +{ + using bc::int2_; + + int data[] = { 1, 2, + 3, 4, + 5, 6, + 7, 8 }; + bc::vector<int2_> vector( + reinterpret_cast<int2_ *>(data), + reinterpret_cast<int2_ *>(data) + 4, + queue + ); + CHECK_RANGE_EQUAL( + int2_, 4, vector, + (int2_(1, 2), int2_(3, 4), int2_(5, 6), int2_(7, 8)) + ); + + bc::vector<int> x_components(4, context); + bc::transform(vector.begin(), + vector.end(), + x_components.begin(), + bc::get<0>(), + queue); + CHECK_RANGE_EQUAL(int, 4, x_components, (1, 3, 5, 7)); + + bc::vector<int> y_components(4, context); + bc::transform(vector.begin(), + vector.end(), + y_components.begin(), + bc::get<1>(), + queue); + CHECK_RANGE_EQUAL(int, 4, y_components, (2, 4, 6, 8)); +} + +BOOST_AUTO_TEST_CASE(transform_pinned_vector) +{ + int data[] = { 2, -3, 4, -5, 6, -7 }; + std::vector<int> vector(data, data + 6); + + bc::buffer buffer(context, + vector.size() * sizeof(int), + bc::buffer::read_write | bc::buffer::use_host_ptr, + &vector[0]); + + bc::transform(bc::make_buffer_iterator<int>(buffer, 0), + bc::make_buffer_iterator<int>(buffer, 6), + bc::make_buffer_iterator<int>(buffer, 0), + bc::abs<int>(), + queue); + + void *ptr = queue.enqueue_map_buffer(buffer, + bc::command_queue::map_read, + 0, + buffer.size()); + BOOST_VERIFY(ptr == &vector[0]); + BOOST_CHECK_EQUAL(vector[0], 2); + BOOST_CHECK_EQUAL(vector[1], 3); + BOOST_CHECK_EQUAL(vector[2], 4); + BOOST_CHECK_EQUAL(vector[3], 5); + BOOST_CHECK_EQUAL(vector[4], 6); + BOOST_CHECK_EQUAL(vector[5], 7); + queue.enqueue_unmap_buffer(buffer, ptr); +} + +BOOST_AUTO_TEST_CASE(transform_popcount) +{ + using boost::compute::uint_; + + uint_ data[] = { 0, 1, 2, 3, 4, 45, 127, 5000, 789, 15963 }; + bc::vector<uint_> input(data, data + 10, queue); + bc::vector<uint_> output(input.size(), context); + + bc::transform( + input.begin(), + input.end(), + output.begin(), + bc::popcount<uint_>(), + queue + ); + CHECK_RANGE_EQUAL(uint_, 10, output, (0, 1, 1, 2, 1, 4, 7, 5, 5, 10)); +} + +// generates the first 25 fibonacci numbers in parallel using the +// rounding-based fibonacci formula +BOOST_AUTO_TEST_CASE(generate_fibonacci_sequence) +{ + using boost::compute::uint_; + + boost::compute::vector<uint_> sequence(25, context); + + BOOST_COMPUTE_FUNCTION(uint_, nth_fibonacci, (const uint_ n), + { + const float golden_ratio = (1.f + sqrt(5.f)) / 2.f; + return floor(pown(golden_ratio, n) / sqrt(5.f) + 0.5f); + }); + + boost::compute::transform( + boost::compute::make_counting_iterator(uint_(0)), + boost::compute::make_counting_iterator(uint_(sequence.size())), + sequence.begin(), + nth_fibonacci, + queue + ); + CHECK_RANGE_EQUAL( + uint_, 25, sequence, + (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, + 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368) + ); +} + +BOOST_AUTO_TEST_CASE(field) +{ + using compute::uint2_; + using compute::uint4_; + using compute::field; + + unsigned int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + compute::vector<uint4_> input( + reinterpret_cast<uint4_ *>(data), + reinterpret_cast<uint4_ *>(data) + 2, + queue + ); + compute::vector<uint2_> output(input.size(), context); + + compute::transform( + input.begin(), + input.end(), + output.begin(), + compute::field<uint2_>("xz"), + queue + ); + + queue.finish(); + + BOOST_CHECK_EQUAL(uint2_(output[0]), uint2_(1, 3)); + BOOST_CHECK_EQUAL(uint2_(output[1]), uint2_(5, 7)); +} + +BOOST_AUTO_TEST_CASE(transform_abs_doctest) +{ +//! [transform_abs] +int data[] = { -1, -2, -3, -4 }; +boost::compute::vector<int> vec(data, data + 4, queue); + +using boost::compute::abs; + +// calculate the absolute value for each element in-place +boost::compute::transform( + vec.begin(), vec.end(), vec.begin(), abs<int>(), queue +); + +// vec == { 1, 2, 3, 4 } +//! [transform_abs] + + CHECK_RANGE_EQUAL(int, 4, vec, (1, 2, 3, 4)); +} + +BOOST_AUTO_TEST_CASE(abs_if_odd) +{ + // return absolute value only for odd values + BOOST_COMPUTE_FUNCTION(int, abs_if_odd, (int x), + { + if(x & 1){ + return abs(x); + } + else { + return x; + } + }); + + int data[] = { -2, -3, -4, -5, -6, -7, -8, -9 }; + compute::vector<int> vector(data, data + 8, queue); + + compute::transform( + vector.begin(), vector.end(), vector.begin(), abs_if_odd, queue + ); + + CHECK_RANGE_EQUAL(int, 8, vector, (-2, +3, -4, +5, -6, +7, -8, +9)); +} + +BOOST_AUTO_TEST_SUITE_END() |