3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-25 13:53:40 +01:00

arrays: clean cache, add traits ...

- also add simple c14 helpers ....
This commit is contained in:
Olivier Parcollet 2013-11-03 21:49:35 +01:00
parent 9cdc139214
commit d7cf223994
7 changed files with 177 additions and 131 deletions

View File

@ -2,7 +2,7 @@
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2012 by O. Parcollet * Copyright (C) 2012-2013 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -22,92 +22,91 @@
#define TRIQS_ARRAYS_CACHE_H #define TRIQS_ARRAYS_CACHE_H
#include "./array.hpp" #include "./array.hpp"
#include <triqs/utility/view_tools.hpp> #include <triqs/utility/view_tools.hpp>
namespace triqs { namespace arrays { #include <triqs/utility/c14.hpp>
namespace triqs {
namespace arrays {
template<typename DataType, typename CacheType> class const_cache; // ----------------- the implementation class -----------------------
template<typename DataType, typename CacheType> class cache; template <typename DataType, bool IsConst> class cache_impl {
template<typename D>
const_cache<D, array<typename D::value_type, D::domain_type::rank> >
make_const_cache( D const & x, memory_layout< D::domain_type::rank> ml = memory_layout< D::domain_type::rank>('C') ) {
return const_cache<D, array<typename D::value_type, D::domain_type::rank> > (x,ml);
}
template<typename D>
cache<D, array<typename D::value_type, D::domain_type::rank> >
make_cache( D const & x, memory_layout< D::domain_type::rank> ml = memory_layout< D::domain_type::rank>('C') ) {
return cache<D, array<typename D::value_type, D::domain_type::rank> > (x,ml);
}
// ----------------- implementation ----------------------------------
// The type of A1, and A2 can already imply a copy. Compile time decision.
template<typename A1, typename A2, typename Enable =void > struct need_copy_ct : mpl::true_{};
template<typename A1, typename A2> struct need_copy_ct<A1,A2, ENABLE_IF(is_amv_value_or_view_class<A1>)> :
mpl::not_<std::is_same< typename A1::value_type, typename A2::value_type> > {};
template<typename DataType, typename CacheType, bool IsConst> class cache_impl {
protected: protected:
typedef memory_layout< DataType::domain_type::rank> ml_t; typedef memory_layout<DataType::domain_type::rank> ml_t;
const ml_t ml; ml_t ml;
typename std::conditional<IsConst, typename const_view_type_if_exists_else_type<DataType>::type, typename view_type_if_exists_else_type<DataType>::type>::type keeper; std::c14::conditional_t<IsConst, typename const_view_type_if_exists_else_type<DataType>::type,
static const bool CT_need_copy = need_copy_ct<DataType,CacheType>::value; typename view_type_if_exists_else_type<DataType>::type> keeper;
const bool need_copy; bool need_copy;
typedef typename std::conditional<IsConst, typename CacheType::const_view_type, typename CacheType::view_type>::type exposed_view_type; using CacheType = array<typename DataType::value_type, DataType::domain_type::rank>;
struct internal_data { using exposed_view_type = std::c14::conditional_t<IsConst, typename CacheType::const_view_type, typename CacheType::view_type>;
CacheType copy; struct internal_data {
exposed_view_type view; CacheType copy;
internal_data(cache_impl const & P,ml_t ml) : copy(CacheType(P.keeper,ml)), view(copy) { exposed_view_type view;
internal_data(cache_impl const& P, ml_t ml) : copy(CacheType(P.keeper, ml)), view(copy) {
#ifdef TRIQS_ARRAYS_CACHE_COPY_VERBOSE #ifdef TRIQS_ARRAYS_CACHE_COPY_VERBOSE
std::cerr<< " Cache : copy made "<< std::endl<< " -- TRACE = --" << std::endl << triqs::utility::stack_trace() << std::endl; std::cerr << " Cache : copy made " << std::endl << " -- TRACE = --" << std::endl << triqs::utility::stack_trace()
<< std::endl;
#endif #endif
} }
}; };
friend struct internal_data; friend struct internal_data;
mutable std::shared_ptr<internal_data> _id; mutable std::shared_ptr<internal_data> _id;
internal_data & id() const { if (!_id) _id= std::make_shared<internal_data>(*this,ml); return *_id;} internal_data& id() const {
if (!_id) _id = std::make_shared<internal_data>(*this, ml);
return *_id;
}
// avoid compiling the transformation keeper-> exposed_view_type when it does not make sense // avoid compiling the transformation keeper-> exposed_view_type when it does not make sense, e.g. expressions
exposed_view_type view1 (mpl::false_) const { if (need_copy) return id().view; else return keeper;} exposed_view_type view1(std::true_type) const {
exposed_view_type view1 (mpl::true_) const { return id().view; } if (need_copy)
exposed_view_type view2 () const { return view1(mpl::bool_<CT_need_copy>());} return id().view;
else
return keeper;
}
exposed_view_type view1(std::false_type) const { return id().view; }
exposed_view_type view2() const { return view1(bool_constant<is_amv_value_or_view_class<DataType>::value>()); }
template<typename D> bool need_copy_dynamic(DataType const& x, std::false_type) const { return false; }
typename std::enable_if< ! is_amv_value_or_view_class<D>::value, bool>::type bool need_copy_dynamic(DataType const& x, std::true_type) const { return (x.indexmap().memory_indices_layout() != ml); }
need_copy_dynamic ( D const & x) const { return false;}
template<typename D>
typename std::enable_if<is_amv_value_or_view_class<D>::value, bool>::type
need_copy_dynamic ( D const & x) const { return (x.indexmap().memory_indices_layout() != ml );}
public : void back_update(std::true_type) {}
cache_impl (DataType const & x, ml_t ml_ = ml_t()): void back_update(std::false_type) {
ml(ml_),keeper (x), if (need_copy) keeper = id().view;
need_copy ( CT_need_copy || need_copy_dynamic(x) || (!has_contiguous_data(x)) ) {} }
void update() { if (need_copy && _id) id().view = keeper;}
exposed_view_type view () const { return view2();} public:
operator exposed_view_type () const { return view2();} cache_impl(DataType const& x, ml_t ml_ = ml_t()) : ml(ml_), keeper(x) {
need_copy = (!is_amv_value_or_view_class<DataType>::value) || need_copy_dynamic(x, is_amv_value_or_view_class<DataType>()) ||
(!has_contiguous_data(x));
}
~cache_impl() { back_update(bool_constant< IsConst>()); }
cache_impl(cache_impl &&) = default;
cache_impl(cache_impl const&) = delete;
cache_impl& operator =(cache_impl const&) = delete;
cache_impl& operator =(cache_impl &&) = delete;
void update() {
if (need_copy && _id) id().view = keeper;
}
exposed_view_type view() const { return view2(); }
operator exposed_view_type() const { return view2(); }
}; };
// Const case : just add the back copy in the destructor // ---------------- Users class and factories ------------------
template<typename DataType, typename CacheType> class const_cache : public cache_impl<DataType,CacheType,true> {
typedef cache_impl<DataType,CacheType,true> B;
typedef typename B::ml_t ml_t;
public :
const_cache (DataType const & x, ml_t ml = ml_t() ): B(x,ml) {}
};
// Non const case : just add the back copy in the destructor template <typename DataType> using cache = cache_impl<DataType, false>;
template<typename DataType, typename CacheType> class cache : public cache_impl<DataType,CacheType,false> { template <typename DataType> using const_cache = cache_impl<DataType, true>;
static_assert( is_amv_value_or_view_class<DataType>::value, "non const cache only for regular classes and views, not expressions");
typedef cache_impl<DataType,CacheType,false> B; template <typename D>
typedef typename B::ml_t ml_t; const_cache<D> make_const_cache(D const& x, memory_layout<D::domain_type::rank> ml = memory_layout<D::domain_type::rank>{'C'}) {
public : return {x, ml};
cache (DataType const & x, ml_t ml = ml_t() ): B(x,ml) {} }
~cache() { back_update(); }
void back_update() { if (this->need_copy) this->keeper = this->id().view;} template <typename D>
}; cache<D> make_cache(D const& x, memory_layout<D::domain_type::rank> ml = memory_layout<D::domain_type::rank>{'C'}) {
}}//namespace triqs::arrays return {x, ml};
}
}
} // namespace triqs::arrays
#endif #endif

View File

@ -73,10 +73,11 @@ namespace triqs { namespace arrays {
TYPE_ENABLE_IFC(value_type,vec) operator[] (Args && args) const { return f(a[std::forward<Args>(args)],b[std::forward<Args>(args)]);} TYPE_ENABLE_IFC(value_type,vec) operator[] (Args && args) const { return f(a[std::forward<Args>(args)],b[std::forward<Args>(args)]);}
}; };
/* already defined in traist
template<typename ... T> struct _and; template<typename ... T> struct _and;
template<typename T0, typename ... T> struct _and<T0, T...> : std::integral_constant<bool, T0::value && _and<T...>::value>{}; template<typename T0, typename ... T> struct _and<T0, T...> : std::integral_constant<bool, T0::value && _and<T...>::value>{};
template<typename T> struct _and<T> : T{}; template<typename T> struct _and<T> : T{};
*/
template<typename F, int arity, bool b, typename ... A> struct ImmutableCuboidArray<map_impl_result<F,arity,b,A...>> : std::true_type{}; template<typename F, int arity, bool b, typename ... A> struct ImmutableCuboidArray<map_impl_result<F,arity,b,A...>> : std::true_type{};
template<typename F, int arity, bool b, typename ... A> struct ImmutableArray <map_impl_result<F,arity,b,A...>> : _and<typename ImmutableArray <typename std::remove_reference<A>::type>::type...>{}; template<typename F, int arity, bool b, typename ... A> struct ImmutableArray <map_impl_result<F,arity,b,A...>> : _and<typename ImmutableArray <typename std::remove_reference<A>::type>::type...>{};

View File

@ -119,7 +119,8 @@ namespace arrays {
for (size_t u = 0; u < ArrayType::rank; ++u) d2[u] = dims_out[u]; for (size_t u = 0; u < ArrayType::rank; ++u) d2[u] = dims_out[u];
resize_or_check(A, d2); resize_or_check(A, d2);
if (C_reorder) { if (C_reorder) {
read_array(g, name, cache<ArrayType, typename ArrayType::regular_type>(A).view(), false); read_array(g, name, make_cache(A).view(), false);
//read_array(g, name, cache<ArrayType, typename ArrayType::regular_type>(A).view(), false);
} else } else
ds.read(__get_array_data_ptr(A), h5::data_type_memory<typename ArrayType::value_type>(), data_space(A), dataspace); ds.read(__get_array_data_ptr(A), h5::data_type_memory<typename ArrayType::value_type>(), data_space(A), dataspace);
} }

View File

@ -32,17 +32,14 @@
#include <triqs/utility/exceptions.hpp> #include <triqs/utility/exceptions.hpp>
#include <sstream> #include <sstream>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/char.hpp> #include <boost/mpl/char.hpp>
#include <boost/type_traits/is_arithmetic.hpp> #include <boost/type_traits/is_arithmetic.hpp>
#include <boost/type_traits/is_complex.hpp> #include <boost/type_traits/is_complex.hpp>
#include <triqs/utility/compiler_details.hpp> #include <triqs/utility/compiler_details.hpp>
#include "./traits.hpp"
#include <triqs/utility/macros.hpp> #include <triqs/utility/macros.hpp>
// LEADS to an error on OS X???
//#include <triqs/utility/c14.hpp>
#include "./traits.hpp"
namespace boost { namespace serialization { class access;}} namespace boost { namespace serialization { class access;}}
@ -74,18 +71,18 @@ namespace triqs {
using triqs::make_clone; using triqs::make_clone;
/// Is the data contiguous /// Is the data contiguous
template<typename A> typename boost::disable_if<is_amv_value_or_view_class<A>,bool>::type has_contiguous_data(A const &) {return false;} template<typename A> TYPE_DISABLE_IFC(bool, is_amv_value_or_view_class<A>::value) has_contiguous_data(A const &) {return false;}
template<typename A> typename boost::enable_if<is_amv_value_class<A>,bool>::type has_contiguous_data(A const &) {return true;} template<typename A> TYPE_ENABLE_IFC(bool, is_amv_value_class<A>::value) has_contiguous_data(A const &) {return true;}
template<typename A> typename boost::enable_if<is_amv_view_class<A>, bool>::type has_contiguous_data(A const & v){return v.indexmap().is_contiguous();} template<typename A> TYPE_ENABLE_IFC(bool, is_amv_view_class<A>::value) has_contiguous_data(A const & v){return v.indexmap().is_contiguous();}
template< typename A> template< typename A>
typename boost::enable_if<is_amv_view_class<A> >::type ENABLE_IF(is_amv_view_class<A>)
resize_or_check_if_view ( A & a, typename A::shape_type const & sha) { resize_or_check_if_view ( A & a, typename A::shape_type const & sha) {
if (a.shape()!=sha) TRIQS_RUNTIME_ERROR<< "Size mismatch : view class shape = "<<a.shape() << " expected "<<sha; if (a.shape()!=sha) TRIQS_RUNTIME_ERROR<< "Size mismatch : view class shape = "<<a.shape() << " expected "<<sha;
} }
template< typename A> template< typename A>
typename boost::enable_if<is_amv_value_class<A> >::type ENABLE_IF(is_amv_value_class<A>)
resize_or_check_if_view ( A & a, typename A::shape_type const & sha) { if (a.shape()!=sha) a.resize(sha); } resize_or_check_if_view ( A & a, typename A::shape_type const & sha) { if (a.shape()!=sha) a.resize(sha); }
}}//namespace triqs::arrays }}//namespace triqs::arrays
#endif #endif

View File

@ -20,55 +20,60 @@
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_ARRAYS_IMPL_TRAITS_H #ifndef TRIQS_ARRAYS_IMPL_TRAITS_H
#define TRIQS_ARRAYS_IMPL_TRAITS_H #define TRIQS_ARRAYS_IMPL_TRAITS_H
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/concept_check.hpp>
#include <triqs/utility/concept_tools.hpp> #include <triqs/utility/concept_tools.hpp>
#include <triqs/utility/traits.hpp>
namespace triqs { namespace arrays { namespace triqs {
namespace mpl=boost::mpl; namespace arrays {
namespace mpl = boost::mpl;
// The ImmutableCuboidArray concept // The ImmutableCuboidArray concept
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(ImmutableCuboidArray); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(ImmutableCuboidArray);
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableCuboidArray,(ImmutableCuboidArray)); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableCuboidArray, (ImmutableCuboidArray));
// The ImmutableArray concept // The ImmutableArray concept
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableArray,(ImmutableCuboidArray)); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableArray, (ImmutableCuboidArray));
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableArray,(ImmutableArray)(MutableCuboidArray)); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableArray, (ImmutableArray)(MutableCuboidArray));
// The ImmutableMatrix concept
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableMatrix,(ImmutableCuboidArray));
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableMatrix,(ImmutableMatrix)(MutableCuboidArray));
// The ImmutableVector concept // The ImmutableMatrix concept
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableVector,(ImmutableCuboidArray)); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableMatrix, (ImmutableCuboidArray));
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableVector,(ImmutableVector)(MutableCuboidArray)); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableMatrix, (ImmutableMatrix)(MutableCuboidArray));
namespace Tag { struct array{}; struct array_view {}; } // The ImmutableVector concept
template <typename T> struct is_array : std::is_base_of<Tag::array,T> {}; TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableVector, (ImmutableCuboidArray));
template <typename T> struct is_array_view : std::is_base_of<Tag::array_view,T> {}; TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableVector, (ImmutableVector)(MutableCuboidArray));
template <typename T> struct is_array_or_view : boost::mpl::or_< is_array<T>, is_array_view<T> > {};
namespace Tag { struct vector{}; struct vector_view {};} namespace Tag {
template <typename T> struct is_vector : std::is_base_of<Tag::vector,T> {}; struct array {};
template <typename T> struct is_vector_view : std::is_base_of<Tag::vector_view,T> {}; struct array_view {};
template <typename T> struct is_vector_or_view : boost::mpl::or_< is_vector<T>, is_vector_view<T> > {}; struct vector {};
struct vector_view {};
struct matrix_view {};
struct matrix {};
}
template <typename T> struct is_array : std::is_base_of<Tag::array, T> {};
template <typename T> struct is_array_view : std::is_base_of<Tag::array_view, T> {};
template <typename T> struct is_array_or_view : _or<is_array<T>, is_array_view<T>> {};
namespace Tag { struct matrix_view {}; struct matrix {}; } template <typename T> struct is_vector : std::is_base_of<Tag::vector, T> {};
template <typename T> struct is_matrix : std::is_base_of<Tag::matrix,T> {}; template <typename T> struct is_vector_view : std::is_base_of<Tag::vector_view, T> {};
template <typename T> struct is_matrix_view : std::is_base_of<Tag::matrix_view,T> {}; template <typename T> struct is_vector_or_view : _or<is_vector<T>, is_vector_view<T>> {};
template <typename T> struct is_matrix_or_view : boost::mpl::or_< is_matrix<T>, is_matrix_view<T> > {};
template <class T> struct is_amv_value_class : boost::mpl::or_< is_array<T>, is_matrix<T>, is_vector<T> > {}; template <typename T> struct is_matrix : std::is_base_of<Tag::matrix, T> {};
template <class T> struct is_amv_view_class : boost::mpl::or_< is_array_view<T>, is_matrix_view<T>, is_vector_view<T> > {}; template <typename T> struct is_matrix_view : std::is_base_of<Tag::matrix_view, T> {};
template <class T> struct is_amv_value_or_view_class : boost::mpl::or_< is_amv_value_class<T>, is_amv_view_class<T> > {}; template <typename T> struct is_matrix_or_view : _or<is_matrix<T>, is_matrix_view<T>> {};
template <class S> struct is_scalar : boost::mpl::or_<std::is_arithmetic<S > , boost::is_complex<S> > {}; template <class T> struct is_amv_value_class : _or<is_array<T>, is_matrix<T>, is_vector<T>> {};
template <class T> struct is_amv_view_class : _or<is_array_view<T>, is_matrix_view<T>, is_vector_view<T>> {};
template<class S, class A> struct is_scalar_for : template <class T> struct is_amv_value_or_view_class : _or<is_amv_value_class<T>, is_amv_view_class<T>> {};
boost::mpl::if_<is_scalar<typename A::value_type > , is_scalar<S>,boost::is_same<S,typename A::value_type > >::type {};
}}//namespace triqs::arrays template <class S> struct is_scalar : _or<std::is_arithmetic<S>, boost::is_complex<S>> {};
template <class S, class A>
struct is_scalar_for
: std::conditional<is_scalar<typename A::value_type>::value, is_scalar<S>, boost::is_same<S, typename A::value_type>>::type {
};
}
} // namespace triqs::arrays
#endif #endif

View File

@ -21,12 +21,17 @@
#ifndef TRIQS_C14_FIX_H #ifndef TRIQS_C14_FIX_H
#define TRIQS_C14_FIX_H #define TRIQS_C14_FIX_H
#include <memory> #include <memory>
#include <functional> //#include <functional>
#include <tuple>
// a few that will be C++14, use in advance.... // a few that will be C++14, use in advance....
namespace std { namespace std {
namespace c14 { namespace c14 {
// helpers
template <bool B, class T, class F> using conditional_t = typename conditional<B, T, F>::type;
template <class T> using remove_reference_t = typename remove_reference<T>::type;
// use simply std::c14::plus<>() ... // use simply std::c14::plus<>() ...
template<typename T = void> struct plus: std::plus<T>{}; template<typename T = void> struct plus: std::plus<T>{};

38
triqs/utility/traits.hpp Normal file
View File

@ -0,0 +1,38 @@
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2011 by O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once
namespace triqs {
// MPL traits
template<typename ... T> struct _or;
template<typename T0, typename ... T> struct _or<T0,T...> : std::integral_constant<bool,T0::value || _or<T...>::value>{};
template<> struct _or<> : std::false_type{};
template<typename ... T> struct _and;
template<typename T0, typename ... T> struct _and<T0,T...> : std::integral_constant<bool,T0::value && _and<T...>::value>{};
template<> struct _and<> : std::true_type{};
// helpers
template<bool B> using bool_constant = std::integral_constant<bool,B>;
}