iloop + c++14

This commit is contained in:
Christian Zimmermann 2019-05-17 15:10:33 +02:00
parent 8e271ca0e4
commit 8ce2f52070
5 changed files with 152 additions and 4 deletions

View file

@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 2.8)
project(multi_array)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -g -Wpedantic -Ofast -march=native -faligned-new -funroll-loops -fopenmp")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -g -Wpedantic -O0 -march=native -faligned-new -funroll-loops -fopenmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -g -Wpedantic -Ofast -march=native -faligned-new -funroll-loops -fopenmp")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14 -g -Wpedantic -O0 -march=native -faligned-new -funroll-loops -fopenmp")
enable_testing()

View file

@ -8,6 +8,7 @@
#include "pack_num.h"
#include "map_range.h"
#include <functional>
#include "xfor/iloop.h"
namespace MultiArrayTools
{
@ -120,6 +121,15 @@ namespace MultiArrayTools
auto mkArray(const std::shared_ptr<Ranges>&... rs, const T& val)
-> MultiArray<T,Ranges...>;
template <class OpTp, class IndTp, class VarTp, class LTp>
auto mkILoop(const OpTp& opTp, const IndTp& indTp, const VarTp& varTp, const LTp& lTp,
const std::array<size_t,std::tuple_size<LTp>::value>& umpos,
const std::array<size_t,std::tuple_size<VarTp>::value>& setzero)
-> MultiArrayHelper::ILoop<OpTp,IndTp,VarTp,LTp>
{
return MultiArrayHelper::ILoop<OpTp,IndTp,VarTp,LTp>(opTp, indTp, varTp, lTp, umpos, setzero);
}
template <class IndexType>
inline void For(const std::shared_ptr<IndexType>& ind, const std::function<void(void)>& ll)
{

View file

@ -130,6 +130,15 @@ namespace MultiArrayTools
MAB::mInit = true;
}
template <typename T, class... SRanges>
Slice<T,SRanges...>& Slice<T,SRanges...>::operator=(T val)
{
OperationRoot<T,SRanges...> opr(data(), begin());
OperationValue<T> opv(val);
opr = opv;
return *this;
}
template <typename T, class... SRanges>
const T& Slice<T,SRanges...>::operator[](const IType& i) const
{

View file

@ -25,7 +25,7 @@ namespace MultiArrayTools
const T* data = nullptr);
ConstSlice(const std::shared_ptr<SRanges>&... ranges, const T* data = nullptr);
ConstSlice(const MultiArrayBase<T,AnonymousRange>& ma, SIZET<SRanges>... sizes);
virtual const T& operator[](const IType& i) const final;
virtual const T& at(const typename IType::MetaType& meta) const override;
@ -69,7 +69,9 @@ namespace MultiArrayTools
Slice(const std::tuple<std::shared_ptr<SRanges>...>& ranges,
T* data = nullptr);
Slice(const std::shared_ptr<SRanges>&... ranges, T* data = nullptr);
Slice& operator=(T val);
virtual const T& operator[](const IType& i) const final;
virtual T& operator[](const IType& i) final;
virtual const T& at(const typename IType::MetaType& meta) const override;

127
src/include/xfor/iloop.h Normal file
View file

@ -0,0 +1,127 @@
#ifndef __ma_iloop_h__
#define __ma_iloop_h__
#include <cstdlib>
#include <memory>
#include <tuple>
#include <array>
namespace MultiArrayHelper
{
template <size_t N>
struct NN
{
template <class LTp>
static inline constexpr size_t lsize(const LTp& ltp)
{
typedef typename std::tuple_element<N,LTp>::type LType;
return LType::SIZE + NN<N-1>::lsize(ltp);
}
template <class LTp>
static inline auto rootSteps(const LTp& ltp, std::intptr_t i = 0)
{
constexpr size_t M = std::tuple_size<LTp>::value;
return std::get<M-N-1>(ltp).rootSteps(i).extend( NN<N-1>::rootSteps(ltp,i) );
}
template <class VarTp>
static inline void zero(VarTp& vtp, const std::array<size_t,std::tuple_size<VarTp>::value>& setzero)
{
if(std::get<N>(setzero)){
(*std::get<N>(vtp)) = 0.;
}
NN<N-1>::zero(vtp, setzero);
}
template <class LTp, class ExtType>
static inline size_t exec(LTp& ltp, const std::array<size_t,std::tuple_size<LTp>::value>& umpos,
size_t mpos, ExtType pos)
{
NN<N-1>::exec(ltp,umpos,mpos,pos);
std::get<N>(ltp)(std::get<N>(umpos)*mpos, pos.template nn<NN<N-1>::lsize(ltp)>());
return 0;
}
};
template <>
struct NN<0>
{
template <class LTp>
static inline constexpr size_t lsize(const LTp& ltp)
{
typedef typename std::tuple_element<0,LTp>::type LType;
return LType::SIZE;
}
template <class LTp>
static inline auto rootSteps(const LTp& ltp, std::intptr_t i = 0)
{
constexpr size_t M = std::tuple_size<LTp>::value;
return std::get<M-1>(ltp).rootSteps(i);
}
template <class VarTp>
static inline void zero(VarTp& vtp, const std::array<size_t,std::tuple_size<VarTp>::value>& setzero)
{
if(std::get<0>(setzero)){
(*std::get<0>(vtp)) = 0.;
}
}
template <class LTp, class ExtType>
static inline size_t exec(LTp& ltp, const std::array<size_t,std::tuple_size<LTp>::value>& umpos,
size_t mpos, ExtType pos)
{
std::get<0>(ltp)(std::get<0>(umpos)*mpos, pos);
return 0;
}
};
template <class OpTp, class IndTp, class VarTp, class LTp>
class ILoop
{
private:
static constexpr size_t LTpSize = std::tuple_size<LTp>::value;
static constexpr size_t VarTpSize = std::tuple_size<VarTp>::value;
OpTp mOpTp;
IndTp mIndTp;
mutable VarTp mVarTp;
mutable LTp mLTp;
std::array<size_t,LTpSize> mUmpos; // ll(mpos, pos) or ll(0, pos)
std::array<size_t,VarTpSize> mSetzero; // set variable to zero after each cycle
public:
static constexpr size_t SIZE = NN<LTpSize-1>::lsize(std::declval<LTp>());
static constexpr bool CONT = false;
typedef decltype(NN<LTpSize-1>::rootSteps(mLTp)) ExtType;
ILoop(const OpTp& opTp, const IndTp& indTp, const VarTp& varTp, const LTp& lTp,
const std::array<size_t,LTpSize>& umpos, const std::array<size_t,VarTpSize>& setzero) :
mOpTp(opTp), mIndTp(indTp), mVarTp(varTp), mLTp(lTp), mUmpos(umpos), mSetzero(setzero) {}
inline size_t operator()(size_t mpos, ExtType pos)
{
NN<VarTpSize-1>::zero(mVarTp, mSetzero);
//VCHECK(mpos);
NN<LTpSize-1>::exec(mLTp, mUmpos, mpos, pos);
return 0;
}
auto rootSteps(std::intptr_t i = 0) const
-> ExtType
{
return NN<LTpSize-1>::rootSteps(mLTp,i);
}
};
}
#endif