Commit d2a0a8c3 authored by gbalduzz's avatar gbalduzz
Browse files

Merge branch 'fix_develop_137' into ct_int

parents 80fd4631 6a1a29b9
Loading
Loading
Loading
Loading
+99 −0
Original line number Diff line number Diff line
// Copyright (C) 2018 ETH Zurich
// Copyright (C) 2018 UT-Battelle, LLC
// All rights reserved.
//
// See LICENSE for terms of usage.
// See CITATION.md for citation guidelines, if DCA++ is used for scientific publications.
//
// Author: Giovanni Balduzzi (gbalduzz@itp.phys.ethz.ch)
//
// This file implements a class to store a subset of a domain distributed among different MPI ranks.
//
// INTERNAL: This class can only be used with dmn_variadic when it's wrapped with dmn_0.

#ifndef DCA_FUNCTION_DOMAINS_LOCAL_DOMAIN_HPP
#define DCA_FUNCTION_DOMAINS_LOCAL_DOMAIN_HPP

#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

#include "dca/util/integer_division.hpp"

namespace dca {
namespace func {
// dca::func::

template <typename BaseDomain, int id = 0>
class LocalDomain {
public:
  using element_type = typename BaseDomain::element_type;  // For putting LocalDomain in dmn_0.
  using this_type = LocalDomain<BaseDomain>;

  template <class Grouping>
  static void initialize(const Grouping& group);

  static std::size_t get_physical_size() {
    return elements_.size();
  }
  static std::size_t get_offset() {
    return offset_;
  }

  static std::size_t get_size() {
    assert(initialized_);
    return padded_size_;
  }
  static std::string get_name() {
    return "Local_" + BaseDomain::get_name();
  }
  static const std::vector<element_type>& get_elements() {
    assert(initialized_);
    return elements_;
  }
  static bool is_initialized() {
    return initialized_;
  }

private:
  static bool initialized_;
  static std::vector<element_type> elements_;
  static std::size_t padded_size_;
  static std::size_t offset_;
};

template <class BaseDomain, int id>
bool LocalDomain<BaseDomain, id>::initialized_ = false;
template <class BaseDomain, int id>
std::vector<typename LocalDomain<BaseDomain, id>::element_type> LocalDomain<BaseDomain, id>::elements_;
template <class BaseDomain, int id>
std::size_t LocalDomain<BaseDomain, id>::padded_size_ = 0;
template <class BaseDomain, int id>
std::size_t LocalDomain<BaseDomain, id>::offset_ = 0;

template <class BaseDomain, int id>
template <class Grouping>
void LocalDomain<BaseDomain, id>::initialize(const Grouping& group) {
  if (initialized_) {
    throw(std::logic_error("Domain " + get_name() + " is already initialized."));
  }

  const std::size_t global_size = BaseDomain::get_size();
  padded_size_ = dca::util::ceilDiv(global_size, std::size_t(group.get_size()));

  const std::size_t start = std::min(padded_size_ * group.get_id(), global_size);
  const std::size_t end = std::min(start + padded_size_, global_size);

  const auto physical_size = end - start;
  offset_ = start;
  elements_.resize(physical_size);
  std::copy_n(BaseDomain::get_elements().data() + start, physical_size, elements_.data());

  initialized_ = true;
}

}  // namespace func
}  // namespace dca

#endif  // DCA_FUNCTION_DOMAINS_LOCAL_DOMAIN_HPP
+20 −13
Original line number Diff line number Diff line
@@ -50,17 +50,26 @@ public:
  function(const std::string& name = default_name_);

  // Copy constructor
  // Constructs the function with the name name and a copy of the elements of other.
  // Constructs the function with the a copy of elements and name of other.
  // Precondition: The other function has been resetted, if the domain had been initialized after
  //               the other function's construction.
  function(const function<scalartype, domain>& other, const std::string& name = default_name_);
  function(const function<scalartype, domain>& other);
  // Same as above, but with name = 'name'.
  function(const function<scalartype, domain>& other, const std::string& name) : function(other) {
    name_ = name;
  }

  // Move constructor
  // Constructs the function with the name name and the elements of other using move semantics.
  // Constructs the function with elements and name of other using move semantics.
  // Precondition: The other function has been resetted, if the domain had been initialized after
  //               the other function's construction.
  // Postcondition: The other function is in a non-specified state.
  function(function<scalartype, domain>&& other, const std::string& name = default_name_);
  function(function<scalartype, domain>&& other);
  // Same as above, but with name = 'name'.
  function(function<scalartype, domain>&& other, const std::string& name)
      : function(std::move(other)) {
    name_ = name;
  }

  // Copy assignment operator
  // Replaces the function's elements with a copy of the elements of other.
@@ -191,7 +200,6 @@ public:
  void operator*=(const function<scalartype, domain>& other);
  void operator/=(const function<scalartype, domain>& other);


  void operator=(scalartype c);
  void operator+=(scalartype c);
  void operator-=(scalartype c);
@@ -267,9 +275,8 @@ function<scalartype, domain>::function(const std::string& name)
}

template <typename scalartype, class domain>
function<scalartype, domain>::function(const function<scalartype, domain>& other,
                                       const std::string& name)
    : name_(name),
function<scalartype, domain>::function(const function<scalartype, domain>& other)
    : name_(other.name_),
      function_type(__PRETTY_FUNCTION__),
      dmn(),
      Nb_elements(dmn.get_size()),
@@ -286,8 +293,8 @@ function<scalartype, domain>::function(const function<scalartype, domain>& other
}

template <typename scalartype, class domain>
function<scalartype, domain>::function(function<scalartype, domain>&& other, const std::string& name)
    : name_(name),
function<scalartype, domain>::function(function<scalartype, domain>&& other)
    : name_(std::move(other.name_)),
      function_type(__PRETTY_FUNCTION__),
      dmn(),
      Nb_elements(dmn.get_size()),
@@ -623,7 +630,7 @@ void function<scalartype, domain>::unpack(const concurrency_t& concurrency, char
  concurrency.unpack(buffer, buffer_size, position, *this);
}

}  // func
}  // dca
}  // namespace func
}  // namespace dca

#endif  // DCA_FUNCTION_FUNCTION_HPP
+18 −9
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@ class Buffer : public std::vector<unsigned char> {
public:
  using Container = std::vector<unsigned char>;

  Buffer() = default;

  Buffer(std::size_t n) : Container(n) {}

  // Copies obj in the buffer as a plain sequence of bytes.
  template <class T, typename = std::enable_if_t<std::is_trivially_copyable<T>::value>>
  Buffer& operator<<(const T& obj);
@@ -46,6 +50,13 @@ public:
  template <class T1, class T2>
  Buffer& operator>>(std::pair<T1, T2>& p);

  // Copies n objects of type T in the buffer as a plain sequence of bytes.
  template <class T>
  void write(const T* ptr, std::size_t n = 1);
  // Read n objects o f type T from the buffer as a plain sequence of bytes.
  template <class T>
  void read(T* ptr, std::size_t n = 1);

  // Retrieves the position of the next read.
  std::size_t tellg() const {
    return read_idx_;
@@ -55,14 +66,12 @@ public:
    read_idx_ = idx;
  }

private:
  // Copies n objects of type T in the buffer as a plain sequence of bytes.
  template <class T>
  void write(const T* ptr, std::size_t n = 1);
  // Read n objects o f type T from the buffer as a plain sequence of bytes.
  template <class T>
  void read(T* ptr, std::size_t n = 1);
  void clear() {
    Container::clear();
    read_idx_ = 0;
  }

private:
  std::size_t read_idx_ = 0;
};

@@ -152,7 +161,7 @@ Buffer& Buffer::operator>>(std::pair<T1, T2>& p) {
  return (*this) >> p.first >> p.second;
}

}  // io
}  // dca
}  // namespace io
}  // namespace dca

#endif  // DCA_IO_BUFFER_HPP
+0 −67
Original line number Diff line number Diff line
// Copyright (C) 2018 ETH Zurich
// Copyright (C) 2018 UT-Battelle, LLC
// All rights reserved.
//
// See LICENSE.txt for terms of usage.
//  See CITATION.md for citation guidelines, if DCA++ is used for scientific publications.
//
// Author: Giovanni Balduzzi(gbalduzz@itp.phys.ethz.ch)
//
// This file provides a lightweight proxy to access blocks of a matrix. The underlying matrix must
// not be destroyed while this object is in use. A const and a non const version are provided.

#ifndef DCA_LINALG_MAKE_CONSTANT_VIEW_HPP
#define DCA_LINALG_MAKE_CONSTANT_VIEW_HPP

#include <memory>

#include "dca/linalg/matrix_view.hpp"

namespace dca {
namespace linalg {
// dca::linalg::

template <typename ScalarType, DeviceType device_t>
auto inline makeConstantView(const ScalarType* data, const std::pair<int, int> size, const int ld) {
  return std::make_unique<const MatrixView<ScalarType, device_t>>(const_cast<ScalarType*>(data),
                                                                  size, ld);
}

template <typename ScalarType, DeviceType device_t>
inline auto makeConstantView(ScalarType* const data, const int size, const int ld) {
  return makeConstantView<ScalarType, device_t>(data, std::make_pair(size, size), ld);
}

template <typename ScalarType, DeviceType device_t>
inline auto makeConstantView(ScalarType* const data, const int size) {
  return makeConstantView<ScalarType, device_t>(data, std::make_pair(size, size), size);
}

template <typename ScalarType, DeviceType device_t, template <typename, DeviceType> class Matrix>
inline auto makeConstantView(const Matrix<ScalarType, device_t>& mat) {
  return makeConstantView<ScalarType, device_t>(mat.ptr(), mat.size(), mat.leadingDimension());
}

template <typename ScalarType, DeviceType device_t, template <typename, DeviceType> class Matrix>
inline auto makeConstantView(const Matrix<ScalarType, device_t>& mat, const int offset_i,
                             const int offset_j) {
  assert(offset_i < mat.nrCols());
  assert(offset_j < mat.nrRows());
  return makeConstantView<ScalarType, device_t>(
      mat.ptr(offset_i, offset_j), std::make_pair(mat.nrRows() - offset_i, mat.nrCols() - offset_j),
      mat.leadingDimension());
}

template <typename ScalarType, DeviceType device_t, template <typename, DeviceType> class Matrix>
inline auto makeConstantView(const Matrix<ScalarType, device_t>& mat, const int offset_i,
                             const int offset_j, const int ni, const int nj) {
  assert(ni + offset_i <= mat.nrRows());
  assert(nj + offset_j <= mat.nrCols());
  return makeConstantView<ScalarType, device_t>(mat.ptr(offset_i, offset_j), std::make_pair(ni, nj),
                                                mat.leadingDimension());
}

}  // linalg
}  // dca

#endif  // DCA_LINALG_MAKE_CONSTANT_VIEW_HPP
+48 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ template <typename ScalarType, DeviceType device_name = linalg::CPU>
class MatrixView {
public:
  using Pair = std::pair<int, int>;
  MatrixView(ScalarType* data, Pair size);
  MatrixView(ScalarType* data, Pair size, int ld);
  MatrixView(ScalarType* data, int size, int ld);
  MatrixView(ScalarType* data, int size);
@@ -98,6 +99,10 @@ private:
  const std::pair<int, int> size_;
};

template <typename ScalarType, DeviceType device_t>
MatrixView<ScalarType, device_t>::MatrixView(ScalarType* const data, const Pair size)
    : MatrixView(data, size, size.first) {}

template <typename ScalarType, DeviceType device_t>
MatrixView<ScalarType, device_t>::MatrixView(ScalarType* const data, const Pair size, const int ld)
    : ptr_(data), ldm_(ld), size_(size) {}
@@ -167,7 +172,48 @@ void MatrixView<ScalarType, device_t>::print(std::ostream& out) const {
  out << "\n" << std::endl;
}

}  // linalg
}  // dca
// Methods for returning a pointer to constant matrix view from non const arguments
template <typename ScalarType, DeviceType device_t>
auto inline makeConstantView(const ScalarType* data, const std::pair<int, int> size, const int ld) {
  return std::make_unique<const MatrixView<ScalarType, device_t>>(const_cast<ScalarType*>(data),
                                                                  size, ld);
}

template <typename ScalarType, DeviceType device_t>
auto inline makeConstantView(ScalarType* const data, const int size, const int ld) {
  return makeConstantView<ScalarType, device_t>(data, std::make_pair(size, size), ld);
}

template <typename ScalarType, DeviceType device_t>
auto inline makeConstantView(ScalarType* const data, const int size) {
  return makeConstantView<ScalarType, device_t>(data, std::make_pair(size, size), size);
}

template <template <typename, DeviceType> class Matrix, typename ScalarType, DeviceType device_t>
auto inline makeConstantView(const Matrix<ScalarType, device_t>& mat) {
  return makeConstantView<ScalarType, device_t>(mat.ptr(), mat.size(), mat.leadingDimension());
}

template <template <typename, DeviceType> class Matrix, typename ScalarType, DeviceType device_t>
auto inline makeConstantView(const Matrix<ScalarType, device_t>& mat, const int offset_i,
                             const int offset_j) {
  assert(offset_i < mat.nrCols());
  assert(offset_j < mat.nrRows());
  return makeConstantView<ScalarType, device_t>(
      mat.ptr(offset_i, offset_j), std::make_pair(mat.nrRows() - offset_i, mat.nrCols() - offset_j),
      mat.leadingDimension());
}

template <template <typename, DeviceType> class Matrix, typename ScalarType, DeviceType device_t>
auto inline makeConstantView(const Matrix<ScalarType, device_t>& mat, const int offset_i,
                             const int offset_j, const int ni, const int nj) {
  assert(ni + offset_i <= mat.nrRows());
  assert(nj + offset_j <= mat.nrCols());
  return makeConstantView<ScalarType, device_t>(mat.ptr(offset_i, offset_j), std::make_pair(ni, nj),
                                                mat.leadingDimension());
}

}  // namespace linalg
}  // namespace dca

#endif  // DCA_LINALG_MATRIX_VIEW_HPP
Loading