Peano
Loading...
Searching...
No Matches
CompressedFloat.h
Go to the documentation of this file.
1//
2//
3// @todo It is very likely that this class is not required anymore and is a
4// legacy file from the LLVM papers that should be removed from the
5// repository.
6#pragma once
7
8#include <cstdint>
9#include <concepts>
10
11
18// https://stackoverflow.com/a/3221914/5769882
19#define STRCAT_INNER(a, b) a##b
20#define STRCAT(a, b) STRCAT_INNER(a, b)
21
22template<typename X>
23concept NUM = std::integral<X> || std::floating_point<X>;
24
25namespace std {
26 template<typename CF>
27 CF abs(const CF &cf) {
28 auto i = cf.__get() > 0;
29 if (i) return cf;
30 else return -cf;
31 }
32}
33
34namespace tarch {
35namespace la {
36
37 template<typename T, unsigned char BITS = sizeof(T) * 8, unsigned char ALIGNMENT = alignof(T)> requires std::is_floating_point_v<T>
38 class alignas(ALIGNMENT) CompressedFloat {
39 __attribute__((packed)) std::uint64_t data: BITS;
40
41 T __get() const {
42 union {
43 std::uint64_t byte_data;
44 T float_data;
45 } U;
46
47 static_assert(sizeof(T) * 8 >= BITS);
48
49 auto dataLocal = this->data;
50
51 U.byte_data = dataLocal << (sizeof(T) * 8 - BITS);
52 auto float_data = U.float_data;
53 return float_data;
54 }
55
56 void __set(T float_data) {
57 union {
58 std::uint64_t byte_data;
59 T float_data;
60 } U;
61
62 U.float_data = float_data;
63 this->data = U.byte_data >> (sizeof(T) * 8 - BITS);
64 }
65
66 public:
67 CompressedFloat() = default;
68
69 CompressedFloat(const CompressedFloat &copy) = default;
70
71 CompressedFloat(const T &value) {
72 this->__set(value);
73 }
74
75 CompressedFloat &operator=(const CompressedFloat &other) = default;
76
77 template<NUM X>
78 CompressedFloat &operator=(const X &value) {
79 this->__set((T) value);
80 return *this;
81 }
82
83#define UNARY_PREFIX_OP(op) \
84 CompressedFloat &operator op() { \
85 auto f = this->__get(); \
86 f op; \
87 this->__set(f); \
88 return *this; \
89 } \
90
91 UNARY_PREFIX_OP(++)
92 UNARY_PREFIX_OP(--)
93
94#define UNARY_POSTFIX_OP(op) \
95 const CompressedFloat operator op(std::int32_t) { \
96 auto oldThis = CompressedFloat(*this); \
97 this->operator op(); \
98 return oldThis; \
99 } \
100
101 UNARY_POSTFIX_OP(++)
102 UNARY_POSTFIX_OP(--)
103
104 T operator -() const {
105 return -this->__get();
106 }
107
108#undef UNARY_POSTFIX_OP
109
110#define ARITHMETIC_OP(op) \
111 template<NUM X> \
112 CompressedFloat &operator STRCAT(op, =) (const X &scalar) { \
113 this->__set(this->__get() op scalar); \
114 return *this; \
115 } \
116 \
117 template<NUM X> \
118 T operator op (const X &scalar) const { \
119 return this->__get() op scalar; \
120 } \
121 \
122 template<NUM X> \
123 friend X& operator STRCAT(op, =) (X &scalar, const CompressedFloat cf) { \
124 scalar STRCAT(op, =) cf.__get(); \
125 return scalar; \
126 } \
127 \
128 template<NUM X> \
129 friend X operator op (const X &scalar, const CompressedFloat cf) { \
130 return scalar op cf.__get(); \
131 } \
132
133 ARITHMETIC_OP(+)
134 ARITHMETIC_OP(-)
135 ARITHMETIC_OP(*)
136 ARITHMETIC_OP(/)
137
138#undef ARITHMETIC_OP
139
140#define SELF_ARITHMETIC_OP(op) \
141 CompressedFloat &operator STRCAT(op, =) (const CompressedFloat &scalar) { \
142 this->__set(this->__get() op scalar.__get()); \
143 return *this; \
144 } \
145 \
146 T operator op (const CompressedFloat &scalar) const { \
147 return this->__get() op scalar; \
148 } \
149
150 SELF_ARITHMETIC_OP(+)
151 SELF_ARITHMETIC_OP(-)
152 SELF_ARITHMETIC_OP(*)
153 SELF_ARITHMETIC_OP(/)
154
155#undef SELF_ARITHMETIC_OP
156
157 bool operator !() const {
158 return !this->data;
159 }
160
161#define COMPARISON_OP(op) \
162 template<NUM X> \
163 bool operator op (const X &scalar) const { \
164 return this->__get() op scalar; \
165 } \
166 \
167 template<NUM X> \
168 friend bool operator op (const X &scalar, const CompressedFloat &cf) { \
169 return scalar op cf.__get(); \
170 } \
171
172 COMPARISON_OP(<)
173 COMPARISON_OP(<=)
174 COMPARISON_OP(==)
175 COMPARISON_OP(!=)
176 COMPARISON_OP(>=)
177 COMPARISON_OP(>)
178
179 #undef COMPARISON_OP
180
181#define SELF_COMPARISON_OP(op) \
182 bool operator op (const CompressedFloat &cf) const { \
183 return this->__get() op cf.__get(); \
184 } \
185
186 SELF_COMPARISON_OP(<)
187 SELF_COMPARISON_OP(<=)
188 SELF_COMPARISON_OP(==)
189 SELF_COMPARISON_OP(!=)
190 SELF_COMPARISON_OP(>=)
191 SELF_COMPARISON_OP(>)
192
193#undef SELF_COMPARISON_OP
194
195 template<NUM X>
196 operator X() const {
197 return (X) this->__get();
198 }
199
200 friend CompressedFloat std::abs(const CompressedFloat &cf);
201
202 };
203
204}
205}
206
207#undef STRCAT_INNER
208#undef STRCAT
209
210
__attribute__((always_inline, const)) inline static double pow_gamma(double x)
Returns the argument to the power given by the adiabatic index.
double abs(double value)
Returns the absolute value of a type by redirecting to std::abs.
Have to include this header, as I need access to the SYCL_EXTERNAL keyword.
Definition accelerator.h:19