#include "multi_array_operation.h" /* ========================= * * --- TEMPLATE CODE --- * * ========================= */ namespace MultiArrayTools { namespace { using namespace MultiArrayHelper; } /*************************** * OperationTemplate * ***************************/ template template auto OperationBase::operator+(const OperationBase& in) const -> Operation,OperationClass,Second> { return Operation,OperationClass,Second>(THIS(), in.THIS()); } template template auto OperationBase::operator-(const OperationBase& in) const -> Operation,OperationClass,Second> { return Operation,OperationClass,Second>(THIS(), in.THIS()); } template template auto OperationBase::operator*(const OperationBase& in) const -> Operation,OperationClass,Second> { return Operation,OperationClass,Second>(THIS(), in.THIS()); } template template auto OperationBase::operator/(const OperationBase& in) const -> Operation,OperationClass,Second> { return Operation,OperationClass,Second>(THIS(), in.THIS()); } template template auto OperationBase::c(const std::shared_ptr& ind) const -> Contraction { return Contraction(THIS(), ind); } template template auto OperationBase::sl(const std::shared_ptr&... inds) const -> ConstSlice { ConstSlice out(inds->range()...); out.define(inds...) = THIS(); return out; } template template auto OperationBase::slc(const std::shared_ptr&... inds) const -> SliceContraction { return SliceContraction (THIS(), inds...); } template template auto OperationBase::p(const std::shared_ptr&... inds) const -> ConstOperationRoot { auto ma = std::make_shared> (inds->range()... , static_cast(0)); (*ma)(inds...) = THIS(); return ConstOperationRoot(ma, inds...); } template template auto OperationBase::to(const std::shared_ptr&... inds) const -> MultiArray { MultiArray out(inds->range()...); out(inds...) = THIS(); return out; } template template auto OperationBase::a(const std::shared_ptr>& ll, const Args&... args) const -> Operation,OperationClass, Args...> { return Operation,OperationClass, Args...>(ll, THIS(), args...); } /***************************************** * OperationMaster::AssignmentExpr * *****************************************/ template OperationMaster::AssignmentExpr:: AssignmentExpr(OperationMaster& m, const OpClass& sec) : mM(m), mSec(sec) {} template inline void OperationMaster::AssignmentExpr:: operator()(size_t start, ExtType last) const { //VCHECK(mSec.template get(last)); mM.set(start, mSec.template get(last) ); } template typename OperationMaster::AssignmentExpr::ExtType OperationMaster::AssignmentExpr:: rootSteps(std::intptr_t iPtrNum) const { return mSec.rootSteps(iPtrNum); } /************************* * OperationMaster * *************************/ template OperationMaster:: OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, IndexType& index, bool doParallel) : mSecond(second), mDataPtr(ma.data()), mIndex(index), mDoParallel(doParallel) { performAssignment(0); } template OperationMaster:: OperationMaster(T* data, const OpClass& second, IndexType& index, bool doParallel) : mSecond(second), mDataPtr(data), mIndex(index), mDoParallel(doParallel) { performAssignment(0); } template void OperationMaster::performAssignment(std::intptr_t blockIndexNum) { AssignmentExpr ae(*this, mSecond); // Expression to be executed within loop if(mDoParallel){ const auto ploop = mIndex.pifor( 1, mSecond.loop(ae) ); ploop(); // execute overall loop(s) and so internal hidden loops and so the inherited expressions } else { const auto loop = mIndex.ifor( 1, mSecond.loop(ae) ); loop(); // execute overall loop(s) and so internal hidden loops and so the inherited expressions } } template inline T OperationMaster::get(size_t pos) const { return mDataPtr[pos]; } /**************************** * ConstOperationRoot * ****************************/ template ConstOperationRoot:: ConstOperationRoot(const MultiArrayBase& ma, const std::shared_ptr&... indices) : mDataPtr(ma.data()), mIndex( ma.begin() ) { //VCHECK(ma.data()); mIndex(indices...); mOff = mIndex.pos(); } template ConstOperationRoot:: ConstOperationRoot(std::shared_ptr > maptr, const std::shared_ptr&... indices) : mDataPtr(maptr->data()), mIndex(maptr->begin()), mMaPtr(maptr) { mIndex(indices...); mOff = mIndex.pos(); } template ConstOperationRoot:: ConstOperationRoot(const T* data, const IndexType& ind) : mDataPtr(data), mIndex( ind ) { mOff = mIndex.pos(); } template template inline T ConstOperationRoot::get(ET pos) const { return mDataPtr[pos.val()+mOff]; } template template inline const ConstOperationRoot& ConstOperationRoot::set(ET pos) const { mIndex = pos.val(); mOff = mIndex.pos(); return *this; } template const T* ConstOperationRoot::data() const { return mDataPtr + mIndex().pos(); } template MExt ConstOperationRoot::rootSteps(std::intptr_t iPtrNum) const { return MExt(getStepSize( mIndex, iPtrNum )); //return MExt(getStepSize( getRootIndices( mIndex->info() ), iPtrNum )); } template template Expr ConstOperationRoot::loop(Expr exp) const { return exp; } /******************** * StaticCast * ********************/ template StaticCast::StaticCast(const Op& op) : mOp(op) {} template template inline T StaticCast::get(ET pos) const { return static_cast( mOp.get(pos) ); } template template inline const StaticCast& StaticCast::set(ET pos) const { mOp.set(pos); return *this; } template auto StaticCast::rootSteps(std::intptr_t iPtrNum) const -> decltype(mOp.rootSteps(iPtrNum)) { return mOp.rootSteps(iPtrNum); } template template Expr StaticCast::loop(Expr exp) const { return mOp.loop(exp); } /**************************** * MetaOperationRoot * ****************************/ template MetaOperationRoot:: MetaOperationRoot(const std::shared_ptr& ind) : mWorkIndex(*ind), mIndex( ind ) { } template template inline typename MetaOperationRoot::value_type MetaOperationRoot::get(ET pos) const { //VCHECK(pos.val()); //VCHECK(mDataPtr); //VCHECK(mDataPtr[pos.val()]) return (mWorkIndex = pos.val()).meta(); } template template inline const MetaOperationRoot& MetaOperationRoot::set(ET pos) const { assert(0); //(*mIndex) = pos.val(); return *this; } template MExt MetaOperationRoot::rootSteps(std::intptr_t iPtrNum) const { return MExt(getStepSize( *mIndex, iPtrNum )); //return MExt(getStepSize( getRootIndices( mIndex->info() ), iPtrNum )); } template template Expr MetaOperationRoot::loop(Expr exp) const { return exp; } /*********************** * OperationRoot * ***********************/ template OperationRoot:: OperationRoot(MutableMultiArrayBase& ma, const std::shared_ptr&... indices) : mDataPtr(ma.data()), mIndex( ma.begin() ) { mIndex(indices...); mOff = mIndex.pos(); } template OperationRoot:: OperationRoot(T* data, const IndexType& ind) : mDataPtr(data), mIndex( ind ) { mOff = mIndex.pos(); } template template OperationMaster,OpClass,Ranges...> OperationRoot::operator=(const OpClass& in) { return OperationMaster,OpClass,Ranges...>(mDataPtr, in, mIndex, mDoParallel); } template template OperationMaster,OpClass,Ranges...> OperationRoot::operator+=(const OpClass& in) { return OperationMaster,OpClass,Ranges...>(mDataPtr, in, mIndex, mDoParallel); } template OperationMaster,OperationRoot,Ranges...> OperationRoot::operator=(const OperationRoot& in) { return operator= >(in); } template OperationRoot& OperationRoot::par() { mDoParallel = true; return *this; } template template inline T OperationRoot::get(ET pos) const { return mDataPtr[pos.val()+mOff]; } template template inline const OperationRoot& OperationRoot::set(ET pos) const { mIndex = pos.val(); mOff = mIndex.pos(); return *this; } template MExt OperationRoot::rootSteps(std::intptr_t iPtrNum) const { return MExt(getStepSize( mIndex, iPtrNum )); //return MExt(getStepSize( mIndex.info(), iPtrNum )); } template template Expr OperationRoot::loop(Expr exp) const { return exp; } template T* OperationRoot::data() const { return mDataPtr + mIndex().pos(); } template template auto OperationRoot::sl(const std::shared_ptr&... inds) -> Slice { Slice out(inds->range()...); out.define(inds...) = *this; return out; } /************************ * OperationValue * ************************/ template OperationValue::OperationValue(const T& val) : mVal(val) {} template template inline T OperationValue::get(ET pos) const { return mVal; } template template inline const OperationValue& OperationValue::set(ET pos) const { return *this; } template MExt OperationValue::rootSteps(std::intptr_t iPtrNum) const { return MExt(0); } template template Expr OperationValue::loop(Expr exp) const { return exp; } /******************* * Operation * *******************/ template Operation::Operation(const Ops&... ops) : mOps(ops...) { static_assert( FISSTATIC, "need function instance for non-static function" ); } template Operation::Operation(std::shared_ptr ff, const Ops&... ops) : mOps(ops...), mF(ff) { static_assert( not FISSTATIC, "using instance of function supposed to be static" ); } template template inline T Operation::get(ET pos) const { typedef std::tuple OpTuple; return PackNum:: template mkOpExpr(mF, pos, mOps); } template template inline const Operation& Operation::set(ET pos) const { PackNum::setOpPos(mOps,pos); return *this; } template auto Operation::rootSteps(std::intptr_t iPtrNum) const -> decltype(PackNum::mkSteps(iPtrNum, mOps)) { return PackNum::mkSteps(iPtrNum, mOps); } template template auto Operation::loop(Expr exp) const -> decltype(PackNum::mkLoop( mOps, exp )) { return PackNum::mkLoop( mOps, exp ); } /********************* * Contraction * *********************/ template Contraction::Contraction(const Op& op, std::shared_ptr ind) : mOp(op), mInd(ind) {} // forward loop !!!! template template inline T Contraction::get(ET pos) const { return mOp.template get(pos); } template template inline const Contraction& Contraction::set(ET pos) const { mOp.set(pos); return *this; } template auto Contraction::rootSteps(std::intptr_t iPtrNum) const -> decltype(mOp.rootSteps(iPtrNum)) { return mOp.rootSteps(iPtrNum); } template template auto Contraction::loop(Expr exp) const -> decltype(mInd->iforh(1,mOp.loop(exp))) { return mInd->iforh(1,mOp.loop(exp)); } /************************** * SliceContraction * **************************/ template SliceContraction::SliceContraction(const Op& op, std::shared_ptr... ind) : mOp(op), mCont(std::make_shared >(ind->range()...)), mTarOp(*mCont,ind...) { } // forward loop !!!! template template inline const MultiArray& SliceContraction::get(ET pos) const { *mCont = 0; mOp.set(pos); mTarOp = mOp; return *mCont; } template template inline const SliceContraction& SliceContraction::set(ET pos) const { mOp.set(pos); return *this; } template auto SliceContraction::rootSteps(std::intptr_t iPtrNum) const -> decltype(mOp.rootSteps(iPtrNum)) { return mOp.rootSteps(iPtrNum); } template template auto SliceContraction::loop(Expr exp) const -> decltype(mOp.loop(exp)) { return mOp.loop(exp); } }