Skip to content

Commit

Permalink
Allow different memory layouts for block_gf and block_gf_view
Browse files Browse the repository at this point in the history
  • Loading branch information
Wentzell committed Sep 6, 2024
1 parent 3ee630d commit 8a95e3a
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 196 deletions.
16 changes: 8 additions & 8 deletions c++/triqs/cpp2py_converters/gf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace cpp2py {
template <typename M, typename T> struct is_view<triqs::gfs::gf_view<M, T>> : std::true_type {};
template <typename M, typename T> struct is_view<triqs::gfs::gf_const_view<M, T>> : std::true_type {};

template <typename M, typename T, int A, bool C> struct is_view<triqs::gfs::block_gf_view<M, T, A, C>> : std::true_type {};
template <typename M, typename T, typename L, int A, bool C> struct is_view<triqs::gfs::block_gf_view<M, T, L, A, C>> : std::true_type {};

// -----------------------------------
// gf
Expand Down Expand Up @@ -147,11 +147,11 @@ namespace cpp2py {
// block_gf
// -----------------------------------

template <typename M, typename T, int A> struct py_converter<triqs::gfs::block_gf<M, T, A>> {
using conv_t = py_converter<triqs::gfs::block_gf_view<M, T, A>>;
using c_type = triqs::gfs::block_gf<M, T, A>;
template <typename M, typename T, int A> struct py_converter<triqs::gfs::block_gf<M, T, C_layout, A>> {
using conv_t = py_converter<triqs::gfs::block_gf_view<M, T, C_stride_layout, A>>;
using c_type = triqs::gfs::block_gf<M, T, C_layout, A>;

static PyObject *c2py(triqs::gfs::block_gf_view<M, T, A> g) { return conv_t::c2py(g); }
static PyObject *c2py(triqs::gfs::block_gf_view<M, T, C_stride_layout, A> g) { return conv_t::c2py(g); }
static bool is_convertible(PyObject *ob, bool raise_exception) { return conv_t::is_convertible(ob, raise_exception); }
static c_type py2c(PyObject *ob) { return c_type{conv_t::py2c(ob)}; }
};
Expand All @@ -160,9 +160,9 @@ namespace cpp2py {
// block_gf_const_view
// -----------------------------------

template <typename M, typename T, int A> struct py_converter<triqs::gfs::block_gf_const_view<M, T, A>> {
using conv_t = py_converter<triqs::gfs::block_gf_view<M, T, A>>;
using c_type = triqs::gfs::block_gf_const_view<M, T, A>;
template <typename M, typename T, int A> struct py_converter<triqs::gfs::block_gf_const_view<M, T, C_stride_layout, A>> {
using conv_t = py_converter<triqs::gfs::block_gf_view<M, T, C_stride_layout, A>>;
using c_type = triqs::gfs::block_gf_const_view<M, T, C_stride_layout, A>;

static PyObject *c2py(c_type g) = delete; // You can not convert a C++ const_view to a Python Gf ! Violates const correctness.
static bool is_convertible(PyObject *ob, bool raise_exception) { return conv_t::is_convertible(ob, raise_exception); }
Expand Down
47 changes: 26 additions & 21 deletions c++/triqs/gfs/block/block_gf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,26 @@ namespace triqs::gfs {
/*----------------------------------------------------------
* Declaration of main types : gf, gf_view, gf_const_view
*--------------------------------------------------------*/
template <typename Mesh, typename Target = matrix_valued, int Arity = 1> class block_gf;
template <typename Mesh, typename Target = matrix_valued, int Arity = 1, bool IsConst = false> class block_gf_view;
template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_layout, int Arity = 1> class block_gf;
template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout, int Arity = 1, bool IsConst = false>
class block_gf_view;

// aliases
template <typename Mesh, typename Target = matrix_valued, int Arity = 1> using block_gf_const_view = block_gf_view<Mesh, Target, Arity, true>;
template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout, int Arity = 1>
using block_gf_const_view = block_gf_view<Mesh, Target, Layout, Arity, true>;

template <typename Mesh, typename Target = matrix_valued> using block2_gf = block_gf<Mesh, Target, 2>;
template <typename Mesh, typename Target = matrix_valued> using block2_gf_view = block_gf_view<Mesh, Target, 2, false>;
template <typename Mesh, typename Target = matrix_valued> using block2_gf_const_view = block_gf_view<Mesh, Target, 2, true>;
template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_layout> using block2_gf = block_gf<Mesh, Target, Layout, 2>;
template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout>
using block2_gf_view = block_gf_view<Mesh, Target, Layout, 2, false>;
template <typename Mesh, typename Target = matrix_valued, typename Layout = nda::C_stride_layout>
using block2_gf_const_view = block_gf_view<Mesh, Target, Layout, 2, true>;

/// --------------------------- CTAD ---------------------------------

template <typename Mesh, typename Target> block_gf(std::vector<gf<Mesh, Target>>) -> block_gf<Mesh, Target, 1>;
template <typename Mesh> block_gf(Mesh const &, gf_struct_t const &) -> block_gf<Mesh, matrix_valued, 1>;
template <typename Mesh, typename Target, int Arity, bool IsConst>
block_gf(block_gf_view<Mesh, Target, Arity, IsConst>) -> block_gf<Mesh, Target, Arity>;
template <typename Mesh, typename Target, typename Layout> block_gf(std::vector<gf<Mesh, Target, Layout>>) -> block_gf<Mesh, Target, Layout, 1>;
template <typename Mesh> block_gf(Mesh const &, gf_struct_t const &) -> block_gf<Mesh, matrix_valued>;
template <typename Mesh, typename Target, typename Layout, int Arity, bool IsConst>
block_gf(block_gf_view<Mesh, Target, Layout, Arity, IsConst>) -> block_gf<Mesh, Target, typename Layout::contiguous_t, Arity>;

/// --------------------------- traits ---------------------------------

Expand All @@ -53,10 +57,11 @@ namespace triqs::gfs {
//
template <typename G, int n = 0> inline constexpr bool is_block_gf_v = false;

template <typename Mesh, typename Target, int Arity> inline constexpr bool is_block_gf_v<block_gf<Mesh, Target, Arity>, Arity> = true;
template <typename Mesh, typename Target, typename Layout, int Arity>
inline constexpr bool is_block_gf_v<block_gf<Mesh, Target, Layout, Arity>, Arity> = true;

template <typename Mesh, typename Target, int Arity, bool IsConst>
inline constexpr bool is_block_gf_v<block_gf_view<Mesh, Target, Arity, IsConst>, Arity> = true;
template <typename Mesh, typename Target, typename Layout, int Arity, bool IsConst>
inline constexpr bool is_block_gf_v<block_gf_view<Mesh, Target, Layout, Arity, IsConst>, Arity> = true;

template <typename, typename = std::void_t<>> inline constexpr int arity_of = -1;

Expand Down Expand Up @@ -101,7 +106,7 @@ namespace triqs::gfs {

/// --------------------------- implementation ---------------------------------

template <typename Mesh, typename Target, int Arity> class block_gf : TRIQS_CONCEPT_TAG_NAME(BlockGreenFunction) {
template <typename Mesh, typename Target, typename Layout, int Arity> class block_gf : TRIQS_CONCEPT_TAG_NAME(BlockGreenFunction) {
using this_t = block_gf; // for common code
public:
static constexpr bool is_view = false;
Expand All @@ -111,15 +116,15 @@ namespace triqs::gfs {
using mesh_t = Mesh;
using target_t = Target;

using regular_type = block_gf<Mesh, Target, Arity>;
using mutable_view_type = block_gf_view<Mesh, Target, Arity>;
using view_type = block_gf_view<Mesh, Target, Arity, false>;
using const_view_type = block_gf_view<Mesh, Target, Arity, true>;
using regular_type = block_gf<Mesh, Target, Layout, Arity>;
using mutable_view_type = block_gf_view<Mesh, Target, typename Layout::with_lowest_guarantee_t, Arity>;
using view_type = block_gf_view<Mesh, Target, typename Layout::with_lowest_guarantee_t, Arity, false>;
using const_view_type = block_gf_view<Mesh, Target, typename Layout::with_lowest_guarantee_t, Arity, true>;

/// The associated real type
using real_t = block_gf<Mesh, typename Target::real_t, Arity>;
using real_t = block_gf<Mesh, typename Target::real_t, Layout, Arity>;

using g_t = gf<Mesh, Target>;
using g_t = gf<Mesh, Target, Layout>;
using data_t = std::conditional_t<Arity == 1, std::vector<g_t>, std::vector<std::vector<g_t>>>;
using block_names_t = std::conditional_t<Arity == 1, std::vector<std::string>, std::vector<std::vector<std::string>>>;

Expand Down Expand Up @@ -159,7 +164,7 @@ namespace triqs::gfs {
block_gf() = default;

/// From a block_gf_view of the same kind
template <bool IsConst2> block_gf(block_gf_view<Mesh, Target, Arity, IsConst2> const &g) : block_gf(impl_tag{}, g) {}
template <typename L, bool Cnst> block_gf(block_gf_view<Mesh, Target, L, Arity, Cnst> const &g) : block_gf(impl_tag{}, g) {}

/// Construct from anything which models BlockGreenFunction.
// TODO: We would like to refine this, G should have the same mesh, target, at least ...
Expand Down
37 changes: 21 additions & 16 deletions c++/triqs/gfs/block/block_gf_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

namespace triqs::gfs {

template <typename Mesh, typename Target, int Arity, bool IsConst> class block_gf_view : is_view_tag, TRIQS_CONCEPT_TAG_NAME(BlockGreenFunction) {
template <typename Mesh, typename Target, typename Layout, int Arity, bool IsConst>
class block_gf_view : is_view_tag, TRIQS_CONCEPT_TAG_NAME(BlockGreenFunction) {
using this_t = block_gf_view; // for common code

public:
Expand All @@ -32,15 +33,15 @@ namespace triqs::gfs {
using mesh_t = Mesh;
using target_t = Target;

using regular_type = block_gf<Mesh, Target, Arity>;
using mutable_view_type = block_gf_view<Mesh, Target, Arity>;
using view_type = block_gf_view<Mesh, Target, Arity, false>;
using const_view_type = block_gf_view<Mesh, Target, Arity, true>;
using regular_type = block_gf<Mesh, Target, typename Layout::contiguous_t, Arity>;
using mutable_view_type = block_gf_view<Mesh, Target, Layout, Arity>;
using view_type = block_gf_view<Mesh, Target, Layout, Arity, false>;
using const_view_type = block_gf_view<Mesh, Target, Layout, Arity, true>;

/// The associated real type
using real_t = block_gf_view<Mesh, typename Target::real_t, Arity, IsConst>;
using real_t = block_gf_view<Mesh, typename Target::real_t, Layout, Arity, IsConst>;

using g_t = std::conditional_t<IsConst, gf_const_view<Mesh, Target>, gf_view<Mesh, Target>>;
using g_t = std::conditional_t<IsConst, gf_const_view<Mesh, Target, Layout>, gf_view<Mesh, Target, Layout>>;
using data_t = std::conditional_t<Arity == 1, std::vector<g_t>, std::vector<std::vector<g_t>>>;
using block_names_t = std::conditional_t<Arity == 1, std::vector<std::string>, std::vector<std::vector<std::string>>>;

Expand Down Expand Up @@ -80,17 +81,20 @@ namespace triqs::gfs {

block_gf_view() = default;

block_gf_view(block_gf<Mesh, Target, Arity> const &g)
template <typename L>
block_gf_view(block_gf<Mesh, Target, L, Arity> const &g)
requires(IsConst)
: block_gf_view(impl_tag{}, g) {}

block_gf_view(block_gf<Mesh, Target, Arity> &g)
template <typename L>
block_gf_view(block_gf<Mesh, Target, L, Arity> &g)
requires(!IsConst)
: block_gf_view(impl_tag{}, g) {}

block_gf_view(block_gf<Mesh, Target, Arity> &&g) noexcept : block_gf_view(impl_tag{}, std::move(g)) {}
template <typename L> block_gf_view(block_gf<Mesh, Target, L, Arity> &&g) noexcept : block_gf_view(impl_tag{}, std::move(g)) {}

block_gf_view(block_gf_view<Mesh, Target, Arity, !IsConst> const &g)
template <typename L>
block_gf_view(block_gf_view<Mesh, Target, L, Arity, !IsConst> const &g)
requires(IsConst)
: block_gf_view(impl_tag{}, g) {}

Expand Down Expand Up @@ -173,17 +177,17 @@ namespace triqs::gfs {
_glist = data_t{x._glist}; // copy of vector<vector<gf_view>>, makes new views on the gf of x
name = x.name;
}
void rebind(block_gf_view<Mesh, Target, Arity, !IsConst> const &X) noexcept
void rebind(block_gf_view<Mesh, Target, Layout, Arity, !IsConst> const &X) noexcept
requires(IsConst)
{
rebind(block_gf_view{X});
}
void rebind(block_gf<Mesh, Target, Arity> const &X) noexcept
void rebind(block_gf<Mesh, Target, Layout, Arity> const &X) noexcept
requires(IsConst)
{
rebind(block_gf_view{X});
}
void rebind(block_gf<Mesh, Target, Arity> &X) noexcept { rebind(block_gf_view{X}); }
void rebind(block_gf<Mesh, Target, Layout, Arity> &X) noexcept { rebind(block_gf_view{X}); }

public:
//----------------------------- print -----------------------------
Expand All @@ -199,6 +203,7 @@ namespace triqs::gfs {
* Delete std::swap for views
*-----------------------------------------------------------------------------------------------------*/
namespace std {
template <typename Mesh, typename Target, int Arity, bool IsConst>
void swap(triqs::gfs::block_gf_view<Mesh, Target, Arity, IsConst> &a, triqs::gfs::block_gf_view<Mesh, Target, Arity, IsConst> &b) = delete;
template <typename Mesh, typename Target, typename Layout, int Arity, bool IsConst>
void swap(triqs::gfs::block_gf_view<Mesh, Target, Layout, Arity, IsConst> &a,
triqs::gfs::block_gf_view<Mesh, Target, Layout, Arity, IsConst> &b) = delete;
} // namespace std
8 changes: 6 additions & 2 deletions c++/triqs/gfs/block/expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,14 @@ namespace triqs {
// we implement them trivially.

#define DEFINE_OPERATOR(OP1, OP2) \
template <typename Mesh, typename Target, int Arity, typename T> void operator OP1(block_gf_view<Mesh, Target, Arity> g, T const &x) { \
template <typename Mesh, typename Target, typename Layout, int Arity, typename T> \
void operator OP1(block_gf_view<Mesh, Target, Layout, Arity> g, T const &x) { \
g = g OP2 x; \
} \
template <typename Mesh, typename Target, int Arity, typename T> void operator OP1(block_gf<Mesh, Target, Arity> &g, T const &x) { g = g OP2 x; }
template <typename Mesh, typename Target, typename Layout, int Arity, typename T> \
void operator OP1(block_gf<Mesh, Target, Layout, Arity> &g, T const &x) { \
g = g OP2 x; \
}

DEFINE_OPERATOR(+=, +);
DEFINE_OPERATOR(-=, -);
Expand Down
23 changes: 13 additions & 10 deletions c++/triqs/gfs/block/factories.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,27 @@ namespace triqs::gfs {
// ------------------------------- Free Factories for regular type --------------------------------------------------

///
template <typename V, typename T> block_gf<V, T> make_block_gf(int n, gf<V, T> const &g) { return {n, g}; }
template <typename V, typename T, typename L> block_gf<V, T, L> make_block_gf(int n, gf<V, T, L> const &g) { return {n, g}; }

///
template <typename V, typename T> block_gf<V, T> make_block_gf(std::vector<gf<V, T>> v) { return {std::move(v)}; }
template <typename V, typename T, typename L> block_gf<V, T, L> make_block_gf(std::vector<gf<V, T, L>> v) { return {std::move(v)}; }

///
template <typename V, typename T> block_gf<V, T> make_block_gf(std::initializer_list<gf<V, T>> const &v) { return {v}; }
template <typename V, typename T, typename L> block_gf<V, T, L> make_block_gf(std::initializer_list<gf<V, T, L>> const &v) { return {v}; }

///
template <typename V, typename T> block_gf<V, T> make_block_gf(std::vector<std::string> const &b, gf<V, T> const &g) { return {b, g}; }
template <typename V, typename T, typename L> block_gf<V, T, L> make_block_gf(std::vector<std::string> const &b, gf<V, T, L> const &g) {
return {b, g};
}

///
template <typename V, typename T> block_gf<V, T> make_block_gf(std::vector<std::string> const &b, std::vector<gf<V, T>> v) {
template <typename V, typename T, typename L> block_gf<V, T, L> make_block_gf(std::vector<std::string> const &b, std::vector<gf<V, T, L>> v) {
return {b, std::move(v)};
}

///
template <typename V, typename T> block_gf<V, T> make_block_gf(std::vector<std::string> b, std::initializer_list<gf<V, T>> const &v) {
template <typename V, typename T, typename L>
block_gf<V, T, L> make_block_gf(std::vector<std::string> b, std::initializer_list<gf<V, T, L>> const &v) {
return {b, v};
}

Expand Down Expand Up @@ -99,12 +102,12 @@ namespace triqs::gfs {
// ------------------------------- Free Factories for block2_gf --------------------------------------------------

/// From the size n x p and the g from a number and a gf to be copied
template <typename V, typename T> block2_gf<V, T> make_block2_gf(int n, int p, gf<V, T> const &g) { return {n, p, g}; }
template <typename V, typename T, typename L> block2_gf<V, T, L> make_block2_gf(int n, int p, gf<V, T, L> const &g) { return {n, p, g}; }

// from vector<tuple<string,string>>, vector<gf>
template <typename V, typename T>
block2_gf<V, T> make_block2_gf(std::vector<std::string> const &block_names1, std::vector<std::string> const &block_names2,
std::vector<std::vector<gf<V, T>>> vv) {
template <typename V, typename T, typename L>
block2_gf<V, T, L> make_block2_gf(std::vector<std::string> const &block_names1, std::vector<std::string> const &block_names2,
std::vector<std::vector<gf<V, T, L>>> vv) {
if (block_names1.size() != vv.size())
TRIQS_RUNTIME_ERROR << "make_block2_gf(vector<string>, vector<string>>, vector<vector<gf>>): incompatible outer vector size!";
for (auto const &v : vv) {
Expand Down
6 changes: 3 additions & 3 deletions c++/triqs/gfs/block/functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@

namespace triqs::gfs {

template <typename V, typename T, int A> auto fourier(block_gf<V, T, A> const &g) {
template <typename V, typename T, typename L, int A> auto fourier(block_gf<V, T, L, A> const &g) {
return make_lazy_transform([](auto &&x) { return fourier(x); }, g);
};

template <typename V, typename T, int A> auto fourier(block_gf<V, T, A> &g) {
template <typename V, typename T, typename L, int A> auto fourier(block_gf<V, T, L, A> &g) {
return make_lazy_transform([](auto &&x) { return fourier(x); }, g);
};

template <typename V, typename T, int A, bool C> auto fourier(block_gf_view<V, T, A, C> g) {
template <typename V, typename T, typename L, int A, bool C> auto fourier(block_gf_view<V, T, L, A, C> g) {
return make_lazy_transform([](auto &&x) { return fourier(x); }, g);
};

Expand Down
Loading

0 comments on commit 8a95e3a

Please sign in to comment.