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 <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
|
@ -81,10 +81,6 @@ namespace CNORXZ
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Allocator;
|
class Allocator;
|
||||||
|
|
||||||
// definition: ranges/xpr/pos_type.h
|
|
||||||
template <class PosT>
|
|
||||||
class CPosInterface;
|
|
||||||
|
|
||||||
// definition: ranges/xpr/vpos_type.h
|
// definition: ranges/xpr/vpos_type.h
|
||||||
class VPosBase;
|
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
|
#endif
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace CNORXZ
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SizeT mSize = 0;
|
SizeT mSize = 0;
|
||||||
IndexId<L> mId = 0;
|
IndexId<L> mId;
|
||||||
Xpr mXpr;
|
Xpr mXpr;
|
||||||
PosT mStep;
|
PosT mStep;
|
||||||
typedef decltype(mXpr.rootSteps(mId)) XPosT;
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,12 +97,22 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
return UPos(mExt + in.val());
|
return UPos(mExt + in.val());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr SPos<0> UPos::operator*(const SPos<0>& a) const
|
||||||
|
{
|
||||||
|
return SPos<0>();
|
||||||
|
}
|
||||||
|
|
||||||
template <class PosT>
|
template <class PosT>
|
||||||
constexpr UPos UPos::operator*(const PosT& in) const
|
constexpr UPos UPos::operator*(const PosT& in) const
|
||||||
{
|
{
|
||||||
return UPos(mExt * in.val());
|
return UPos(mExt * in.val());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr SPos<0> UPos::operator()(const SPos<0>& a) const
|
||||||
|
{
|
||||||
|
return SPos<0>();
|
||||||
|
}
|
||||||
|
|
||||||
template <class PosT>
|
template <class PosT>
|
||||||
constexpr UPos UPos::operator()(const PosT& in) const
|
constexpr UPos UPos::operator()(const PosT& in) const
|
||||||
|
@ -477,14 +487,107 @@ namespace CNORXZ
|
||||||
VPosRef<PosT> b(&a);
|
VPosRef<PosT> b(&a);
|
||||||
return DPos(mP->vexec( &b ));
|
return DPos(mP->vexec( &b ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class PosT>
|
template <class PosT>
|
||||||
inline DPos DPosRef::extend(const PosT& a) const
|
inline DPos DPosRef::extend(const PosT& a) const
|
||||||
{
|
{
|
||||||
return DPos(mP->vextend( a ));
|
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
|
#endif
|
||||||
|
|
|
@ -7,27 +7,6 @@
|
||||||
namespace CNORXZ
|
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>
|
template <SizeT N>
|
||||||
class SPos
|
class SPos
|
||||||
{
|
{
|
||||||
|
@ -71,9 +50,13 @@ namespace CNORXZ
|
||||||
template <class PosT>
|
template <class PosT>
|
||||||
constexpr UPos operator+(const PosT& a) const;
|
constexpr UPos operator+(const PosT& a) const;
|
||||||
|
|
||||||
|
constexpr SPos<0> operator*(const SPos<0>& a) const;
|
||||||
|
|
||||||
template <class PosT>
|
template <class PosT>
|
||||||
constexpr UPos operator*(const PosT& a) const;
|
constexpr UPos operator*(const PosT& a) const;
|
||||||
|
|
||||||
|
constexpr SPos<0> operator()(const SPos<0>& a) const;
|
||||||
|
|
||||||
template <class PosT>
|
template <class PosT>
|
||||||
constexpr UPos operator()(const PosT& a) const;
|
constexpr UPos operator()(const PosT& a) const;
|
||||||
|
|
||||||
|
@ -234,27 +217,131 @@ namespace CNORXZ
|
||||||
template <class PosT>
|
template <class PosT>
|
||||||
inline DPos extend(const PosT& a) const;
|
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_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_scalar_pos_type<SPos<N>> { CXZ_CVAL_TRUE; };
|
||||||
template <SizeT N> struct is_static_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_pos_type<UPos> { CXZ_CVAL_TRUE; };
|
||||||
template <> struct is_scalar_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_pos_type<FPos> { CXZ_CVAL_TRUE; };
|
||||||
template <> struct is_scalar_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_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_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 <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 <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<DPos> { CXZ_CVAL_TRUE; };
|
||||||
template <> struct is_pos_type<DPosRef> { 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>
|
template <class BPosT, class NPosT>
|
||||||
struct pos_depth<MPos<BPosT,NPosT>>
|
struct pos_depth<MPos<BPosT,NPosT>>
|
||||||
{
|
{
|
||||||
static constexpr SizeT value = pos_depth<NPosT>::value + 1;
|
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
|
} // end namespace CNORXZInternal
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue