llvm-project/pstl/test/test_transform_reduce.cpp
JF Bastien e637637ae4 Initial PSTL commit
The initial commit of the Parallel STL upstream (under LLVM umbrella) based on
Parallel STL 20181204 open source release, which is available by
https://github.com/intel/parallelstl

Author: Mikhail Dvorskiy <mikhail.dvorskiy@intel.com>

Differential Revision: https://reviews.llvm.org/D55889

llvm-svn: 349653
2018-12-19 17:45:32 +00:00

135 lines
4.5 KiB
C++

// -*- C++ -*-
//===-- test_transform_reduce.cpp -----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Tests for inner_product
#include "pstl/execution"
#include "pstl/numeric"
#include "utils.h"
using namespace TestUtils;
// Equal for all types
template <typename T>
static bool
Equal(T x, T y)
{
return x == y;
}
// Functor for xor-operation for modeling binary operations in inner_product
class XOR
{
public:
template <typename T>
T
operator()(const T& left, const T& right) const
{
return left ^ right;
}
};
// Model of User-defined class
class MyClass
{
public:
int32_t my_field;
MyClass() { my_field = 0; }
MyClass(int32_t in) { my_field = in; }
MyClass(const MyClass& in) { my_field = in.my_field; }
friend MyClass
operator+(const MyClass& x, const MyClass& y)
{
return MyClass(x.my_field + y.my_field);
}
friend MyClass
operator-(const MyClass& x)
{
return MyClass(-x.my_field);
}
friend MyClass operator*(const MyClass& x, const MyClass& y) { return MyClass(x.my_field * y.my_field); }
bool
operator==(const MyClass& in)
{
return my_field == in.my_field;
}
};
template <typename T>
void
CheckResults(const T& expected, const T& in)
{
EXPECT_TRUE(Equal(expected, in), "wrong result of transform_reduce");
}
// We need to check correctness only for "int" (for example) except cases
// if we have "floating-point type"-specialization
void
CheckResults(const float32_t& expected, const float32_t& in)
{
}
// Test for different types and operations with different iterators
struct test_transform_reduce
{
template <typename Policy, typename InputIterator1, typename InputIterator2, typename T, typename BinaryOperation1,
typename BinaryOperation2, typename UnaryOp>
void
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
T init, BinaryOperation1 opB1, BinaryOperation2 opB2, UnaryOp opU)
{
auto expectedB = std::inner_product(first1, last1, first2, init, opB1, opB2);
auto expectedU = transform_reduce_serial(first1, last1, init, opB1, opU);
T resRA = std::transform_reduce(exec, first1, last1, first2, init, opB1, opB2);
CheckResults(expectedB, resRA);
resRA = std::transform_reduce(exec, first1, last1, init, opB1, opU);
CheckResults(expectedU, resRA);
}
};
template <typename T, typename BinaryOperation1, typename BinaryOperation2, typename UnaryOp, typename Initializer>
void
test_by_type(T init, BinaryOperation1 opB1, BinaryOperation2 opB2, UnaryOp opU, Initializer initObj)
{
std::size_t maxSize = 100000;
Sequence<T> in1(maxSize, initObj);
Sequence<T> in2(maxSize, initObj);
for (std::size_t n = 0; n < maxSize; n = n < 16 ? n + 1 : size_t(3.1415 * n))
{
invoke_on_all_policies(test_transform_reduce(), in1.begin(), in1.begin() + n, in2.begin(), in2.begin() + n,
init, opB1, opB2, opU);
invoke_on_all_policies(test_transform_reduce(), in1.cbegin(), in1.cbegin() + n, in2.cbegin(), in2.cbegin() + n,
init, opB1, opB2, opU);
}
}
int32_t
main()
{
test_by_type<int32_t>(42, std::plus<int32_t>(), std::multiplies<int32_t>(), std::negate<int32_t>(),
[](std::size_t a) -> int32_t { return int32_t(rand() % 1000); });
test_by_type<int64_t>(0, [](const int64_t& a, const int64_t& b) -> int64_t { return a | b; }, XOR(),
[](const int64_t& x) -> int64_t { return x * 2; },
[](std::size_t a) -> int64_t { return int64_t(rand() % 1000); });
test_by_type<float32_t>(1.0f, std::multiplies<float32_t>(),
[](const float32_t& a, const float32_t& b) -> float32_t { return a + b; },
[](const float32_t& x) -> float32_t { return x + 2; },
[](std::size_t a) -> float32_t { return rand() % 1000; });
test_by_type<MyClass>(MyClass(), std::plus<MyClass>(), std::multiplies<MyClass>(), std::negate<MyClass>(),
[](std::size_t a) -> MyClass { return MyClass(rand() % 1000); });
std::cout << done() << std::endl;
return 0;
}