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

[SYCL] Introduce sycl complex marray specialization's testing #1661

Draft
wants to merge 6 commits into
base: intel
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 34 additions & 2 deletions SYCL/Complex/sycl_complex_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ template <> const char *get_typename<double>() { return "double"; }
template <> const char *get_typename<float>() { return "float"; }
template <> const char *get_typename<sycl::half>() { return "sycl::half"; }

// Helper to test each complex specilization
/// Helper to test each complex specilization

// Overload for cplx_test_cases
template <template <typename> typename action, typename... argsT>
bool test_valid_types(sycl::queue &Q, argsT... args) {
Expand Down Expand Up @@ -195,8 +196,17 @@ template <> auto constexpr init_deci(sycl::half re) {
return static_cast<float>(re);
}

// Helper for comparing SyclCPLX and standard c++ results
template <typename Tout, typename Tin, std::size_t NumElements>
auto constexpr convert_marray(sycl::marray<std::complex<Tin>, NumElements> c) {
sycl::marray<std::complex<Tout>, NumElements> rtn;
for (std::size_t i = 0; i < NumElements; ++i)
rtn[i] = c[i];
return rtn;
}

/// Helper for comparing SyclCPLX and standard c++ results

// Complex overloads
template <typename T>
bool check_results(experimental::complex<T> output, std::complex<T> reference,
bool is_device) {
Expand All @@ -210,7 +220,19 @@ bool check_results(experimental::complex<T> output, std::complex<T> reference,
}
return true;
}
template <typename T, std::size_t NumElements>
bool check_results(sycl::marray<experimental::complex<T>, NumElements> output,
sycl::marray<std::complex<T>, NumElements> reference,
bool is_device) {
for (std::size_t i = 0; i < NumElements; ++i) {
if (!check_results(output[i], reference[i], is_device)) {
return false;
}
}
return true;
}

// Scalar overloads
template <typename T>
bool check_results(T output, T reference, bool is_device) {
if (!almost_equal_scalar(output, reference, SYCL_CPLX_TOL_ULP)) {
Expand All @@ -223,3 +245,13 @@ bool check_results(T output, T reference, bool is_device) {
}
return true;
}
template <typename T, std::size_t NumElements>
bool check_results(sycl::marray<T, NumElements> output,
sycl::marray<T, NumElements> reference, bool is_device) {
for (std::size_t i = 0; i < NumElements; ++i) {
if (!check_results(output[i], reference[i], is_device)) {
return false;
}
}
return true;
}
94 changes: 94 additions & 0 deletions SYCL/Complex/sycl_complex_marray_getters_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsycl-device-code-split=per_kernel %s -o %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %GPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out

#include "sycl_complex_marray_test_cases.hpp"

template <typename T> struct test_real {
bool operator()(sycl::queue &Q, const std::vector<double> &init,
const std::vector<double> &ref = {}, bool use_ref = false) {
bool pass = true;

/* std::complex test cases */
sycl::marray<T, GETTERS_TEST_CASE_SIZE> std_in;
/* sycl::complex test cases */
sycl::marray<experimental::complex<T>, GETTERS_TEST_CASE_SIZE> cplx_in;

for (std::size_t i = 0; i < GETTERS_TEST_CASE_SIZE; ++i) {
std_in[i] = static_cast<T>(init[i]);
cplx_in[i] =
experimental::complex<T>{static_cast<T>(init[i]), static_cast<T>(0)};
}

auto *cplx_out =
sycl::malloc_shared<sycl::marray<T, GETTERS_TEST_CASE_SIZE>>(1, Q);

/* Check cplx::complex output from device */
Q.single_task([=]() { *cplx_out = cplx_in.real(); }).wait();
pass &= check_results(*cplx_out, std_in, /*is_device*/ true);

/* Check cplx::complex output from host */
*cplx_out = cplx_in.real();
pass &= check_results(*cplx_out, std_in, /*is_device*/ false);

sycl::free(cplx_out, Q);

return pass;
}
};

template <typename T> struct test_imag {
bool operator()(sycl::queue &Q, const std::vector<double> &init,
const std::vector<double> &ref = {}, bool use_ref = false) {
bool pass = true;

/* std::complex test cases */
sycl::marray<T, GETTERS_TEST_CASE_SIZE> std_in;
/* sycl::complex test cases */
sycl::marray<experimental::complex<T>, GETTERS_TEST_CASE_SIZE> cplx_in;

for (std::size_t i = 0; i < GETTERS_TEST_CASE_SIZE; ++i) {
std_in[i] = static_cast<T>(init[i]);
cplx_in[i] =
experimental::complex<T>{static_cast<T>(0), static_cast<T>(init[i])};
}

auto *cplx_out =
sycl::malloc_shared<sycl::marray<T, GETTERS_TEST_CASE_SIZE>>(1, Q);

/* Check cplx::complex output from device */
Q.single_task([=]() { *cplx_out = cplx_in.imag(); }).wait();
pass &= check_results(*cplx_out, std_in, /*is_device*/ true);

/* Check cplx::complex output from host */
*cplx_out = cplx_in.imag();
pass &= check_results(*cplx_out, std_in, /*is_device*/ false);

sycl::free(cplx_out, Q);

return pass;
}
};

int main() {
sycl::queue Q;

bool test_passes = true;

/* Test real getter */

{
marray_scalar_test_cases<test_real> test;
test_passes &= test(Q);
}

/* Test imag getter */

{
marray_scalar_test_cases<test_imag> test;
test_passes &= test(Q);
}

return !test_passes;
}
Loading