/** * @file RandUtils.h * @author bab2min (bab2min@gmail.com) * @brief * @version 0.4.0 * @date 2021-09-17 * * @copyright Copyright (c) 2020-2021 * */ #ifndef EIGENRAND_RAND_UTILS_NEON_H #define EIGENRAND_RAND_UTILS_NEON_H #include namespace Eigen { namespace internal { template struct RawbitsMaker { EIGEN_STRONG_INLINE Packet4i rawbits(Rng& rng) { if (sizeof(RngResult) == 8) { uint64_t v[2]; v[0] = rng(); v[1] = rng(); return vld1q_s32((int32_t*)v); } else { uint32_t v[4]; v[0] = rng(); v[1] = rng(); v[2] = rng(); v[3] = rng(); return vld1q_s32((int32_t*)v); } } EIGEN_STRONG_INLINE Packet4i rawbits_34(Rng& rng) { if (sizeof(RngResult) == 8) { uint64_t v[2]; v[0] = rng(); v[1] = rng(); return vld1q_s32((int32_t*)v); } else { uint32_t v[4]; v[0] = rng(); v[1] = rng(); v[2] = rng(); v[3] = rng(); return vld1q_s32((int32_t*)v); } } EIGEN_STRONG_INLINE Packet4i rawbits_half(Rng& rng) { if (sizeof(decltype(rng())) == 8) { uint64_t v[2]; v[0] = rng(); v[1] = 0; return vld1q_s32((int32_t*)v); } else { uint32_t v[4]; v[0] = rng(); v[1] = rng(); v[2] = 0; v[3] = 0; return vld1q_s32((int32_t*)v); } } }; template struct RawbitsMaker { EIGEN_STRONG_INLINE Packet4i rawbits(Rng& rng) { return rng(); } EIGEN_STRONG_INLINE Packet4i rawbits_34(Rng& rng) { return rng(); } EIGEN_STRONG_INLINE Packet4i rawbits_half(Rng& rng) { return rng(); } }; template struct UniformRealUtils : public RawbitsMaker { EIGEN_STRONG_INLINE Packet4f zero_to_one(Rng& rng) { return pdiv((Packet4f)vcvtq_f32_s32(pand(this->rawbits(rng), pset1(0x7FFFFFFF))), pset1(0x7FFFFFFF)); } EIGEN_STRONG_INLINE Packet4f uniform_real(Rng& rng) { return bit_to_ur_float(this->rawbits_34(rng)); } }; template struct functor_traits > { enum { Cost = HugeCost, PacketAccess = 0, IsRepeatable = false }; }; } } #endif