more operation tests + fix SFor (compatibility with For) + more RIndex utils

This commit is contained in:
Christian Zimmermann 2024-04-28 20:06:00 +02:00
parent af32689c00
commit be33c429bf
12 changed files with 177 additions and 31 deletions

View file

@ -379,6 +379,12 @@ namespace CNORXZ
return OpRoot<T,IndexT>(a, ind); return OpRoot<T,IndexT>(a, ind);
} }
template <typename T, class IndexT>
constexpr decltype(auto) oproot(T* a, const Sptr<IndexT>& ind)
{
return OpRoot<T,IndexT>(a, ind);
}
/*=================+ /*=================+
| Operation | | Operation |
+=================*/ +=================*/

View file

@ -217,6 +217,9 @@ namespace CNORXZ
template <typename T, class IndexT> template <typename T, class IndexT>
constexpr decltype(auto) oproot(ArrayBase<T>& a, const Sptr<IndexT>& ind); constexpr decltype(auto) oproot(ArrayBase<T>& a, const Sptr<IndexT>& ind);
template <typename T, class IndexT>
constexpr decltype(auto) oproot(T* a, const Sptr<IndexT>& ind);
template <class F, class... Ops> template <class F, class... Ops>
class Operation : public OpInterface<Operation<F,Ops...>> class Operation : public OpInterface<Operation<F,Ops...>>
{ {

View file

@ -150,7 +150,9 @@ namespace CNORXZ
constexpr SPos<I> i; constexpr SPos<I> i;
const auto pos = last + mExt( i ); const auto pos = last + mExt( i );
if constexpr(I < N-1){ if constexpr(I < N-1){
return mF(mXpr(pos),exec<I+1>(last)); auto x = mXpr(pos);
mF(x,exec<I+1>(last));
return x;
} }
else { else {
return mXpr(pos); return mXpr(pos);
@ -164,7 +166,9 @@ namespace CNORXZ
constexpr SPos<I> i; constexpr SPos<I> i;
const auto pos = mExt( i ); const auto pos = mExt( i );
if constexpr(I < N-1){ if constexpr(I < N-1){
return mF(mXpr(pos),exec<I+1>()); auto x = mXpr(pos);
mF(x,exec<I+1>());
return x;
} }
else { else {
return mXpr(pos); return mXpr(pos);

View file

@ -152,7 +152,7 @@ namespace CNORXZ
typedef typename std::remove_reference<decltype(*pack[CSizeT<0>{}])>::type I0; typedef typename std::remove_reference<decltype(*pack[CSizeT<0>{}])>::type I0;
if constexpr(is_rank_index<I0>::value){ if constexpr(is_rank_index<I0>::value){
// preliminary: // preliminary:
CXZ_ASSERT(this->formatIsTrivial(), CXZ_ASSERT(mA->formatIsTrivial(),
"array has non-trivial format, rank operations require trivial format"); "array has non-trivial format, rank operations require trivial format");
auto ri = pack[CSizeT<0>{}]; auto ri = pack[CSizeT<0>{}];
auto li = iter<1,sizeof...(Indices)> auto li = iter<1,sizeof...(Indices)>
@ -235,15 +235,15 @@ namespace CNORXZ
template <typename T> template <typename T>
const Vector<const T*>& RCArray<T>::buffermap() const const Vector<const T*>& RCArray<T>::buffermap() const
{ {
return mBuf; return mMap;
} }
template <typename T> template <typename T>
template <class TarI, class RTarI, class SrcI, class RSrcI, class I> template <class LoopI, class SrcI, class RSrcI, class I>
void RCArray<T>::load(const Sptr<RIndex<TarI,RTarI>>& lpi, const Sptr<RIndex<SrcI,RSrcI>>& ai, void RCArray<T>::load(const Sptr<LoopI>& lpi, const Sptr<RIndex<SrcI,RSrcI>>& ai,
const Sptr<I>& i, const Sptr<Vector<SizeT>>& imap) const const Sptr<I>& i, const Sptr<Vector<SizeT>>& imap) const
{ {
mA->checkFormatCompatibility(ai->local()*i); mA->checkFormatCompatibility(mindex(ai->local()*i));
const SizeT blocks = i->pmax().val(); const SizeT blocks = i->pmax().val();
setupBuffer(lpi, ai, imap, *mA, mBuf, mMap, blocks); setupBuffer(lpi, ai, imap, *mA, mBuf, mMap, blocks);
} }

View file

@ -130,8 +130,8 @@ namespace CNORXZ
@param i Index for non-ranked dimensions. @param i Index for non-ranked dimensions.
@param imap Index position map. @param imap Index position map.
*/ */
template <class TarI, class RTarI, class SrcI, class RSrcI, class I> template <class LoopI, class SrcI, class RSrcI, class I>
void load(const Sptr<RIndex<TarI,RTarI>>& lpi, const Sptr<RIndex<SrcI,RSrcI>>& ai, void load(const Sptr<LoopI>& lpi, const Sptr<RIndex<SrcI,RSrcI>>& ai,
const Sptr<I>& i, const Sptr<Vector<SizeT>>& imap) const; const Sptr<I>& i, const Sptr<Vector<SizeT>>& imap) const;
/** Load all data from other ranks that is accessed by f(i). /** Load all data from other ranks that is accessed by f(i).

View file

@ -11,14 +11,14 @@ namespace CNORXZ
+================*/ +================*/
template <typename T, class RIndexT, class IndexT> template <typename T, class RIndexT, class IndexT>
constexpr CROpRoot<T,RIndexT,IndexT>::CROpRoot(const RArray<T>& a, const Sptr<RIndexT>& ri, constexpr CROpRoot<T,RIndexT,IndexT>::CROpRoot(const RCArray<T>& a, const Sptr<RIndexT>& ri,
const Sptr<IndexT>& li) : const Sptr<IndexT>& li) :
mData(a.map()), mData(a.buffermap().data()),
mRIndex(ri), mRIndex(ri),
mIndex(li) mIndex(li)
{ {
CXZ_ASSERT(a.map().size() == ri->lmax().val(), CXZ_ASSERT(a.buffermap().size() == ri->lmax().val(),
"data map not properly initialized: map size = " << a.map.size() "data map not properly initialized: map size = " << a.buffermap().size()
<< ", rank index range size = " << ri->lmax().val()); << ", rank index range size = " << ri->lmax().val());
} }
@ -43,7 +43,7 @@ namespace CNORXZ
} }
template <typename T, class RIndexT, class IndexT> template <typename T, class RIndexT, class IndexT>
constexpr decltype(auto) croproot(const RArray<T>& a, const Sptr<RIndexT>& ri, constexpr decltype(auto) croproot(const RCArray<T>& a, const Sptr<RIndexT>& ri,
const Sptr<IndexT>& li) const Sptr<IndexT>& li)
{ {
return CROpRoot<T,RIndexT,IndexT>(a,ri,li); return CROpRoot<T,RIndexT,IndexT>(a,ri,li);
@ -56,12 +56,12 @@ namespace CNORXZ
template <typename T, class RIndexT, class IndexT> template <typename T, class RIndexT, class IndexT>
constexpr ROpRoot<T,RIndexT,IndexT>::ROpRoot(RArray<T>& a, const Sptr<RIndexT>& ri, constexpr ROpRoot<T,RIndexT,IndexT>::ROpRoot(RArray<T>& a, const Sptr<RIndexT>& ri,
const Sptr<IndexT>& li) : const Sptr<IndexT>& li) :
mData(a.map()), mData(a.buffermap().data()),
mRIndex(ri), mRIndex(ri),
mIndex(li) mIndex(li)
{ {
CXZ_ASSERT(a.map().size() == ri->lmax().val(), CXZ_ASSERT(a.buffermap().size() == ri->lmax().val(),
"data map not properly initialized: map size = " << a.map.size() "data map not properly initialized: map size = " << a.buffermap().size()
<< ", rank index range size = " << ri->lmax().val()); << ", rank index range size = " << ri->lmax().val());
} }

View file

@ -25,7 +25,7 @@ namespace CNORXZ
typedef COpInterface<CROpRoot<T,RIndexT,IndexT>> OI; typedef COpInterface<CROpRoot<T,RIndexT,IndexT>> OI;
constexpr CROpRoot() = default; constexpr CROpRoot() = default;
constexpr CROpRoot(const RArray<T>& a, const Sptr<RIndexT>& ri, constexpr CROpRoot(const RCArray<T>& a, const Sptr<RIndexT>& ri,
const Sptr<IndexT>& li); const Sptr<IndexT>& li);
template <class PosT> template <class PosT>
@ -38,13 +38,13 @@ namespace CNORXZ
private: private:
const T** mData; const T* const* mData;
Sptr<RIndexT> mRIndex; Sptr<RIndexT> mRIndex;
Sptr<IndexT> mIndex; Sptr<IndexT> mIndex;
}; };
template <typename T, class RIndexT, class IndexT> template <typename T, class RIndexT, class IndexT>
constexpr decltype(auto) croproot(const RArray<T>& a, const Sptr<RIndexT>& ri, constexpr decltype(auto) croproot(const RCArray<T>& a, const Sptr<RIndexT>& ri,
const Sptr<IndexT>& li); const Sptr<IndexT>& li);
template <typename T, class RIndexT, class IndexT> template <typename T, class RIndexT, class IndexT>

View file

@ -382,6 +382,12 @@ namespace CNORXZ
return mK; return mK;
} }
template <class IndexI, class IndexK, class I1>
decltype(auto) operator*(const Sptr<RIndex<IndexI,IndexK>>& a, const Sptr<I1>& b)
{
return iptrMul(a, b);
}
/*=====================+ /*=====================+
| RRangeFactory | | RRangeFactory |
+=====================*/ +=====================*/

View file

@ -179,6 +179,13 @@ namespace CNORXZ
return std::make_shared<RIndex<IndexI,IndexK>>(i,k); return std::make_shared<RIndex<IndexI,IndexK>>(i,k);
} }
/** Make index pack of a RIndex and another index.
@param a pointer to RIndex.
@param b pointer to another index.
*/
template <class IndexI, class IndexK, class I1>
decltype(auto) operator*(const Sptr<RIndex<IndexI,IndexK>>& a, const Sptr<I1>& b);
// Traits!!! // Traits!!!
template <class I> template <class I>
struct is_rank_index struct is_rank_index

View file

@ -108,19 +108,25 @@ namespace
RArray<Double> res( MArray<Double>(mRXRange->sub(1)), mGeom2 ); RArray<Double> res( MArray<Double>(mRXRange->sub(1)), mGeom2 );
EXPECT_EQ(res.size(), comp.size()); EXPECT_EQ(res.size(), comp.size());
typedef UIndex<SizeT> UI; typedef UIndex<SizeT> UI;
RIndex<MIndex<UI,UI,UI,UI>,MIndex<UI,UI,UI,UI>> x(mRXRange); auto x = std::make_shared<RIndex<MIndex<UI,UI,UI,UI>,MIndex<UI,UI,UI,UI>>>(mRXRange);
RIndex<MIndex<UI,UI,UI,UI>,MIndex<UI,UI,UI,UI>> y(mRXRange); auto y = std::make_shared<RIndex<MIndex<UI,UI,UI,UI>,MIndex<UI,UI,UI,UI>>>(mRXRange);
SIndex<SizeT,4> A(mSpRange); auto xy = std::make_shared<RIndex<MIndex<UI,UI,UI,UI>,MIndex<UI,UI,UI,UI>>>(mRXRange);
SIndex<SizeT,4> B(mSpRange); auto A = std::make_shared<SIndex<SizeT,4>>(mSpRange);
/* auto B = std::make_shared<SIndex<SizeT,4>>(mSpRange);
Sptr<Vector<SizeT>> imap1;
Sptr<Vector<SizeT>> imap2;
// block 1: // block 1:
mM1.load(,A*B*a*b); //mM1.load(mindexPtr(y*x), x, mindexPtr(A*B), imap1);
mM2.load(,A*B*a*b); //mM2.load(mindexPtr(y*x), xy, mindexPtr(A*B), imap2);
res(y) += (mM1(x*A*B*a*b) * mM2(xy*B*A*b*a)).c(x*A*B*a*b); /*
res(y) = ( mM1(x*A*B) * mM2(xy*B*A)).c(mindexPtr(x*A*B));
// block 2: // block 2:
mM1.load(,A*B*a*b); mM1.load(,A*B*a*b);
mM2.load(,A*B*a*b); mM2.load(,A*B*a*b);
res(y) += (mM1(x*A*B*a*b) * mM2(xy*B*A*b*a)).c(x*A*B*a*b); res(y) += (mM1(x*A*B*a*b) * mM2(xy*B*A*b*a)).c(mindexPtr(x*A*B));
// block 3: // block 3:
mM1.load(,A*B*a*b); mM1.load(,A*B*a*b);
mM2.load(,A*B*a*b); mM2.load(,A*B*a*b);

View file

@ -155,6 +155,120 @@ namespace
COpRoot<double,MCCI1x> mOR1i2j; COpRoot<double,MCCI1x> mOR1i2j;
}; };
class Op_Test : public ::testing::Test
{
protected:
Op_Test()
{
mXr = CRangeFactory(7).create();
mAr = CRangeFactory(4).create();
mIr = CRangeFactory(5).create();
SizeT off = 15;
const SizeT m1s = mAr->size() * mXr->size() * mAr->size();
mM1 = Numbers::get(off, m1s);
off += m1s;
const SizeT m2s = mXr->size() * mXr->size() * mIr->size();
mM2 = Numbers::get(off, m2s);
off += m2s;
const SizeT m3s = mXr->size() * mAr->size() * mAr->size() * mIr->size();
mM3 = Numbers::get(off, m3s);
off += m3s;
}
RangePtr mXr;
RangePtr mAr;
RangePtr mIr;
Vector<Double> mM1; // a,x,a
Vector<Double> mM2; // x,x,i
Vector<Double> mM3; // x,a,a,i
};
TEST_F(Op_Test, Assign)
{
Vector<Double> r1(mXr->size()*mXr->size()*mIr->size(),0);
Vector<Double> r2(mXr->size()*mIr->size(),0);
auto x = std::make_shared<CIndex>(mXr);
auto y = std::make_shared<CIndex>(mXr);
auto i = std::make_shared<SIndex<SizeT,5>>(mIr);
oproot(r1.data(), mindexPtr(y*x*i)) = coproot(mM2.data(), mindexPtr(y*x*i));
oproot(r2.data(), mindexPtr(x*i)) = coproot(mM2.data(), mindexPtr(x*x*i));
for(SizeT ii = 0; ii != r1.size(); ++ii){
EXPECT_EQ(r1[ii], mM2[ii]);
}
for(SizeT xi = 0; xi != mXr->size(); ++xi){
for(SizeT ii = 0; ii != mIr->size(); ++ii){
const SizeT r2i = xi*mIr->size() + ii;
const SizeT m2i = xi*mIr->size()*(1 + mXr->size()) + ii;
EXPECT_EQ(r2[r2i], mM2[m2i]);
}
}
}
TEST_F(Op_Test, Multiply)
{
Vector<Double> r1(mIr->size()*mXr->size()*mAr->size(),0);
auto x = std::make_shared<CIndex>(mXr);
auto a = std::make_shared<SIndex<SizeT,4>>(mAr);
auto i = std::make_shared<SIndex<SizeT,5>>(mIr);
oproot(r1.data(), mindexPtr(i*x*a)) = coproot(mM2.data(), mindexPtr(x*x*i))
* coproot(mM3.data(), mindexPtr(x*a*a*i)) * coproot(mM1.data(), mindexPtr(a*x*a));
for(SizeT ii = 0; ii != mIr->size(); ++ii){
for(SizeT xi = 0; xi != mXr->size(); ++xi){
for(SizeT ai = 0; ai != mAr->size(); ++ai){
const SizeT r1i = (ii*mXr->size() + xi)*mAr->size() + ai;
const SizeT m2i = (xi*mXr->size() + xi)*mIr->size() + ii;
const SizeT m3i = ((xi*mAr->size() + ai)*mAr->size() + ai)*mIr->size() + ii;
const SizeT m1i = (ai*mXr->size() + xi)*mAr->size() + ai;
EXPECT_EQ(r1[r1i], mM2[m2i]*mM3[m3i]*mM1[m1i]);
}
}
}
}
TEST_F(Op_Test, Contract)
{
Vector<Double> r1(mIr->size()*mXr->size(),0);
auto x = std::make_shared<CIndex>(mXr);
auto y = std::make_shared<CIndex>(mXr);
auto a = std::make_shared<SIndex<SizeT,4>>(mAr);
auto b = std::make_shared<SIndex<SizeT,4>>(mAr);
auto i = std::make_shared<SIndex<SizeT,5>>(mIr);
oproot(r1.data(), mindexPtr(i*x)) =
(coproot(mM2.data(), mindexPtr(y*x*i)) * coproot(mM3.data(), mindexPtr(x*a*b*i)) *
coproot(mM1.data(), mindexPtr(b*y*a))).c(mindexPtr(a*b*y));
for(SizeT ii = 0; ii != mIr->size(); ++ii){
for(SizeT xi = 0; xi != mXr->size(); ++xi){
Double rx = 0;
const SizeT r1i = ii*mXr->size() + xi;
for(SizeT ai = 0; ai != mAr->size(); ++ai){
for(SizeT bi = 0; bi != mAr->size(); ++bi){
for(SizeT yi = 0; yi != mXr->size(); ++yi){
const SizeT m2i = (yi*mXr->size() + xi)*mIr->size() + ii;
const SizeT m3i = ((xi*mAr->size() + ai)*mAr->size() + bi) *
mIr->size() + ii;
const SizeT m1i = (bi*mXr->size() + yi)*mAr->size() + ai;
rx += mM2.at(m2i) * mM3.at(m3i) * mM1.at(m1i);
}
}
}
EXPECT_FLOAT_EQ(r1[r1i], rx);
}
}
}
TEST_F(OpCont_CR_Test, Basics) TEST_F(OpCont_CR_Test, Basics)
{ {
EXPECT_EQ(mOp2.data(), mData1.data()); EXPECT_EQ(mOp2.data(), mData1.data());

View file

@ -247,7 +247,7 @@ namespace
TEST_F(For_Test, SFor) TEST_F(For_Test, SFor)
{ {
auto loop = mkSFor<sSize>(IndexId<0>(mId1), TestXpr1( IndexId<0>(mId1) ), auto loop = mkSFor<sSize>(IndexId<0>(mId1), TestXpr1( IndexId<0>(mId1) ),
[](const auto& a, const auto& b) { return a + b; }); [](auto& a, const auto& b) { return a += b; });
const UPos rs = loop.rootSteps(IndexId<0>(mId1)); const UPos rs = loop.rootSteps(IndexId<0>(mId1));
EXPECT_EQ(rs.val(), 1u); EXPECT_EQ(rs.val(), 1u);