6 #include "../ProxyRefOpMixin.hpp"
15 #include <type_traits>
27 inline static constexpr
unsigned mantissa = 23;
28 inline static constexpr
unsigned exponent = 8;
34 inline static constexpr
unsigned mantissa = 52;
35 inline static constexpr
unsigned exponent = 11;
38 template<
typename Integral>
41 unsigned inMantissaBits,
42 unsigned inExponentBits,
43 unsigned outMantissaBits,
44 unsigned outExponentBits) -> Integral
46 const Integral inMantissaMask = (Integral{1} << inMantissaBits) - 1u;
47 const Integral inExponentMask = (Integral{1} << inExponentBits) - 1u;
49 Integral inMantissa = inFloat & inMantissaMask;
50 const Integral inExponent = (inFloat >> inMantissaBits) & inExponentMask;
51 const Integral inSign = inFloat >> inExponentBits >> inMantissaBits;
53 const Integral outExponentMask = (Integral{1} << outExponentBits) - 1u;
56 outExponent = outExponentMask;
61 const int outExponentMax = 1 << (outExponentBits - 1);
62 const int outExponentMin = -outExponentMax + 1;
63 const int outExponentBias = outExponentMax - 1;
64 const int inExponentBias = (1 << (inExponentBits - 1)) - 1;
66 const int exponent =
static_cast<int>(inExponent) - inExponentBias;
67 const auto clampedExponent = std::clamp(exponent, outExponentMin, outExponentMax);
68 if(clampedExponent == outExponentMin || clampedExponent == outExponentMax)
70 outExponent = clampedExponent + outExponentBias;
72 assert(outExponent < (1u << outExponentBits));
74 const Integral packedMantissa = inMantissaBits > outMantissaBits
75 ? inMantissa >> (inMantissaBits - outMantissaBits)
76 : inMantissa << (outMantissaBits - inMantissaBits);
77 const Integral packedExponent = outExponent << outMantissaBits;
78 const Integral packedSign = inSign << outExponentBits << outMantissaBits;
80 const auto outFloat =
static_cast<Integral
>(packedMantissa | packedExponent | packedSign);
85 template<
typename E,
typename M>
91 template<auto E, auto M>
104 template<
typename Float,
typename StoredIntegralCV,
typename VHExp,
typename VHMan,
typename SizeType>
109 ,
ProxyRefOpMixin<BitPackedFloatRef<Float, StoredIntegralCV, VHExp, VHMan, SizeType>, Float>
113 std::is_same_v<Float, float> || std::is_same_v<Float, double>,
114 "Types other than float or double are not implemented yet");
116 std::numeric_limits<Float>::is_iec559,
117 "Only IEEE754/IEC559 floating point formats are implemented");
119 using FloatBits = std::conditional_t<std::is_same_v<Float, float>, std::uint32_t, std::uint64_t>;
124 decltype(
integBits(std::declval<VHExp>(), std::declval<VHMan>())),
160 const FloatBits packedFloat = intref;
161 const FloatBits unpackedFloat
162 =
repackFloat(packedFloat, VHMan::value(), VHExp::value(), Bits::mantissa, Bits::exponent);
171 FloatBits unpackedFloat = 0;
173 const FloatBits packedFloat
174 =
repackFloat(unpackedFloat, Bits::mantissa, Bits::exponent, VHMan::value(), VHExp::value());
175 intref = packedFloat;
180 template<
typename RecordDim>
182 = std::conditional_t<mp_contains<FlatRecordDim<RecordDim>,
double>::value, std::uint64_t, std::uint32_t>;
201 typename TArrayExtents,
203 typename ExponentBits =
typename TArrayExtents::value_type,
204 typename MantissaBits = ExponentBits,
216 using size_type =
typename TArrayExtents::value_type;
221 static constexpr std::size_t blobCount = mp_size<FlatRecordDim<TRecordDim>>::value;
226 return static_cast<size_type
>(VHExp::value());
232 return static_cast<size_type
>(VHMan::value());
237 TArrayExtents extents = {},
238 ExponentBits exponentBits = {},
239 MantissaBits mantissaBits = {},
242 , VHExp{exponentBits}
243 , VHMan{mantissaBits}
245 assert(this->exponentBits() > 0);
249 constexpr
auto blobSize(size_type )
const -> size_type
251 constexpr
auto bitsPerStoredIntegral =
static_cast<size_type
>(
sizeof(
StoredIntegral) * CHAR_BIT);
252 const auto bitsNeeded
257 template<std::size_t... RecordCoords>
263 template<std::size_t... RecordCoords,
typename Blobs>
277 reinterpret_cast<QualifiedStoredIntegral*
>(&blobs[blob][0]),
279 static_cast<const VHExp&
>(*
this),
280 static_cast<const VHMan&
>(*this)};
289 typename ExponentBits = unsigned,
290 typename MantissaBits = ExponentBits,
291 typename LinearizeArrayIndexFunctor = LinearizeArrayIndexRight,
292 typename StoredIntegral =
void>
295 template<
typename ArrayExtents,
typename RecordDim>
301 LinearizeArrayIndexFunctor,
303 !std::is_void_v<StoredIntegral>,
309 template<
typename Mapping>
313 template<
typename... Ts>
318 typename TArrayExtents,
320 typename ExponentBits =
typename TArrayExtents::value_type,
321 typename MantissaBits = ExponentBits,
334 using size_type =
typename TArrayExtents::value_type;
340 using Permuter = PermuteFields<FlatRecordDim<TRecordDim>>;
341 static constexpr std::size_t blobCount = 1;
346 return static_cast<size_type
>(VHExp::value());
352 return static_cast<size_type
>(VHMan::value());
357 TArrayExtents extents = {},
358 ExponentBits exponentBits = {},
359 MantissaBits mantissaBits = {},
362 , VHExp{exponentBits}
363 , VHMan{mantissaBits}
365 assert(this->exponentBits() > 0);
369 constexpr
auto blobSize(size_type )
const -> size_type
371 constexpr
auto bitsPerStoredIntegral =
static_cast<size_type
>(
sizeof(
StoredIntegral) * CHAR_BIT);
372 const auto bitsNeeded = TLinearizeArrayIndexFunctor{}.size(Base::extents())
373 *
static_cast<size_type
>(exponentBits() + mantissaBits() + 1)
374 *
static_cast<size_type
>(flatFieldCount<TRecordDim>);
378 template<std::size_t... RecordCoords>
384 template<std::size_t... RecordCoords,
typename Blobs>
390 constexpr
auto flatFieldIndex =
static_cast<size_type
>(
392 const auto bitOffset = ((TLinearizeArrayIndexFunctor{}(ai, Base::extents())
393 *
static_cast<size_type
>(flatFieldCount<TRecordDim>))
395 *
static_cast<size_type
>(exponentBits() + mantissaBits() + 1);
401 reinterpret_cast<QualifiedStoredIntegral*
>(&blobs[0][0]),
403 static_cast<const VHExp&
>(*
this),
404 static_cast<const VHMan&
>(*this)};
411 typename ExponentBits = unsigned,
412 typename MantissaBits = ExponentBits,
413 typename LinearizeArrayIndexFunctor = LinearizeArrayIndexRight,
414 template<
typename>
typename PermuteFields = PermuteFieldsInOrder,
415 typename StoredIntegral =
void>
418 template<
typename ArrayExtents,
typename RecordDim>
424 LinearizeArrayIndexFunctor,
427 !std::is_void_v<StoredIntegral>,
433 template<
typename Mapping>
440 typename ExponentBits,
441 typename MantissaBits,
442 typename LinearizeArrayIndexFunctor,
444 typename PermuteFields,
445 typename StoredIntegral>
451 LinearizeArrayIndexFunctor,
#define LLAMA_UNLIKELY
Expands to unlikely if [[unlikely]] supported by the compiler. Use as [[LLAMA_UNLIKELY]].
#define LLAMA_DECLSPEC_EMPTY_BASES
#define LLAMA_BEGIN_SUPPRESS_HOST_DEVICE_WARNING
#define LLAMA_FN_HOST_ACC_INLINE
#define LLAMA_END_SUPPRESS_HOST_DEVICE_WARNING
std::conditional_t< mp_contains< FlatRecordDim< RecordDim >, double >::value, std::uint64_t, std::uint32_t > StoredIntegralFor
auto repackFloat(Integral inFloat, unsigned inMantissaBits, unsigned inExponentBits, unsigned outMantissaBits, unsigned outExponentBits) -> Integral
constexpr bool isBitPackedFloatAoS
constexpr bool isBitPackedFloatSoA
std::integral_constant< decltype(V), V > Constant
Used as template argument to specify a constant/compile-time value.
ArrayExtents(Args...) -> ArrayExtents< typename internal::IndexTypeFromArgs< std::size_t, Args... >::type,(Args{}, dyn)... >
constexpr std::size_t flatRecordCoord
std::conditional_t< std::is_const_v< FromT >, const ToT, ToT > CopyConst
Alias for ToT, adding const if FromT is const qualified.
constexpr auto roundUpToMultiple(Integral n, Integral mult) -> Integral
Returns the integral n rounded up to be a multiple of mult.
typename internal::GetTypeImpl< RecordDim, RecordCoordOrTags... >::type GetType
CRTP mixin for proxy reference types to support all compound assignment and increment/decrement opera...
constexpr auto value() const
PermuteFields< FlatRecordDim< TRecordDim > > Permuter
constexpr BitPackedFloatAoS(TArrayExtents extents={}, ExponentBits exponentBits={}, MantissaBits mantissaBits={}, TRecordDim={})
constexpr auto mantissaBits() const -> size_type
TStoredIntegral StoredIntegral
static constexpr auto isComputed(RecordCoord< RecordCoords... >)
TLinearizeArrayIndexFunctor LinearizeArrayIndexFunctor
constexpr auto compute(typename Base::ArrayIndex ai, RecordCoord< RecordCoords... >, Blobs &blobs) const
constexpr auto exponentBits() const -> size_type
constexpr auto blobSize(size_type) const -> size_type
static constexpr auto isComputed(RecordCoord< RecordCoords... >)
TStoredIntegral StoredIntegral
constexpr auto compute(typename Base::ArrayIndex ai, RecordCoord< RecordCoords... >, Blobs &blobs) const
constexpr auto exponentBits() const -> size_type
TLinearizeArrayIndexFunctor LinearizeArrayIndexFunctor
constexpr BitPackedFloatSoA(TArrayExtents extents={}, ExponentBits exponentBits={}, MantissaBits mantissaBits={}, TRecordDim={})
constexpr auto mantissaBits() const -> size_type
constexpr auto blobSize(size_type) const -> size_type
typename ArrayExtents::Index ArrayIndex
Retains the order of the record dimension's fields.
constexpr auto operator=(Float f) -> BitPackedFloatRef &
constexpr BitPackedFloatRef(StoredIntegralCV *p, SizeType bitOffset, VHExp vhExp, VHMan vhMan)
constexpr auto operator=(const BitPackedFloatRef &other) -> BitPackedFloatRef &
BitPackedFloatRef(const BitPackedFloatRef &)=default