Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tests] Add Input Data Sweep tests #1429

Merged
merged 30 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
062fa13
Add test which sweeps through many potential input data types
danhoeflinger Mar 1, 2024
90aae5f
checking type support + comment
danhoeflinger Mar 4, 2024
74c7f34
turning off std::reverse_iterator for sycl_iterator
danhoeflinger Mar 5, 2024
47d0242
formatting
danhoeflinger Mar 5, 2024
5c72fde
fixing policies, freeing data
danhoeflinger Mar 5, 2024
8c4a8a2
removing unnecessary .c_str()
danhoeflinger Mar 5, 2024
b27779e
using usm_data_transfer class
danhoeflinger Mar 5, 2024
dc66cd3
formatting
danhoeflinger Mar 5, 2024
1e6a572
Add overload for make_new_policy, relocate all overloads
danhoeflinger Mar 5, 2024
19cd85f
using _ONEDPL_DEBUG_SYCL
danhoeflinger Mar 5, 2024
870528b
splitting tests into sequence types
danhoeflinger Mar 5, 2024
a70e344
sycl_iter can be used as perm_src
danhoeflinger Mar 5, 2024
9a939b5
using const ref strings
danhoeflinger Mar 6, 2024
dd8b74e
adding bool type for host_iterator
danhoeflinger Mar 7, 2024
e237261
adding test for usm shared allocator vectors
danhoeflinger Mar 7, 2024
bf346f8
add host and shared usm allocator iterators to test suite
danhoeflinger Mar 8, 2024
c0f098b
codespell fix
danhoeflinger Mar 8, 2024
745c808
reenable usm_alloc as perm src
danhoeflinger Mar 8, 2024
35dae70
removing debug define
danhoeflinger Mar 11, 2024
bb3bc54
removing the ability for usm_allocator std::vector::iterator to be us…
danhoeflinger Mar 11, 2024
b3a7778
testing as perm iter src only if we can expect it to work
danhoeflinger Mar 11, 2024
8f6d514
test bugfix
danhoeflinger Mar 12, 2024
c93a2ea
removing std::vector<bool> input tests, as they are UB for oneDPL
danhoeflinger Mar 13, 2024
2b4a384
using new utility to skip usm_allocator tests
danhoeflinger Apr 3, 2024
e0b67d9
check each value type
danhoeflinger Apr 3, 2024
aa92899
extra brace and policy fixes for unnamed lambda
danhoeflinger Apr 11, 2024
4be67f4
fixing create new policy after rebase
danhoeflinger Apr 24, 2024
db45d75
reduce the tests run with usm_allocators
danhoeflinger Apr 24, 2024
17d71ae
fix rebase remove redundant make_policy overloads
danhoeflinger Apr 25, 2024
3358b52
further fixes for bad rebase
danhoeflinger Apr 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions test/parallel_api/iterator/input_data_sweep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// -*- C++ -*-
//===-- input_data_sweep.h ------------------------------------------------===//
//
// Copyright (C) Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// This file incorporates work covered by the following copyright and permission
// notice:
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
//
//===----------------------------------------------------------------------===//

#ifndef _INPUT_DATA_SWEEP_H
#define _INPUT_DATA_SWEEP_H

#include "support/utils.h"
#include _PSTL_TEST_HEADER(execution)
#include _PSTL_TEST_HEADER(algorithm)
#include _PSTL_TEST_HEADER(iterator)

#include "support/utils_invoke.h"

#if TEST_DPCPP_BACKEND_PRESENT
template <int __recurse, int __reverses, bool __read = true, bool __reset_read = true, bool __write = true,
bool __check_write = true, bool __usable_as_perm_map = true, bool __usable_as_perm_src = true,
bool __is_reversible = true, typename Policy, typename InputIterator1, typename InputIterator2,
typename OutputIterator, typename OriginalIterator1, typename OriginalIterator2, typename ExpectedIterator,
typename T>
void
wrap_recurse(Policy&& exec, InputIterator1 first, InputIterator1 last, InputIterator2 copy_from_first,
OutputIterator copy_to_first, OriginalIterator1 orig_first, OriginalIterator2 orig_out_first,
ExpectedIterator expected_first, T trash, const std::string& input_descr)
{
auto exec1 = TestUtils::create_new_policy_idx<0>(exec);
auto exec2 = TestUtils::create_new_policy_idx<1>(exec);
auto exec3 = TestUtils::create_new_policy_idx<2>(exec);
auto exec4 = TestUtils::create_new_policy_idx<3>(exec);
auto exec5 = TestUtils::create_new_policy_idx<4>(exec);
auto exec6 = TestUtils::create_new_policy_idx<5>(exec);
auto exec7 = TestUtils::create_new_policy_idx<6>(exec);
auto exec8 = TestUtils::create_new_policy_idx<7>(exec);
auto exec9 = TestUtils::create_new_policy_idx<8>(exec);
auto exec10 = TestUtils::create_new_policy_idx<9>(exec);
auto exec11 = TestUtils::create_new_policy_idx<10>(exec);
auto exec12 = TestUtils::create_new_policy_idx<11>(exec);
auto exec13 = TestUtils::create_new_policy_idx<12>(exec);

oneapi::dpl::counting_iterator<size_t> counting(size_t{0});

const auto n = last - first;

//Run the tests
auto get_expect = [n](auto exp) {
if constexpr (__reverses % 2 == 0)
{
return exp;
}
else
{
return std::make_reverse_iterator(exp + n);
}
};

# if _ONEDPL_DEBUG_SYCL
std::cout << input_descr << ":";
# endif // _ONEDPL_DEBUG_SYCL

if constexpr (__read)
{
oneapi::dpl::fill(exec1, orig_out_first, orig_out_first + n, trash);
if constexpr (__reset_read)
{
//Reset data if required
oneapi::dpl::copy(exec2, expected_first, expected_first + n, orig_first);
}

//Run test
oneapi::dpl::copy(exec3, first, last, copy_to_first);

//get expected sequence with proper number of reverses
auto expect = get_expect(expected_first);
std::string msg = std::string("wrong read effect from ") + input_descr;
//verify result using original unwrapped output
EXPECT_EQ_N(expect, orig_out_first, n, msg.c_str());
# if _ONEDPL_DEBUG_SYCL
std::cout << " read pass,";
# endif // _ONEDPL_DEBUG_SYCL
}
if constexpr (__write)
{
//Reset data
if constexpr (__check_write)
{
//only reset output data if we intend to check it afterward
oneapi::dpl::fill(exec4, orig_first, orig_first + n, trash);
}

oneapi::dpl::copy(exec5, copy_from_first, copy_from_first + n, first);
//check write if required (ignore discard iterator)
if constexpr (__check_write)
{
//copy back data from original unwrapped sequence
std::vector<T> copy_back(n);
oneapi::dpl::copy(exec6, orig_first, orig_first + n, copy_back.begin());

//get expected sequence with proper number of reverses
auto expect = get_expect(expected_first);
std::string msg = std::string("wrong write effect from ") + input_descr;
//verify copied back data
EXPECT_EQ_N(expect, copy_back.begin(), n, msg.c_str());
# if _ONEDPL_DEBUG_SYCL
std::cout << " write pass";
# endif // _ONEDPL_DEBUG_SYCL
}
else
{
# if _ONEDPL_DEBUG_SYCL
std::cout << " write pass (no check)";
# endif // _ONEDPL_DEBUG_SYCL
}
}
if constexpr (!__read && !__write)
{
# if _ONEDPL_DEBUG_SYCL
std::cout << " has no valid tests";
# endif // _ONEDPL_DEBUG_SYCL
}
# if _ONEDPL_DEBUG_SYCL
std::cout << std::endl;
# endif // _ONEDPL_DEBUG_SYCL

// Now recurse with a layer of wrappers if requested
if constexpr (__recurse > 0)
{
# if _ONEDPL_DEBUG_SYCL
std::cout << std::endl << "Recursing on " << input_descr << ":" << std::endl;
# endif // _ONEDPL_DEBUG_SYCL
oneapi::dpl::discard_iterator discard{};
// iterate through all wrappers and recurse - 1
auto noop = [](auto i) { return i; };

if constexpr (__is_reversible)
{ // std::reverse_iterator(it)
auto reversed_first = ::std::make_reverse_iterator(last);
auto reversed_last = ::std::make_reverse_iterator(first);
std::string new_input_descr = std::string("std::reverse(") + input_descr + std::string(")");
//TODO: Look at device copyability of std::reverse_iterator and re-enable recurse
wrap_recurse<0, __reverses + 1, __read, __reset_read, __write, __check_write, __usable_as_perm_map,
__usable_as_perm_src, __is_reversible>(exec7, reversed_first, reversed_last, copy_from_first,
copy_to_first, orig_first, orig_out_first,
expected_first, trash, new_input_descr);
}

{ //transform_iterator(it,noop{})
auto trans = oneapi::dpl::make_transform_iterator(first, noop);
std::string new_input_descr = std::string("transform_iterator(") + input_descr + std::string(", noop)");
wrap_recurse<__recurse - 1, __reverses, __read, __reset_read, /*__write=*/false, __check_write,
__usable_as_perm_map, __usable_as_perm_src, __is_reversible>(
exec8, trans, trans + n, discard, copy_to_first, orig_first, orig_out_first, expected_first, trash,
new_input_descr);
}

if constexpr (__usable_as_perm_src)
{ //permutation_iteartor(it,noop{})
std::string new_input_descr = std::string("permutation_iterator(") + input_descr + std::string(", noop)");
auto perm = oneapi::dpl::make_permutation_iterator(first, noop);
wrap_recurse<__recurse - 1, __reverses, __read, __reset_read, __write, __check_write, __usable_as_perm_map,
__usable_as_perm_src, __is_reversible>(exec9, perm, perm + n, copy_from_first, copy_to_first,
orig_first, orig_out_first, expected_first, trash,
new_input_descr);
}

if constexpr (__usable_as_perm_src)
{ //permutation_iterator(it,counting_iter)
std::string new_input_descr =
std::string("permutation_iterator(") + input_descr + std::string(", counting_iterator)");
auto perm = oneapi::dpl::make_permutation_iterator(first, counting);
wrap_recurse<__recurse - 1, __reverses, __read, __reset_read, __write, __check_write, __usable_as_perm_map,
__usable_as_perm_src, __is_reversible>(exec11, perm, perm + n, copy_from_first, copy_to_first,
orig_first, orig_out_first, expected_first, trash,
new_input_descr);
}

if constexpr (__usable_as_perm_map)
{ //permutation_iterator(counting_iterator,it)
std::string new_input_descr =
std::string("permutation_iterator(counting_iterator,") + input_descr + std::string(")");
auto perm = oneapi::dpl::make_permutation_iterator(counting, first);
wrap_recurse<__recurse - 1, __reverses, __read, __reset_read, /*__write=*/false, __check_write,
__usable_as_perm_map, __usable_as_perm_src, __is_reversible>(
exec10, perm, perm + n, discard, copy_to_first, orig_first, orig_out_first, expected_first, trash,
new_input_descr);
}

{ //zip_iterator(counting_iterator,it)
std::string new_input_descr =
std::string("zip_iterator(counting_iterator,") + input_descr + std::string(")");
auto zip = oneapi::dpl::make_zip_iterator(counting, first);
auto zip_out = oneapi::dpl::make_zip_iterator(discard, copy_to_first);
wrap_recurse<__recurse - 1, __reverses, __read, __reset_read, /*__write=*/false, __check_write,
/*__usable_as_perm_map=*/false, __usable_as_perm_src, __is_reversible>(
exec12, zip, zip + n, discard, zip_out, orig_first, orig_out_first, expected_first, trash,
new_input_descr);
}

{ //zip_iterator(it, discard_iterator)
std::string new_input_descr =
std::string("zip_iterator(") + input_descr + std::string(", discard_iterator)");
auto zip = oneapi::dpl::make_zip_iterator(first, discard);
auto zip_in = oneapi::dpl::make_zip_iterator(copy_from_first, counting);
wrap_recurse<__recurse - 1, __reverses, /*__read=*/false, false, __write, __check_write,
/*__usable_as_perm_map=*/false, __usable_as_perm_src, __is_reversible>(
exec13, zip, zip + n, zip_in, discard, orig_first, orig_out_first, expected_first, trash,
new_input_descr);
}
}
}

#endif //TEST_DPCPP_BACKEND_PRESENT

#endif //_INPUT_DATA_SWEEP_H
94 changes: 94 additions & 0 deletions test/parallel_api/iterator/input_data_sweep_counting_iter.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// -*- C++ -*-
//===-- input_data_sweep_counting_iter.pass.cpp ---------------------------===//
//
// Copyright (C) Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// This file incorporates work covered by the following copyright and permission
// notice:
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
//
//===----------------------------------------------------------------------===//

#include "support/utils.h"
#include _PSTL_TEST_HEADER(execution)
#include _PSTL_TEST_HEADER(algorithm)
#include _PSTL_TEST_HEADER(iterator)

#include "input_data_sweep.h"

#include "support/utils_invoke.h"

#if TEST_DPCPP_BACKEND_PRESENT

//This test is written without indirection from invoke_on_all_hetero_policies to make clear exactly which types
// are being tested, and to limit the number of types to be within reason.

template <typename T, int __recurse, typename Policy>
void
test(Policy&& policy, T trash, size_t n, const std::string& type_text)
{
if constexpr (std::is_integral_v<T>)
{
if (TestUtils::has_types_support<T>(policy.queue().get_device()))
{

TestUtils::usm_data_transfer<sycl::usm::alloc::shared, T> copy_out(policy.queue(), n);
oneapi::dpl::counting_iterator<int> counting(0);
oneapi::dpl::counting_iterator<T> my_counting(0);
//counting_iterator
wrap_recurse<__recurse, 0, /*__read =*/true, /*__reset_read=*/false, /*__write=*/false,
/*__check_write=*/false, /*__usable_as_perm_map=*/true, /*__usable_as_perm_src=*/true,
/*__is_reversible=*/true>(policy, my_counting, my_counting + n, counting, copy_out.get_data(),
my_counting, copy_out.get_data(), counting, trash,
std::string("counting_iterator<") + type_text + std::string(">"));
}
else
{
TestUtils::unsupported_types_notifier(policy.queue().get_device());
}
}
}

#endif //TEST_DPCPP_BACKEND_PRESENT

int
main()
{
#if TEST_DPCPP_BACKEND_PRESENT

constexpr size_t n = 10;

auto q = TestUtils::get_test_queue();

auto policy = TestUtils::make_new_policy<class Kernel1>(q);

auto policy1 = TestUtils::create_new_policy_idx<0>(policy);
auto policy2 = TestUtils::create_new_policy_idx<1>(policy);
auto policy3 = TestUtils::create_new_policy_idx<2>(policy);
auto policy4 = TestUtils::create_new_policy_idx<3>(policy);
auto policy5 = TestUtils::create_new_policy_idx<4>(policy);

// baseline with no wrapping
test<float, 0>(policy1, -666.0f, n, "float");
test<double, 0>(policy2, -666.0, n, "double");
test<std::uint64_t, 0>(policy3, 999, n, "uint64_t");

// big recursion step: 1 and 2 layers of wrapping
test<std::int32_t, 2>(policy4, -666, n, "int32_t");

// special case: discard iterator
oneapi::dpl::counting_iterator<int> counting(0);
oneapi::dpl::discard_iterator discard{};
wrap_recurse<1, 0, /*__read =*/false, /*__reset_read=*/false, /*__write=*/true,
/*__check_write=*/false, /*__usable_as_perm_map=*/false, /*__usable_as_perm_src=*/true,
/*__is_reversible=*/true>(policy5, discard, discard + n, counting, discard, discard, discard, discard,
-666, "discard_iterator");

#endif // TEST_DPCPP_BACKEND_PRESENT

return TestUtils::done(TEST_DPCPP_BACKEND_PRESENT);
}
Loading
Loading