Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

[SYCL][ESIMD] Add function that let iterating over types and dims #588

Merged
39 changes: 8 additions & 31 deletions SYCL/ESIMD/api/functional/ctors/ctor_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct initializer {

// Descriptor class for the case of calling constructor in variable declaration
// context.
struct var_declaration {
struct var_decl {
static std::string get_description() { return "variable declaration"; }

template <typename DataT, int NumElems>
Expand All @@ -57,7 +57,7 @@ struct var_declaration {

// Descriptor class for the case of calling constructor in rvalue in an
// expression context.
struct rval_in_expression {
struct rval_in_expr {
static std::string get_description() { return "rvalue in an expression"; }

template <typename DataT, int NumElems>
Expand Down Expand Up @@ -92,42 +92,19 @@ class const_ref {
}
};

template <typename DataT, typename TestT>
using run_test_with_one_elem = test<DataT, 1, TestT>;

template <typename DataT, typename TestT>
using run_test_with_eight_elems = test<DataT, 8, TestT>;

template <typename DataT, typename TestT>
using run_test_with_sixteen_elems = test<DataT, 16, TestT>;

template <typename DataT, typename TestT>
using run_test_with_thirty_two_elems = test<DataT, 32, TestT>;

template <typename TestT, typename... T>
bool run_verification_for_type(sycl::queue &queue,
const named_type_pack<T...> &types) {
bool passed{true};

passed &= for_all_types<run_test_with_one_elem, TestT>(types, queue);
passed &= for_all_types<run_test_with_eight_elems, TestT>(types, queue);
passed &= for_all_types<run_test_with_sixteen_elems, TestT>(types, queue);
passed &= for_all_types<run_test_with_thirty_two_elems, TestT>(types, queue);
return passed;
}

int main(int argc, char **argv) {
sycl::queue queue{esimd_test::ESIMDSelector{},
esimd_test::createExceptionHandler()};

bool passed{true};

auto types{get_tested_types<tested_types::all>()};
const auto types{get_tested_types<tested_types::all>()};
const auto dims{get_all_dimensions()};

passed &= run_verification_for_type<initializer>(queue, types);
passed &= run_verification_for_type<var_declaration>(queue, types);
passed &= run_verification_for_type<rval_in_expression>(queue, types);
passed &= run_verification_for_type<const_ref>(queue, types);
passed &= for_all_types_and_dims<test, initializer>(types, dims, queue);
passed &= for_all_types_and_dims<test, var_decl>(types, dims, queue);
passed &= for_all_types_and_dims<test, rval_in_expr>(types, dims, queue);
passed &= for_all_types_and_dims<test, const_ref>(types, dims, queue);

std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
return passed ? 0 : 1;
Expand Down
39 changes: 7 additions & 32 deletions SYCL/ESIMD/api/functional/ctors/ctor_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct initializer {

// Descriptor class for the case of calling constructor in variable declaration
// context
struct var_declaration {
struct var_decl {
static std::string get_description() { return "variable declaration"; }

template <typename DataT, int NumElems>
Expand All @@ -54,7 +54,7 @@ struct var_declaration {

// Descriptor class for the case of calling constructor in rvalue in an
// expression context
struct rval_in_expression {
struct rval_in_expr {
static std::string get_description() { return "rvalue in an expression"; }

template <typename DataT, int NumElems>
Expand Down Expand Up @@ -116,44 +116,19 @@ template <typename DataT, int NumElems, typename TestCaseT> struct test {
}
};

template <typename DataT, typename TestT>
using run_test_with_one_elem = test<DataT, 1, TestT>;

template <typename DataT, typename TestT>
using run_test_with_eight_elems = test<DataT, 8, TestT>;

template <typename DataT, typename TestT>
using run_test_with_sixteen_elems = test<DataT, 16, TestT>;

template <typename DataT, typename TestT>
using run_test_with_thirty_two_elems = test<DataT, 32, TestT>;

template <typename TestT, typename... T>
bool run_verification_with_chosen_test_type(
sycl::queue &queue, const named_type_pack<T...> &types) {
bool passed{true};

passed &= for_all_types<run_test_with_one_elem, TestT>(types, queue);
passed &= for_all_types<run_test_with_eight_elems, TestT>(types, queue);
passed &= for_all_types<run_test_with_sixteen_elems, TestT>(types, queue);
passed &= for_all_types<run_test_with_thirty_two_elems, TestT>(types, queue);
return passed;
}

int main(int argc, char **argv) {
sycl::queue queue{esimd_test::ESIMDSelector{},
esimd_test::createExceptionHandler()};

bool passed{true};

const auto types{get_tested_types<tested_types::all>()};
const auto dims{get_all_dimensions()};

passed &= run_verification_with_chosen_test_type<initializer>(queue, types);
passed &=
run_verification_with_chosen_test_type<var_declaration>(queue, types);
passed &=
run_verification_with_chosen_test_type<rval_in_expression>(queue, types);
passed &= run_verification_with_chosen_test_type<const_ref>(queue, types);
passed &= for_all_types_and_dims<test, initializer>(types, dims, queue);
passed &= for_all_types_and_dims<test, var_decl>(types, dims, queue);
passed &= for_all_types_and_dims<test, rval_in_expr>(types, dims, queue);
passed &= for_all_types_and_dims<test, const_ref>(types, dims, queue);

std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
return passed ? 0 : 1;
Expand Down
71 changes: 52 additions & 19 deletions SYCL/ESIMD/api/functional/type_coverage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ namespace esimd_test {
namespace api {
namespace functional {

// Integer pack to store provided int values
template <int... T> struct values_pack {
values_pack() {}
};

// Type pack to store types and underlying data type names to use with
// type_name_string
template <typename... T> struct named_type_pack {
Expand Down Expand Up @@ -86,28 +91,56 @@ template <tested_types required> auto get_tested_types() {
}
}

// Factory method to retrieve pre-defined values_pack, to have the same
// default dimensions over the tests
auto get_all_dimensions() { return values_pack<1, 8, 16, 32>(); }

// Run action for each of types given by named_type_pack instance
template <template <typename, typename...> class action,
typename... actionArgsT, typename... types, typename... argsT>
inline bool for_all_types(const named_type_pack<types...> &typeList,
argsT &&... args) {
template <template <typename, int, typename...> class Action, int N,
typename... ActionArgsT, typename... Types, typename... ArgsT>
inline bool for_all_types(const named_type_pack<Types...> &type_list,
ArgsT &&... args) {
bool passed{true};

size_t type_name_index = 0;

// Run action for each type from named_type_pack... parameter pack
((passed &= Action<Types, N, ActionArgsT...>{}(
std::forward<ArgsT>(args)..., type_list.names[type_name_index]),
++type_name_index),
...);
// The unary right fold expression is used for parameter pack expansion.
// Every expression with comma operator is strictly sequenced, so we can
// increment safely. And of course the fold expression would not be optimized
// out due to side-effects.
// Additional pair of brackets is required because of precedence of increment
// operator relative to the comma operator.
//
// Note that there is actually no difference in left or right fold expression
// for the comma operator, as it would give the same order of actions
// execution and the same order of the type name index increment: both the
// "(expr0, (exr1, expr2))" and "((expr0, expr1), expr2)" would give the same
// result as simple "expr0, expr1, expr2"

return passed;
}

// Calls for_all_types for each vector length by values_pack instance
template <template <typename, int, typename...> class Action,
typename... ActionArgsT, typename... Types, int... Dims,
typename... ArgsT>
inline bool for_all_types_and_dims(const named_type_pack<Types...> &type_list,
const values_pack<Dims...> &dim_list,
ArgsT &&... args) {
bool passed{true};

// run action for each type from types... parameter pack
size_t typeNameIndex = 0;

int packExpansion[] = {
(passed &= action<types, actionArgsT...>{}(std::forward<argsT>(args)...,
typeList.names[typeNameIndex]),
++typeNameIndex,
0 // Dummy initialization value
)...};
// Every initializer clause is sequenced before any initializer clause that
// follows it in the braced-init-list. Every expression in comma operator is
// also strictly sequenced. So we can use increment safely. We still should
// discard dummy results, but this initialization should not be optimized out
// due side-effects
static_cast<void>(packExpansion);
// Run action for each value from values_pack... parameter pack
((passed &= for_all_types<Action, Dims, ActionArgsT...>(
type_list, std::forward<ArgsT>(args)...)),
...);
// The unary right fold expression is used for parameter pack expansion.
// An additional pair of brackets is required because of precedence of any
// operator relatively to the comma operator.

return passed;
}
Expand Down