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

[SYCL][ESIMD] Provide the for_all_combinations utility #721

Merged
merged 9 commits into from
Jan 28, 2022
13 changes: 6 additions & 7 deletions SYCL/ESIMD/api/functional/ctors/ctor_array_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ class const_ref {

// The main test routine.
// Using functor class to be able to iterate over the pre-defined data types.
template <typename DataT, int NumElems, typename TestCaseT> class run_test {
template <typename DataT, typename DimT, typename TestCaseT> class run_test {
static constexpr int NumElems = DimT::value;

public:
bool operator()(sycl::queue &queue, const std::string &data_type) {

Expand Down Expand Up @@ -172,13 +174,10 @@ int main(int, char **) {

const auto types = get_tested_types<tested_types::all>();
const auto dims = get_all_dimensions();
const auto contexts = unnamed_type_pack<initializer, var_decl, rval_in_expr,
const_ref>::generate();

// Run for specific combinations of types, vector length, and invocation
// contexts.
passed &= for_all_types_and_dims<run_test, initializer>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, var_decl>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, rval_in_expr>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, const_ref>(types, dims, queue);
passed &= for_all_combinations<run_test>(types, dims, contexts, queue);

std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
return passed ? 0 : 1;
Expand Down
11 changes: 6 additions & 5 deletions SYCL/ESIMD/api/functional/ctors/ctor_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ class const_ref {

// The main test routine.
// Using functor class to be able to iterate over the pre-defined data types.
template <typename DataT, int NumElems, typename TestCaseT> class run_test {
template <typename DataT, typename DimT, typename TestCaseT> class run_test {
static constexpr int NumElems = DimT::value;

public:
bool operator()(sycl::queue &queue, const std::string &data_type) {
bool passed = true;
Expand Down Expand Up @@ -155,11 +157,10 @@ int main(int, char **) {

const auto types = get_tested_types<tested_types::all>();
const auto dims = get_all_dimensions();
const auto contexts = unnamed_type_pack<initializer, var_decl, rval_in_expr,
const_ref>::generate();

passed &= for_all_types_and_dims<run_test, initializer>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, var_decl>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, rval_in_expr>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, const_ref>(types, dims, queue);
passed &= for_all_combinations<run_test>(types, dims, contexts, queue);

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

// Struct that calls simd in provided context and then verifies obtained result.
template <typename DataT, int NumElems, typename TestCaseT> struct run_test {
template <typename DataT, typename DimT, typename TestCaseT> struct run_test {
static constexpr int NumElems = DimT::value;

bool operator()(sycl::queue &queue, const std::string &data_type) {
bool passed = true;
DataT default_val{};
Expand Down Expand Up @@ -119,11 +121,10 @@ int main(int, char **) {

const auto types = get_tested_types<tested_types::all>();
const auto dims = get_all_dimensions();
const auto contexts = unnamed_type_pack<initializer, var_decl, rval_in_expr,
const_ref>::generate();

passed &= for_all_types_and_dims<run_test, initializer>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, var_decl>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, rval_in_expr>(types, dims, queue);
passed &= for_all_types_and_dims<run_test, const_ref>(types, dims, queue);
passed &= for_all_combinations<run_test>(types, dims, contexts, queue);

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

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

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

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

template <typename DataT, int NumElems>
Expand Down Expand Up @@ -191,30 +191,32 @@ class FillCtorTestDescription
}
};

template <typename DataT, int NumElems, typename TestCaseT, typename BaseVal,
typename Step>
template <init_val... Values> auto get_init_values_pack() {
return value_pack<init_val, Values...>::generate_unnamed();
}

template <typename DataT, typename DimT, typename TestCaseT, typename BaseValT,
typename StepT>
class run_test {
static constexpr int NumElems = DimT::value;
static constexpr init_val BaseVal = BaseValT::value;
static constexpr init_val Step = StepT::value;
using KernelT = kernel_for_fill<DataT, NumElems, TestCaseT, BaseVal, Step>;

public:
bool operator()(sycl::queue &queue, const std::string &data_type) {
static_assert(std::is_same_v<typename BaseVal::value_type, init_val>,
"BaseVal template parameter should be init_val type.");
static_assert(std::is_same_v<typename Step::value_type, init_val>,
"Step template parameter should be init_val type.");

shared_vector<DataT> result(NumElems, shared_allocator<DataT>(queue));

const auto base_value = get_value<DataT, BaseVal::value>();
const auto step_value = get_value<DataT, Step::value>(base_value);
const auto base_value = get_value<DataT, BaseVal>();
const auto step_value = get_value<DataT, Step>(base_value);

queue.submit([&](sycl::handler &cgh) {
DataT *const out = result.data();

cgh.single_task<kernel_for_fill<DataT, NumElems, TestCaseT,
BaseVal::value, Step::value>>(
[=]() SYCL_ESIMD_KERNEL {
TestCaseT::template call_simd_ctor<DataT, NumElems>(
base_value, step_value, out);
});
cgh.single_task<KernelT>([=]() SYCL_ESIMD_KERNEL {
TestCaseT::template call_simd_ctor<DataT, NumElems>(base_value,
step_value, out);
});
});
queue.wait_and_throw();
bool passed = true;
Expand All @@ -228,8 +230,7 @@ class run_test {
// constructor.
DataT expected_value = base_value;
for (size_t i = 1; i < result.size(); ++i) {
if constexpr (BaseVal::value == init_val::nan ||
Step::value == init_val::nan) {
if constexpr (BaseVal == init_val::nan || Step == init_val::nan) {

if (!std::isnan(result[i])) {
passed = false;
Expand All @@ -241,9 +242,8 @@ class run_test {
log_msg += ", with context: " + TestCaseT::get_description();
log_msg += ". The element at index: " + std::to_string(i) +
", is not nan, but it should.";
log_msg +=
", with base value: " + init_val_to_string<BaseVal::value>();
log_msg += ", with step value: " + init_val_to_string<Step::value>();
log_msg += ", with base value: " + init_val_to_string<BaseVal>();
log_msg += ", with step value: " + init_val_to_string<Step>();

log::note(log_msg);
}
Expand All @@ -262,33 +262,12 @@ class run_test {
bool fail_test(size_t index, DataT retrieved, DataT expected,
const std::string &data_type) {
const auto description =
FillCtorTestDescription<DataT, NumElems, TestCaseT, BaseVal::value,
Step::value>(index, retrieved, expected,
data_type);
FillCtorTestDescription<DataT, NumElems, TestCaseT, BaseVal, Step>(
index, retrieved, expected, data_type);
log::fail(description);

return false;
}
};

// Iterating over provided types and dimensions, running test for each of
// them.
template <typename TestT, init_val BaseVal, init_val Step, typename... Types,
int... Dims>
bool run_verification(
sycl::queue &queue,
const esimd_functional::values_pack<Dims...> &dimensions,
const esimd_functional::named_type_pack<Types...> &types) {

typedef std::integral_constant<init_val, BaseVal> base_value;
typedef std::integral_constant<init_val, Step> step_value;

bool passed = true;
passed &= esimd_functional::for_all_types_and_dims<run_test, TestT,
base_value, step_value>(
types, dimensions, queue);

return passed;
}

} // namespace esimd_test::api::functional::ctors
40 changes: 20 additions & 20 deletions SYCL/ESIMD/api/functional/ctors/ctor_fill_accuracy_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,38 @@

using namespace sycl::ext::intel::experimental::esimd;
using namespace esimd_test::api::functional;
using init_val = ctors::init_val;

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

bool passed = true;

const auto fp_types = get_tested_types<tested_types::fp>();
const auto single_dim = values_pack<8>();
// Using single dimension and context to verify the accuracy of operations
// with floating point data types
const auto types = get_tested_types<tested_types::fp>();
const auto dims = get_dimensions<8>();
const auto contexts = unnamed_type_pack<ctors::var_decl>::generate();

// Run for specific combinations of types, base and step values and vector
// length.
// The first init_val value it's a base value and the second init_val value
// it's a step value.
#ifdef SIMD_RUN_TEST_WITH_DENORM_INIT_VAL_AND_ULP_STEP
passed &= ctors::run_verification<ctors::var_dec, ctors::init_val::denorm,
ctors::init_val::ulp>(queue, single_dim,
fp_types);
{
const auto base_values = ctors::get_init_values_pack<init_val::denorm>();
const auto step_values = ctors::get_init_values_pack<init_val::ulp>();
passed &= for_all_combinations<ctors::run_test>(
types, dims, contexts, base_values, step_values, queue);
}
#endif
passed &= ctors::run_verification<ctors::var_dec, ctors::init_val::inexact,
ctors::init_val::ulp>(queue, single_dim,
fp_types);
passed &= ctors::run_verification<ctors::var_dec, ctors::init_val::min,
ctors::init_val::ulp>(queue, single_dim,
fp_types);

passed &= ctors::run_verification<ctors::var_dec, ctors::init_val::inexact,
ctors::init_val::ulp_half>(
queue, single_dim, fp_types);
passed &= ctors::run_verification<ctors::var_dec, ctors::init_val::min,
ctors::init_val::ulp_half>(
queue, single_dim, fp_types);
{
const auto base_values =
ctors::get_init_values_pack<init_val::inexact, init_val::min>();
const auto step_values =
ctors::get_init_values_pack<init_val::ulp, init_val::ulp_half>();
passed &= for_all_combinations<ctors::run_test>(
types, dims, contexts, base_values, step_values, queue);
}

std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
return passed ? 0 : 1;
Expand Down
Loading