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

[SYCL][ESIMD] Add test for esimd copy constructor #578

Merged
merged 34 commits into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
dca65d7
[SYCL][ESIMD] Add common file for test for simd constructors
vasilytric Nov 22, 2021
f59683b
[SYCL][ESIMD] Add test for simd copy constructor
vasilytric Nov 22, 2021
460bbd9
[SYCL][ESIMD] Move common.hpp into SYCL\ESIMD\api\functional
vasilytric Nov 24, 2021
c0932b4
[SYCL][ESIMD] Updating logic for comparing and initializing variables
vasilytric Nov 24, 2021
3f3cc72
[SYCL][ESIMD] Update logic for generating reference data
vasilytric Nov 24, 2021
3c4a51f
[SYCL][ESIMD] Update comments
vasilytric Nov 24, 2021
ec90c52
[SYCL][ESIMD] Update formatting in ctor_copy.cpp
vasilytric Nov 24, 2021
d5856d2
[SYCL][ESIMD] Replace including <CL/sycl.hpp> to <sycl/sycl.hpp>
vasilytric Nov 24, 2021
573abdb
[SYCL][ESIMD] Rename vector_with_allocator and shared_allocator
vasilytric Nov 24, 2021
0bab576
[SYCL][ESIMD] Make reference data const
vasilytric Nov 24, 2021
8710841
[SYCL][ESIMD] Enforce default-construction in copy constructor test
vasilytric Nov 24, 2021
f3b1c77
[SYCL][ESIMD] Make const_ref struct a class type
vasilytric Nov 24, 2021
92b81b1
[SYCL][ESIMD] Make result_data constant variable
vasilytric Nov 24, 2021
74c1794
[SYCL][ESIMD] Add static asserd for generate_ref_data function
vasilytric Nov 24, 2021
b8bf6ac
[SYCL][ESIMD] Add static_assert(is_fp_type<T>) for inf() function
vasilytric Nov 24, 2021
d18c4e0
[SYCL][ESIMD] Add reserving storage in vector with reference data
vasilytric Nov 25, 2021
a999454
[SYCL][ESIMD] Add static_cast for non const values in initializer list
vasilytric Nov 25, 2021
0eafaa6
[SYCL][ESIMD] Move common functions and some methods to common files
vasilytric Nov 25, 2021
18d8c35
[SYCL][ESIMD] Add namespaces to common files in functional\ctors folder
vasilytric Nov 25, 2021
a1b88db
[SYCL][ESIMD] Update comments for common.hpp and value.hpp
vasilytric Nov 26, 2021
3e7019d
[SYCL][ESIMD] Structures changes in test for copy constructor
vasilytric Nov 26, 2021
4bd389b
[SYCL][ESIMD] Small changes in value.hpp
vasilytric Nov 26, 2021
9b47083
[SYCL][ESIMD] Remove bit_cast due to it defined in esimd_test_utils.hpp
vasilytric Nov 26, 2021
848b257
[SYCL][ESIMD] Rename "are_equal" to "are_bitwise_equal"
vasilytric Nov 26, 2021
ef65095
[SYCL][ESIMD] Rename is_floating_point_v to is_sycl_floating_point_v
vasilytric Nov 26, 2021
1f1f8b9
[SYCL][ESIMD] Run bitwise comparison if provided tye is unsigned
vasilytric Nov 26, 2021
55ea733
[SYCL][ESIMD] Add comment for values in generate_ref_data function
vasilytric Nov 26, 2021
465eb5f
[SYCL][ESIMD] Remove is_sycl_type because it dont use anywhere
vasilytric Nov 26, 2021
ddf461a
[SYCL][ESIMD] Fix in are_bitwise_equal function
vasilytric Dec 2, 2021
b3128b3
Merge branch 'intel' into simd_ctor_coy
vasilytric Dec 9, 2021
4037dc7
[SYCL][ESIMD] Add "XREQUIRES" field and description of unsupp platform
vasilytric Dec 9, 2021
9730af7
[SYCL][ESIMD] Add TEST_WITH_COPY_FROM macro into ctor_copy tests
vasilytric Dec 9, 2021
2f98073
[SYCL][ESIMD] Replace "RefType" with "DataT" in functional/value.hpp
vasilytric Dec 9, 2021
05453a2
[SYCL][ESIMD] Disable ctor_copy test for esimd API
vasilytric Dec 9, 2021
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
68 changes: 68 additions & 0 deletions SYCL/ESIMD/api/functional/common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//===-- common.hpp - This file provides common functions for simd constructors
// tests -------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Common file for tests on simd class.
///
//===----------------------------------------------------------------------===//

#pragma once

#include <sycl/ext/intel/experimental/esimd.hpp>
#include <sycl/sycl.hpp>

#include "../../esimd_test_utils.hpp"
#include "logger.hpp"
#include "type_coverage.hpp"
#include "type_traits.hpp"
#include "value.hpp"

#include <vector>

namespace esimd_test {
namespace api {
namespace functional {

namespace details {

// Bitwise comparison for two values
template <typename T> bool are_bitwise_equal(T lhs, T rhs) {
constexpr size_t size{sizeof(T)};

// Such type-punning is OK from the point of strict aliasing rules
const auto &lhs_bytes = reinterpret_cast<const unsigned char(&)[size]>(lhs);
const auto &rhs_bytes = reinterpret_cast<const unsigned char(&)[size]>(rhs);

bool result{true};
for (size_t i = 0; i < size; ++i) {
result &= lhs_bytes[i] == rhs_bytes[i];
}
return result;
}

} // namespace details

// A wrapper to speed-up bitwise comparison
template <typename T> bool are_bitwise_equal(T lhs, T rhs) {
// We are safe to compare unsigned integral types using `==` operator.
// Still for any other type we might consider the bitwise comparison,
// including:
// - floating-point types, due to nan with opcodes
// - signed integer types, to avoid a possibility of UB on trap
// representation (negative zero) value access
if constexpr (std::is_unsigned_v<T>) {
return lhs == rhs;
} else {
return details::are_bitwise_equal(lhs, rhs);
}
}

} // namespace functional
} // namespace api
} // namespace esimd_test
87 changes: 87 additions & 0 deletions SYCL/ESIMD/api/functional/ctors/common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//===-- common.hpp - Define common code for simd ctors tests --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file provides common things for simd ctors tests.
///
//===----------------------------------------------------------------------===//

#pragma once

#include "../common.hpp"

namespace esimd_test {
namespace api {
namespace functional {
namespace ctors {

// Dummy kernel for submitting some code into device side.
template <typename DataT, int NumElems, typename T> struct Kernel;

template <typename DataT>
using shared_allocator = sycl::usm_allocator<DataT, sycl::usm::alloc::shared>;

template <typename DataT>
using shared_vector = std::vector<DataT, shared_allocator<DataT>>;

// Calls simd constructor in provided invocation context, which depends on the
// TestCaseT type. TestCaseT is a struct, that should have call_simd_ctor method
// that should return constructed object of simd class.
// This function returns std::vector instance with the output data.
template <typename DataT, int NumElems, typename TestCaseT>
auto call_simd(sycl::queue &queue, const shared_vector<DataT> &ref_data) {

shared_vector<DataT> result{NumElems, shared_allocator<DataT>{queue}};

queue.submit([&](sycl::handler &cgh) {
const auto ref = ref_data.data();
auto out = result.data();

cgh.single_task<Kernel<DataT, NumElems, TestCaseT>>(
[=]() SYCL_ESIMD_KERNEL {
sycl::ext::intel::experimental::esimd::simd<DataT, NumElems>
result_simd =
TestCaseT::template call_simd_ctor<DataT, NumElems>(ref);
result_simd.copy_to(out);
});
});
return result;
}

// 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> struct test {
bool operator()(sycl::queue &queue, const std::string &data_type) {
bool passed{true};

std::vector<DataT> generated_data{generate_ref_data<DataT, NumElems>()};
shared_vector<DataT> ref_data{generated_data.begin(), generated_data.end(),
shared_allocator<DataT>{queue}};

const auto result_data =
call_simd<DataT, NumElems, TestCaseT>(queue, ref_data);

for (size_t it = 0; it < ref_data.size(); it++) {
if (!are_bitwise_equal(ref_data[it], result_data[it])) {
passed = false;
log::fail<NumElems>(
"Simd by " + TestCaseT::get_description() +
" failed, retrieved: " + std::to_string(result_data[it]) +
", expected: " + std::to_string(ref_data[it]),
data_type);
}
}

return passed;
}
};

} // namespace ctors
} // namespace functional
} // namespace api
} // namespace esimd_test
125 changes: 125 additions & 0 deletions SYCL/ESIMD/api/functional/ctors/ctor_copy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//==------- ctor_copy.cpp - DPC++ ESIMD on-device test --------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// REQUIRES: gpu
// UNSUPPORTED: cuda || hip
// RUN: %clangxx -fsycl %s -fsycl-device-code-split=per_kernel -o %t.out
// RUN: %GPU_RUN_PLACEHOLDER %t.out
//
// Test for esimd copy constructor.

#include "common.hpp"

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

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

template <typename DataT, int NumElems>
static simd<DataT, NumElems> call_simd_ctor(const DataT *ref_data) {
simd<DataT, NumElems> source_simd;
source_simd.copy_from(ref_data);
simd<DataT, NumElems> simd_by_init = simd<DataT, NumElems>(source_simd);
return simd_by_init;
}
};

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

template <typename DataT, int NumElems>
static simd<DataT, NumElems> call_simd_ctor(const DataT *ref_data) {
simd<DataT, NumElems> source_simd;
source_simd.copy_from(ref_data);
simd<DataT, NumElems> simd_by_var_decl{source_simd};
return simd_by_var_decl;
}
};

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

template <typename DataT, int NumElems>
static simd<DataT, NumElems> call_simd_ctor(const DataT *ref_data) {
simd<DataT, NumElems> source_simd;
source_simd.copy_from(ref_data);
simd<DataT, NumElems> simd_by_rval;
simd_by_rval = simd<DataT, NumElems>(source_simd);
return simd_by_rval;
}
};

// Descriptor class for the case of calling constructor in const reference
// context.
class const_ref {
public:
static std::string get_description() { return "const reference"; }

template <typename DataT, int NumElems>
static simd<DataT, NumElems> call_simd_ctor(const DataT *ref_data) {
simd<DataT, NumElems> source_simd;
source_simd.copy_from(ref_data);
return call_simd_by_const_ref<DataT, NumElems>(
simd<DataT, NumElems>(source_simd));
}

private:
template <typename DataT, int NumElems>
static simd<DataT, NumElems>
call_simd_by_const_ref(const simd<DataT, NumElems> &simd_by_const_ref) {
return simd_by_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>()};

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);

std::cout << (passed ? "=== Test passed\n" : "=== Test FAILED\n");
return passed ? 0 : 1;
}
35 changes: 35 additions & 0 deletions SYCL/ESIMD/api/functional/type_traits.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===-- type_traits.hpp - Define functions for iterating with datatypes. --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file provides function for iterating with data types.
///
//===----------------------------------------------------------------------===//

#pragma once

#include <type_traits>

namespace esimd_test {
namespace api {
namespace functional {
namespace type_traits {

template <typename T>
using is_sycl_floating_point =
std::bool_constant<std::is_floating_point_v<T> ||
std::is_same_v<T, sycl::half>>;

template <typename T>
inline constexpr bool is_sycl_floating_point_v{
is_sycl_floating_point<T>::value};

} // namespace type_traits
} // namespace functional
} // namespace api
} // namespace esimd_test
Loading