Project
Loading...
Searching...
No Matches
simdtypes.h
Go to the documentation of this file.
1// Copyright 2019-2023 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef RANS_INTERNAL_COMMON_SIMDTYPES_H_
17#define RANS_INTERNAL_COMMON_SIMDTYPES_H_
18
20
21#ifdef RANS_SIMD
22
23#include <immintrin.h>
24#include <cstdint>
25#include <cstring>
26
28
30{
31
32enum class SIMDWidth : uint32_t { SSE = 128u,
33 AVX = 256u };
34
35[[nodiscard]] inline constexpr size_t getLaneWidthBits(SIMDWidth width) noexcept { return static_cast<size_t>(width); };
36
37[[nodiscard]] inline constexpr size_t getLaneWidthBytes(SIMDWidth width) noexcept { return utils::toBytes(static_cast<size_t>(width)); };
38
39[[nodiscard]] inline constexpr size_t getAlignment(SIMDWidth width) noexcept { return getLaneWidthBytes(width); };
40
41template <class T, size_t N>
42[[nodiscard]] inline constexpr T* assume_aligned(T* ptr) noexcept
43{
44 return reinterpret_cast<T*>(__builtin_assume_aligned(ptr, N, 0));
45};
46
47template <class T, SIMDWidth width_V>
48[[nodiscard]] inline constexpr T* assume_aligned(T* ptr) noexcept
49{
50 constexpr size_t alignment = getAlignment(width_V);
51 return assume_aligned<T, alignment>(ptr);
52};
53
54template <typename T, SIMDWidth width_V>
55[[nodiscard]] inline constexpr bool isAligned(T* ptr)
56{
57 // only aligned iff ptr is divisible by alignment
58 constexpr size_t alignment = getAlignment(width_V);
59 return !(reinterpret_cast<uintptr_t>(ptr) % alignment);
60};
61
62template <typename T>
63[[nodiscard]] inline constexpr size_t getElementCount(SIMDWidth width) noexcept
64{
65 return getLaneWidthBytes(width) / sizeof(T);
66};
67
68template <typename T>
69[[nodiscard]] inline constexpr SIMDWidth getSimdWidth(size_t nHardwareStreams) noexcept
70{
71 return static_cast<SIMDWidth>(nHardwareStreams * utils::toBits<T>());
72};
73
74template <SIMDWidth>
75struct SimdInt;
76
77template <>
78struct SimdInt<SIMDWidth::SSE> {
79 using value_type = __m128i;
80};
81
82#ifdef RANS_AVX2
83template <>
84struct SimdInt<SIMDWidth::AVX> {
85 using value_type = __m256i;
86};
87#endif
88
89template <SIMDWidth width_V>
90using simdI_t = typename SimdInt<width_V>::value_type;
91
92using simdIsse_t = simdI_t<SIMDWidth::SSE>;
93#ifdef RANS_AVX2
94using simdIavx_t = simdI_t<SIMDWidth::AVX>;
95#endif
96
97template <SIMDWidth>
98struct SimdDouble;
99
100template <>
101struct SimdDouble<SIMDWidth::SSE> {
102 using value_type = __m128d;
103};
104
105#ifdef RANS_AVX2
106template <>
107struct SimdDouble<SIMDWidth::AVX> {
108 using value_type = __m256d;
109};
110#endif
111
112template <SIMDWidth width_V>
113using simdD_t = typename SimdDouble<width_V>::value_type;
114
115using simdDsse_t = simdD_t<SIMDWidth::SSE>;
116#ifdef RANS_AVX2
117using simdDavx_t = simdD_t<SIMDWidth::AVX>;
118#endif
119} // namespace o2::rans::internal::simd
120
121#endif /* RANS_SIMD */
122
123#endif /* RANS_INTERNAL_COMMON_SIMDTYPES_H_ */
TBranch * ptr
common helper classes and functions
preprocessor defines to enable features based on CPU architecture
GLint GLsizei width
Definition glcorearb.h:270
constexpr size_t toBytes(size_t bits) noexcept
Definition utils.h:163