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

[SYCL][ESIMD] Add mutator for test input data #789

Merged
merged 7 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
115 changes: 115 additions & 0 deletions SYCL/ESIMD/api/functional/mutator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//===-- mutator.hpp - This file provides common function and classes to mutate
// reference data. ---------------------------------------------------===//
//
// 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 function and classes to mutate reference data.
///
//===----------------------------------------------------------------------===//

#pragma once

#include "type_traits.hpp"
#include "value.hpp"
#include <sycl/sycl.hpp>

// for std::for_each
#include <algorithm>
#include <vector>

namespace esimd_test::api::functional {

// In some test cases it’s possible to pass a reference data as the input data
// directly without any modification. For example, if we check some copy
// constructor or memory move operation it’s OK to have any data values as the
// input ones. But in most cases we need to consider the possibility of UB for
// C++ operations due to modification of input values.
//
// Mutation mechanism covers such requirement.
// The mutator namespace is intended to store such mutators alongside with
// the generic ones provided below.
namespace mutator {

// Replace specific reference values to the bigger ones, so we can safely
// substract `val` later.
template <typename T> class For_subtraction {
T m_value;

public:
For_subtraction(T val)
: m_value((assert(val > 0 && "Invalid value."), val)) {}

void operator()(T &val) {
// Floating point variable with infinity value shouldn't be changed.
if constexpr (type_traits::is_sycl_signed_v<T>) {
if constexpr (type_traits::is_sycl_floating_point_v<T>) {
// sycl::half will be converted to float
if (std::isinf(val)) {
return;
}
}

const T lower_border = value<T>::lowest() + m_value;
if (val < lower_border) {
val = lower_border;
}
}
}
};

// Replace specific reference values to the smaller ones, so we can safely add
// `val` later.
template <typename T> class For_addition {
T m_value;

public:
For_addition(T val) : m_value((assert(val > 0 && "Invalid value."), val)) {}

void operator()(T &val) {
// Floating point variable with infinity value shouldn't be changed.
if constexpr (type_traits::is_sycl_floating_point_v<T>) {
// sycl::half will be converted to float
if (std::isinf(val)) {
return;
}
}

if constexpr (type_traits::is_sycl_signed_v<T>) {
const T upper_border = value<T>::max() - m_value;
if (val > upper_border) {
val = upper_border;
}
}
}
};

// Replace specific reference values to the divided ones, so we can safely
// multiply to `val` later.
template <typename T> class For_multiplication {
T m_value;

public:
For_multiplication(T val)
: m_value((assert(val > 0 && "Invalid value."), val)) {}

void operator()(T &val) {
if (val != value<T>::denorm_min()) {
val /= m_value;
}
}
};

} // namespace mutator

// Applies provided mutator to each value for provided container.
template <typename T, typename MutatorT>
inline void mutate(std::vector<T> &input_vector, MutatorT &&mutator) {
std::for_each(input_vector.begin(), input_vector.end(), mutator);
}

} // namespace esimd_test::api::functional
9 changes: 9 additions & 0 deletions SYCL/ESIMD/api/functional/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#pragma once

#include <sycl/sycl.hpp>

#include <type_traits>
#include <utility>

Expand All @@ -27,6 +29,13 @@ template <typename T>
inline constexpr bool is_sycl_floating_point_v{
is_sycl_floating_point<T>::value};

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

template <typename T>
inline constexpr bool is_sycl_signed_v{is_sycl_signed<T>::value};

template <typename T>
using is_nonconst_rvalue_reference =
std::bool_constant<std::is_rvalue_reference_v<T> &&
Expand Down
4 changes: 3 additions & 1 deletion SYCL/ESIMD/api/functional/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
//===----------------------------------------------------------------------===//

#pragma once

#include "../../esimd_test_utils.hpp"
#include "type_traits.hpp"
#include <CL/sycl.hpp>
#include <sycl/sycl.hpp>

#include <climits>
#include <limits>
Expand Down
4 changes: 3 additions & 1 deletion SYCL/ESIMD/esimd_test_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
//
//===----------------------------------------------------------------------===//

#include <CL/sycl.hpp>
#pragma once

#include <sycl/sycl.hpp>

#define NOMINMAX

Expand Down