Skip to content

Commit

Permalink
[test] Reduce for algorithm testing with debug builds to prevent time…
Browse files Browse the repository at this point in the history
…outs (#2058)

This PR constrains testing in SYCL for-based algorithms when compiling in debug mode as test timeouts have been observed on BMG / Arc. With debug builds, a single input to test the large-submitter path is used per type. Release build testing remains unchanged, and a larger set of inputs are assessed.

---------

Signed-off-by: Matthew Michel <matthew.michel@intel.com>
  • Loading branch information
mmichel11 authored Feb 11, 2025
1 parent dbf9c08 commit 4f216b4
Show file tree
Hide file tree
Showing 16 changed files with 75 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,14 @@ template <typename T>
void
test()
{
const std::size_t max_len = TestUtils::get_pattern_for_max_n();
const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
const std::size_t max_len = test_sizes.back();

Sequence<T> actual(max_len);

Sequence<T> data(max_len, [](::std::size_t i) { return T(i); });

for (::std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : ::std::size_t(3.1415 * len))
for (std::size_t len : test_sizes)
{
invoke_on_all_policies<>()(test_one_policy<T>(), data.begin(), data.begin() + len, actual.begin(),
actual.begin() + len);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ template <typename T1, typename T2>
void
test()
{
const std::size_t max_len = TestUtils::get_pattern_for_max_n();
const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
const std::size_t max_len = test_sizes.back();
Sequence<T2> actual(max_len);
Sequence<T1> data(max_len, [](::std::size_t i) { return T1(i); });

for (::std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : ::std::size_t(3.1415 * len))
for (std::size_t len : test_sizes)
{
invoke_on_all_policies<0>()(test_one_policy<T1, T2>(),
data.begin(), data.begin() + len, actual.begin(), actual.begin() + len);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ template <typename T, typename Convert>
void
test(T trash, Convert convert)
{
size_t max_n = TestUtils::get_pattern_for_max_n();
// Try sequences of various lengths.
for (size_t n = 0; n <= max_n; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : TestUtils::get_pattern_for_test_sizes())
{
// count is number of output elements, plus a handful
// more for sake of detecting buffer overruns.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,7 @@ test_fill_by_type(::std::size_t n)
int
main()
{

const std::size_t N = TestUtils::get_pattern_for_max_n();

for (::std::size_t n = 0; n < N; n = n < 16 ? n + 1 : size_t(3.1415 * n))
for (std::size_t n : TestUtils::get_pattern_for_test_sizes())
{
test_fill_by_type<std::int8_t>(n);
test_fill_by_type<std::int16_t>(n);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ template <typename T>
void
test_generate_by_type()
{
size_t max_n = TestUtils::get_pattern_for_max_n();
for (size_t n = 0; n <= max_n; n = n < 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : TestUtils::get_pattern_for_test_sizes())
{
Sequence<T> in(n, [](size_t) -> T { return T(0); }); //fill by zero

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ template <typename T1, typename T2, typename Pred>
void
test(Pred pred)
{
const std::size_t max_len = TestUtils::get_pattern_for_max_n();
const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
const std::size_t max_len = test_sizes.back();

const T1 value = T1(0);
const T1 new_value = T1(666);
Expand All @@ -124,7 +125,7 @@ test(Pred pred)

Sequence<T2> data(max_len, [=](::std::size_t i) { return i % 3 == 2 ? T1(i) : value; });

for (::std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : ::std::size_t(3.1415 * len))
for (std::size_t len : test_sizes)
{
#ifdef _PSTL_TEST_REPLACE
invoke_on_all_policies<0>()(test_replace<T1, T2>{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,8 @@ template <typename T, typename Convert, typename Predicate>
void
test(T trash, const T& old_value, const T& new_value, Predicate pred, Convert convert)
{
const size_t max_n = TestUtils::get_pattern_for_max_n();
// Try sequences of various lengths.
for (size_t n = 0; n <= max_n; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : TestUtils::get_pattern_for_test_sizes())
{
Sequence<T> in(n, [&](size_t k) -> T { return convert(n ^ k); });
Sequence<T> out(n, [=](size_t) { return trash; });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,13 @@ template <typename T>
void
test()
{
const std::int32_t max_len = TestUtils::get_pattern_for_max_n();
const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
const std::int32_t max_len = test_sizes.back();

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 (std::int32_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::int32_t(3.1415 * len))
for (std::int32_t len : test_sizes)
{
std::int32_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
for (auto shift : shifts)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,17 @@ template <typename T1, typename T2>
void
test()
{

const std::size_t max_len = TestUtils::get_pattern_for_max_n();
const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
const std::int32_t max_len = test_sizes.back();

Sequence<T2> actual(max_len, [](::std::size_t i) { return T1(i); });

Sequence<T1> data(max_len, [](::std::size_t i) { return T1(i); });

for (::std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : ::std::size_t(3.1415 * len))
for (std::int32_t len : test_sizes)
{
::std::size_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
for (::std::size_t shift : shifts)
std::int32_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
for (std::int32_t shift : shifts)
{
if (shift > 0 && shift < len)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@ template <typename T>
void
test()
{
const std::size_t max_len = TestUtils::get_pattern_for_max_n();
const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
const std::size_t max_len = test_sizes.back();

Sequence<T> data(max_len);
Sequence<T> actual(max_len);

for (::std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : ::std::size_t(3.1415 * len))
for (std::size_t len : test_sizes)
{
invoke_on_all_policies<>()(test_one_policy<T>(), data.begin(), data.begin() + len, actual.begin(),
actual.begin() + len);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,24 +100,29 @@ test(Predicate pred, _IteratorAdapter adap = {})
{
// Testing is restricted for debug build + OpenMP backend as without optimization the compiler generates
// very slow code leading to test timeouts.

const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
size_t max_n =
#if PSTL_USE_DEBUG && ONEDPL_USE_OPENMP_BACKEND
10000;
#else
TestUtils::get_pattern_for_max_n();
test_sizes.back();
#endif
for (size_t n = 0; n <= max_n; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : test_sizes)
{
Sequence<In1> in1(n, [](size_t k) { return k % 5 != 1 ? In1(3 * k + 7) : 0; });
Sequence<In2> in2(n, [](size_t k) { return k % 7 != 2 ? In2(5 * k + 5) : 0; });
if (n <= max_n)
{
Sequence<In1> in1(n, [](size_t k) { return k % 5 != 1 ? In1(3 * k + 7) : 0; });
Sequence<In2> in2(n, [](size_t k) { return k % 7 != 2 ? In2(5 * k + 5) : 0; });

Sequence<Out> out(n, [](size_t) { return -1; });
Sequence<Out> out(n, [](size_t) { return -1; });

invoke_on_all_policies<CallNumber>()(test_one_policy(), adap(in1.begin()), adap(in1.end()), adap(in2.begin()),
adap(in2.end()), adap(out.begin()), adap(out.end()), pred);
invoke_on_all_policies<CallNumber + 1>()(test_one_policy(), adap(in1.cbegin()), adap(in1.cend()),
adap(in2.cbegin()), adap(in2.cend()), adap(out.begin()),
adap(out.end()), pred);
invoke_on_all_policies<CallNumber>()(test_one_policy(), adap(in1.begin()), adap(in1.end()), adap(in2.begin()),
adap(in2.end()), adap(out.begin()), adap(out.end()), pred);
invoke_on_all_policies<CallNumber + 1>()(test_one_policy(), adap(in1.cbegin()), adap(in1.cend()),
adap(in2.cbegin()), adap(in2.cend()), adap(out.begin()),
adap(out.end()), pred);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ template <::std::size_t CallNumber, typename Tin, typename Tout, typename _Op =
void
test()
{
size_t max_n = TestUtils::get_pattern_for_max_n();
for (size_t n = 0; n <= max_n; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : TestUtils::get_pattern_for_test_sizes())
{
Sequence<Tin> in(n, [](std::int32_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ template <typename T>
void
test()
{
const size_t max_n = TestUtils::get_pattern_for_max_n();
for (size_t n = 0; n <= max_n; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : TestUtils::get_pattern_for_test_sizes())
{
Sequence<T> in_out(n, Gen<T>());
Sequence<T> expected(n, Gen<T>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ void
test()
{
const ::std::int64_t init_val = 999;
const size_t max_n = TestUtils::get_pattern_for_max_n();
for (size_t n = 1; n <= max_n; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : TestUtils::get_pattern_for_test_sizes())
{
{
Sequence<_Type> in1(n, [=](size_t k) { return (3 * k) % std::numeric_limits<_Type>::max(); });
Expand Down Expand Up @@ -197,8 +196,7 @@ void
test_inplace()
{
const ::std::int64_t init_val = 999;
const size_t max_n = TestUtils::get_pattern_for_max_n();
for (size_t n = 1; n <= max_n; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
for (size_t n : TestUtils::get_pattern_for_test_sizes())
{
{
Sequence<_Type> in1(n, [=](size_t k) { return k % std::numeric_limits<_Type>::max(); });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ template <typename T1, typename T2, typename Pred>
void
test(Pred pred)
{
const std::size_t max_len = TestUtils::get_pattern_for_max_n();
const auto test_sizes = TestUtils::get_pattern_for_test_sizes();
const std::size_t max_len = test_sizes.back();

const T2 value = T2(77);
const T1 trash = T1(31);
Expand All @@ -148,7 +149,7 @@ test(Pred pred)

Sequence<T2> data(max_len, [=](::std::size_t i) { return i % 3 == 2 ? T2(i * i) : value; });

for (::std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : ::std::size_t(3.1415 * len))
for (std::size_t len : test_sizes)
{
invoke_on_all_policies<0>()(test_adjacent_difference<T1>(), data.begin(), data.begin() + len, actual.begin(),
actual.begin() + len, trash);
Expand Down
41 changes: 29 additions & 12 deletions test/support/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1014,26 +1014,43 @@ generate_arithmetic_data(T* input, std::size_t size, std::uint32_t seed)
}
}

// Utility that models __estimate_best_start_size in the SYCL backend parallel_for
// to ensure large enough inputs are used to test the large submitter path.
// A multiplier to the max n is added to ensure we get a few separate test inputs for
// this path.
std::size_t
get_pattern_for_max_n()
// Utility that models __estimate_best_start_size in the SYCL backend parallel_for to ensure large enough inputs are
// used to test the large submitter path. A multiplier to the max n is added to ensure we get a few separate test inputs
// for this path. For debug testing, only test with a single large n to avoid timeouts. Returns a monotonically increasing
// sequence for use in testing.
inline std::vector<std::size_t>
get_pattern_for_test_sizes()
{
#if TEST_DPCPP_BACKEND_PRESENT
std::size_t max_n = 0;
// We do not enable large input size testing for FPGA devices as __parallel_for_submitter_fpga only has a single
// implementation with the standard input sizes providing full coverage, and testing large inputs is slow with the
// FPGA emulator.
#if TEST_DPCPP_BACKEND_PRESENT && !ONEDPL_FPGA_DEVICE
sycl::queue q = TestUtils::get_test_queue();
sycl::device d = q.get_device();
constexpr std::size_t max_iters_per_item = 16;
constexpr std::size_t multiplier = 4;
constexpr std::size_t max_work_group_size = 512;
std::size_t __max_n = multiplier * max_iters_per_item * max_work_group_size *
d.get_info<sycl::info::device::max_compute_units>();
__max_n = std::min(std::size_t{10000000}, __max_n);
return __max_n;
const std::size_t large_submitter_limit =
max_iters_per_item * max_work_group_size * d.get_info<sycl::info::device::max_compute_units>();
#endif
#if TEST_DPCPP_BACKEND_PRESENT && !PSTL_USE_DEBUG && !ONEDPL_FPGA_DEVICE
std::size_t cap = 10000000;
max_n = multiplier * large_submitter_limit;
// Ensure that TestUtils::max_n <= max_n <= cap
max_n = std::max(TestUtils::max_n, std::min(cap, max_n));
#else
return TestUtils::max_n;
max_n = TestUtils::max_n;
#endif
// Generate the sequence of test input sizes
std::vector<std::size_t> sizes;
for (std::size_t n = 0; n <= max_n; n = n <= 16 ? n + 1 : std::size_t(3.1415 * n))
sizes.push_back(n);
#if TEST_DPCPP_BACKEND_PRESENT && PSTL_USE_DEBUG && !ONEDPL_FPGA_DEVICE
if (max_n < large_submitter_limit)
sizes.push_back(large_submitter_limit);
#endif
return sizes;
}

} /* namespace TestUtils */
Expand Down

0 comments on commit 4f216b4

Please sign in to comment.