gem5 [DEVELOP-FOR-25.1]
Loading...
Searching...
No Matches
mxfp.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef __ARCH_AMDGPU_COMMON_DTYPE_MXFP_HH__
33#define __ARCH_AMDGPU_COMMON_DTYPE_MXFP_HH__
34
35#include <cmath>
36#include <cstdint>
37#include <iostream>
38
40
41namespace gem5
42{
43
44namespace AMDGPU
45{
46
47// Base class for all microscaling types. The sizes of everything are
48// determined by the enum fields in the FMT struct. All of these share the
49// same operator overloads which convert to float before arithmetic and
50// convert back if assigned to a microscaling type.
51template<typename FMT>
52class mxfp
53{
54 public:
55 mxfp() = default;
57 {
59 }
60
61 // Set raw bits, used by gem5 to set a raw value read from VGPRs.
62 mxfp(const uint32_t& raw)
63 {
64 // The info unions end up being "left" aligned. For example, in FP4
65 // only the bits 31:28 are used. Shift the input by the storage size
66 // of 32 by the type size (sign + exponent + mantissa bits).
67 data = raw;
68 data <<= (32 - int(FMT::sbits) - int(FMT::ebits) - int(FMT::mbits));
69 }
70
71 mxfp(const mxfp& f)
72 {
73 FMT conv_out;
74 conv_out = convertMXFP<FMT, decltype(f.getFmt())>(f.getFmt());
75 data = conv_out.storage;
76 }
77
78 mxfp&
79 operator=(const float& f)
80 {
82 return *this;
83 }
84
85 mxfp&
87 {
88 FMT conv_out;
89 conv_out = convertMXFP<FMT, decltype(f.getFmt())>(f.getFmt());
90 data = conv_out.storage;
91 return *this;
92 }
93
94 operator float() const
95 {
96 binary32 out;
97 FMT in;
98 in.storage = data;
100
101 return out.fp32;
102 }
103
104 constexpr static int
106 {
107 return int(FMT::mbits) + int(FMT::ebits) + int(FMT::sbits);
108 }
109
110 // Intentionally use storage > size() so that a storage type is not needed
111 // as a template parameter.
112 uint32_t data = 0;
113
114 FMT
115 getFmt() const
116 {
117 FMT out;
118 out.storage = data;
119 return out;
120 }
121
122 void
123 setFmt(FMT in)
124 {
125 data = in.storage;
126 }
127
128 // Used for upcasting
129 void
130 scaleMul(const float& f)
131 {
132 binary32 bfp;
133 bfp.fp32 = f;
134 int scale_val = bfp.exp;
135
136 // Scale value of 0xFF is NaN. Scaling by NaN returns NaN.
137 // In this implementation, types without NaN define it as max().
138 if (scale_val == 0xFF) {
139 data = FMT::nan;
140 return;
141 }
142
143 scale_val -= bfp.bias;
144
145 FMT in = getFmt();
146 int exp = in.exp;
147
148 // Our value is zero, scaling by anything remains zero.
149 if (exp == 0 && in.mant == 0) {
150 return;
151 }
152
153 if (exp + scale_val > max_exp<FMT>()) {
154 in.exp = max_exp<FMT>();
155 } else if (exp + scale_val < min_exp<FMT>()) {
156 in.exp = min_exp<FMT>();
157 } else {
158 in.exp = exp + scale_val;
159 }
160
161 data = in.storage;
162 }
163
164 // Used for downcasting
165 void
166 scaleDiv(const float& f)
167 {
168 binary32 bfp;
169 bfp.fp32 = f;
170 int scale_val = bfp.exp;
171
172 // Scale value of 0xFF is NaN. Scaling by NaN returns NaN.
173 // In this implementation, types without NaN define it as max().
174 if (scale_val == 0xFF) {
175 data = FMT::nan;
176 return;
177 }
178
179 scale_val -= bfp.bias;
180
181 FMT in = getFmt();
182 int exp = in.exp;
183
184 // Our value is zero, scaling by anything remains zero.
185 if (exp == 0 && in.mant == 0) {
186 return;
187 }
188
189 if (exp - scale_val > max_exp<FMT>()) {
190 in.exp = max_exp<FMT>();
191 } else if (exp - scale_val < min_exp<FMT>()) {
192 in.exp = min_exp<FMT>();
193 } else {
194 in.exp = exp - scale_val;
195
196 // Output become denorm
197 if (in.exp == 0) {
198 uint32_t m = in.mant | 1 << FMT::mbits;
199 m >>= 1;
200 in.mant = m & mask(FMT::mbits);
201 }
202 }
203
204 data = in.storage;
205 }
206
207 // Helper method specific to AMDGPU instructions.
208 void
209 omodModifier(unsigned omod)
210 {
211 // When the VOP3 form is used, instructions with a floating-point
212 // result can apply an output modifier (OMOD field) that multiplies
213 // the result by: 0.5, 1.0, 2.0 or 4.0
214 //
215 // 2-bit field in encoding:
216 // 0: Do nothing
217 // 1: Multiply by 2
218 // 2: Multiply by 4
219 // 3: Divide by 2 (multiply by 1/2)
220 assert(omod < 4);
221
222 if (omod == 1) scaleMul(2.0f);
223 if (omod == 2) scaleMul(4.0f);
224 if (omod == 3) scaleDiv(2.0f);
225 }
226
227 void
228 clamp(bool do_clamp)
229 {
230 if (do_clamp) {
231 if (*this > 1.0f) {
232 *this = 1.0f;
233 } else if (*this < 0.0f) {
234 *this = 0.0f;
235 }
236 }
237 }
238
239 void
241 {
242 data &= 0x7fffffff;
243 }
244
245 void
247 {
248 data ^= 0x80000000;
249 }
250
251 private:
253
254 uint32_t
256 {
257 binary32 in;
258 in.fp32 = f;
259
260 FMT out;
261 out.storage = 0;
262
264
265 return out.storage;
266 }
267};
268
269// Unary operators
270template<typename T>
271inline T operator+(T a)
272{
273 return a;
274}
275
276template<typename T>
277inline T operator-(T a)
278{
279 // Flip sign bit
280 a.data ^= 0x80000000;
281 return a;
282}
283
284template<typename T>
285inline T operator++(T a)
286{
287 a = a + T(1.0f);
288 return a;
289}
290
291template<typename T>
292inline T operator--(T a)
293{
294 a = a - T(1.0f);
295 return a;
296}
297
298template<typename T>
299inline T operator++(T a, int)
300{
301 T original = a;
302 ++a;
303 return original;
304}
305
306template<typename T>
307inline T operator--(T a, int)
308{
309 T original = a;
310 --a;
311 return original;
312}
313
314// Math operators
315template<typename T>
316inline T operator+(T a, T b)
317{
318 return T(float(a) + float(b));
319}
320
321template<typename T>
322inline T operator-(T a, T b)
323{
324 return T(float(a) - float(b));
325}
326
327template<typename T>
328inline T operator*(T a, T b)
329{
330 return T(float(a) * float(b));
331}
332
333template<typename T>
334inline T operator/(T a, T b)
335{
336 return T(float(a) / float(b));
337}
338
339template<typename T>
340inline T operator+=(T &a, T b)
341{
342 a = a + b;
343 return a;
344}
345
346template<typename T>
347inline T operator-=(T &a, T b)
348{
349 a = a - b;
350 return a;
351}
352
353template<typename T>
354inline T operator*=(T &a, T b)
355{
356 a = a * b;
357 return a;
358}
359
360template<typename T>
361inline T operator/=(T &a, T b)
362{
363 a = a / b;
364 return a;
365}
366
367// Comparison operators
368template<typename T>
369inline bool operator<(T a, T b)
370{
371 return float(a) < float(b);
372}
373
374template<typename T>
375inline bool operator>(T a, T b)
376{
377 return float(a) > float(b);
378}
379
380template<typename T>
381inline bool operator<=(T a, T b)
382{
383 return float(a) <= float(b);
384}
385
386template<typename T>
387inline bool operator>=(T a, T b)
388{
389 return float(a) >= float(b);
390}
391
392template<typename T>
393inline bool operator==(T a, T b)
394{
395 return float(a) == float(b);
396}
397
398template<typename T>
399inline bool operator!=(T a, T b)
400{
401 return float(a) != float(b);
402}
403
404} // namespace AMDGPU
405
406} // namespace gem5
407
408#endif // __ARCH_AMDGPU_COMMON_DTYPE_MXFP_HH__
void clamp(bool do_clamp)
Definition mxfp.hh:228
mxfp(const mxfp &f)
Definition mxfp.hh:71
FMT getFmt() const
Definition mxfp.hh:115
void scaleMul(const float &f)
Definition mxfp.hh:130
void setFmt(FMT in)
Definition mxfp.hh:123
void omodModifier(unsigned omod)
Definition mxfp.hh:209
mxfp & operator=(const mxfp &f)
Definition mxfp.hh:86
uint32_t float_to_mxfp(float f)
Definition mxfp.hh:255
static constexpr int size()
Definition mxfp.hh:105
mxfp(const uint32_t &raw)
Definition mxfp.hh:62
void scaleDiv(const float &f)
Definition mxfp.hh:166
mxfp & operator=(const float &f)
Definition mxfp.hh:79
mxfp(float f)
Definition mxfp.hh:56
T operator-=(T &a, T b)
Definition mxfp.hh:347
bool operator<(T a, T b)
Definition mxfp.hh:369
bool operator==(T a, T b)
Definition mxfp.hh:393
T operator*=(T &a, T b)
Definition mxfp.hh:354
T operator--(T a)
Definition mxfp.hh:292
T operator++(T a)
Definition mxfp.hh:285
T operator*(T a, T b)
Definition mxfp.hh:328
T operator-(T a)
Definition mxfp.hh:277
union gem5::AMDGPU::binary32_u binary32
T operator+(T a)
Definition mxfp.hh:271
T operator+=(T &a, T b)
Definition mxfp.hh:340
dFMT convertMXFP(sFMT in, mxfpRoundingMode mode=roundTiesToEven, uint32_t seed=0)
bool operator!=(T a, T b)
Definition mxfp.hh:399
bool operator<=(T a, T b)
Definition mxfp.hh:381
T operator/(T a, T b)
Definition mxfp.hh:334
bool operator>=(T a, T b)
Definition mxfp.hh:387
bool operator>(T a, T b)
Definition mxfp.hh:375
T operator/=(T &a, T b)
Definition mxfp.hh:361
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > b
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 6 > f
Definition misc_types.hh:68
Bitfield< 0 > m
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36

Generated on Mon Oct 27 2025 04:12:28 for gem5 by doxygen 1.14.0