3
0
mirror of https://github.com/triqs/dft_tools synced 2024-11-01 11:43:47 +01:00
dft_tools/triqs/arrays/indexmaps/cuboid/mem_layout.hpp
Olivier Parcollet cfe3532c94 array & gf transpose
- implement transposed_view for arrays.
- .transpose method for gf
- wrapped to python
- add call op. for GfImTime, using C++
- Added ChangeLog
- rm matrix_stack
- start cleaning old code
2014-05-22 16:08:23 +02:00

111 lines
5.0 KiB
C++

/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2012 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/>.
*
******************************************************************************/
#ifndef TRIQS_ARRAYS_INDEXMAP_MEMORY_LAYOUT_H
#define TRIQS_ARRAYS_INDEXMAP_MEMORY_LAYOUT_H
#include "../permutation.hpp"
#include "../../impl/flags.hpp"
namespace triqs { namespace arrays {
namespace indexmaps { namespace mem_layout {
/* The storage order is given by a permutation P stored in a ull_t (unsigned long long) as in permutations::..
* P[0] : the fastest index,
* P[RANK-1] : the slowest index
* Example :
* 012 : Fortran, the first index is the fastest
* 210: C the last index is the fastest
* 120 : storage (i,j,k) is : index j is fastest, then k, then i
*
* index_to_memory_rank : i ---> r : to the index (0,1, ... etc), associates the rank in memory
* e.g. r=0 : fastest index, r = RANK-1 : the slowest
* memory_rank_to_index : the inverse mapping : r---> i :
* 0-> the fastest index, etc..
*
* All these computations can be done *at compile time* (constexpr)
*/
constexpr int memory_rank_to_index(ull_t p, int r) { return permutations::apply(p, r);}
constexpr int index_to_memory_rank(ull_t p, int r) { return permutations::apply(permutations::inverse(p), r);}
constexpr bool is_fortran (ull_t p){ return p == permutations::identity(permutations::size(p));}
constexpr bool is_c (ull_t p){ return p == permutations::ridentity(permutations::size(p));}
constexpr ull_t fortran_order (int n){ return permutations::identity(n);}
constexpr ull_t c_order (int n){ return permutations::ridentity(n);}
template<int n> struct fortran_order_tr { static constexpr ull_t value = permutations::identity(n);};
template<int n> struct c_order_tr { static constexpr ull_t value = permutations::ridentity(n);};
// From the flag in the template definition to the real traversal_order
// 0 -> C order
// 1 -> Fortran Order
// Any other number interpreted as a permutation ?
constexpr ull_t _get_traversal_order (int rank, ull_t fl, ull_t to) { return (flags::traversal_order_c(fl) ? c_order(rank) :
(flags::traversal_order_fortran(fl) ? fortran_order(rank) : (to==0 ? c_order(rank) : to )));}
template< int rank, ull_t fl, ull_t to> struct get_traversal_order { static constexpr ull_t value = _get_traversal_order (rank,fl,to); };
}}
struct memory_layout_fortran {};
struct memory_layout_c {};
#define FORTRAN_LAYOUT (triqs::arrays::memory_layout_fortran())
#define C_LAYOUT (triqs::arrays::memory_layout_fortran())
// stores the layout == order of the indices in memory
// wrapped into a little type to make constructor unambigous.
template<int Rank>
struct memory_layout {
ull_t value;
explicit memory_layout (ull_t v) : value(v) {assert((permutations::size(v)==Rank));}
explicit memory_layout (char ml='C') {
assert( (ml=='C') || (ml == 'F'));
value = (ml=='F' ? indexmaps::mem_layout::fortran_order(Rank) : indexmaps::mem_layout::c_order(Rank));
}
memory_layout (memory_layout_fortran) { value = indexmaps::mem_layout::fortran_order(Rank); }
memory_layout (memory_layout_c) { value = indexmaps::mem_layout::c_order(Rank); }
template<typename ... INT>
explicit memory_layout(int i0, int i1, INT ... in) : value (permutations::permutation(i0,i1,in...)){
static_assert( sizeof...(in)==Rank-2, "Error");
}
memory_layout (const memory_layout & C) = default;
memory_layout (memory_layout && C) = default;
memory_layout & operator =( memory_layout const &) = default;
memory_layout & operator =( memory_layout && x) = default;
bool operator ==( memory_layout const & ml) const { return value == ml.value;}
bool operator !=( memory_layout const & ml) const { return value != ml.value;}
friend std::ostream &operator<<(std::ostream &out, memory_layout const &s) {
permutations::print(out, s.value);
return out;
}
};
template <int R, typename... INT> memory_layout<R> transpose(memory_layout<R> ml, INT... is) {
static_assert(sizeof...(INT)==R, "!");
return memory_layout<R>{permutations::compose(ml.value, permutations::inverse(permutations::permutation(is...)))};
}
}}//namespace triqs::arrays
#endif