EPos + EFor (for extensions, simd vectorization, etc)
This commit is contained in:
parent
b47000d015
commit
7904d77bd8
6 changed files with 277 additions and 30 deletions
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include "macros.h"
|
||||
#include "assert.h"
|
||||
|
|
|
@ -81,10 +81,6 @@ namespace CNORXZ
|
|||
template <typename T>
|
||||
class Allocator;
|
||||
|
||||
// definition: ranges/xpr/pos_type.h
|
||||
template <class PosT>
|
||||
class CPosInterface;
|
||||
|
||||
// definition: ranges/xpr/vpos_type.h
|
||||
class VPosBase;
|
||||
|
||||
|
|
|
@ -184,6 +184,43 @@ namespace CNORXZ
|
|||
}
|
||||
|
||||
|
||||
/************
|
||||
* EFor *
|
||||
************/
|
||||
|
||||
template <SizeT N, SizeT L, class PosT, class Xpr>
|
||||
constexpr EFor<N,L,PosT,Xpr>::EFor(const IndexId<L>& id, const PosT& step, const Xpr& xpr) :
|
||||
mId(id),
|
||||
mStep(step),
|
||||
mXpr(xpr),
|
||||
mExt(mXpr.RootSteps(mId))
|
||||
{
|
||||
static_assert(is_pos_type<PosT>::value, "got non-pos type");
|
||||
}
|
||||
|
||||
template <SizeT N, SizeT L, class PosT, class Xpr>
|
||||
template <class PosT1, class PosT2>
|
||||
constexpr SizeT EFor<N,L,PosT,Xpr>::operator()(const PosT1& mlast, const PosT2& last) const
|
||||
{
|
||||
auto mpos = mkEPos<N>(mlast, mStep);
|
||||
auto pos = mkEPos<N>(last, mExt);
|
||||
return mXpr(mpos, pos);
|
||||
}
|
||||
|
||||
template <SizeT N, SizeT L, class PosT, class Xpr>
|
||||
constexpr SizeT EFor<N,L,PosT,Xpr>::operator()() const
|
||||
{
|
||||
auto mpos = mkEPos<N>(SPos<0>(), mStep);
|
||||
auto pos = mkEPos<N>(SPos<0>(), mExt);
|
||||
return mXpr(mpos, pos);
|
||||
}
|
||||
|
||||
template <SizeT N, SizeT L, class PosT, class Xpr>
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) EFor<N,L,PosT,Xpr>::rootSteps(const IndexId<I>& id) const
|
||||
{
|
||||
return mXpr.rootSteps(id);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace CNORXZ
|
|||
|
||||
private:
|
||||
SizeT mSize = 0;
|
||||
IndexId<L> mId = 0;
|
||||
IndexId<L> mId;
|
||||
Xpr mXpr;
|
||||
PosT mStep;
|
||||
typedef decltype(mXpr.rootSteps(mId)) XPosT;
|
||||
|
@ -95,7 +95,30 @@ namespace CNORXZ
|
|||
|
||||
};
|
||||
|
||||
// Extension For (Vectorization)
|
||||
template <SizeT N, SizeT L, class PosT, class Xpr>
|
||||
class EFor : public XprInterface<EFor<N,L,PosT,Xpr>>
|
||||
{
|
||||
public:
|
||||
DEFAULT_MEMBERS(EFor);
|
||||
|
||||
constexpr EFor(const IndexId<L>& id, const PosT& step, const Xpr& xpr);
|
||||
|
||||
template <class PosT1, class PosT2>
|
||||
constexpr SizeT operator()(const PosT1& mlast, const PosT2& last) const;
|
||||
|
||||
constexpr SizeT operator()() const;
|
||||
|
||||
template <SizeT I>
|
||||
constexpr decltype(auto) rootSteps(const IndexId<I>& id) const;
|
||||
|
||||
private:
|
||||
IndexId<L> mId;
|
||||
Xpr mXpr;
|
||||
PosT mStep;
|
||||
typedef decltype(mXpr.rootSteps(mId)) XPosT;
|
||||
XPosT mExt;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -98,12 +98,22 @@ namespace CNORXZ
|
|||
return UPos(mExt + in.val());
|
||||
}
|
||||
|
||||
constexpr SPos<0> UPos::operator*(const SPos<0>& a) const
|
||||
{
|
||||
return SPos<0>();
|
||||
}
|
||||
|
||||
template <class PosT>
|
||||
constexpr UPos UPos::operator*(const PosT& in) const
|
||||
{
|
||||
return UPos(mExt * in.val());
|
||||
}
|
||||
|
||||
constexpr SPos<0> UPos::operator()(const SPos<0>& a) const
|
||||
{
|
||||
return SPos<0>();
|
||||
}
|
||||
|
||||
template <class PosT>
|
||||
constexpr UPos UPos::operator()(const PosT& in) const
|
||||
{
|
||||
|
@ -485,6 +495,99 @@ namespace CNORXZ
|
|||
return DPos(mP->vextend( a ));
|
||||
}
|
||||
|
||||
/************
|
||||
* EPos *
|
||||
************/
|
||||
|
||||
template <class BPosT, class... OPosTs>
|
||||
constexpr EPos<BPosT,OPosTs...>::EPos(const BPosT& b, const OPosTs&... os) :
|
||||
BPosT(b),
|
||||
mP(os...)
|
||||
{}
|
||||
|
||||
template <class BPosT, class... OPosTs>
|
||||
constexpr EPos<BPosT,OPosTs...>::EPos(BPosT&& b, OPosTs&&... os) :
|
||||
BPosT(b),
|
||||
mP(os...)
|
||||
{}
|
||||
|
||||
template <class BPosT, class... OPosTs>
|
||||
constexpr decltype(auto) EPos<BPosT,OPosTs...>::val() const
|
||||
{
|
||||
return ival(std::index_sequence_for<OPosTs...>{});
|
||||
}
|
||||
|
||||
template <class BPosT, class... OPosTs>
|
||||
constexpr decltype(auto) EPos<BPosT,OPosTs...>::next() const
|
||||
{
|
||||
return inext(std::index_sequence_for<OPosTs...>{});
|
||||
}
|
||||
|
||||
template <class BPosT, class... OPosTs>
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) EPos<BPosT,OPosTs...>::ival(std::index_sequence<Is...> is) const
|
||||
{
|
||||
if constexpr(is_static_pos_type<EPos<BPosT,OPosTs...>>::value){
|
||||
return std::index_sequence<std::get<Is>(mP).val()...>{};
|
||||
}
|
||||
else {
|
||||
return Arr<SizeT,is.size()> { std::get<Is>(mP).val()... };
|
||||
}
|
||||
}
|
||||
|
||||
template <class BPosT, class... OPosTs>
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) EPos<BPosT,OPosTs...>::inext(std::index_sequence<Is...> is) const
|
||||
{
|
||||
typedef EPos<decltype(next()),decltype(std::get<Is>(mP).next())...> OEPosT;
|
||||
return OEPosT(next(), std::get<Is>(mP).next()...);
|
||||
}
|
||||
|
||||
/*********************************
|
||||
* Traits and Helper-Classes *
|
||||
*********************************/
|
||||
|
||||
template <SizeT N, class BPosT, class OPosT>
|
||||
decltype(auto) mkEPos(const BPosT& a, const OPosT& b)
|
||||
{
|
||||
return mkiEPos(a, b, std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <SizeT N, class BPosT, class OPosT, SizeT... Is>
|
||||
decltype(auto) mkiEPos(const BPosT& a, const OPosT& b, std::index_sequence<Is...> is)
|
||||
{
|
||||
return EPos<BPosT,decltype(b*SPos<Is>())...>(a, b*SPos<Is>()...);
|
||||
}
|
||||
|
||||
template <class OPosT1, class OPosT2, class... OPosTs>
|
||||
constexpr bool pos_type_consecutive_2<OPosT1,OPosT2,OPosTs...>::eval()
|
||||
{
|
||||
if constexpr(is_static_pos_type<OPosT1>::value and is_static_pos_type<OPosT2>::value){
|
||||
if constexpr(sizeof...(OPosTs) != 0){
|
||||
return OPosT1().val() < OPosT2().val() and pos_type_consecutive<OPosT2,OPosTs...>::value;
|
||||
}
|
||||
else {
|
||||
return OPosT1().val() < OPosT2().val();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class OPosT1, class... OPosTs>
|
||||
constexpr bool pos_type_same<OPosT1,OPosTs...>::eval()
|
||||
{
|
||||
if constexpr(is_static_pos_type<OPosT1>::value){
|
||||
if constexpr(sizeof...(OPosTs) != 0){
|
||||
return OPosT1().val() == 0 and pos_type_same<OPosTs...>::value;
|
||||
}
|
||||
else {
|
||||
return OPosT1().val() == 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,27 +7,6 @@
|
|||
namespace CNORXZ
|
||||
{
|
||||
|
||||
template <class T>
|
||||
struct is_pos_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <class T>
|
||||
struct is_scalar_pos_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <class T>
|
||||
struct is_static_pos_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <class PosT>
|
||||
struct pos_depth
|
||||
{
|
||||
pos_depth()
|
||||
{
|
||||
static_assert(is_pos_type<PosT>::value,
|
||||
"pos_depth is only defined for pos types");
|
||||
}
|
||||
|
||||
static constexpr SizeT value = 1;
|
||||
};
|
||||
|
||||
template <SizeT N>
|
||||
class SPos
|
||||
{
|
||||
|
@ -71,9 +50,13 @@ namespace CNORXZ
|
|||
template <class PosT>
|
||||
constexpr UPos operator+(const PosT& a) const;
|
||||
|
||||
constexpr SPos<0> operator*(const SPos<0>& a) const;
|
||||
|
||||
template <class PosT>
|
||||
constexpr UPos operator*(const PosT& a) const;
|
||||
|
||||
constexpr SPos<0> operator()(const SPos<0>& a) const;
|
||||
|
||||
template <class PosT>
|
||||
constexpr UPos operator()(const PosT& a) const;
|
||||
|
||||
|
@ -235,26 +218,130 @@ namespace CNORXZ
|
|||
inline DPos extend(const PosT& a) const;
|
||||
};
|
||||
|
||||
// for common call of extension vector elements
|
||||
// BPos = base pos type
|
||||
// OPos = offset pos type (i.e. step/ext * for index of lowest for layer)
|
||||
// currently EPos must be used only at the lowest for layer
|
||||
template <class BPosT, class... OPosTs>
|
||||
class EPos : public BPosT
|
||||
{
|
||||
private:
|
||||
Tuple<OPosTs...> mP;
|
||||
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) ival(std::index_sequence<Is...> is) const;
|
||||
|
||||
template <SizeT... Is>
|
||||
constexpr decltype(auto) inext(std::index_sequence<Is...> is) const;
|
||||
|
||||
public:
|
||||
DEFAULT_MEMBERS(EPos);
|
||||
|
||||
constexpr EPos(const BPosT& b, const OPosTs&... os);
|
||||
constexpr EPos(BPosT&& b, OPosTs&&... os);
|
||||
|
||||
constexpr decltype(auto) val() const;
|
||||
constexpr decltype(auto) next() const;
|
||||
};
|
||||
|
||||
/*********************************
|
||||
* Traits and Helper-Classes *
|
||||
*********************************/
|
||||
|
||||
template <class T>
|
||||
struct is_pos_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <class T>
|
||||
struct is_scalar_pos_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <class T>
|
||||
struct is_static_pos_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <class T>
|
||||
struct is_epos_type { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <class PosT>
|
||||
struct pos_depth
|
||||
{
|
||||
static constexpr SizeT value = is_pos_type<PosT>::value ? 1 : 0;
|
||||
};
|
||||
|
||||
template <class OPosT1, class OPosT2, class... OPosTs>
|
||||
struct pos_type_consecutive_2
|
||||
{
|
||||
private:
|
||||
static constexpr bool eval();
|
||||
|
||||
public:
|
||||
static constexpr bool value = eval();
|
||||
};
|
||||
|
||||
template <class OPosT1, class... OPosTs>
|
||||
struct pos_type_consecutive
|
||||
{
|
||||
static constexpr bool value = sizeof...(OPosTs) == 0 ? is_pos_type<OPosT1>::value : pos_type_consecutive_2<OPosT1,OPosTs...>::value;
|
||||
};
|
||||
|
||||
template <class OPosT1, class... OPosTs>
|
||||
struct pos_type_same
|
||||
{
|
||||
private:
|
||||
static constexpr bool eval();
|
||||
|
||||
public:
|
||||
static constexpr bool value = eval();
|
||||
};
|
||||
|
||||
template <class PosT> struct pos_type_is_consecutive { CXZ_CVAL_FALSE; };
|
||||
|
||||
template <SizeT N, class BPosT, class OPosT>
|
||||
decltype(auto) mkEPos(const BPosT& a, const OPosT& b);
|
||||
|
||||
template <SizeT N, class BPosT, class OPosT, SizeT... Is>
|
||||
decltype(auto) mkiEPos(const BPosT& a, const OPosT& b, std::index_sequence<Is...> is);
|
||||
|
||||
/**************************************************
|
||||
* Traits and Helper-Classes: Specializations *
|
||||
**************************************************/
|
||||
|
||||
template <SizeT N> struct is_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
|
||||
template <SizeT N> struct is_scalar_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
|
||||
template <SizeT N> struct is_static_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <> struct is_pos_type<UPos> { CXZ_CVAL_TRUE; };
|
||||
template <> struct is_scalar_pos_type<UPos> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <> struct is_pos_type<FPos> { CXZ_CVAL_TRUE; };
|
||||
template <> struct is_scalar_pos_type<FPos> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <SizeT N, SizeT... Ms> struct is_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
|
||||
template <SizeT N, SizeT... Ms> struct is_scalar_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
|
||||
template <SizeT N, SizeT... Ms> struct is_static_pos_type<SFPos<N,Ms...>> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <class BPosT, class NPosT> struct is_pos_type<MPos<BPosT,NPosT>> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <> struct is_pos_type<DPos> { CXZ_CVAL_TRUE; };
|
||||
template <> struct is_pos_type<DPosRef> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <class BPosT, class... OPosTs> struct is_pos_type<EPos<BPosT,OPosTs...>> { CXZ_CVAL_TRUE; };
|
||||
template <class BPosT, class... OPosTs> struct is_scalar_pos_type<EPos<BPosT,OPosTs...>>
|
||||
{ static constexpr bool value = is_scalar_pos_type<BPosT>::value; };
|
||||
template <class BPosT, class... OPosTs> struct is_static_pos_type<EPos<BPosT,OPosTs...>>
|
||||
{ static constexpr bool value = is_static_pos_type<BPosT>::value and (is_static_pos_type<OPosTs>::value and ...); };
|
||||
template <class BPosT, class... OPosTs> struct is_epos_type<EPos<BPosT,OPosTs...>> { CXZ_CVAL_TRUE; };
|
||||
|
||||
template <class BPosT, class NPosT>
|
||||
struct pos_depth<MPos<BPosT,NPosT>>
|
||||
{
|
||||
static constexpr SizeT value = pos_depth<NPosT>::value + 1;
|
||||
};
|
||||
|
||||
template <class BPosT, class... OPosTs>
|
||||
struct pos_type_is_consecutive<EPos<BPosT,OPosTs...>>
|
||||
{
|
||||
static constexpr bool value = pos_type_is_consecutive<OPosTs...>::value;
|
||||
};
|
||||
|
||||
} // end namespace CNORXZInternal
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue