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:
parent
9cdc139214
commit
d7cf223994
@ -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 <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;
|
||||
template<typename DataType, typename CacheType> class cache;
|
||||
|
||||
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 {
|
||||
// ----------------- the implementation class -----------------------
|
||||
template <typename DataType, bool IsConst> class cache_impl {
|
||||
protected:
|
||||
typedef memory_layout<DataType::domain_type::rank> ml_t;
|
||||
const 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;
|
||||
static const bool CT_need_copy = need_copy_ct<DataType,CacheType>::value;
|
||||
const bool need_copy;
|
||||
typedef typename std::conditional<IsConst, typename CacheType::const_view_type, typename CacheType::view_type>::type exposed_view_type;
|
||||
ml_t ml;
|
||||
std::c14::conditional_t<IsConst, typename const_view_type_if_exists_else_type<DataType>::type,
|
||||
typename view_type_if_exists_else_type<DataType>::type> keeper;
|
||||
bool need_copy;
|
||||
using CacheType = array<typename DataType::value_type, DataType::domain_type::rank>;
|
||||
using exposed_view_type = std::c14::conditional_t<IsConst, typename CacheType::const_view_type, typename CacheType::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) {
|
||||
#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<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
|
||||
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_<CT_need_copy>());}
|
||||
// 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<is_amv_value_or_view_class<DataType>::value>()); }
|
||||
|
||||
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 false;}
|
||||
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); }
|
||||
|
||||
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 );}
|
||||
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 ( CT_need_copy || need_copy_dynamic(x) || (!has_contiguous_data(x)) ) {}
|
||||
void update() { if (need_copy && _id) id().view = keeper;}
|
||||
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
|
||||
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) {}
|
||||
};
|
||||
// ---------------- Users class and factories ------------------
|
||||
|
||||
// Non const case : just add the back copy in the destructor
|
||||
template<typename DataType, typename CacheType> class cache : public cache_impl<DataType,CacheType,false> {
|
||||
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;
|
||||
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 <typename DataType> using cache = cache_impl<DataType, false>;
|
||||
template <typename DataType> using const_cache = cache_impl<DataType, true>;
|
||||
|
||||
template <typename D>
|
||||
const_cache<D> make_const_cache(D const& x, memory_layout<D::domain_type::rank> ml = memory_layout<D::domain_type::rank>{'C'}) {
|
||||
return {x, ml};
|
||||
}
|
||||
|
||||
template <typename D>
|
||||
cache<D> make_cache(D const& x, memory_layout<D::domain_type::rank> ml = memory_layout<D::domain_type::rank>{'C'}) {
|
||||
return {x, ml};
|
||||
}
|
||||
}
|
||||
} // namespace triqs::arrays
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -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)]);}
|
||||
};
|
||||
|
||||
/* already defined in traist
|
||||
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 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 ImmutableArray <map_impl_result<F,arity,b,A...>> : _and<typename ImmutableArray <typename std::remove_reference<A>::type>::type...>{};
|
||||
|
@ -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<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
|
||||
ds.read(__get_array_data_ptr(A), h5::data_type_memory<typename ArrayType::value_type>(), data_space(A), dataspace);
|
||||
}
|
||||
|
@ -32,17 +32,14 @@
|
||||
#include <triqs/utility/exceptions.hpp>
|
||||
#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/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/is_complex.hpp>
|
||||
#include <triqs/utility/compiler_details.hpp>
|
||||
#include "./traits.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;}}
|
||||
|
||||
@ -74,18 +71,18 @@ namespace triqs {
|
||||
using triqs::make_clone;
|
||||
|
||||
/// 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> typename boost::enable_if<is_amv_value_class<A>,bool>::type 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_DISABLE_IFC(bool, is_amv_value_or_view_class<A>::value) has_contiguous_data(A const &) {return false;}
|
||||
template<typename A> TYPE_ENABLE_IFC(bool, is_amv_value_class<A>::value) has_contiguous_data(A const &) {return true;}
|
||||
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>
|
||||
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) {
|
||||
if (a.shape()!=sha) TRIQS_RUNTIME_ERROR<< "Size mismatch : view class shape = "<<a.shape() << " expected "<<sha;
|
||||
}
|
||||
|
||||
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); }
|
||||
}}//namespace triqs::arrays
|
||||
#endif
|
||||
|
@ -20,13 +20,11 @@
|
||||
******************************************************************************/
|
||||
#ifndef 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/traits.hpp>
|
||||
|
||||
namespace triqs { namespace arrays {
|
||||
namespace triqs {
|
||||
namespace arrays {
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
// The ImmutableCuboidArray concept
|
||||
@ -45,30 +43,37 @@ namespace triqs { namespace arrays {
|
||||
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(ImmutableVector, (ImmutableCuboidArray));
|
||||
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT_R(MutableVector, (ImmutableVector)(MutableCuboidArray));
|
||||
|
||||
namespace Tag { struct array{}; struct array_view {}; }
|
||||
namespace Tag {
|
||||
struct array {};
|
||||
struct array_view {};
|
||||
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 : boost::mpl::or_< is_array<T>, is_array_view<T> > {};
|
||||
template <typename T> struct is_array_or_view : _or<is_array<T>, is_array_view<T>> {};
|
||||
|
||||
namespace Tag { struct vector{}; struct vector_view {};}
|
||||
template <typename T> struct is_vector : std::is_base_of<Tag::vector, T> {};
|
||||
template <typename T> struct is_vector_view : std::is_base_of<Tag::vector_view, T> {};
|
||||
template <typename T> struct is_vector_or_view : boost::mpl::or_< is_vector<T>, is_vector_view<T> > {};
|
||||
template <typename T> struct is_vector_or_view : _or<is_vector<T>, is_vector_view<T>> {};
|
||||
|
||||
namespace Tag { struct matrix_view {}; struct matrix {}; }
|
||||
template <typename T> struct is_matrix : std::is_base_of<Tag::matrix, T> {};
|
||||
template <typename T> struct is_matrix_view : std::is_base_of<Tag::matrix_view, T> {};
|
||||
template <typename T> struct is_matrix_or_view : boost::mpl::or_< is_matrix<T>, is_matrix_view<T> > {};
|
||||
template <typename T> struct is_matrix_or_view : _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 <class T> struct is_amv_view_class : boost::mpl::or_< is_array_view<T>, is_matrix_view<T>, is_vector_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 <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 T> struct is_amv_value_or_view_class : _or<is_amv_value_class<T>, is_amv_view_class<T>> {};
|
||||
|
||||
template <class S> struct is_scalar : boost::mpl::or_<std::is_arithmetic<S > , boost::is_complex<S> > {};
|
||||
template <class S> struct is_scalar : _or<std::is_arithmetic<S>, boost::is_complex<S>> {};
|
||||
|
||||
template<class S, class A> struct is_scalar_for :
|
||||
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, 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
|
||||
|
||||
|
@ -21,13 +21,18 @@
|
||||
#ifndef TRIQS_C14_FIX_H
|
||||
#define TRIQS_C14_FIX_H
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
//#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
// a few that will be C++14, use in advance....
|
||||
|
||||
namespace std {
|
||||
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<>() ...
|
||||
template<typename T = void> struct plus: std::plus<T>{};
|
||||
|
||||
|
38
triqs/utility/traits.hpp
Normal file
38
triqs/utility/traits.hpp
Normal 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>;
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user