llvm-project/pstl/test/test_rotate.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

173 lines
5.0 KiB
C++

// -*- C++ -*-
//===-- test_rotate.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.
//
//===----------------------------------------------------------------------===//
#include "pstl_test_config.h"
#include <iterator>
#include "pstl/execution"
#include "pstl/algorithm"
#include "utils.h"
using namespace TestUtils;
template <typename T>
struct wrapper
{
T t;
int move_count;
explicit wrapper(T t_) : t(t_), move_count(0) {}
wrapper&
operator=(const T& t_)
{
t = t_;
return *this;
}
wrapper(const wrapper<T>& a) : move_count(0) { t = a.t; }
wrapper<T>&
operator=(wrapper<T>& a)
{
t = a.t;
return *this;
}
wrapper<T>&
operator=(wrapper<T>&& a)
{
t = a.t;
move_count += 1;
return *this;
}
};
template <typename T>
struct compare
{
bool
operator()(const T& a, const T& b)
{
return a == b;
}
};
template <typename T>
struct compare<wrapper<T>>
{
bool
operator()(const wrapper<T>& a, const wrapper<T>& b)
{
return a.t == b.t;
}
};
#include <typeinfo>
struct test_one_policy
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specializations to skip testing in case of broken configuration
template <typename Iterator, typename Size>
void
operator()(pstl::execution::unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
Iterator actual_e, Size shift)
{
}
template <typename Iterator, typename Size>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
Iterator actual_e, Size shift)
{
}
#endif
template <typename ExecutionPolicy, typename Iterator, typename Size>
void
operator()(ExecutionPolicy&& exec, Iterator data_b, Iterator data_e, Iterator actual_b, Iterator actual_e,
Size shift)
{
using namespace std;
using T = typename iterator_traits<Iterator>::value_type;
Iterator actual_m = std::next(actual_b, shift);
copy(data_b, data_e, actual_b);
Iterator actual_return = rotate(exec, actual_b, actual_m, actual_e);
EXPECT_TRUE(actual_return == std::next(actual_b, std::distance(actual_m, actual_e)), "wrong result of rotate");
auto comparator = compare<T>();
bool check = std::equal(actual_return, actual_e, data_b, comparator);
check = check && std::equal(actual_b, actual_return, std::next(data_b, shift), comparator);
EXPECT_TRUE(check, "wrong effect of rotate");
EXPECT_TRUE(check_move(exec, actual_b, actual_e, shift), "wrong move test of rotate");
}
template <typename ExecutionPolicy, typename Iterator, typename Size>
typename std::enable_if<
is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
!std::is_same<ExecutionPolicy, pstl::execution::sequenced_policy>::value &&
std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value,
bool>::type
check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
{
bool result = all_of(b, e, [](wrapper<float32_t>& a) {
bool temp = a.move_count > 0;
a.move_count = 0;
return temp;
});
return shift == 0 || result;
}
template <typename ExecutionPolicy, typename Iterator, typename Size>
typename std::enable_if<
!(is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
!std::is_same<ExecutionPolicy, pstl::execution::sequenced_policy>::value &&
std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value),
bool>::type
check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
{
return true;
}
};
template <typename T>
void
test()
{
const int32_t max_len = 100000;
Sequence<T> actual(max_len, [](std::size_t i) { return T(i); });
Sequence<T> data(max_len, [](std::size_t i) { return T(i); });
for (int32_t len = 0; len < max_len; len = len <= 16 ? len + 1 : int32_t(3.1415 * len))
{
int32_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
for (auto shift : shifts)
{
if (shift >= 0 && shift < len)
{
invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
actual.begin() + len, shift);
}
}
}
}
int32_t
main()
{
test<int32_t>();
test<wrapper<float64_t>>();
std::cout << done() << std::endl;
return 0;
}