File: TestSIMD_GeneratorCtors.hpp

package info (click to toggle)
kokkos 5.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 15,140 kB
  • sloc: cpp: 225,293; sh: 1,250; python: 78; makefile: 16; fortran: 4; ansic: 2
file content (142 lines) | stat: -rw-r--r-- 4,976 bytes parent folder | download
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