1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright Contributors to the Kokkos project
#ifndef KOKKOS_TEST_SIMD_GENERATOR_CTORS_HPP
#define KOKKOS_TEST_SIMD_GENERATOR_CTORS_HPP
#include <Kokkos_Macros.hpp>
#ifdef KOKKOS_ENABLE_EXPERIMENTAL_CXX20_MODULES
import kokkos.simd;
import kokkos.simd_impl;
#else
#include <Kokkos_SIMD.hpp>
#endif
#include <SIMDTesting_Utilities.hpp>
template <typename Abi, typename DataType>
inline void host_check_gen_ctor() {
if constexpr (is_simd_avail_v<DataType, Abi>) {
using simd_type = Kokkos::Experimental::basic_simd<DataType, Abi>;
using mask_type = typename simd_type::mask_type;
constexpr std::size_t lanes = simd_type::size();
DataType init[lanes];
DataType expected[lanes];
bool init_mask[lanes];
for (std::size_t i = 0; i < lanes; ++i) {
init_mask[i] = (i % 2 == 0);
init[i] = i + 1;
expected[i] = (init_mask[i]) ? init[i] * 10 : init[i];
}
simd_type rhs = Kokkos::Experimental::simd_unchecked_load<simd_type>(
init, Kokkos::Experimental::simd_flag_default);
simd_type blend = Kokkos::Experimental::simd_unchecked_load<simd_type>(
expected, Kokkos::Experimental::simd_flag_default);
#if !(defined(KOKKOS_ENABLE_CUDA) && defined(KOKKOS_COMPILER_MSVC))
if constexpr (std::is_same_v<Abi, Kokkos::Experimental::simd_abi::scalar>) {
simd_type basic(KOKKOS_LAMBDA(std::size_t i) { return init[i]; });
host_check_equality(basic, rhs, lanes);
simd_type lhs(KOKKOS_LAMBDA(std::size_t i) { return init[i] * 10; });
mask_type mask(KOKKOS_LAMBDA(std::size_t i) { return init_mask[i]; });
simd_type result(
KOKKOS_LAMBDA(std::size_t i) { return (mask[i]) ? lhs[i] : rhs[i]; });
host_check_equality(blend, result, lanes);
} else {
simd_type basic([=](std::size_t i) { return init[i]; });
host_check_equality(basic, rhs, lanes);
simd_type lhs([=](std::size_t i) { return init[i] * 10; });
mask_type mask([=](std::size_t i) { return init_mask[i]; });
simd_type result(
[=](std::size_t i) { return (mask[i]) ? lhs[i] : rhs[i]; });
host_check_equality(blend, result, lanes);
}
#endif
}
}
template <typename Abi, typename... DataTypes>
inline void host_check_gen_ctors_all_types(
Kokkos::Experimental::Impl::data_types<DataTypes...>) {
(host_check_gen_ctor<Abi, DataTypes>(), ...);
}
template <typename... Abis>
inline void host_check_gen_ctors_all_abis(
Kokkos::Experimental::Impl::abi_set<Abis...>) {
using DataTypes = Kokkos::Experimental::Impl::data_type_set;
(host_check_gen_ctors_all_types<Abis>(DataTypes()), ...);
}
template <typename Abi, typename DataType>
KOKKOS_INLINE_FUNCTION void device_check_gen_ctor() {
if constexpr (is_type_v<Kokkos::Experimental::basic_simd<DataType, Abi>>) {
using simd_type = Kokkos::Experimental::basic_simd<DataType, Abi>;
using mask_type = typename simd_type::mask_type;
constexpr std::size_t lanes = simd_type::size();
DataType init[lanes];
DataType expected[lanes];
bool init_mask[lanes];
for (std::size_t i = 0; i < lanes; ++i) {
if (i % 3 == 0) {
init_mask[i] = true;
} else {
init_mask[i] = false;
}
init[i] = 7;
expected[i] = (init_mask[i]) ? init[i] * 9 : init[i];
}
mask_type mask(KOKKOS_LAMBDA(std::size_t i) { return init_mask[i]; });
simd_type basic(KOKKOS_LAMBDA(std::size_t i) { return init[i]; });
simd_type rhs = Kokkos::Experimental::simd_unchecked_load<simd_type>(
init, Kokkos::Experimental::simd_flag_default);
device_check_equality(basic, rhs, lanes);
simd_type lhs(KOKKOS_LAMBDA(std::size_t i) { return init[i] * 9; });
simd_type result(
KOKKOS_LAMBDA(std::size_t i) { return (mask[i]) ? lhs[i] : rhs[i]; });
simd_type blend = Kokkos::Experimental::simd_unchecked_load<simd_type>(
expected, Kokkos::Experimental::simd_flag_default);
device_check_equality(result, blend, lanes);
}
}
template <typename Abi, typename... DataTypes>
KOKKOS_INLINE_FUNCTION void device_check_gen_ctors_all_types(
Kokkos::Experimental::Impl::data_types<DataTypes...>) {
(device_check_gen_ctor<Abi, DataTypes>(), ...);
}
template <typename... Abis>
KOKKOS_INLINE_FUNCTION void device_check_gen_ctors_all_abis(
Kokkos::Experimental::Impl::abi_set<Abis...>) {
using DataTypes = Kokkos::Experimental::Impl::data_type_set;
(device_check_gen_ctors_all_types<Abis>(DataTypes()), ...);
}
class simd_device_gen_ctor_functor {
public:
KOKKOS_INLINE_FUNCTION void operator()(int) const {
device_check_gen_ctors_all_abis(
Kokkos::Experimental::Impl::device_abi_set());
}
};
TEST(simd, host_gen_ctors) {
host_check_gen_ctors_all_abis(Kokkos::Experimental::Impl::host_abi_set());
}
TEST(simd, device_gen_ctors) {
Kokkos::parallel_for(1, simd_device_gen_ctor_functor());
}
#endif
|