TiledArray  0.7.0
elemental.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2014 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Drew Lewis
19  * Department of Chemistry, Virginia Tech
20  *
21  * elemental.h
22  * March 23, 2014
23  *
24  */
25 
26 #ifndef TILEDARRAY_ELEMENTAL_H__INCLUDED
27 #define TILEDARRAY_ELEMENTAL_H__INCLUDED
28 
29 #include <TiledArray/config.h>
30 
31 #if TILEDARRAY_HAS_ELEMENTAL
32 
33 #if HAVE_ELEMENTAL_H
34 
36 # include <elemental.hpp>
37 
38 namespace TiledArray {
39 
40  template<typename Tile>
41  elem::DistMatrix<typename Tile::value_type> array_to_elem(const DistArray<Tile> &array,
42  const elem::Grid &grid){
43  // Check that the Array is 2-d
44  TA_USER_ASSERT(array.range().rank() == 2u,
45  "TiledArray::array_to_elem(): The array dimension must be 2.");
46 
47  // Construct the elemental matrix
48  using T = typename Tile::value_type;
49  auto sizes = array.trange().elements_range().extent_data();
50  elem::DistMatrix<T> mat(sizes[0], sizes[1], grid);
51  elem::Zero(mat);
52 
53  //Create the Axpy interface to fill elemental matrix
54  elem::AxpyInterface<T> interface;
55  // Attach matrix to interface
56  interface.Attach(elem::LOCAL_TO_GLOBAL, mat);
57 
58  // Get array iterators
59  typename DistArray<Tile>::const_iterator it = array.begin();
60  typename DistArray<Tile>::const_iterator end = array.end();
61 
62  for(; it != end; ++it){
63  // Get tile matrix location info
64  const typename DistArray<Tile>::value_type tile = *it;
65 
66  // Get tile range data
67  const auto* MADNESS_RESTRICT const tile_lower = tile.range().lobound_data();
68  const auto* MADNESS_RESTRICT const tile_extent = tile.range().extent_data();
69  const std::size_t tile_lower_0 = tile_lower[0];
70  const std::size_t tile_lower_1 = tile_lower[1];
71  const std::size_t tile_extent_0 = tile_extent[0];
72  const std::size_t tile_extent_1 = tile_extent[1];
73 
74  // Create Eigen RowMajor Map of tile
75  const Eigen::Map<
77  Eigen::AutoAlign> eig_row_map = eigen_map(tile, tile_extent_0, tile_extent_1);
78 
79  // Create ColMajor EigenMatrix from RowMajor Map
81 
82  // Make Elemental local matrix and attach the data.
83  elem::Matrix<T> ElemBlock;
84  ElemBlock.Attach(CMatrix.rows(), CMatrix.cols(), CMatrix.data(), CMatrix.rows());
85 
86  // Attach elem local matrix to elem global matrix
87  interface.Axpy(1.0, ElemBlock, tile_lower_0, tile_lower_1);
88  }
89  interface.Detach(); // Does communication using elemental
90 
91  return mat;
92  }
93 
94  template<typename Tile>
95  void elem_to_array(DistArray<Tile> &array, elem::DistMatrix<typename Tile::value_type> &mat){
96  using T = typename Tile::value_type;
97  TA_USER_ASSERT(array.range().rank()==2u, "TiledArray::elem_to_array(): requires the array to have dimension 2");
98  TA_USER_ASSERT((array.trange().elements_range().extent()[0]==mat.Height()) &&
99  (array.trange().elements_range().extent()[1] == mat.Width()),
100  "TiledArray::elem_to_array(): requires the shape of the elem matrix and the array to be the same.");
101 
102  // Make interface and attach mat
103  elem::AxpyInterface<T> interface;
104  interface.Attach(elem::GLOBAL_TO_LOCAL, mat);
105 
106  // Get iterators to array
107  typename DistArray<Tile>::iterator it = array.begin();
108  typename DistArray<Tile>::iterator end = array.end();
109 
110  // Loop over tiles and improperly assign the data to them in column major
111  // format.
112  for(;it != end; ++it){
113  // Get tile matrix location info
114  typename DistArray<Tile>::value_type tile = *it;
115 
116  // Get tile range data
117  const auto* MADNESS_RESTRICT const tile_lower = tile.range().lobound_data();
118  const auto* MADNESS_RESTRICT const tile_extent = tile.range().extent_data();
119  const std::size_t tile_lower_0 = tile_lower[0];
120  const std::size_t tile_lower_1 = tile_lower[1];
121  const std::size_t tile_extent_0 = tile_extent[0];
122  const std::size_t tile_extent_1 = tile_extent[1];
123 
124  // Make Elemental local matrix and attach the data.
125  elem::Matrix<T> ElemBlock;
126  ElemBlock.Attach(tile_extent_0, tile_extent_1, tile.data(), tile_extent_0);
127 
128  // need to zero tile so Axpy doesn't add to it.
129  std::fill(ElemBlock.Buffer(), ElemBlock.Buffer()+tile_extent_0*tile_extent_1, 0.0);
130 
131  // Attach elem local matrix to elem global matrix
132  interface.Axpy(1.0, ElemBlock, tile_lower_0, tile_lower_1);
133  }
134  interface.Detach(); // Does communication using elemental
135 
136  // now we have to go back and fix it so the tiles are row major ordered.
137  it = array.begin();
138  for(;it != end; ++it){
139  // Get tile and size
140  typename DistArray<Tile>::value_type tile = *it;
141 
142  // Get tile range data
143  const auto* MADNESS_RESTRICT const tile_extent = tile.range().extent_data();
144  const std::size_t tile_extent_0 = tile_extent[0];
145  const std::size_t tile_extent_1 = tile_extent[1];
146 
147  // copy to row major matrix
150  Eigen::AutoAlign > (tile.data(),tile_extent_0,tile_extent_1);
151 
152  // Finally copy the data back into the tile in the correct format.
153  std::copy(row_mat.data(), row_mat.data()+row_mat.size(), tile.data());
154  }
155  }
156 
157 } // namespace TiledArray
158 
159 #elif HAVE_EL_H // end of HAVE_ELEMENTAL_H
160 
161 // pacify clang warnings about tautological comparisons in El/macros/GuardAndPayload.h
162 #ifdef __clang__
163 #pragma clang diagnostic push
164 #pragma clang diagnostic ignored "-Wtautological-compare"
165 #endif // __clang__
166 
167 # include <El.hpp>
168 
169 #ifdef __clang__
170 #pragma clang diagnostic pop
171 #endif // __clang__
172 
174 
175 #else
176 # error "TILEDARRAY_HAS_ELEMENTAL set but neither HAVE_EL_H nor HAVE_ELEMENTAL_H set: file an issue at " TILEDARRAY_PACKAGE_URL
177 #endif
178 
179 #endif // TILEDARRAY_HAS_ELEMENTAL
180 
181 #endif // TILEDARRAY_ELEMENTAL_H__INCLUDED
impl_type::const_iterator const_iterator
Local tile const iterator.
Definition: dist_array.h:70
impl_type::value_type value_type
Tile type.
Definition: dist_array.h:64
Eigen::Map< const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor >, Eigen::AutoAlign > eigen_map(const Tensor< T, A > &tensor, const std::size_t m, const std::size_t n)
Construct a const Eigen::Map object for a given Tensor object.
Definition: eigen.h:66
impl_type::iterator iterator
Local tile iterator.
Definition: dist_array.h:69
DistArray< Tile, Policy > copy(const DistArray< Tile, Policy > &a)
Definition: utils.h:58
decltype(auto) range() const
Range accessor.
Definition: tile.h:192
#define TA_USER_ASSERT(a, m)
Definition: error.h:123