Skip to content

Commit

Permalink
Updates for XSIMD
Browse files Browse the repository at this point in the history
  • Loading branch information
Pencilcaseman committed Aug 17, 2023
1 parent b0ce70f commit f988b68
Show file tree
Hide file tree
Showing 4 changed files with 1,161 additions and 1,082 deletions.
26 changes: 13 additions & 13 deletions librapid/include/librapid/core/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,68 +165,68 @@
# define LIBRAPID_AVX512
# define LIBRAPID_ARCH ARCH_AVX512_2
# define LIBRAPID_ARCH_NAME "AVX512"
# define LIBRAPID_DEFAULT_MEM_ALIGN 256
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
#elif defined(__AVX512F__) || defined(__AVX512__)
# define LIBRAPID_AVX512
# define LIBRAPID_ARCH ARCH_AVX512
# define LIBRAPID_ARCH_NAME "AVX512"
# define LIBRAPID_DEFAULT_MEM_ALIGN 256
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
#elif defined(__AVX2__)
# define LIBRAPID_AVX2
# define LIBRAPID_ARCH ARCH_AVX2
# define LIBRAPID_ARCH_NAME "AVX2"
# define LIBRAPID_DEFAULT_MEM_ALIGN 128
# define LIBRAPID_DEFAULT_MEM_ALIGN 32
#elif defined(__AVX__)
# define LIBRAPID_AVX
# define LIBRAPID_ARCH ARCH_AVX
# define LIBRAPID_ARCH_NAME "AVX"
# define LIBRAPID_DEFAULT_MEM_ALIGN 128
# define LIBRAPID_DEFAULT_MEM_ALIGN 32
#elif defined(__SSE4_2__)
# define LIBRAPID_SSE42
# define LIBRAPID_ARCH ARCH_SSE4_2
# define LIBRAPID_ARCH_NAME "SSE4.2"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
#elif defined(__SSE4_1__)
# define LIBRAPID_SSE41
# define LIBRAPID_ARCH ARCH_SSE4_1
# define LIBRAPID_ARCH_NAME "SSE4.1"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
#elif defined(__SSSE3__)
# define LIBRAPID_SSSE3
# define LIBRAPID_ARCH ARCH_SSSE3
# define LIBRAPID_ARCH_NAME "SSSE3"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
#elif defined(__SSE3__)
# define LIBRAPID_SSE3
# define LIBRAPID_ARCH ARCH_SSE3
# define LIBRAPID_ARCH_NAME "SSE3"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
#elif defined(__SSE2__) || defined(__x86_64__)
# define LIBRAPID_SSE2
# define LIBRAPID_ARCH ARCH_SSE2
# define LIBRAPID_ARCH_NAME "SSE2"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
#elif defined(__SSE__)
# define LIBRAPID_SSE
# define LIBRAPID_ARCH ARCH_SSE
# define LIBRAPID_ARCH_NAME "SSE"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
#elif defined(_M_IX86_FP) // Defined in MS compiler. 1: SSE, 2: SSE2
# if _M_IX86_FP == 1
# define LIBRAPID_SSE
# define LIBRAPID_ARCH ARCH_SSE
# define LIBRAPID_ARCH_NAME "SSE"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
# elif _M_IX86_FP == 2
# define LIBRAPID_SSE2
# define LIBRAPID_ARCH ARCH_SSE2
# define LIBRAPID_ARCH_NAME "SSE2"
# define LIBRAPID_DEFAULT_MEM_ALIGN 64
# define LIBRAPID_DEFAULT_MEM_ALIGN 16
# endif // _M_IX86_FP
#else
# define LIBRAPID_ARCH ARCH_NONE
# define LIBRAPID_ARCH_NAME "None"
# define LIBRAPID_DEFAULT_MEM_ALIGN 32
# define LIBRAPID_DEFAULT_MEM_ALIGN 1
#endif // Instruction set detection

// Check for 32bit vs 64bit
Expand Down
4 changes: 0 additions & 4 deletions librapid/include/librapid/core/librapidPch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@

#include <xsimd/xsimd.hpp>

#if defined(_MSC_VER)
# pragma warning(pop)
#endif

// MPFR (modified) -- arbitrary precision floating point numbers
#if defined(LIBRAPID_USE_MULTIPREC)
# include <mpirxx.h>
Expand Down
237 changes: 119 additions & 118 deletions librapid/include/librapid/math/vectorForward.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,124 +2,125 @@
#define LIBRAPID_MATH_VECTOR_FORWARD_HPP

namespace librapid {
namespace vectorDetail {
template<typename T, size_t N>
struct GenericVectorStorage;

template<typename T, size_t N>
struct SimdVectorStorage;

template<typename T, size_t N>
struct VectorStorageType {
using type = std::conditional_t<(typetraits::TypeInfo<T>::packetWidth > 1),
SimdVectorStorage<T, N>, GenericVectorStorage<T, N>>;
};

template<typename Storage0, typename Storage1>
auto vectorStorageTypeMerger() {
using Scalar0 = typename typetraits::TypeInfo<Storage0>::Scalar;
using Scalar1 = typename typetraits::TypeInfo<Storage1>::Scalar;
static constexpr size_t packetWidth0 = typetraits::TypeInfo<Scalar0>::packetWidth;
static constexpr size_t packetWidth1 = typetraits::TypeInfo<Scalar1>::packetWidth;
if constexpr (packetWidth0 > 1 && packetWidth1 > 1) {
return SimdVectorStorage<typename Storage0::Scalar, Storage0::dims> {};
} else {
return GenericVectorStorage<typename Storage0::Scalar, Storage0::dims> {};
}
}

template<typename T, size_t N>
using VectorStorage = typename VectorStorageType<T, N>::type;

template<typename Storage0, typename Storage1>
using VectorStorageMerger = decltype(vectorStorageTypeMerger<Storage0, Storage1>());

template<typename Derived>
class VectorBase {
public:
using Scalar = typename typetraits::TypeInfo<Derived>::Scalar;
using IndexType = typename typetraits::TypeInfo<Derived>::IndexType;
using IndexTypeConst = typename typetraits::TypeInfo<Derived>::IndexTypeConst;
using GetType = typename typetraits::TypeInfo<Derived>::GetType;

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE const auto &derived() const {
return static_cast<const Derived &>(*this);
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE auto &derived() {
return static_cast<Derived &>(*this);
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE auto eval() const { return derived(); }

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE virtual IndexTypeConst
operator[](int64_t index) const {
return derived()[index];
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE virtual IndexType operator[](int64_t index) {
return derived()[index];
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst x() const {
return derived()[0];
}
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst y() const {
return derived()[1];
}
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst z() const {
return derived()[2];
}
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst w() const {
return derived()[3];
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType x() { return derived()[0]; }
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType y() { return derived()[1]; }
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType z() { return derived()[2]; }
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType w() { return derived()[3]; }

LIBRAPID_NODISCARD virtual std::string str(const std::string &format) const {
return derived().str(format);
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE virtual GetType _get(size_t index) const {
return derived()._get(index);
}
};
} // namespace vectorDetail

template<typename ScalarType, size_t NumDims>
class Vector;

namespace vectorDetail {
template<typename LHS, typename RHS, typename Op>
struct BinaryVecOp;

template<typename Val, typename Op>
struct UnaryVecOp;

template<typename Scalar, size_t N, typename LHS, typename RHS, typename Op,
size_t... Indices>
LIBRAPID_ALWAYS_INLINE void assignImpl(Vector<Scalar, N> &dst,
const BinaryVecOp<LHS, RHS, Op> &src,
std::index_sequence<Indices...>);

template<typename Scalar, size_t N, typename Val, typename Op, size_t... Indices>
LIBRAPID_ALWAYS_INLINE void assignImpl(Vector<Scalar, N> &dst,
const UnaryVecOp<Val, Op> &src,
std::index_sequence<Indices...>);

template<typename Scalar, size_t N, typename LHS, typename RHS, typename Op>
LIBRAPID_ALWAYS_INLINE void assign(Vector<Scalar, N> &dst,
const BinaryVecOp<LHS, RHS, Op> &src);

template<typename Scalar, size_t N, typename Val, typename Op>
LIBRAPID_ALWAYS_INLINE void assign(Vector<Scalar, N> &dst, const UnaryVecOp<Val, Op> &src);
} // namespace vectorDetail

template<typename ScalarType, size_t NumDims>
class Vector;
namespace vectorDetail {
template<typename T, size_t N>
struct GenericVectorStorage;

template<typename T, size_t N>
struct SimdVectorStorage;

template<typename T, size_t N>
struct VectorStorageType {
using type = std::conditional_t<(typetraits::TypeInfo<T>::packetWidth > 1),
SimdVectorStorage<T, N>, GenericVectorStorage<T, N>>;
};

template<typename Storage0, typename Storage1>
auto vectorStorageTypeMerger() {
using Scalar0 = typename typetraits::TypeInfo<Storage0>::Scalar;
using Scalar1 = typename typetraits::TypeInfo<Storage1>::Scalar;
static constexpr size_t packetWidth0 = typetraits::TypeInfo<Scalar0>::packetWidth;
static constexpr size_t packetWidth1 = typetraits::TypeInfo<Scalar1>::packetWidth;
if constexpr (packetWidth0 > 1 && packetWidth1 > 1) {
return SimdVectorStorage<typename Storage0::Scalar, Storage0::dims> {};
} else {
return GenericVectorStorage<typename Storage0::Scalar, Storage0::dims> {};
}
}

template<typename T, size_t N>
using VectorStorage = typename VectorStorageType<T, N>::type;

template<typename Storage0, typename Storage1>
using VectorStorageMerger = decltype(vectorStorageTypeMerger<Storage0, Storage1>());

template<typename Derived>
class VectorBase {
public:
using Scalar = typename typetraits::TypeInfo<Derived>::Scalar;
using IndexType = typename typetraits::TypeInfo<Derived>::IndexType;
using IndexTypeConst = typename typetraits::TypeInfo<Derived>::IndexTypeConst;
using GetType = typename typetraits::TypeInfo<Derived>::GetType;

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE const auto &derived() const {
return static_cast<const Derived &>(*this);
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE auto &derived() {
return static_cast<Derived &>(*this);
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE auto eval() const { return derived(); }

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE virtual IndexTypeConst
operator[](int64_t index) const {
return derived()[index];
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE virtual IndexType operator[](int64_t index) {
return derived()[index];
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst x() const {
return derived()[0];
}
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst y() const {
return derived()[1];
}
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst z() const {
return derived()[2];
}
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexTypeConst w() const {
return derived()[3];
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType x() { return derived()[0]; }
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType y() { return derived()[1]; }
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType z() { return derived()[2]; }
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE IndexType w() { return derived()[3]; }

template<typename T_, typename Char, typename Ctx>
void str(const fmt::formatter<T_, Char> &formatter, Ctx &ctx) const {
derived().str(formatter, ctx);
}

LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE virtual GetType _get(size_t index) const {
return derived()._get(index);
}
};
} // namespace vectorDetail

template<typename ScalarType, size_t NumDims>
class Vector;

namespace vectorDetail {
template<typename LHS, typename RHS, typename Op>
struct BinaryVecOp;

template<typename Val, typename Op>
struct UnaryVecOp;

template<typename Scalar, size_t N, typename LHS, typename RHS, typename Op,
size_t... Indices>
LIBRAPID_ALWAYS_INLINE void assignImpl(Vector<Scalar, N> &dst,
const BinaryVecOp<LHS, RHS, Op> &src,
std::index_sequence<Indices...>);

template<typename Scalar, size_t N, typename Val, typename Op, size_t... Indices>
LIBRAPID_ALWAYS_INLINE void assignImpl(Vector<Scalar, N> &dst,
const UnaryVecOp<Val, Op> &src,
std::index_sequence<Indices...>);

template<typename Scalar, size_t N, typename LHS, typename RHS, typename Op>
LIBRAPID_ALWAYS_INLINE void assign(Vector<Scalar, N> &dst,
const BinaryVecOp<LHS, RHS, Op> &src);

template<typename Scalar, size_t N, typename Val, typename Op>
LIBRAPID_ALWAYS_INLINE void assign(Vector<Scalar, N> &dst, const UnaryVecOp<Val, Op> &src);
} // namespace vectorDetail

template<typename ScalarType, size_t NumDims>
class Vector;
} // namespace librapid

#endif // LIBRAPID_MATH_VECTOR_FORWARD_HPP
Loading

0 comments on commit f988b68

Please sign in to comment.