diff --git a/.gitignore b/.gitignore index 2c62f47..8bf2737 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build/ install/ */build/ */install/ +src/lib/hl_ops/*.cc \ No newline at end of file diff --git a/src/include/high_level_operation.cc.h b/src/include/high_level_operation.cc.h index 9a1878d..02dc46d 100644 --- a/src/include/high_level_operation.cc.h +++ b/src/include/high_level_operation.cc.h @@ -176,8 +176,6 @@ namespace MultiArrayTools typename B::template RetT res; Create::template cx::template ccx::template cccx (res,mIn,inds...); - // assert(res.op.init()); - //assert(res.outer.init()); return res; } @@ -262,26 +260,47 @@ namespace MultiArrayTools if(dim > 2){ auto ci1 = di->getP(dim-2)->reduced(); auto ci2 = di->getP(dim-1)->reduced(); - //auto ci1 = std::dynamic_pointer_cast>(di->getP(dim-2)); - //auto ci2 = std::dynamic_pointer_cast>(di->getP(dim-1)); assert(ci1 != nullptr); assert(ci2 != nullptr); auto odi = mkSubSpaceX(di, dim-2); auto mi = mkMIndex(is..., odi); - //this->assign(in, mi, ci1->getIndex(), ci2->getIndex()); this->assign(in, mi, ci1, ci2); } else { assert(dim == 2 or dim == 1); - //auto ci1 = std::dynamic_pointer_cast>(di->getP(dim-2)); auto ci1 = di->getP(dim-1)->reduced(); assert(ci1 != nullptr); auto odi = mkSubSpaceX(di, dim-1); auto mi = mkMIndex(is..., odi); this->assign(in, mi, ci1); } - //INDS::template CallHLOp<> call; - //call.assign(*this, in, is..., di); + return *this; + } + + template + template + HighLevelOpHolder& HighLevelOpHolder::xplus(const HighLevelOpHolder& in, + const std::shared_ptr& di, + const std::shared_ptr&... is) + { + const size_t dim = di->dim(); + if(dim > 2){ + auto ci1 = di->getP(dim-2)->reduced(); + auto ci2 = di->getP(dim-1)->reduced(); + assert(ci1 != nullptr); + assert(ci2 != nullptr); + auto odi = mkSubSpaceX(di, dim-2); + auto mi = mkMIndex(is..., odi); + this->plus(in, mi, ci1, ci2); + } + else { + assert(dim == 2 or dim == 1); + auto ci1 = di->getP(dim-1)->reduced(); + assert(ci1 != nullptr); + auto odi = mkSubSpaceX(di, dim-1); + auto mi = mkMIndex(is..., odi); + this->plus(in, mi, ci1); + } return *this; } @@ -305,12 +324,11 @@ namespace MultiArrayTools const std::shared_ptr& mi, const std::shared_ptr&... inds) { - //VCHECK(printInd(inds...)); auto xx = mkArrayPtr(nullr()); ROP& opr = *mOp->get(); if(in.root()){ auto inx = in; - opr.par() = *inx.get(); + opr.par().assign( *inx.get(), mkMIndex(mi,inds...) )(); return *this; } auto loop = mkPILoop @@ -318,8 +336,6 @@ namespace MultiArrayTools auto inx = in; auto dop = inx.create(inds...); DynamicO gexp; - //VCHECK(dop.outer.init()); - //VCHECK(dop.op.init()); if(dop.outer.init()){ gexp = mkDynOp1(mkMOp(dop.outer,dop.op)); } @@ -347,7 +363,7 @@ namespace MultiArrayTools ROP& opr = *mOp->get(); if(in.root()){ auto inx = in; - opr.par() += *inx.get(); + opr.par().plus( *inx.get(), mkMIndex(mi,inds...) )(); return *this; } auto loop = mkPILoop diff --git a/src/include/high_level_operation.h b/src/include/high_level_operation.h index 31198bd..68a823a 100644 --- a/src/include/high_level_operation.h +++ b/src/include/high_level_operation.h @@ -13,6 +13,11 @@ namespace MultiArrayTools typedef CR::IndexType CI; typedef std::shared_ptr CIP; + typedef OperationRoot OpCD; + typedef OperationRoot OpD; + extern template class OperationRoot; + extern template class OperationRoot; + template DynamicO mkDynOp1(const Op& op); @@ -90,6 +95,11 @@ namespace MultiArrayTools }; + extern template class HighLevelOpBase; + extern template class HighLevelOpBase; + extern template class HighLevelOpRoot; + extern template class HighLevelOpRoot; + template auto mkFOp(const Ops&... ops) { @@ -125,7 +135,21 @@ namespace MultiArrayTools #undef reg_ind3 }; - + extern template class HighLevelOp,2>; + extern template class HighLevelOp,2>; + extern template class HighLevelOp,2>; + extern template class HighLevelOp,2>; + extern template class HighLevelOp,2>; + extern template class HighLevelOp,2>; + extern template class HighLevelOp,2>; + extern template class HighLevelOp,2>; + +#define regFunc1(fff) \ + extern template class HighLevelOp,1>; \ + extern template class HighLevelOp,1>; +#include "extensions/math.h" +#undef regFunc1 + template class HighLevelOpHolder { @@ -161,6 +185,11 @@ namespace MultiArrayTools const std::shared_ptr& di, const std::shared_ptr&... is); + template + HighLevelOpHolder& xplus(const HighLevelOpHolder& in, + const std::shared_ptr& di, + const std::shared_ptr&... is); + template HighLevelOpHolder& assign(const HighLevelOpHolder& in, const std::shared_ptr& mi, @@ -172,6 +201,9 @@ namespace MultiArrayTools const std::shared_ptr&... inds); }; + extern template class HighLevelOpHolder; + extern template class HighLevelOpHolder; + template HighLevelOpHolder mkSFunc(const HighLevelOpHolder& a, const HighLevelOpHolder&... as); @@ -179,87 +211,19 @@ namespace MultiArrayTools template HighLevelOpHolder mkHLO(const ROP& op); -#define SP " " #define regFunc1(fff) template \ HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); #include "extensions/math.h" #undef regFunc1 -#undef SP - /* - template - struct SetLInds - { - template - static inline void mkLIT(const ITuple& itp, const std::shared_ptr& di); - template - struct xx - { - template - static inline void assign(Tar& tar, const Args&... args, - const ITp& itp, const std::shared_ptr&... is); +#define regFunc1(fff) template \ + HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); \ + extern template HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); \ + extern template HighLevelOpHolder hl_##fff (const HighLevelOpHolder& in); +#include "extensions/math.h" +#undef regFunc1 + - template - static inline void plus(Tar& tar, const Args&... args, - const ITp& itp, const std::shared_ptr&... is); - }; - }; - - template <> - struct SetLInds<0> - { - template - static inline void mkLIT(const ITuple& itp, const std::shared_ptr& di); - - template - struct xx - { - template - static inline void assign(Tar& tar, const Args&... args, - const ITp& itp, const std::shared_ptr&... is); - - template - static inline void plus(Tar& tar, const Args&... args, - const ITp& itp, const std::shared_ptr&... is); - }; - }; - - template - struct INDS - { - class CallHLOpBase - { - private: - size_t mDepth; - public: - size_t depth() const; - - void assign(const HighLevelOpHolder& target, const HighLevelOpHolder& source, - const std::shared_ptr&... is, - const std::shared_ptr& di) const = 0; - - void plus(const HighLevelOpHolder& target, const HighLevelOpHolder& source, - const std::shared_ptr&... is, - const std::shared_ptr& di) const = 0; - }; - - template - class CallHLOp - { - private: - typedef std::tuple...> ITuple; - static vector> sNext; - public: - void assign(HighLevelOpHolder& target, const HighLevelOpHolder& source, - const std::shared_ptr&... is, - const std::shared_ptr& di) const override final; - - void plus(HighLevelOpHolder& target, const HighLevelOpHolder& source, - const std::shared_ptr&... is, - const std::shared_ptr& di) const override final; - }; - }; - */ } #endif diff --git a/src/include/multi_array_operation.cc.h b/src/include/multi_array_operation.cc.h index fe50e41..6096506 100644 --- a/src/include/multi_array_operation.cc.h +++ b/src/include/multi_array_operation.cc.h @@ -711,6 +711,17 @@ namespace MultiArrayTools (mOrigDataPtr,*this,in))); } + template + template + auto ParallelOperationRoot::assign(const OpClass& in, const std::shared_ptr& i) const + -> decltype(i->pifor(1,in.loop(AssignmentExpr2,OpClass> + (mOrigDataPtr,*this,in)))) + { + static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" ); + return i->pifor(1,in.loop(AssignmentExpr2,OpClass> + (mOrigDataPtr,*this,in))); + } + template template auto ParallelOperationRoot::plus(const OpClass& in) @@ -721,6 +732,17 @@ namespace MultiArrayTools (mOrigDataPtr,*this,in))); } + template + template + auto ParallelOperationRoot::plus(const OpClass& in, const std::shared_ptr& i) const + -> decltype(i->pifor(1,in.loop(AddExpr,OpClass> + (mOrigDataPtr,*this,in)))) + { + static_assert( OpClass::SIZE == decltype(in.rootSteps())::SIZE, "Ext Size mismatch" ); + return i->pifor(1,in.loop(AddExpr,OpClass> + (mOrigDataPtr,*this,in))); + } + template template ParallelOperationRoot& ParallelOperationRoot::operator=(const OpClass& in) diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h index 14c9b5d..871db03 100644 --- a/src/include/multi_array_operation.h +++ b/src/include/multi_array_operation.h @@ -587,11 +587,21 @@ namespace MultiArrayTools -> decltype(mIndex.pifor(1,in.loop(AssignmentExpr2,OpClass,OpIndexAff::TARGET> (mOrigDataPtr,*this,in)))); - template + template + auto assign(const OpClass& in, const std::shared_ptr& i) const + -> decltype(i->pifor(1,in.loop(AssignmentExpr2,OpClass> + (mOrigDataPtr,*this,in)))); + + template auto plus(const OpClass& in) -> decltype(mIndex.pifor(1,in.loop(AddExpr,OpClass,OpIndexAff::TARGET> (mOrigDataPtr,*this,in)))); + template + auto plus(const OpClass& in, const std::shared_ptr& i) const + -> decltype(i->pifor(1,in.loop(AddExpr,OpClass> + (mOrigDataPtr,*this,in)))); + template ParallelOperationRoot& operator=(const OpClass& in); diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index f39782c..b948709 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,4 +1,7 @@ +execute_process ( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/mk_hl_op.sh + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ ) + set(libmultiarray_a_SOURCES ${CMAKE_SOURCE_DIR}/src/lib/ranges/range_base.cc ${CMAKE_SOURCE_DIR}/src/lib/ranges/anonymous_range.cc @@ -16,6 +19,12 @@ foreach(ccfile ${cc_files}) ${ccfile}) endforeach(ccfile) +file(GLOB cc_files "${CMAKE_SOURCE_DIR}/src/lib/hl_ops/*.cc") +foreach(ccfile ${cc_files}) + set(libmultiarray_a_SOURCES ${libmultiarray_a_SOURCES} + ${ccfile}) +endforeach(ccfile) + add_library(multiarray_obj OBJECT ${libmultiarray_a_SOURCES} ) diff --git a/src/lib/high_level_operation.cc b/src/lib/high_level_operation.cc index 28601ce..50a0299 100644 --- a/src/lib/high_level_operation.cc +++ b/src/lib/high_level_operation.cc @@ -21,4 +21,15 @@ namespace MultiArrayTools return odi; } + template class OperationRoot; + template class OperationRoot; + + template class HighLevelOpHolder; + template class HighLevelOpHolder; + + template class HighLevelOpBase; + template class HighLevelOpBase; + template class HighLevelOpRoot; + template class HighLevelOpRoot; + } diff --git a/src/lib/mk_hl_op.sh b/src/lib/mk_hl_op.sh new file mode 100755 index 0000000..964a6f9 --- /dev/null +++ b/src/lib/mk_hl_op.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +for x in $(cat ../include/extensions/math.h) ; do + test "${x}" = "#ifdef" && continue + test "${x}" = "#endif" && continue + test "${x}" = "regFunc1" && continue + xx=${x#regFunc1\(} + fff=${xx%\)} + file=hl_ops/${fff}.cc + test -f ${file} && rm -f ${file} + echo "#include \"multi_array_header.h\"" >> ${file} + echo "#include \"high_level_operation.h\"" >> ${file} + echo "" >> ${file} + echo "namespace MultiArrayTools" >> ${file} + echo "{" >> ${file} + echo " template class HighLevelOp,1>;" >> ${file} + echo " template class HighLevelOp,1>;" >> ${file} + echo " template HighLevelOpHolder hl_${fff} (const HighLevelOpHolder& in);" >> ${file} + echo " template HighLevelOpHolder hl_${fff} (const HighLevelOpHolder& in);" >> ${file} + echo "}" >> ${file} +done + +for fff in plus minus multiplies divides ; do + file=hl_ops/${fff}.cc + test -f ${file} && rm -f ${fff} + echo "#include \"multi_array_header.h\"" >> ${file} + echo "#include \"high_level_operation.h\"" >> ${file} + echo "" >> ${file} + echo "namespace MultiArrayTools" >> ${file} + echo "{" >> ${file} + echo " template class HighLevelOp,2>;" >> ${file} + echo " template class HighLevelOp,2>;" >> ${file} + echo "}" >> ${file} +done