alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
SimdWhereExpr.hpp
Go to the documentation of this file.
1/* Copyright 2025 René Widera
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5/** @file This file provides a basic implementation of a SIMD vector.
6 *
7 * The implementation is based on the class Vec:
8 * - the storge policy should become the native SIMD implementation e.g. std::simd
9 * - load/ store and simd specifics should be implemented in the storage policy
10 * - the name of storage policy should be changed
11 *
12 * The current operator operations rely on compilers auto vectorization.
13 */
14
15#pragma once
16
17#include "alpaka/Simd.hpp"
18
19namespace alpaka
20{
21 template<concepts::SimdMask Mask, concepts::Simd T_Simd>
23 {
24 Mask const& m_mask;
25 T_Simd& value;
26
27 constexpr SimdWhereExpr(Mask const& m, T_Simd& v) : m_mask(m), value(v)
28 {
29 }
30
31 // disable copy and move constructors/operators to avoid pointing to invalid references.
32 constexpr SimdWhereExpr(SimdWhereExpr const&) = delete;
33 constexpr SimdWhereExpr(SimdWhereExpr&&) = delete;
34 constexpr SimdWhereExpr& operator=(SimdWhereExpr const&) = delete;
35 constexpr SimdWhereExpr& operator=(SimdWhereExpr&&) = delete;
36
37 using value_type = typename T_Simd::type;
38
39 constexpr void operator=(concepts::Simd auto const& rhs)
40 requires std::same_as<value_type, typename ALPAKA_TYPEOF(rhs)::type>
41 {
42 if constexpr(requires { value.where(m_mask); })
43 value.where(m_mask) = rhs.asNativeType();
44 else
45 value.update(m_mask, rhs);
46 }
47
49 {
50 if constexpr(requires { value.where(m_mask); })
51 value.where(m_mask) = rhs;
52 else
53 value.update(m_mask, static_cast<value_type>(rhs));
54 }
55
56#define ALPAKA_SIMD_EXPR_ASSIGN_OP(op_name, op) \
57 constexpr void operator op_name(concepts::Simd auto const& rhs) \
58 { \
59 if constexpr(requires { value.where(m_mask); }) \
60 value.where(m_mask) op_name rhs.asNativeType(); \
61 else \
62 value.update(m_mask, value op rhs); \
63 } \
64 constexpr void operator op_name(concepts::LosslesslyConvertible<value_type> auto const& rhs) \
65 { \
66 if constexpr(requires { value.where(m_mask); }) \
67 value.where(m_mask) op_name rhs; \
68 else \
69 value.update(m_mask, value op rhs); \
70 }
71
76
77#undef ALPAKA_SIMD_EXPR_ASSIGN_OP
78 };
79
80 /** Conditionally update each component of an SIMD pack
81 *
82 * @param mask SIMD pack of booleans, where each component is true for the element in v which should be overwritten
83 * with the value assigned to the returned expression
84 * @param value SIMD vector to which the mask is applied
85 */
86 template<concepts::SimdMask T_Mask, concepts::Simd T_Simd>
87 constexpr SimdWhereExpr<T_Mask, T_Simd> where(T_Mask const& mask, T_Simd& value)
88 {
89 return {mask, value};
90 }
91} // namespace alpaka
#define ALPAKA_SIMD_EXPR_ASSIGN_OP(op_name, op)
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
Concept to check if a type can be lossless converted to another type.
main alpaka namespace.
Definition alpaka.hpp:76
constexpr SimdWhereExpr< T_Mask, T_Simd > where(T_Mask const &mask, T_Simd &value)
Conditionally update each component of an SIMD pack.
typename T_Simd::type value_type
constexpr SimdWhereExpr & operator=(SimdWhereExpr &&)=delete
constexpr SimdWhereExpr(SimdWhereExpr const &)=delete
constexpr SimdWhereExpr(SimdWhereExpr &&)=delete
constexpr void operator=(concepts::Simd auto const &rhs)
constexpr SimdWhereExpr & operator=(SimdWhereExpr const &)=delete
constexpr void operator=(concepts::LosslesslyConvertible< value_type > auto const &rhs)
constexpr SimdWhereExpr(Mask const &m, T_Simd &v)