From d7cf22399424f53f81b44dbff21efe80ed131577 Mon Sep 17 00:00:00 2001 From: Olivier Parcollet Date: Sun, 3 Nov 2013 21:49:35 +0100 Subject: [PATCH] arrays: clean cache, add traits ... - also add simple c14 helpers .... --- triqs/arrays/cache.hpp | 155 +++++++++++++------------- triqs/arrays/functional/map.hpp | 3 +- triqs/arrays/h5/simple_read_write.hpp | 3 +- triqs/arrays/impl/common.hpp | 19 ++-- triqs/arrays/impl/traits.hpp | 81 +++++++------- triqs/utility/c14.hpp | 9 +- triqs/utility/traits.hpp | 38 +++++++ 7 files changed, 177 insertions(+), 131 deletions(-) create mode 100644 triqs/utility/traits.hpp diff --git a/triqs/arrays/cache.hpp b/triqs/arrays/cache.hpp index 9936f0bf..cd0b94f3 100644 --- a/triqs/arrays/cache.hpp +++ b/triqs/arrays/cache.hpp @@ -2,7 +2,7 @@ * * 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 * terms of the GNU General Public License as published by the Free Software @@ -22,92 +22,91 @@ #define TRIQS_ARRAYS_CACHE_H #include "./array.hpp" #include -namespace triqs { namespace arrays { +#include +namespace triqs { +namespace arrays { - template class const_cache; - template class cache; - - template - const_cache > - make_const_cache( D const & x, memory_layout< D::domain_type::rank> ml = memory_layout< D::domain_type::rank>('C') ) { - return const_cache > (x,ml); - } - - template - cache > - make_cache( D const & x, memory_layout< D::domain_type::rank> ml = memory_layout< D::domain_type::rank>('C') ) { - return cache > (x,ml); - } - - // ----------------- implementation ---------------------------------- - - // The type of A1, and A2 can already imply a copy. Compile time decision. - template struct need_copy_ct : mpl::true_{}; - template struct need_copy_ct)> : - mpl::not_ > {}; - - template class cache_impl { + // ----------------- the implementation class ----------------------- + template class cache_impl { protected: - typedef memory_layout< DataType::domain_type::rank> ml_t; - const ml_t ml; - typename std::conditional::type, typename view_type_if_exists_else_type::type>::type keeper; - static const bool CT_need_copy = need_copy_ct::value; - const bool need_copy; - typedef typename std::conditional::type exposed_view_type; - struct internal_data { - CacheType copy; - exposed_view_type view; - internal_data(cache_impl const & P,ml_t ml) : copy(CacheType(P.keeper,ml)), view(copy) { + typedef memory_layout ml_t; + ml_t ml; + std::c14::conditional_t::type, + typename view_type_if_exists_else_type::type> keeper; + bool need_copy; + using CacheType = array; + using exposed_view_type = std::c14::conditional_t; + struct internal_data { + CacheType 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 - 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 - } - }; - friend struct internal_data; - mutable std::shared_ptr _id; - internal_data & id() const { if (!_id) _id= std::make_shared(*this,ml); return *_id;} + } + }; + friend struct internal_data; + mutable std::shared_ptr _id; + internal_data& id() const { + if (!_id) _id = std::make_shared(*this, ml); + return *_id; + } - // avoid compiling the transformation keeper-> exposed_view_type when it does not make sense - exposed_view_type view1 (mpl::false_) const { if (need_copy) return id().view; else return keeper;} - exposed_view_type view1 (mpl::true_) const { return id().view; } - exposed_view_type view2 () const { return view1(mpl::bool_());} + // avoid compiling the transformation keeper-> exposed_view_type when it does not make sense, e.g. expressions + exposed_view_type view1(std::true_type) const { + if (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::value>()); } - template - typename std::enable_if< ! is_amv_value_or_view_class::value, bool>::type - need_copy_dynamic ( D const & x) const { return false;} - - template - typename std::enable_if::value, bool>::type - need_copy_dynamic ( D const & x) const { return (x.indexmap().memory_indices_layout() != ml );} + bool need_copy_dynamic(DataType const& x, std::false_type) const { return false; } + bool need_copy_dynamic(DataType const& x, std::true_type) const { return (x.indexmap().memory_indices_layout() != ml); } - public : - cache_impl (DataType const & x, ml_t ml_ = ml_t()): - ml(ml_),keeper (x), - 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();} - operator exposed_view_type () const { return view2();} + void back_update(std::true_type) {} + void back_update(std::false_type) { + if (need_copy) keeper = id().view; + } + + public: + cache_impl(DataType const& x, ml_t ml_ = ml_t()) : ml(ml_), keeper(x) { + need_copy = (!is_amv_value_or_view_class::value) || need_copy_dynamic(x, is_amv_value_or_view_class()) || + (!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 - template class const_cache : public cache_impl { - typedef cache_impl B; - typedef typename B::ml_t ml_t; - public : - const_cache (DataType const & x, ml_t ml = ml_t() ): B(x,ml) {} - }; + // ---------------- Users class and factories ------------------ - // Non const case : just add the back copy in the destructor - template class cache : public cache_impl { - static_assert( is_amv_value_or_view_class::value, "non const cache only for regular classes and views, not expressions"); - typedef cache_impl B; - typedef typename B::ml_t ml_t; - public : - 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;} - }; -}}//namespace triqs::arrays + template using cache = cache_impl; + template using const_cache = cache_impl; + + template + const_cache make_const_cache(D const& x, memory_layout ml = memory_layout{'C'}) { + return {x, ml}; + } + + template + cache make_cache(D const& x, memory_layout ml = memory_layout{'C'}) { + return {x, ml}; + } +} +} // namespace triqs::arrays #endif - diff --git a/triqs/arrays/functional/map.hpp b/triqs/arrays/functional/map.hpp index 73e2d93f..4dd8eafe 100644 --- a/triqs/arrays/functional/map.hpp +++ b/triqs/arrays/functional/map.hpp @@ -73,10 +73,11 @@ namespace triqs { namespace arrays { TYPE_ENABLE_IFC(value_type,vec) operator[] (Args && args) const { return f(a[std::forward(args)],b[std::forward(args)]);} }; + /* already defined in traist template struct _and; template struct _and : std::integral_constant::value>{}; template struct _and : T{}; - +*/ template struct ImmutableCuboidArray> : std::true_type{}; template struct ImmutableArray > : _and::type>::type...>{}; diff --git a/triqs/arrays/h5/simple_read_write.hpp b/triqs/arrays/h5/simple_read_write.hpp index d5d85bdb..f55ef991 100644 --- a/triqs/arrays/h5/simple_read_write.hpp +++ b/triqs/arrays/h5/simple_read_write.hpp @@ -119,7 +119,8 @@ namespace arrays { for (size_t u = 0; u < ArrayType::rank; ++u) d2[u] = dims_out[u]; resize_or_check(A, d2); if (C_reorder) { - read_array(g, name, cache(A).view(), false); + read_array(g, name, make_cache(A).view(), false); + //read_array(g, name, cache(A).view(), false); } else ds.read(__get_array_data_ptr(A), h5::data_type_memory(), data_space(A), dataspace); } diff --git a/triqs/arrays/impl/common.hpp b/triqs/arrays/impl/common.hpp index f0c66b15..9009411d 100644 --- a/triqs/arrays/impl/common.hpp +++ b/triqs/arrays/impl/common.hpp @@ -32,17 +32,14 @@ #include #include -#include -#include -#include -#include -#include #include #include #include #include -#include "./traits.hpp" #include +// LEADS to an error on OS X??? +//#include +#include "./traits.hpp" namespace boost { namespace serialization { class access;}} @@ -74,18 +71,18 @@ namespace triqs { using triqs::make_clone; /// Is the data contiguous - template typename boost::disable_if,bool>::type has_contiguous_data(A const &) {return false;} - template typename boost::enable_if,bool>::type has_contiguous_data(A const &) {return true;} - template typename boost::enable_if, bool>::type has_contiguous_data(A const & v){return v.indexmap().is_contiguous();} + template TYPE_DISABLE_IFC(bool, is_amv_value_or_view_class::value) has_contiguous_data(A const &) {return false;} + template TYPE_ENABLE_IFC(bool, is_amv_value_class::value) has_contiguous_data(A const &) {return true;} + template TYPE_ENABLE_IFC(bool, is_amv_view_class::value) has_contiguous_data(A const & v){return v.indexmap().is_contiguous();} template< typename A> - typename boost::enable_if >::type + ENABLE_IF(is_amv_view_class) 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 = "< - typename boost::enable_if >::type + ENABLE_IF(is_amv_value_class) resize_or_check_if_view ( A & a, typename A::shape_type const & sha) { if (a.shape()!=sha) a.resize(sha); } }}//namespace triqs::arrays #endif diff --git a/triqs/arrays/impl/traits.hpp b/triqs/arrays/impl/traits.hpp index 22f7caec..76740a10 100644 --- a/triqs/arrays/impl/traits.hpp +++ b/triqs/arrays/impl/traits.hpp @@ -20,55 +20,60 @@ ******************************************************************************/ #ifndef TRIQS_ARRAYS_IMPL_TRAITS_H #define TRIQS_ARRAYS_IMPL_TRAITS_H -#include -#include -#include -#include #include +#include -namespace triqs { namespace arrays { - namespace mpl=boost::mpl; +namespace triqs { +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_R(MutableCuboidArray,(ImmutableCuboidArray)); + TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableCuboidArray, (ImmutableCuboidArray)); - // The ImmutableArray concept - TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableArray,(ImmutableCuboidArray)); - 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 ImmutableArray concept + TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableArray, (ImmutableCuboidArray)); + TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableArray, (ImmutableArray)(MutableCuboidArray)); - // The ImmutableVector concept - TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableVector,(ImmutableCuboidArray)); - TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableVector,(ImmutableVector)(MutableCuboidArray)); + // The ImmutableMatrix concept + TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableMatrix, (ImmutableCuboidArray)); + TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableMatrix, (ImmutableMatrix)(MutableCuboidArray)); - namespace Tag { struct array{}; struct array_view {}; } - template struct is_array : std::is_base_of {}; - template struct is_array_view : std::is_base_of {}; - template struct is_array_or_view : boost::mpl::or_< is_array, is_array_view > {}; + // The ImmutableVector concept + TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableVector, (ImmutableCuboidArray)); + TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableVector, (ImmutableVector)(MutableCuboidArray)); - namespace Tag { struct vector{}; struct vector_view {};} - template struct is_vector : std::is_base_of {}; - template struct is_vector_view : std::is_base_of {}; - template struct is_vector_or_view : boost::mpl::or_< is_vector, is_vector_view > {}; + namespace Tag { + struct array {}; + struct array_view {}; + struct vector {}; + struct vector_view {}; + struct matrix_view {}; + struct matrix {}; + } + template struct is_array : std::is_base_of {}; + template struct is_array_view : std::is_base_of {}; + template struct is_array_or_view : _or, is_array_view> {}; - namespace Tag { struct matrix_view {}; struct matrix {}; } - template struct is_matrix : std::is_base_of {}; - template struct is_matrix_view : std::is_base_of {}; - template struct is_matrix_or_view : boost::mpl::or_< is_matrix, is_matrix_view > {}; + template struct is_vector : std::is_base_of {}; + template struct is_vector_view : std::is_base_of {}; + template struct is_vector_or_view : _or, is_vector_view> {}; - template struct is_amv_value_class : boost::mpl::or_< is_array, is_matrix, is_vector > {}; - template struct is_amv_view_class : boost::mpl::or_< is_array_view, is_matrix_view, is_vector_view > {}; - template struct is_amv_value_or_view_class : boost::mpl::or_< is_amv_value_class, is_amv_view_class > {}; + template struct is_matrix : std::is_base_of {}; + template struct is_matrix_view : std::is_base_of {}; + template struct is_matrix_or_view : _or, is_matrix_view> {}; - template struct is_scalar : boost::mpl::or_ , boost::is_complex > {}; - - template struct is_scalar_for : - boost::mpl::if_ , is_scalar,boost::is_same >::type {}; + template struct is_amv_value_class : _or, is_matrix, is_vector> {}; + template struct is_amv_view_class : _or, is_matrix_view, is_vector_view> {}; + template struct is_amv_value_or_view_class : _or, is_amv_view_class> {}; -}}//namespace triqs::arrays + template struct is_scalar : _or, boost::is_complex> {}; + + template + struct is_scalar_for + : std::conditional::value, is_scalar, boost::is_same>::type { + }; +} +} // namespace triqs::arrays #endif diff --git a/triqs/utility/c14.hpp b/triqs/utility/c14.hpp index 7673d6b4..a3549b6f 100644 --- a/triqs/utility/c14.hpp +++ b/triqs/utility/c14.hpp @@ -21,12 +21,17 @@ #ifndef TRIQS_C14_FIX_H #define TRIQS_C14_FIX_H #include -#include +//#include +#include // a few that will be C++14, use in advance.... namespace std { - namespace c14 { + namespace c14 { + + // helpers + template using conditional_t = typename conditional::type; + template using remove_reference_t = typename remove_reference::type; // use simply std::c14::plus<>() ... template struct plus: std::plus{}; diff --git a/triqs/utility/traits.hpp b/triqs/utility/traits.hpp new file mode 100644 index 00000000..660e7660 --- /dev/null +++ b/triqs/utility/traits.hpp @@ -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 . + * + ******************************************************************************/ +#pragma once + +namespace triqs { + + // MPL traits + template struct _or; + template struct _or : std::integral_constant::value>{}; + template<> struct _or<> : std::false_type{}; + + template struct _and; + template struct _and : std::integral_constant::value>{}; + template<> struct _and<> : std::true_type{}; + + // helpers + template using bool_constant = std::integral_constant; + +} +