From 358f327a63fad68769c26b4cee68a0ad8ca08a9c Mon Sep 17 00:00:00 2001 From: Christian Zimmermann Date: Tue, 26 Dec 2017 15:13:50 +0100 Subject: [PATCH] replace VIWB by IndexInfo in blocking routines -> remaining performance lack in get() --- src/multi_array_operation.h | 110 ++++++++++++++++++++++++++++++++--- src/operation_utils.cc | 80 ++++++++++++++++++++++++- src/operation_utils.h | 12 +++- src/pack_num.h | 21 ++++++- src/ranges/container_range.h | 4 +- src/ranges/index_info.h | 3 +- src/ranges/multi_range.h | 4 +- src/ranges/rpack_num.h | 8 +-- src/ranges/single_range.h | 4 +- src/tests/op_perf_test.cc | 3 +- src/tests/op_unit_test.cc | 3 +- 11 files changed, 227 insertions(+), 25 deletions(-) diff --git a/src/multi_array_operation.h b/src/multi_array_operation.h index 6ee1c78..37eadce 100644 --- a/src/multi_array_operation.h +++ b/src/multi_array_operation.h @@ -47,10 +47,16 @@ namespace MultiArrayTools template MBlock makeBlock(T* vec, size_t stepSize, size_t blockSize); + // dont use this for now !! template std::shared_ptr seekBlockIndex(std::shared_ptr ownIdx, const OpClass& second); + template + const IndexInfo* seekBlockIndex(const IndexInfo* ownII, + const OpClass& second); + + template class OperationTemplate { @@ -99,12 +105,13 @@ namespace MultiArrayTools OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, std::shared_ptr& index, - std::shared_ptr blockIndex); - + const IndexInfo* blockIndex); + MBlock& get(); const Block& get() const; std::vector block(const std::shared_ptr blockIndex, bool init = false) const; + std::vector block(const IndexInfo* blockIndex, bool init = false) const; const OperationMaster& block() const; protected: @@ -137,6 +144,7 @@ namespace MultiArrayTools const Block& get() const; std::vector block(const std::shared_ptr blockIndex, bool init = false) const; + std::vector block(const IndexInfo* blockIndex, bool init = false) const; const ConstOperationRoot& block() const; protected: @@ -171,10 +179,12 @@ namespace MultiArrayTools const MBlock& get() const; MBlock& get(); - + + OperationRoot& set(const IndexInfo* blockIndex); OperationRoot& set(std::shared_ptr blockIndex); std::vector block(const std::shared_ptr blockIndex, bool init = false) const; + std::vector block(const IndexInfo* blockIndex, bool init = false) const; const OperationRoot& block() const; protected: @@ -188,6 +198,7 @@ namespace MultiArrayTools IndexInfo mIInfo; mutable MBlock mBlock; std::shared_ptr mBlockIndex; // predefine to save time + const IndexInfo* mBlockII; // predefine to save time }; template @@ -206,6 +217,7 @@ namespace MultiArrayTools const BlockResult& get() const; std::vector block(const std::shared_ptr blockIndex, bool init = false) const; + std::vector block(const IndexInfo* blockIndex, bool init = false) const; const Operation& block() const; protected: @@ -226,6 +238,7 @@ namespace MultiArrayTools const BlockResult& get() const; std::vector block(const std::shared_ptr blockIndex, bool init = false) const; + std::vector block(const IndexInfo* blockIndex, bool init = false) const; const Contraction& block() const; protected: @@ -260,10 +273,12 @@ namespace MultiArrayTools return MBlock(vec, 0, blockSize, stepSize); } + // dont use this for now !! template std::shared_ptr seekBlockIndex(std::shared_ptr ownIdx, const OpClass& second) { + assert(0); // dont use this for now !! std::vector > ivec; seekIndexInst(ownIdx, ivec); std::map, std::vector > mp; @@ -279,6 +294,20 @@ namespace MultiArrayTools return mp.begin()->first; } + template + const IndexInfo* seekBlockIndex(const IndexInfo* ownII, + const OpClass& second) + + { + const IndexInfo* ii = ownII; + while(ii->type() == IndexType::CONT or + ii->type() == IndexType::MULTI){ + ii = ii->getPtr(ii->dim()-1); + } + return ii; + } + + /*************************** * OperationTemplate * ***************************/ @@ -334,7 +363,7 @@ namespace MultiArrayTools std::shared_ptr& index) : mSecond(second), mArrayRef(ma), mIndex(mkIndex(index)), mIInfo(*mIndex) { - auto blockIndex = seekBlockIndex( make_viwb( mIndex ), second); + auto blockIndex = seekBlockIndex( &mIInfo, second); std::intptr_t blockIndexNum = blockIndex->getPtrNum(); block(blockIndex, true); @@ -347,7 +376,7 @@ namespace MultiArrayTools OperationMaster:: OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, std::shared_ptr& index, - std::shared_ptr blockIndex) : + const IndexInfo* blockIndex) : mSecond(second), mArrayRef(ma), mIndex(mkIndex(index)), mIInfo(*mIndex) { std::intptr_t blockIndexNum = blockIndex->getPtrNum(); @@ -356,7 +385,6 @@ namespace MultiArrayTools performAssignment(blockIndexNum); } - template std::shared_ptr::IndexType> OperationMaster:: @@ -411,6 +439,17 @@ namespace MultiArrayTools return btv; } + template + std::vector OperationMaster::block(const IndexInfo* blockIndex, bool init) const + { + std::vector btv(1, getBlockType( &mIInfo, blockIndex, true) ); + if(init){ + mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); + } + return btv; + } + + template const OperationMaster& OperationMaster::block() const { @@ -451,6 +490,7 @@ namespace MultiArrayTools template std::vector ConstOperationRoot::block(const std::shared_ptr blockIndex, bool init) const { + assert(0); std::vector btv(1, getBlockType( make_viwb( mIndex ), blockIndex, true) ); if(init){ mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); @@ -458,6 +498,16 @@ namespace MultiArrayTools return btv; } + template + std::vector ConstOperationRoot::block(const IndexInfo* blockIndex, bool init) const + { + std::vector btv(1, getBlockType( &mIInfo, blockIndex, true) ); + if(init){ + mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); + } + return btv; + } + template const ConstOperationRoot& ConstOperationRoot::block() const { @@ -475,7 +525,7 @@ namespace MultiArrayTools const std::shared_ptr&... indices) : //OperationTemplate >(this), mArrayRef(ma), mIndex( mkIndex( ma, indices... ) ), mIInfo(*mIndex), - mBlockIndex(nullptr) + mBlockIndex(nullptr), mBlockII(nullptr) {} template @@ -493,8 +543,8 @@ namespace MultiArrayTools template OperationMaster OperationRoot::operator=(const OpClass& in) { - if(mBlockIndex){ - return OperationMaster(mArrayRef, in, mIndex, mBlockIndex); + if(mBlockII != nullptr){ + return OperationMaster(mArrayRef, in, mIndex, mBlockII); } else { return OperationMaster(mArrayRef, in, mIndex); @@ -522,10 +572,20 @@ namespace MultiArrayTools mBlockIndex = blockIndex; return *this; } + + template + OperationRoot& + OperationRoot::set(const IndexInfo* blockIndex) + { + mBlockII = blockIndex; + return *this; + } + template std::vector OperationRoot::block(const std::shared_ptr blockIndex, bool init) const { + assert(0); std::vector btv(1, getBlockType( make_viwb( mIndex ), blockIndex, true) ); if(init){ mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); @@ -533,6 +593,16 @@ namespace MultiArrayTools return btv; } + template + std::vector OperationRoot::block(const IndexInfo* blockIndex, bool init) const + { + std::vector btv(1, getBlockType( &mIInfo, blockIndex, true) ); + if(init){ + mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max()); + } + return btv; + } + template const OperationRoot& OperationRoot::block() const { @@ -559,6 +629,7 @@ namespace MultiArrayTools template std::vector Operation::block(const std::shared_ptr blockIndex, bool init) const { + assert(0); std::vector btv; PackNum::makeBlockTypeVec(btv, mOps, blockIndex, init); if(init){ @@ -567,6 +638,18 @@ namespace MultiArrayTools return btv; } + template + std::vector Operation::block(const IndexInfo* blockIndex, bool init) const + { + std::vector btv; + PackNum::makeBlockTypeVec(btv, mOps, blockIndex, init); + if(init){ + mRes.init(blockIndex->max()); + } + return btv; + } + + template const Operation& Operation::block() const { @@ -603,6 +686,15 @@ namespace MultiArrayTools return mOp.block(blockIndex, init); } + template + std::vector Contraction::block(const IndexInfo* blockIndex, bool init) const + { + if(init){ + mRes.init(blockIndex->max()); + } + return mOp.block(blockIndex, init); + } + template const Contraction& Contraction::block() const { diff --git a/src/operation_utils.cc b/src/operation_utils.cc index a8f9689..d70ceb6 100644 --- a/src/operation_utils.cc +++ b/src/operation_utils.cc @@ -12,7 +12,9 @@ namespace MultiArrayTools void seekIndexInst(std::shared_ptr i, std::vector >& ivec) { + std::cout << __func__ << ":" << std::endl; for(size_t inum = 0; inum != i->rangePtr()->dim(); ++inum){ + std::cout << i->getPtrNum() << std::endl; auto ii = i->getPtr(inum); if(ii->type() == IndexType::MULTI or ii->type() == IndexType::CONT){ @@ -20,8 +22,24 @@ namespace MultiArrayTools } ivec.push_back(ii); } + std::cout << std::endl; } + void seekIndexInst(const IndexInfo* i, std::vector& ivec) + { + std::cout << __func__ << ":" << std::endl; + for(size_t inum = 0; inum != i->dim(); ++inum){ + std::cout << i->getPtrNum() << std::endl; + auto ii = i->getPtr(inum); + if(ii->type() == IndexType::MULTI or + ii->type() == IndexType::CONT){ + seekIndexInst(ii, ivec); + } + ivec.push_back(ii); + } + std::cout << std::endl; + } + BTSS getBlockType(std::shared_ptr i, std::shared_ptr j, bool first, size_t higherStepSize) @@ -59,6 +77,43 @@ namespace MultiArrayTools return out; } + BTSS getBlockType(const IndexInfo* i, + const IndexInfo* j, + bool first, size_t higherStepSize) + { + // returning BlockType and step size is redundant (change in the future) + // stepSize == 0 => VALUE + // stepSize == 1 => BLOCK + // stepSize > 1 => SPLIT :) + BTSS out(BlockType::VALUE, 0); + size_t lastNum = i->dim(); + + for(size_t inum = 0; inum != lastNum; ++inum){ + auto ii = i->getPtr(inum); + if(ii->getPtrNum() == j->getPtrNum()){ + + if(inum == lastNum - 1 and first){ + out = BTSS(BlockType::BLOCK, 1); + } + else { + first = false; + out = BTSS(BlockType::SPLIT, i->getStepSize(inum) * higherStepSize + out.second); + } + continue; + } + + if(ii->type() == IndexType::MULTI or + ii->type() == IndexType::CONT){ + + BTSS tmp = getBlockType(ii, j, inum == lastNum - 1, i->getStepSize(inum) * higherStepSize); + if(tmp.first != BlockType::VALUE){ + out = tmp; + } + } + } + return out; + } + size_t getBTNum(const std::vector& mp, BlockType bt) { size_t out = 0; @@ -92,7 +147,30 @@ namespace MultiArrayTools } } - + + void minimizeAppearanceOfType(std::map >& mp, + BlockType bt) + { + size_t minNum = getBTNum( mp.begin()->second, bt ); + for(auto& mm: mp){ + size_t tmp = getBTNum( mm.second, bt ); + if(tmp < minNum){ + minNum = tmp; + } + } + + for(auto mit = mp.begin(); mit != mp.end(); ){ + size_t tmp = getBTNum( mit->second, bt ); + if(tmp > minNum){ + mit = mp.erase(mit); + } + else { + ++mit; + } + } + + } + } // end namespace MultiArrayTools diff --git a/src/operation_utils.h b/src/operation_utils.h index c101522..ee1d54e 100644 --- a/src/operation_utils.h +++ b/src/operation_utils.h @@ -10,6 +10,8 @@ #include "block/block.h" #include "ranges/vindex_base.h" +#include "ranges/index_info.h" + namespace MultiArrayTools { @@ -24,18 +26,26 @@ namespace MultiArrayTools void seekIndexInst(std::shared_ptr i, std::vector >& ivec); - //void seekIndexInst(const IndexInfo& i, std::vector& ivec); + void seekIndexInst(const IndexInfo* i, std::vector& ivec); BTSS getBlockType(std::shared_ptr i, std::shared_ptr j, bool first, size_t higherStepSize = 1); + BTSS getBlockType(const IndexInfo* i, + const IndexInfo* j, + bool first, size_t higherStepSize = 1); + size_t getBTNum(const std::vector& mp, BlockType bt); void minimizeAppearanceOfType(std::map, std::vector >& mp, BlockType bt); + void minimizeAppearanceOfType(std::map >& mp, + BlockType bt); + + } // end namespace MultiArrayTools diff --git a/src/pack_num.h b/src/pack_num.h index 0a3e677..0c4b8e0 100644 --- a/src/pack_num.h +++ b/src/pack_num.h @@ -27,6 +27,16 @@ namespace MultiArrayHelper PackNum::makeBlockTypeVec(btv, ops, idxPtr, init); } + template + static void makeBlockTypeVec(std::vector >& btv, + const std::tuple& ops, + const IndexInfo* idxPtr, bool init) + { + auto subvec = std::move( std::get(ops).block(idxPtr, init) ); + btv.insert(btv.end(), subvec.begin(), subvec.end() ); + PackNum::makeBlockTypeVec(btv, ops, idxPtr, init); + } + template static void unpackArgs(BlockResult& res, const ArgTuple& tp, const Args&... args) { @@ -62,7 +72,16 @@ namespace MultiArrayHelper auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) ); btv.insert(btv.end(), subvec.begin(), subvec.end() ); } - + + template + static void makeBlockTypeVec(std::vector >& btv, + const std::tuple& ops, + const IndexInfo* idxPtr, bool init) + { + auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) ); + btv.insert(btv.end(), subvec.begin(), subvec.end() ); + } + template static void printTuple(std::ostream& out, const std::tuple& tp){ out << std::get(tp); diff --git a/src/ranges/container_range.h b/src/ranges/container_range.h index 6c0a880..0ee6926 100644 --- a/src/ranges/container_range.h +++ b/src/ranges/container_range.h @@ -53,7 +53,7 @@ namespace MultiArrayTools // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== - IndexType type(); + IndexType type() const; ContainerIndex& operator++(); ContainerIndex& operator--(); @@ -216,7 +216,7 @@ namespace MultiArrayTools } template - IndexType ContainerIndex::type() { return IndexType::CONT; } + IndexType ContainerIndex::type() const { return IndexType::CONT; } template ContainerIndex& ContainerIndex::operator++() diff --git a/src/ranges/index_info.h b/src/ranges/index_info.h index d267dc2..93dc4ca 100644 --- a/src/ranges/index_info.h +++ b/src/ranges/index_info.h @@ -64,7 +64,8 @@ namespace MultiArrayTools mPtrNum( reinterpret_cast( &ind ) ), mDim(ind.vrange()->dim()), mMax(ind.max()), - mStepSize(stepSize) + mStepSize(stepSize), + mType(ind.type()) {} template diff --git a/src/ranges/multi_range.h b/src/ranges/multi_range.h index 7d4a799..cd6db00 100644 --- a/src/ranges/multi_range.h +++ b/src/ranges/multi_range.h @@ -70,7 +70,7 @@ namespace MultiArrayTools // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== - IndexType type(); + IndexType type() const; MultiIndex& operator=(size_t pos); @@ -264,7 +264,7 @@ namespace MultiArrayTools } template - IndexType MultiIndex::type() + IndexType MultiIndex::type() const { return IndexType::MULTI; } diff --git a/src/ranges/rpack_num.h b/src/ranges/rpack_num.h index 82ddcc3..590ae44 100644 --- a/src/ranges/rpack_num.h +++ b/src/ranges/rpack_num.h @@ -166,10 +166,10 @@ namespace MultiArrayHelper } template - static size_t makePos(const std::tuple...>& iPtrTup) + static inline size_t makePos(const std::tuple...>& iPtrTup) { - const auto& idx = *std::get(iPtrTup); - return idx.pos() + RPackNum::makePos(iPtrTup) * idx.max(); + //const auto& idx = *std::get(iPtrTup); + return std::get(iPtrTup)->pos() + RPackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); } template @@ -337,7 +337,7 @@ namespace MultiArrayHelper } template - static size_t makePos(const std::tuple...>& iPtrTup) + static inline size_t makePos(const std::tuple...>& iPtrTup) { return std::get<0>(iPtrTup)->pos(); } diff --git a/src/ranges/single_range.h b/src/ranges/single_range.h index b1ae553..7d8a6cd 100644 --- a/src/ranges/single_range.h +++ b/src/ranges/single_range.h @@ -29,7 +29,7 @@ namespace MultiArrayTools // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== - IndexType type(); + IndexType type() const; SingleIndex& operator=(size_t pos); SingleIndex& operator++(); @@ -121,7 +121,7 @@ namespace MultiArrayTools IndexInterface,U>(range, 0) {} template - IndexType SingleIndex::type() + IndexType SingleIndex::type() const { return IndexType::SINGLE; } diff --git a/src/tests/op_perf_test.cc b/src/tests/op_perf_test.cc index a7cc1fb..db593c6 100644 --- a/src/tests/op_perf_test.cc +++ b/src/tests/op_perf_test.cc @@ -167,7 +167,8 @@ namespace { auto mix = MAT::mkMIndex( alpha, beta, gamma ); std::clock_t begin = std::clock(); - res1(delta, deltap).set(vdeltap) = ma(delta, alpha, alpha, beta, beta, gamma, gamma, deltap).c(mix); + //res1(delta, deltap).set(vdeltap) = ma(delta, alpha, alpha, beta, beta, gamma, gamma, deltap).c(mix); + res1(delta, deltap) = ma(delta, alpha, alpha, beta, beta, gamma, gamma, deltap).c(mix); std::clock_t end = std::clock(); std::cout << "MultiArray time: " << static_cast( end - begin ) / CLOCKS_PER_SEC << std::endl; diff --git a/src/tests/op_unit_test.cc b/src/tests/op_unit_test.cc index dc1394c..394de0f 100644 --- a/src/tests/op_unit_test.cc +++ b/src/tests/op_unit_test.cc @@ -220,7 +220,8 @@ namespace { auto mix = MAT::mkMIndex( alpha, beta, gamma ); std::clock_t begin = std::clock(); - res1(delta, deltap).set(vdeltap) = ma(delta, alpha, alpha, beta, beta, gamma, gamma, deltap).c(mix); + //res1(delta, deltap).set(vdeltap) = ma(delta, alpha, alpha, beta, beta, gamma, gamma, deltap).c(mix); + res1(delta, deltap) = ma(delta, alpha, alpha, beta, beta, gamma, gamma, deltap).c(mix); std::clock_t end = std::clock(); std::cout << "MultiArray time: " << static_cast( end - begin ) / CLOCKS_PER_SEC << std::endl;