2017-02-16 11:20:40 +01:00
|
|
|
// -*- C++ -*-
|
|
|
|
|
|
|
|
#ifndef __multi_array_operation_h__
|
|
|
|
#define __multi_array_operation_h__
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <tuple>
|
2017-03-22 21:51:54 +01:00
|
|
|
#include <cmath>
|
2017-08-30 17:56:38 +02:00
|
|
|
#include <map>
|
|
|
|
#include <utility>
|
2017-02-16 11:20:40 +01:00
|
|
|
|
|
|
|
#include "base_def.h"
|
2017-12-18 11:19:04 +01:00
|
|
|
#include "mbase_def.h"
|
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//#include "block/block.h"
|
2017-12-18 11:19:04 +01:00
|
|
|
#include "operation_utils.h"
|
2017-12-18 13:13:13 +01:00
|
|
|
#include "ranges/rheader.h"
|
|
|
|
#include "pack_num.h"
|
2017-02-16 11:20:40 +01:00
|
|
|
|
2017-12-25 13:44:55 +01:00
|
|
|
#include "ranges/index_info.h"
|
2018-01-15 18:31:47 +01:00
|
|
|
#include "arith.h"
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2017-02-16 11:20:40 +01:00
|
|
|
namespace MultiArrayTools
|
|
|
|
{
|
|
|
|
|
2017-08-26 22:53:02 +02:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
using namespace MultiArrayHelper;
|
|
|
|
}
|
|
|
|
|
2017-08-30 17:56:38 +02:00
|
|
|
template <typename T>
|
2017-12-16 20:38:57 +01:00
|
|
|
Block<T> makeBlock(const T* vec, size_t stepSize, size_t blockSize);
|
2017-12-24 18:14:07 +01:00
|
|
|
|
2017-08-30 17:56:38 +02:00
|
|
|
template <typename T>
|
2017-12-16 20:38:57 +01:00
|
|
|
MBlock<T> makeBlock(T* vec, size_t stepSize, size_t blockSize);
|
2017-08-30 17:56:38 +02:00
|
|
|
|
2017-12-26 15:13:50 +01:00
|
|
|
// dont use this for now !!
|
2017-10-31 19:22:34 +01:00
|
|
|
template <class OpClass>
|
2017-12-10 18:41:53 +01:00
|
|
|
std::shared_ptr<VIWB> seekBlockIndex(std::shared_ptr<VIWB> ownIdx,
|
|
|
|
const OpClass& second);
|
2017-08-30 19:41:49 +02:00
|
|
|
|
2017-12-26 15:13:50 +01:00
|
|
|
template <class OpClass>
|
|
|
|
const IndexInfo* seekBlockIndex(const IndexInfo* ownII,
|
|
|
|
const OpClass& second);
|
|
|
|
|
|
|
|
|
2017-08-30 19:41:49 +02:00
|
|
|
template <typename T, class OperationClass>
|
2017-08-11 11:30:27 +02:00
|
|
|
class OperationTemplate
|
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
2017-12-25 13:44:55 +01:00
|
|
|
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
|
|
|
|
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2017-08-11 11:30:27 +02:00
|
|
|
template <class Second>
|
2017-08-26 17:18:42 +02:00
|
|
|
auto operator+(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,plus<T>,OperationClass,Second>;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
|
|
|
template <class Second>
|
|
|
|
auto operator-(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,minus<T>,OperationClass,Second>;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
|
|
|
template <class Second>
|
|
|
|
auto operator*(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,multiplies<T>,OperationClass,Second>;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
|
|
|
template <class Second>
|
|
|
|
auto operator/(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,divides<T>,OperationClass,Second>;
|
2017-11-05 18:46:38 +01:00
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
template <class IndexType>
|
|
|
|
auto c(std::shared_ptr<IndexType>& ind) const
|
|
|
|
-> Contraction<T,OperationClass,IndexType>;
|
2017-11-05 18:46:38 +01:00
|
|
|
|
2017-08-11 15:26:10 +02:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
friend OperationClass;
|
|
|
|
OperationTemplate() = default;
|
2017-08-11 11:30:27 +02:00
|
|
|
};
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2017-10-31 19:22:34 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2018-01-05 13:56:16 +01:00
|
|
|
class OperationMaster
|
2017-02-24 15:08:42 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2018-01-07 23:08:16 +01:00
|
|
|
class AssignmentExpr
|
|
|
|
{
|
2018-01-13 18:07:52 +01:00
|
|
|
private:
|
|
|
|
AssignmentExpr() = default;
|
|
|
|
//AssignmentExpr(const AssignmentExpr& in) = default;
|
|
|
|
//AssignmentExpr& operator=(const AssignmentExpr& in) = default;
|
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
OperationMaster& mM;
|
|
|
|
const OpClass& mSec;
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-01-07 23:08:16 +01:00
|
|
|
public:
|
2018-01-09 17:24:10 +01:00
|
|
|
static size_t layer() { return 0; }
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-02-12 00:11:24 +01:00
|
|
|
static constexpr size_t LAYER = 0;
|
|
|
|
static constexpr size_t SIZE = OpClass::SIZE;
|
|
|
|
typedef decltype(mSec.rootSteps()) ExtType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
AssignmentExpr(OperationMaster& m, const OpClass& sec);
|
2018-01-07 23:08:16 +01:00
|
|
|
|
2018-02-12 00:11:24 +01:00
|
|
|
AssignmentExpr(const AssignmentExpr& in) = default;
|
2018-01-07 23:08:16 +01:00
|
|
|
AssignmentExpr(AssignmentExpr&& in) = default;
|
2018-01-13 18:07:52 +01:00
|
|
|
//AssignmentExpr& operator=(const AssignmentExpr&& in) = default;
|
2018-01-07 23:08:16 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
inline void operator()(size_t start = 0) const;
|
|
|
|
inline void operator()(size_t start, ExtType last) const;
|
2018-01-07 23:08:16 +01:00
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
2018-01-07 23:08:16 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-08-27 17:52:50 +02:00
|
|
|
typedef T value_type;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef OperationBase<T> OB;
|
2017-08-11 15:26:10 +02:00
|
|
|
typedef ContainerRange<Ranges...> CRange;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef typename MultiRange<Ranges...>::IndexType IndexType;
|
2018-01-04 11:43:45 +01:00
|
|
|
typedef MBlock<T> bType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
static size_t rootNum() { return 1; }
|
2018-01-04 11:43:45 +01:00
|
|
|
|
2017-10-31 19:22:34 +01:00
|
|
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
2017-08-11 15:26:10 +02:00
|
|
|
std::shared_ptr<typename CRange::IndexType>& index);
|
2017-12-24 18:14:07 +01:00
|
|
|
|
|
|
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
|
|
|
std::shared_ptr<typename CRange::IndexType>& index,
|
2017-12-26 15:13:50 +01:00
|
|
|
const IndexInfo* blockIndex);
|
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//MBlock<T>& get();
|
|
|
|
//const Block<T>& get() const;
|
2017-02-27 17:00:51 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
inline void set(size_t pos, T val) { mDataPtr[pos] = val };
|
|
|
|
inline T get(size_t pos);
|
2018-01-15 14:56:22 +01:00
|
|
|
inline const T& get(size_t pos) const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//std::vector<BTSS> block(const IndexInfo* blockIndex, bool init = false) const;
|
|
|
|
//const OperationMaster& block() const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
|
|
|
std::shared_ptr<IndexType> mkIndex(std::shared_ptr<typename CRange::IndexType>& index);
|
2017-12-24 18:14:07 +01:00
|
|
|
void performAssignment(std::intptr_t blockIndexNum);
|
2017-10-31 19:22:34 +01:00
|
|
|
OpClass const& mSecond;
|
2017-08-25 17:02:23 +02:00
|
|
|
MutableMultiArrayBase<T,Ranges...>& mArrayRef;
|
2018-02-13 15:38:03 +01:00
|
|
|
T* mDataPtr;
|
2017-08-11 11:30:27 +02:00
|
|
|
std::shared_ptr<IndexType> mIndex;
|
2017-12-25 13:44:55 +01:00
|
|
|
IndexInfo mIInfo;
|
2018-01-04 11:43:45 +01:00
|
|
|
mutable bType mBlock;
|
2017-02-16 11:20:40 +01:00
|
|
|
};
|
2017-08-10 15:12:26 +02:00
|
|
|
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class... Ranges>
|
2017-10-31 19:22:34 +01:00
|
|
|
class ConstOperationRoot : /*public OperationBase<T>,*/
|
2017-08-30 19:41:49 +02:00
|
|
|
public OperationTemplate<T,ConstOperationRoot<T,Ranges...> >
|
2017-03-16 19:30:43 +01:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef OperationBase<T> OB;
|
2017-08-30 19:41:49 +02:00
|
|
|
typedef OperationTemplate<T,ConstOperationRoot<T,Ranges...> > OT;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef ContainerRange<Ranges...> CRange;
|
|
|
|
typedef typename CRange::IndexType IndexType;
|
2018-01-04 11:43:45 +01:00
|
|
|
typedef Block<T> bType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
static size_t rootNum() { return 1; }
|
2018-01-13 18:07:52 +01:00
|
|
|
static const size_t SIZE = 1;
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2017-08-25 17:02:23 +02:00
|
|
|
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
2017-08-10 15:12:26 +02:00
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//const Block<T>& get() const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-01-14 19:15:05 +01:00
|
|
|
inline const T& get(const ET& pos) const;
|
2018-02-13 15:38:03 +01:00
|
|
|
|
|
|
|
//std::vector<BTSS> block(const IndexInfo* blockIndex, bool init = false) const;
|
|
|
|
//const ConstOperationRoot& block() const;
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr loop(Expr exp) const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
|
|
|
std::shared_ptr<IndexType>
|
|
|
|
mkIndex(const MultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
|
|
|
|
2017-08-25 17:02:23 +02:00
|
|
|
MultiArrayBase<T,Ranges...> const& mArrayRef;
|
2018-02-13 15:38:03 +01:00
|
|
|
const T* mDataPtr;
|
2017-08-10 15:12:26 +02:00
|
|
|
std::shared_ptr<IndexType> mIndex;
|
2017-12-25 13:44:55 +01:00
|
|
|
IndexInfo mIInfo;
|
2018-02-13 15:38:03 +01:00
|
|
|
//mutable bType mBlock;
|
2017-03-16 19:30:43 +01:00
|
|
|
};
|
2017-09-11 12:54:24 +02:00
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class... Ranges>
|
2018-01-05 13:56:16 +01:00
|
|
|
class OperationRoot : public OperationTemplate<T,OperationRoot<T,Ranges...> >
|
2017-03-26 16:55:52 +02:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef OperationBase<T> OB;
|
2017-08-30 19:41:49 +02:00
|
|
|
typedef OperationTemplate<T,OperationRoot<T,Ranges...> > OT;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef ContainerRange<Ranges...> CRange;
|
|
|
|
typedef typename CRange::IndexType IndexType;
|
2018-01-04 11:43:45 +01:00
|
|
|
typedef MBlock<T> bType;
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
static size_t rootNum() { return 1; }
|
2018-01-13 18:07:52 +01:00
|
|
|
static const size_t SIZE = 1;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2017-08-25 17:02:23 +02:00
|
|
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
2017-08-10 15:12:26 +02:00
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
2017-08-11 11:30:27 +02:00
|
|
|
|
2017-10-31 19:22:34 +01:00
|
|
|
template <class OpClass>
|
|
|
|
OperationMaster<T,OpClass,Ranges...> operator=(const OpClass& in);
|
2017-08-11 11:30:27 +02:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//const MBlock<T>& get() const;
|
|
|
|
//MBlock<T>& get();
|
2017-12-26 15:13:50 +01:00
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-01-14 19:15:05 +01:00
|
|
|
inline const T& get(const ET& pos) const;
|
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-01-14 19:15:05 +01:00
|
|
|
inline T& get(const ET& pos);
|
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//OperationRoot& set(const IndexInfo* blockIndex);
|
|
|
|
//std::vector<BTSS> block(const IndexInfo* blockIndex, bool init = false) const;
|
|
|
|
//const OperationRoot& block() const;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr loop(Expr exp) const;
|
2017-05-24 19:01:02 +02:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
|
|
|
std::shared_ptr<IndexType>
|
|
|
|
mkIndex(const MultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
|
|
|
|
2017-08-25 17:02:23 +02:00
|
|
|
MutableMultiArrayBase<T,Ranges...>& mArrayRef;
|
2018-02-13 15:38:03 +01:00
|
|
|
T* mDataPtr;
|
2017-08-10 15:12:26 +02:00
|
|
|
std::shared_ptr<IndexType> mIndex;
|
2017-12-25 13:44:55 +01:00
|
|
|
IndexInfo mIInfo;
|
2018-02-13 15:38:03 +01:00
|
|
|
//mutable bType mBlock;
|
|
|
|
//const IndexInfo* mBlockII; // predefine to save time
|
2017-02-16 11:20:40 +01:00
|
|
|
};
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
template <class Op>
|
|
|
|
size_t sumRootNum()
|
|
|
|
{
|
|
|
|
return typename Op::rootNum();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class Op1, class Op2, class... Ops>
|
|
|
|
size_t sumRootNum()
|
|
|
|
{
|
|
|
|
return typename Op1::rootNum() + sumRootNum<Op2,Ops...>();
|
|
|
|
}
|
2018-01-13 18:07:52 +01:00
|
|
|
|
|
|
|
template <size_t N>
|
|
|
|
struct RootSumN
|
|
|
|
{
|
|
|
|
template <class Op1, class... Ops>
|
|
|
|
struct rs
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = Op1::SIZE + RootSumN<N-1>::template rs<Ops...>::SIZE;
|
2018-01-13 18:07:52 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct RootSumN<0>
|
|
|
|
{
|
|
|
|
template <class Op1>
|
|
|
|
struct rs
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = Op1::SIZE;
|
2018-01-13 18:07:52 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <class... Ops>
|
|
|
|
struct RootSum
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = RootSumN<sizeof...(Ops)-1>::template rs<Ops...>::SIZE;
|
2018-01-13 18:07:52 +01:00
|
|
|
};
|
|
|
|
|
2017-09-11 12:54:24 +02:00
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
2018-01-05 13:56:16 +01:00
|
|
|
class Operation : public OperationTemplate<T,Operation<T,OpFunction,Ops...> >
|
2017-03-22 11:44:33 +01:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef OperationBase<T> OB;
|
2017-08-30 19:41:49 +02:00
|
|
|
typedef OperationTemplate<T,Operation<T,OpFunction,Ops...> > OT;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef OpFunction F;
|
2018-01-04 11:43:45 +01:00
|
|
|
typedef BlockResult<T> bType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
static size_t rootNum() { return sumRootNum<Ops...>(); }
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
private:
|
2018-02-13 15:38:03 +01:00
|
|
|
std::tuple<Ops...> mOps;
|
2018-01-09 17:24:10 +01:00
|
|
|
mutable bType mRes;
|
|
|
|
|
|
|
|
public:
|
2018-02-13 15:38:03 +01:00
|
|
|
typedef decltype(PackNum<sizeof...(Ops)-1>::mkSteps(0, mOps)) ETuple;
|
2018-01-14 19:15:05 +01:00
|
|
|
//typedef decltype(PackNum<sizeof...(Ops)-1>::template mkLoopType<Ops...>) LType;
|
|
|
|
|
2017-08-11 15:26:10 +02:00
|
|
|
Operation(const Ops&... ops);
|
2017-03-22 11:44:33 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//const BlockResult<T>& get() const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-01-14 22:41:35 +01:00
|
|
|
inline T get(const ET& pos) const;
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//std::vector<BTSS> block(const IndexInfo* blockIndex, bool init = false) const;
|
|
|
|
//const Operation& block() const;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
2018-02-13 15:38:03 +01:00
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps));
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
auto loop(Expr exp) const
|
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp));
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2017-03-22 11:44:33 +01:00
|
|
|
};
|
2017-11-04 22:49:55 +01:00
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
2017-11-04 22:49:55 +01:00
|
|
|
class Contraction : public OperationTemplate<T,Contraction<T,Op,IndexType> >
|
2017-11-01 21:26:45 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef T value_type;
|
2017-11-02 21:20:31 +01:00
|
|
|
typedef OperationTemplate<T,Contraction<T,Op,IndexType> > OT;
|
2018-01-04 11:43:45 +01:00
|
|
|
typedef BlockResult<T> bType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
static size_t rootNum() { return typename Op::rootNum(); }
|
2018-01-13 18:07:52 +01:00
|
|
|
static const size_t SIZE = Op::SIZE;
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
|
|
|
|
|
|
|
const Op& mOp;
|
|
|
|
std::shared_ptr<IndexType> mInd;
|
|
|
|
mutable bType mRes;
|
|
|
|
|
|
|
|
public:
|
2018-01-14 19:15:05 +01:00
|
|
|
typedef decltype(mOp.rootSteps(0)) ETuple;
|
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
Contraction(const Op& op, std::shared_ptr<IndexType> ind);
|
2017-11-01 21:26:45 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//const BlockResult<T>& get() const;
|
2017-11-01 21:26:45 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-01-14 22:41:35 +01:00
|
|
|
inline T get(const ET& pos) const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//std::vector<BTSS> block(const IndexInfo* blockIndex, bool init = false) const;
|
|
|
|
//const Contraction& block() const;
|
2017-11-01 21:26:45 +01:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum));
|
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 18:26:56 +01:00
|
|
|
auto loop(Expr exp) const -> decltype(mInd->iforh(exp));
|
2017-11-01 21:26:45 +01:00
|
|
|
};
|
|
|
|
|
2017-08-11 15:26:10 +02:00
|
|
|
}
|
2017-02-16 11:20:40 +01:00
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/* ========================= *
|
|
|
|
* --- TEMPLATE CODE --- *
|
|
|
|
* ========================= */
|
|
|
|
|
|
|
|
namespace MultiArrayTools
|
|
|
|
{
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
using namespace MultiArrayHelper;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2017-12-16 20:38:57 +01:00
|
|
|
Block<T> makeBlock(const T* vec, size_t stepSize, size_t blockSize)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
return Block<T>(vec, 0, blockSize, stepSize);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2017-12-16 20:38:57 +01:00
|
|
|
MBlock<T> makeBlock(T* vec, size_t stepSize, size_t blockSize)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
return MBlock<T>(vec, 0, blockSize, stepSize);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
2017-12-26 15:13:50 +01:00
|
|
|
// dont use this for now !!
|
2017-11-20 21:35:25 +01:00
|
|
|
template <class OpClass>
|
2017-12-11 18:49:43 +01:00
|
|
|
std::shared_ptr<VIWB> seekBlockIndex(std::shared_ptr<VIWB> ownIdx,
|
|
|
|
const OpClass& second)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2017-12-26 15:13:50 +01:00
|
|
|
assert(0); // dont use this for now !!
|
2017-12-11 18:49:43 +01:00
|
|
|
std::vector<std::shared_ptr<VIWB> > ivec;
|
2017-11-20 21:35:25 +01:00
|
|
|
seekIndexInst(ownIdx, ivec);
|
2017-12-11 18:49:43 +01:00
|
|
|
std::map<std::shared_ptr<VIWB>, std::vector<BTSS> > mp;
|
2017-11-20 21:35:25 +01:00
|
|
|
|
|
|
|
for(auto& xx: ivec){
|
|
|
|
mp[xx] = second.block(xx);
|
|
|
|
}
|
|
|
|
// seek minimal number of VALUEs => guarantees absence of conflicting blocks
|
|
|
|
minimizeAppearanceOfType(mp, BlockType::VALUE);
|
|
|
|
// seek mininmal number of SPLITs => maximal vectorization possible
|
|
|
|
minimizeAppearanceOfType(mp, BlockType::SPLIT);
|
|
|
|
|
|
|
|
return mp.begin()->first;
|
|
|
|
}
|
|
|
|
|
2017-12-26 15:13:50 +01:00
|
|
|
template <class OpClass>
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/***************************
|
|
|
|
* OperationTemplate *
|
|
|
|
***************************/
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
|
|
|
auto OperationTemplate<T,OperationClass>::operator+(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,plus<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-01-14 19:15:05 +01:00
|
|
|
return Operation<T,plus<T>,OperationClass,Second>(THIS(), in);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
|
|
|
auto OperationTemplate<T,OperationClass>::operator-(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,minus<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-01-14 19:15:05 +01:00
|
|
|
return Operation<T,minus<T>,OperationClass,Second>(THIS(), in);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
|
|
|
auto OperationTemplate<T,OperationClass>::operator*(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,multiplies<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-01-14 19:15:05 +01:00
|
|
|
return Operation<T,multiplies<T>,OperationClass,Second>(THIS(), in);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
|
|
|
auto OperationTemplate<T,OperationClass>::operator/(const Second& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,divides<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-01-14 19:15:05 +01:00
|
|
|
return Operation<T,divides<T>,OperationClass,Second>(THIS(), in);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class IndexType>
|
|
|
|
auto OperationTemplate<T,OperationClass>::c(std::shared_ptr<IndexType>& ind) const
|
|
|
|
-> Contraction<T,OperationClass,IndexType>
|
|
|
|
{
|
2017-12-25 13:44:55 +01:00
|
|
|
return Contraction<T,OperationClass,IndexType>(THIS(), ind);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
/*****************************************
|
|
|
|
* OperationMaster::AssignmentExpr *
|
|
|
|
*****************************************/
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
|
|
|
AssignmentExpr(OperationMaster& m, const OpClass& sec) :
|
|
|
|
mM(m), mSec(sec) {}
|
|
|
|
|
|
|
|
/*
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
inline void OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
|
|
|
operator()(size_t start)
|
|
|
|
{
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
inline void OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
2018-02-13 15:38:03 +01:00
|
|
|
operator()(size_t start, ExtType last) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
mM.get(start) += mSec.template get<ExtType>(last);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2018-02-12 00:11:24 +01:00
|
|
|
typename OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::ExtType
|
2018-01-14 19:15:05 +01:00
|
|
|
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
2018-02-12 18:26:56 +01:00
|
|
|
rootSteps(std::intptr_t iPtrNum) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
|
|
|
return mSec.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
|
|
|
|
/*************************
|
|
|
|
* OperationMaster *
|
|
|
|
*************************/
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
OperationMaster<T,OpClass,Ranges...>::
|
|
|
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
|
|
|
std::shared_ptr<typename CRange::IndexType>& index) :
|
2018-02-13 15:38:03 +01:00
|
|
|
mSecond(second), mArrayRef(ma), mDataPtr(mArrayRef.data()),
|
2018-01-14 19:15:05 +01:00
|
|
|
mIndex(mkIndex(index)), mIInfo(*mIndex)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
//auto blockIndex = seekBlockIndex( &mIInfo, second);
|
|
|
|
//std::intptr_t blockIndexNum = blockIndex->getPtrNum();
|
2017-12-10 18:41:53 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
//block(blockIndex, true);
|
|
|
|
//second.block(blockIndex, true);
|
2017-12-24 18:14:07 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
performAssignment(0);
|
2017-12-24 18:14:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
OperationMaster<T,OpClass,Ranges...>::
|
|
|
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
|
|
|
std::shared_ptr<typename CRange::IndexType>& index,
|
2017-12-26 15:13:50 +01:00
|
|
|
const IndexInfo* blockIndex) :
|
2018-02-13 15:38:03 +01:00
|
|
|
mSecond(second), mArrayRef(ma), mDataPtr(mArrayRef.data()),
|
2018-01-14 19:15:05 +01:00
|
|
|
mIndex(mkIndex(index)), mIInfo(*mIndex)
|
2017-12-24 18:14:07 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
//std::intptr_t blockIndexNum = blockIndex->getPtrNum();
|
|
|
|
//second.block(blockIndex, true);
|
2017-12-24 18:14:07 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
performAssignment(0);
|
2017-12-24 18:14:07 +01:00
|
|
|
}
|
|
|
|
|
2017-12-25 13:44:55 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
std::shared_ptr<typename OperationMaster<T,OpClass,Ranges...>::IndexType>
|
|
|
|
OperationMaster<T,OpClass,Ranges...>::
|
|
|
|
mkIndex(std::shared_ptr<typename CRange::IndexType>& index)
|
|
|
|
{
|
|
|
|
MultiRangeFactory<Ranges...> mrf( index->range() );
|
|
|
|
std::shared_ptr<MultiRange<Ranges...> > mr =
|
|
|
|
std::dynamic_pointer_cast<MultiRange<Ranges...> >( mrf.create() );
|
|
|
|
auto i = std::make_shared<IndexType>( mr->begin() );
|
|
|
|
(*i) = *index;
|
|
|
|
return i;
|
|
|
|
}
|
2017-12-24 18:14:07 +01:00
|
|
|
|
2017-12-25 13:44:55 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2017-12-24 18:14:07 +01:00
|
|
|
void OperationMaster<T,OpClass,Ranges...>::performAssignment(std::intptr_t blockIndexNum)
|
|
|
|
{
|
2018-01-13 18:07:52 +01:00
|
|
|
#define XX_USE_NEW_LOOP_ROUTINE_XX
|
2018-01-09 17:24:10 +01:00
|
|
|
#ifdef XX_USE_NEW_LOOP_ROUTINE_XX
|
|
|
|
// === N E W ===
|
2018-01-14 19:15:05 +01:00
|
|
|
AssignmentExpr ae(*this, mSecond); // Expression to be executed within loop
|
|
|
|
//const auto hiddenLoop = mSecond.loop(AssignmentExpr(*this, mSecond)); // hidden loop within 'mSecond' e.g. contractions
|
2018-02-13 15:38:03 +01:00
|
|
|
auto loop = mIndex->ifor
|
2018-01-14 19:15:05 +01:00
|
|
|
( mSecond.template loop<AssignmentExpr>
|
|
|
|
( std::move(ae) ) ); // init overall loop(s)
|
|
|
|
loop(); // execute overall loop(s) and so internal hidden loops and so the inherited expressions
|
2018-01-09 17:24:10 +01:00
|
|
|
#else
|
|
|
|
// === O L D ===
|
2017-12-10 18:41:53 +01:00
|
|
|
for(*mIndex = 0; mIndex->pos() != mIndex->max(); mIndex->pp(blockIndexNum) ){
|
2017-12-19 19:05:10 +01:00
|
|
|
block();
|
2017-11-20 21:35:25 +01:00
|
|
|
get() = mSecond.get();
|
|
|
|
}
|
2018-01-09 17:24:10 +01:00
|
|
|
#endif
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
MBlock<T>& OperationMaster<T,OpClass,Ranges...>::get()
|
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
return mBlock;
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
const Block<T>& OperationMaster<T,OpClass,Ranges...>::get() const
|
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
return mBlock;
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2018-01-15 14:56:22 +01:00
|
|
|
inline T& OperationMaster<T,OpClass,Ranges...>::get(size_t pos)
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-01-15 14:56:22 +01:00
|
|
|
//assert(pos < mIndex->max());
|
|
|
|
//if(pos >= mIndex->max()) { VCHECK(pos); VCHECK(mIndex->max()); assert(0); }
|
|
|
|
//VCHECK(pos);
|
2018-02-13 15:38:03 +01:00
|
|
|
return mDataPtr[pos];
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2018-01-15 14:56:22 +01:00
|
|
|
inline const T& OperationMaster<T,OpClass,Ranges...>::get(size_t pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-01-15 14:56:22 +01:00
|
|
|
//VCHECK(pos);
|
2018-02-13 15:38:03 +01:00
|
|
|
return mDataPtr[pos];
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-12-26 15:13:50 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
std::vector<BTSS> OperationMaster<T,OpClass,Ranges...>::block(const IndexInfo* blockIndex, bool init) const
|
|
|
|
{
|
|
|
|
std::vector<BTSS> btv(1, getBlockType( &mIInfo, blockIndex, true) );
|
|
|
|
if(init){
|
|
|
|
mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max());
|
|
|
|
}
|
|
|
|
return btv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
const OperationMaster<T,OpClass,Ranges...>& OperationMaster<T,OpClass,Ranges...>::block() const
|
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
mBlock.set( mIndex->pos() );
|
2017-11-20 21:35:25 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/****************************
|
|
|
|
* ConstOperationRoot *
|
|
|
|
****************************/
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
ConstOperationRoot<T,Ranges...>::
|
|
|
|
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
2017-12-25 13:44:55 +01:00
|
|
|
//OperationTemplate<T,ConstOperationRoot<T,Ranges...> >(this),
|
2018-02-13 15:38:03 +01:00
|
|
|
mArrayRef(ma), mDataPtr(mArrayRef.data()),
|
2018-01-14 19:15:05 +01:00
|
|
|
mIndex( mkIndex(ma,indices...) ), mIInfo(*mIndex)
|
2017-12-25 13:44:55 +01:00
|
|
|
{}
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
std::shared_ptr<typename ConstOperationRoot<T,Ranges...>::IndexType>
|
|
|
|
ConstOperationRoot<T,Ranges...>::
|
|
|
|
mkIndex(const MultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2017-12-25 13:44:55 +01:00
|
|
|
auto i = std::make_shared<IndexType>( ma.range() );
|
2017-11-20 21:35:25 +01:00
|
|
|
(*mIndex)(indices...);
|
2017-12-25 13:44:55 +01:00
|
|
|
return i;
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
const Block<T>& ConstOperationRoot<T,Ranges...>::get() const
|
|
|
|
{
|
|
|
|
block();
|
2017-12-16 20:38:57 +01:00
|
|
|
return mBlock;
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-01-14 19:15:05 +01:00
|
|
|
inline const T& ConstOperationRoot<T,Ranges...>::get(const ET& pos) const
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return mDataPtr[pos.val()];
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-12-26 15:13:50 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
std::vector<BTSS> ConstOperationRoot<T,Ranges...>::block(const IndexInfo* blockIndex, bool init) const
|
|
|
|
{
|
|
|
|
std::vector<BTSS> btv(1, getBlockType( &mIInfo, blockIndex, true) );
|
|
|
|
if(init){
|
|
|
|
mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max());
|
|
|
|
}
|
|
|
|
return btv;
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
const ConstOperationRoot<T,Ranges...>& ConstOperationRoot<T,Ranges...>::block() const
|
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
mBlock.set( (*mIndex)().pos() );
|
2017-11-20 21:35:25 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> ConstOperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return MExt<void>(0u); // !!!!!!
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr ConstOperationRoot<T,Ranges...>::loop(Expr exp) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 00:11:24 +01:00
|
|
|
return exp;
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2017-11-20 21:35:25 +01:00
|
|
|
|
|
|
|
/***********************
|
|
|
|
* OperationRoot *
|
|
|
|
***********************/
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
OperationRoot<T,Ranges...>::
|
|
|
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
2017-12-25 13:44:55 +01:00
|
|
|
//OperationTemplate<T,OperationRoot<T,Ranges...> >(this),
|
2018-02-13 15:38:03 +01:00
|
|
|
mArrayRef(ma), mDataPtr(mArrayRef.data()),
|
|
|
|
mIndex( mkIndex( ma, indices... ) ), mIInfo(*mIndex)
|
|
|
|
//mBlockII(nullptr)
|
2017-12-25 13:44:55 +01:00
|
|
|
{}
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
std::shared_ptr<typename OperationRoot<T,Ranges...>::IndexType>
|
|
|
|
OperationRoot<T,Ranges...>::
|
|
|
|
mkIndex(const MultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2017-12-25 13:44:55 +01:00
|
|
|
auto i = std::make_shared<IndexType>( ma.range() );
|
2017-11-20 21:35:25 +01:00
|
|
|
(*mIndex)(indices...);
|
2017-12-25 13:44:55 +01:00
|
|
|
return i;
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class OpClass>
|
|
|
|
OperationMaster<T,OpClass,Ranges...> OperationRoot<T,Ranges...>::operator=(const OpClass& in)
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
//if(mBlockII != nullptr){
|
|
|
|
// return OperationMaster<T,OpClass,Ranges...>(mArrayRef, in, mIndex, mBlockII);
|
|
|
|
//}
|
|
|
|
//else {
|
2017-12-24 18:14:07 +01:00
|
|
|
return OperationMaster<T,OpClass,Ranges...>(mArrayRef, in, mIndex);
|
2018-02-13 15:38:03 +01:00
|
|
|
//}
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
const MBlock<T>& OperationRoot<T,Ranges...>::get() const
|
|
|
|
{
|
|
|
|
block();
|
2017-12-16 20:38:57 +01:00
|
|
|
return mBlock;
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
MBlock<T>& OperationRoot<T,Ranges...>::get()
|
|
|
|
{
|
|
|
|
block();
|
2017-12-16 20:38:57 +01:00
|
|
|
return mBlock;
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-01-14 19:15:05 +01:00
|
|
|
inline const T& OperationRoot<T,Ranges...>::get(const ET& pos) const
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return mDataPtr[pos.val()];
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-01-14 19:15:05 +01:00
|
|
|
inline T& OperationRoot<T,Ranges...>::get(const ET& pos)
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return mDataPtr[pos.val()];
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-12-26 15:13:50 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
OperationRoot<T,Ranges...>&
|
|
|
|
OperationRoot<T,Ranges...>::set(const IndexInfo* blockIndex)
|
|
|
|
{
|
|
|
|
mBlockII = blockIndex;
|
|
|
|
return *this;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
|
2017-12-26 15:13:50 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
std::vector<BTSS> OperationRoot<T,Ranges...>::block(const IndexInfo* blockIndex, bool init) const
|
|
|
|
{
|
|
|
|
std::vector<BTSS> btv(1, getBlockType( &mIInfo, blockIndex, true) );
|
|
|
|
if(init){
|
|
|
|
mBlock = makeBlock(mArrayRef.data(), btv[0].second, blockIndex->max());
|
|
|
|
}
|
|
|
|
return btv;
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
const OperationRoot<T,Ranges...>& OperationRoot<T,Ranges...>::block() const
|
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
mBlock.set( (*mIndex)().pos() );
|
2017-11-20 21:35:25 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> OperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return MExt<void>(0u); // !!!!!!
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr OperationRoot<T,Ranges...>::loop(Expr exp) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 00:11:24 +01:00
|
|
|
return exp;
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2017-11-20 21:35:25 +01:00
|
|
|
|
|
|
|
/*******************
|
|
|
|
* Operation *
|
|
|
|
*******************/
|
|
|
|
|
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
Operation<T,OpFunction,Ops...>::Operation(const Ops&... ops) :
|
2017-12-25 13:44:55 +01:00
|
|
|
//OperationTemplate<T,Operation<T,OpFunction,Ops...> >(this),
|
2017-11-20 21:35:25 +01:00
|
|
|
mOps(ops...) {}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
const BlockResult<T>& Operation<T,OpFunction,Ops...>::get() const
|
|
|
|
{
|
2017-12-22 14:15:09 +01:00
|
|
|
PackNum<sizeof...(Ops)-1>::template unpackArgs<T,OpFunction>(mRes, mOps);
|
2017-11-20 21:35:25 +01:00
|
|
|
return mRes;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-01-14 22:41:35 +01:00
|
|
|
inline T Operation<T,OpFunction,Ops...>::get(const ET& pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
|
|
|
typedef std::tuple<Ops const&...> OpTuple;
|
2018-02-13 15:38:03 +01:00
|
|
|
return PackNum<sizeof...(Ops)-1>::
|
|
|
|
template mkOpExpr<SIZE,T,ET,OpTuple,OpFunction>(pos, mOps);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-12-26 15:13:50 +01:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
std::vector<BTSS> Operation<T,OpFunction,Ops...>::block(const IndexInfo* blockIndex, bool init) const
|
|
|
|
{
|
|
|
|
std::vector<BTSS> btv;
|
|
|
|
PackNum<sizeof...(Ops)-1>::makeBlockTypeVec(btv, mOps, blockIndex, init);
|
|
|
|
if(init){
|
|
|
|
mRes.init(blockIndex->max());
|
|
|
|
}
|
|
|
|
return btv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
const Operation<T,OpFunction,Ops...>& Operation<T,OpFunction,Ops...>::block() const
|
|
|
|
{
|
2017-12-16 20:38:57 +01:00
|
|
|
//mBlock.set( mIndex->pos() );
|
2017-11-20 21:35:25 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
2018-01-14 19:15:05 +01:00
|
|
|
auto Operation<T,OpFunction,Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
2018-02-13 15:38:03 +01:00
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps))
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
auto Operation<T,OpFunction,Ops...>::loop(Expr exp) const
|
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp ))
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 00:11:24 +01:00
|
|
|
return PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp );
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/*********************
|
|
|
|
* Contraction *
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
Contraction<T,Op,IndexType>::Contraction(const Op& op, std::shared_ptr<IndexType> ind) :
|
2017-12-25 13:44:55 +01:00
|
|
|
//OperationTemplate<T,Contraction<T,Op,IndexType> >(this),
|
2017-11-20 21:35:25 +01:00
|
|
|
mOp(op),
|
|
|
|
mInd(ind) {}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
const BlockResult<T>& Contraction<T,Op,IndexType>::get() const
|
|
|
|
{
|
|
|
|
BlockBinaryOpSelf<T,std::plus<T>,decltype(mOp.get())> f(mRes);
|
|
|
|
for(*mInd = 0; mInd->pos() != mInd->max(); ++(*mInd)){
|
|
|
|
f(mOp.get());
|
|
|
|
}
|
|
|
|
return mRes;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-14 19:15:05 +01:00
|
|
|
// forward loop !!!!
|
|
|
|
template <typename T, class Op, class IndexType>
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-01-14 22:41:35 +01:00
|
|
|
inline T Contraction<T,Op,IndexType>::get(const ET& pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return mOp.template get<ET>(pos);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
/*
|
2017-12-26 15:13:50 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
std::vector<BTSS> Contraction<T,Op,IndexType>::block(const IndexInfo* blockIndex, bool init) const
|
|
|
|
{
|
|
|
|
if(init){
|
|
|
|
mRes.init(blockIndex->max());
|
|
|
|
}
|
|
|
|
return mOp.block(blockIndex, init);
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
const Contraction<T,Op,IndexType>& Contraction<T,Op,IndexType>::block() const
|
|
|
|
{
|
|
|
|
return *this;
|
|
|
|
}
|
2018-02-13 15:38:03 +01:00
|
|
|
*/
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
2018-01-14 19:15:05 +01:00
|
|
|
auto Contraction<T,Op,IndexType>::rootSteps(std::intptr_t iPtrNum) const
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum))
|
|
|
|
{
|
|
|
|
return mOp.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
auto Contraction<T,Op,IndexType>::loop(Expr exp) const -> decltype(mInd->iforh(exp))
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-02-12 00:11:24 +01:00
|
|
|
return mInd->iforh(exp);
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2017-02-16 11:20:40 +01:00
|
|
|
|
|
|
|
#endif
|