Implemented pair tests
MODIFY
test/CMakeLists.txt
test/CMakeLists.txt
@@ -69,6 +69,10 @@ add_hipthrust_test("thrust.hip.find" test_find.cpp)
add_hipthrust_test("thrust.hip.for_each" test_for_each.cpp)
add_hipthrust_test("thrust.hip.memory" test_memory.cpp)
add_hipthrust_test("thrust.hip.mismatch" test_mismatch.cpp)
+add_hipthrust_test("thrust.hip.pair_reduce" test_pair_reduce.cpp)
+add_hipthrust_test("thrust.hip.pair_sort" test_pair_sort.cpp)
+add_hipthrust_test("thrust.hip.pair_transform" test_pair_transform.cpp)
+add_hipthrust_test("thrust.hip.pair" test_pair.cpp)
add_hipthrust_test("thrust.hip.reduce" test_reduce.cpp)
add_hipthrust_test("thrust.hip.remove" test_remove.cpp)
add_hipthrust_test("thrust.hip.replace" test_replace.cpp)

ADD
test/test_assertations.hpp
+// Google Test
+#include <gtest/gtest.h>
+
+//#include <thrust/complex.h>
+
+testing::AssertionResult EqFailureQuite(const char* lhs_expression,
+ const char* rhs_expression,
+ bool ignoring_case) {
+ testing::Message msg;
+ msg << "Expressions during equality check:";
+ msg << "\n " << lhs_expression;
+ msg << "\n " << rhs_expression;
+
+ if (ignoring_case) {
+ msg << "\nIgnoring case";
+ }
+
+ return testing::AssertionFailure() << msg;
+}
+
+testing::AssertionResult CmpHelperEQFailureQuite(const char* lhs_expression,
+ const char* rhs_expression) {
+ return EqFailureQuite(lhs_expression,
+ rhs_expression,
+ false);
+}
+
+template <typename T1, typename T2>
+testing::AssertionResult CmpHelperEQ(const char* lhs_expression,
+ const char* rhs_expression,
+ const T1& lhs,
+ const T2& rhs) {
+ if (lhs == rhs) {
+ return testing::AssertionSuccess();
+ }
+
+ return CmpHelperEQFailureQuite(lhs_expression, rhs_expression);
+}
+
+#define ASSERT_EQ_QUIET(val1, val2)\
+ ASSERT_PRED_FORMAT2(CmpHelperEQ, \
+ val1, val2)
+
+
+/*template <typename T>
+testing::AssertionResult ComplexNearPredFormat(const char* expr1,
+ const char* expr2,
+ const char* abs_error_expr,
+ thrust::complex<T> val1,
+ thrust::complex<T> val2,
+ thrust::complex<double> abs_error){
+ const thrust::complex<double> diff(fabs((double)val1.real() - (double)val2.real())
+ ,fabs((double)val1.imag() - (double)val2.imag()));
+ if (diff.real() <= abs_error.real() &&
+ diff.imag() <= abs_error.imag())
+ return testing::AssertionSuccess();
+
+ return testing::AssertionFailure()
+ << "The difference between " << expr1 << " and " << expr2
+ << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
+ << expr1 << " evaluates to " << val1 << ",\n"
+ << expr2 << " evaluates to " << val2 << ", and\n"
+ << abs_error_expr << " evaluates to " << abs_error << ".";
+}
+
+#define ASSERT_NEAR_COMPLEX_ERROR(val1, val2, abs_error)\
+ ASSERT_PRED_FORMAT3(ComplexNearPredFormat<typename decltype(val1)::value_type>, \
+ val1, val2, abs_error)
+
+
+#define ASSERT_NEAR_COMPLEX(val1, val2)\
+ ASSERT_NEAR_COMPLEX_ERROR(val1, val2, thrust::complex<T>(std::numeric_limits<T>::epsilon(),std::numeric_limits<T>::epsilon()))
+*/

ADD
test/test_pair.cpp
+// MIT License
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Google Test
+#include <gtest/gtest.h>
+
+// Thrust
+#include <thrust/pair.h>
+#include <thrust/tuple.h>
+#include <thrust/swap.h>
+
+// HIP API
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+#include <hip/hip_runtime_api.h>
+
+#define HIP_CHECK(condition) ASSERT_EQ(condition, hipSuccess)
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+#include "test_utils.hpp"
+
+template<
+ class InputType
+>
+struct Params
+{
+ using input_type = InputType;
+};
+
+template<class Params>
+class PairTests : public ::testing::Test
+{
+public:
+ using input_type = typename Params::input_type;
+};
+
+typedef ::testing::Types<
+ Params<short>,
+ Params<int>,
+ Params<long long>,
+ Params<unsigned short>,
+ Params<unsigned int>,
+ Params<unsigned long long>,
+ Params<float>,
+ Params<double>
+> PairTestsParams;
+
+TYPED_TEST_CASE(PairTests, PairTestsParams);
+
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+TYPED_TEST(PairTests, TestPairManipulation)
+{
+ using T = typename TestFixture::input_type;
+ using P = thrust::pair<T,T>;
+
+ // test null constructor
+ P p1;
+ ASSERT_EQ(T(0), p1.first);
+ ASSERT_EQ(T(0), p1.second);
+
+ // test individual value manipulation
+ p1.first = T(1);
+ p1.second = T(2);
+ ASSERT_EQ(T(1), p1.first);
+ ASSERT_EQ(T(2), p1.second);
+
+ // test copy constructor
+ P p2(p1);
+ ASSERT_EQ(p1.first, p2.first);
+ ASSERT_EQ(p1.second, p2.second);
+
+ // test copy from std::pair constructor
+ std::pair<T,T> sp(p1.first, p1.second);
+ ASSERT_EQ(p1.first, sp.first);
+ ASSERT_EQ(p1.second, sp.second);
+
+ // test initialization
+ P p3 = p2;
+ ASSERT_EQ(p2.first, p3.first);
+ ASSERT_EQ(p2.second, p3.second);
+
+ // test initialization from std::pair
+ P p4 = sp;
+ ASSERT_EQ(sp.first, p4.first);
+ ASSERT_EQ(sp.second, p4.second);
+
+ // test copy from pair
+ p4.first = T(2);
+ p4.second = T(3);
+
+ P p5;
+ p5 = p4;
+ ASSERT_EQ(p4.first, p5.first);
+ ASSERT_EQ(p4.second, p5.second);
+
+ // test copy from std::pair
+ sp.first = T(4);
+ sp.second = T(5);
+
+ P p6;
+ p6 = sp;
+ ASSERT_EQ(sp.first, p6.first);
+ ASSERT_EQ(sp.second, p6.second);
+
+ // test initialization from make_pair
+ P p7 = thrust::make_pair(T(6),T(7));
+ ASSERT_EQ(T(6), p7.first);
+ ASSERT_EQ(T(7), p7.second);
+
+ // test copy from make_pair
+ p7 = thrust::make_pair(T(8),T(9));
+ ASSERT_EQ(T(8), p7.first);
+ ASSERT_EQ(T(9), p7.second);
+}
+
+TYPED_TEST(PairTests, TestPairComparison)
+{
+ using T = typename TestFixture::input_type;
+ using P = thrust::pair<T,T>;
+
+ P x, y;
+
+ // test operator ==
+ x.first = x.second = y.first = y.second = T(0);
+ ASSERT_EQ(true, x == y);
+ ASSERT_EQ(true, y == x);
+
+ x.first = y.first = y.second = T(0);
+ x.second = T(1);
+ ASSERT_EQ(false, x == y);
+ ASSERT_EQ(false, y == x);
+
+ // test operator<
+ x.first = T(0); x.second = T(0);
+ y.first = T(0); y.second = T(0);
+ ASSERT_EQ(false, x < y);
+ ASSERT_EQ(false, y < x);
+
+ x.first = T(0); x.second = T(1);
+ y.first = T(2); y.second = T(3);
+ ASSERT_EQ(true, x < y);
+ ASSERT_EQ(false, y < x);
+
+ x.first = T(0); x.second = T(0);
+ y.first = T(0); y.second = T(1);
+ ASSERT_EQ(true, x < y);
+ ASSERT_EQ(false, y < x);
+
+ x.first = T(0); x.second = T(1);
+ y.first = T(0); y.second = T(2);
+ ASSERT_EQ(true, x < y);
+ ASSERT_EQ(false, y < x);
+
+ // test operator!=
+ x.first = y.first = y.second = T(0);
+ x.second = T(1);
+ ASSERT_EQ(true, x != y);
+ ASSERT_EQ(true, y != x);
+
+ x.first = x.second = y.first = y.second = T(0);
+ ASSERT_EQ(false, x != y);
+ ASSERT_EQ(false, y != x);
+
+ // test operator>
+ x.first = T(0); x.second = T(0);
+ y.first = T(0); y.second = T(0);
+ ASSERT_EQ(false, x > y);
+ ASSERT_EQ(false, y > x);
+
+ x.first = T(2); x.second = T(3);
+ y.first = T(0); y.second = T(1);
+ ASSERT_EQ(true, x > y);
+ ASSERT_EQ(false, y > x);
+
+ x.first = T(0); x.second = T(1);
+ y.first = T(0); y.second = T(0);
+ ASSERT_EQ(true, x > y);
+ ASSERT_EQ(false, y > x);
+
+ x.first = T(0); x.second = T(2);
+ y.first = T(0); y.second = T(1);
+ ASSERT_EQ(true, x > y);
+ ASSERT_EQ(false, y > x);
+
+
+ // test operator <=
+ x.first = x.second = y.first = y.second = T(0);
+ ASSERT_EQ(true, x <= y);
+ ASSERT_EQ(true, y <= x);
+
+ x.first = y.first = y.second = T(0);
+ x.second = T(1);
+ ASSERT_EQ(false, x <= y);
+
+ x.first = T(0); x.second = T(1);
+ y.first = T(2); y.second = T(3);
+ ASSERT_EQ(true, x <= y);
+ ASSERT_EQ(false, y <= x);
+
+ x.first = T(0); x.second = T(0);
+ y.first = T(0); y.second = T(1);
+ ASSERT_EQ(true, x <= y);
+ ASSERT_EQ(false, y <= x);
+
+ x.first = T(0); x.second = T(1);
+ y.first = T(0); y.second = T(2);
+ ASSERT_EQ(true, x <= y);
+ ASSERT_EQ(false, y <= x);
+
+
+ // test operator >=
+ x.first = x.second = y.first = y.second = T(0);
+ ASSERT_EQ(true, x >= y);
+ ASSERT_EQ(true, y >= x);
+
+ x.first = x.second = y.first = T(0);
+ y.second = T(1);
+ ASSERT_EQ(false, x >= y);
+
+ x.first = T(2); x.second = T(3);
+ y.first = T(0); y.second = T(1);
+ ASSERT_EQ(true, x >= y);
+ ASSERT_EQ(false, y >= x);
+
+ x.first = T(0); x.second = T(1);
+ y.first = T(0); y.second = T(0);
+ ASSERT_EQ(true, x >= y);
+ ASSERT_EQ(false, y >= x);
+
+ x.first = T(0); x.second = T(2);
+ y.first = T(0); y.second = T(1);
+ ASSERT_EQ(true, x >= y);
+ ASSERT_EQ(false, y >= x);
+}
+
+TYPED_TEST(PairTests, TestPairGet)
+{
+ using T = typename TestFixture::input_type;
+ thrust::host_vector<T> data = get_random_data<T>(2,
+ std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());;
+
+ thrust::pair<T,T> p(data[0], data[1]);
+
+ ASSERT_EQ(data[0], thrust::get<0>(p));
+ ASSERT_EQ(data[1], thrust::get<1>(p));
+}
+
+TEST(PairTests, TestPairTupleSize)
+{
+ int result = thrust::tuple_size< thrust::pair<int,int> >::value;
+ ASSERT_EQ(2, result);
+}
+
+TEST(PairTests, TestPairTupleElement)
+{
+ using type0 = thrust::tuple_element<0, thrust::pair<int, float> >::type;
+ using type1 = thrust::tuple_element<1, thrust::pair<int, float> >::type;
+
+ ASSERT_EQ(typeid(int), typeid(type0));
+ ASSERT_EQ(typeid(float), typeid(type1));
+}
+
+TEST(PairTests, TestPairSwap)
+{
+ int x = 7;
+ int y = 13;
+
+ int z = 42;
+ int w = 0;
+
+ thrust::pair<int,int> a(x,y);
+ thrust::pair<int,int> b(z,w);
+
+ thrust::swap(a,b);
+
+ ASSERT_EQ(z, a.first);
+ ASSERT_EQ(w, a.second);
+ ASSERT_EQ(x, b.first);
+ ASSERT_EQ(y, b.second);
+
+
+ using swappable_pair = thrust::pair<user_swappable,user_swappable>;
+
+ thrust::host_vector<swappable_pair> h_v1(1), h_v2(1);
+ thrust::device_vector<swappable_pair> d_v1(1), d_v2(1);
+
+ thrust::swap_ranges(h_v1.begin(), h_v1.end(), h_v2.begin());
+ thrust::swap_ranges(d_v1.begin(), d_v1.end(), d_v2.begin());
+
+ swappable_pair ref(user_swappable(true), user_swappable(true));
+
+ ASSERT_EQ(ref, h_v1[0]);
+ ASSERT_EQ(ref, h_v1[0]);
+ ASSERT_EQ(ref, (swappable_pair)d_v1[0]);
+ ASSERT_EQ(ref, (swappable_pair)d_v1[0]);
+}
+
+
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC

ADD
test/test_pair_reduce.cpp
+// MIT License
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Google Test
+#include <gtest/gtest.h>
+
+// Thrust
+#include <thrust/pair.h>
+#include <thrust/transform.h>
+#include <thrust/reduce.h>
+
+// HIP API
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+#include <hip/hip_runtime_api.h>
+
+#define HIP_CHECK(condition) ASSERT_EQ(condition, hipSuccess)
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+#include "test_utils.hpp"
+#include "test_assertations.hpp"
+
+template<
+ class InputType
+>
+struct Params
+{
+ using input_type = InputType;
+};
+
+template<class Params>
+class PairReduceTests : public ::testing::Test
+{
+public:
+ using input_type = typename Params::input_type;
+};
+
+typedef ::testing::Types<
+ Params<short>,
+ Params<int>,
+ Params<long long>,
+ Params<unsigned short>,
+ Params<unsigned int>,
+ Params<unsigned long long>,
+ Params<float>,
+ Params<double>
+> PairReduceTestsParams;
+
+TYPED_TEST_CASE(PairReduceTests, PairReduceTestsParams);
+
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+struct make_pair_functor
+{
+ template<typename T1, typename T2>
+ __host__ __device__
+ thrust::pair<T1,T2> operator()(const T1 &x, const T2 &y)
+ {
+ return thrust::make_pair(x,y);
+ } // end operator()()
+}; // end make_pair_functor
+
+
+struct add_pairs
+{
+ template <typename Pair1, typename Pair2>
+ __host__ __device__
+ Pair1 operator()(const Pair1 &x, const Pair2 &y)
+ {
+ return thrust::make_pair(x.first + y.first, x.second + y.second);
+ } // end operator()
+}; // end add_pairs
+
+TYPED_TEST(PairReduceTests, TestPairReduce)
+{
+ using T = typename TestFixture::input_type;
+ using P = thrust::pair<T,T>;
+
+ const std::vector<size_t> sizes = get_sizes();
+ for(auto size : sizes)
+ {
+ thrust::host_vector<T> h_p1 = get_random_data<T>(size,
+ std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());;
+
+ thrust::host_vector<T> h_p2 = get_random_data<T>(size,
+ std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());;
+
+ thrust::host_vector<P> h_pairs(size);
+
+ // zip up pairs on the host
+ thrust::transform(h_p1.begin(), h_p1.end(), h_p2.begin(), h_pairs.begin(), make_pair_functor());
+
+ thrust::device_vector<T> d_p1 = h_p1;
+ thrust::device_vector<T> d_p2 = h_p2;
+ thrust::device_vector<P> d_pairs = h_pairs;
+
+ P init = thrust::make_pair(13,13);
+
+ // reduce on the host
+ P h_result = thrust::reduce(h_pairs.begin(), h_pairs.end(), init, add_pairs());
+
+ // reduce on the device
+ P d_result = thrust::reduce(d_pairs.begin(), d_pairs.end(), init, add_pairs());
+
+ ASSERT_EQ_QUIET(h_result, d_result);
+ }
+}
+
+
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC

ADD
test/test_pair_sort.cpp
+// MIT License
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Google Test
+#include <gtest/gtest.h>
+
+// Thrust
+#include <thrust/pair.h>
+#include <thrust/sort.h>
+#include <thrust/sequence.h>
+
+// HIP API
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+#include <hip/hip_runtime_api.h>
+
+#define HIP_CHECK(condition) ASSERT_EQ(condition, hipSuccess)
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+#include "test_utils.hpp"
+#include "test_assertations.hpp"
+
+template<
+ class InputType
+>
+struct Params
+{
+ using input_type = InputType;
+};
+
+template<class Params>
+class PairSortTests : public ::testing::Test
+{
+public:
+ using input_type = typename Params::input_type;
+};
+
+typedef ::testing::Types<
+ Params<short>,
+ Params<int>,
+ Params<long long>,
+ Params<unsigned short>,
+ Params<unsigned int>,
+ Params<unsigned long long>,
+ Params<float>,
+ Params<double>
+> PairSortTestsParams;
+
+TYPED_TEST_CASE(PairSortTests, PairSortTestsParams);
+
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+struct make_pair_functor
+{
+ template<typename T1, typename T2>
+ __host__ __device__
+ thrust::pair<T1,T2> operator()(const T1 &x, const T2 &y)
+ {
+ return thrust::make_pair(x,y);
+ } // end operator()()
+}; // end make_pair_functor
+
+TYPED_TEST(PairSortTests, TestPairStableSortByKey)
+{
+ using T = typename TestFixture::input_type;
+ using P = thrust::pair<T,T>;
+
+ const std::vector<size_t> sizes = get_sizes();
+ for(auto size : sizes)
+ {
+ thrust::host_vector<T> h_p1 = get_random_data<T>(size,
+ std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());;
+
+ thrust::host_vector<T> h_p2 = get_random_data<T>(size,
+ std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());;
+
+ thrust::host_vector<P> h_pairs(size);
+
+ thrust::host_vector<int> h_values(size);
+ thrust::sequence(h_values.begin(), h_values.end());
+
+ // zip up pairs on the host
+ thrust::transform(h_p1.begin(), h_p1.end(), h_p2.begin(), h_pairs.begin(), make_pair_functor());
+
+ // device arrays
+ thrust::device_vector<P> d_pairs = h_pairs;
+ thrust::device_vector<int> d_values = h_values;
+
+ // sort on the host
+ thrust::stable_sort_by_key(h_pairs.begin(), h_pairs.end(), h_values.begin());
+
+ // sort on the device
+ thrust::stable_sort_by_key(d_pairs.begin(), d_pairs.end(), d_values.begin());
+
+ ASSERT_EQ_QUIET(h_pairs, d_pairs);
+ ASSERT_EQ_QUIET(h_values, d_values);
+ }
+}
+
+
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC

ADD
test/test_pair_transform.cpp
+// MIT License
+//
+// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Google Test
+#include <gtest/gtest.h>
+
+// Thrust
+#include <thrust/host_vector.h>
+#include <thrust/pair.h>
+#include <thrust/tuple.h>
+#include <thrust/transform.h>
+
+// HIP API
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+#include <hip/hip_runtime_api.h>
+
+#define HIP_CHECK(condition) ASSERT_EQ(condition, hipSuccess)
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+#include "test_utils.hpp"
+#include "test_assertations.hpp"
+
+template<
+ class InputType
+>
+struct Params
+{
+ using input_type = InputType;
+};
+
+template<class Params>
+class PairTransformTests : public ::testing::Test
+{
+public:
+ using input_type = typename Params::input_type;
+};
+
+typedef ::testing::Types<
+ Params<short>,
+ Params<int>,
+ Params<long long>,
+ Params<unsigned short>,
+ Params<unsigned int>,
+ Params<unsigned long long>,
+ Params<float>,
+ Params<double>
+> PairTransformTestsParams;
+
+TYPED_TEST_CASE(PairTransformTests, PairTransformTestsParams);
+
+#if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC
+
+struct make_pair_functor
+{
+ template<typename T1, typename T2>
+ __host__ __device__
+ thrust::pair<T1,T2> operator()(const T1 &x, const T2 &y)
+ {
+ return thrust::make_pair(x,y);
+ } // end operator()()
+}; // end make_pair_functor
+
+struct add_pairs
+{
+ template <typename Pair1, typename Pair2>
+ __host__ __device__
+ Pair1 operator()(const Pair1 &x, const Pair2 &y)
+ {
+ return thrust::make_pair(x.first + y.first, x.second + y.second);
+ } // end operator()
+}; // end add_pairs
+
+TYPED_TEST(PairTransformTests, TestPairTransform)
+{
+ using T = typename TestFixture::input_type;
+ using P = thrust::pair<T,T>;
+
+ const std::vector<size_t> sizes = get_sizes();
+ for(auto size : sizes)
+ {
+ thrust::host_vector<T> h_p1 = get_random_data<T>(size,
+ std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());;
+
+ thrust::host_vector<T> h_p2 = get_random_data<T>(size,
+ std::numeric_limits<T>::min(),
+ std::numeric_limits<T>::max());;
+
+ thrust::host_vector<P> h_result(size);
+
+ thrust::device_vector<T> d_p1 = h_p1;
+ thrust::device_vector<T> d_p2 = h_p2;
+ thrust::device_vector<P> d_result(size);
+
+ // zip up pairs on the host
+ thrust::transform(h_p1.begin(), h_p1.end(), h_p2.begin(), h_result.begin(), make_pair_functor());
+
+ // zip up pairs on the device
+ thrust::transform(d_p1.begin(), d_p1.end(), d_p2.begin(), d_result.begin(), make_pair_functor());
+
+ ASSERT_EQ_QUIET(h_result, d_result);
+
+ // TODO: add_pairs operator problem.
+ // add pairs on the host
+ /*thrust::transform(h_result.begin(), h_result.end(), h_result.begin(), h_result.begin(), add_pairs());
+
+ // add pairs on the device
+ thrust::transform(d_result.begin(), d_result.end(), d_result.begin(), d_result.begin(), add_pairs());
+
+ ASSERT_EQ_QUIET(h_result, d_result);*/
+ }
+}
+
+
+#endif // THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_HCC

Implemented pair tests