make_array.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2015 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  * Justus Calvin
19  * Department of Chemistry, Virginia Tech
20  *
21  * array_init.h
22  * Dec 15, 2015
23  *
24  */
25 
26 #ifndef TILEDARRAY_CONVERSIONS_MAKE_ARRAY_H__INCLUDED
27 #define TILEDARRAY_CONVERSIONS_MAKE_ARRAY_H__INCLUDED
28 
30 #include "TiledArray/shape.h"
31 #include "TiledArray/type_traits.h"
32 
34 namespace Eigen {
35 template <typename>
36 class aligned_allocator;
37 } // namespace Eigen
38 
39 namespace TiledArray {
40 
42 
71 template <typename Array, typename Op,
72  typename std::enable_if<is_dense<Array>::value>::type* = nullptr>
73 inline Array make_array(World& world, const detail::trange_t<Array>& trange,
74  const std::shared_ptr<detail::pmap_t<Array> >& pmap,
75  Op&& op) {
76  typedef typename Array::value_type value_type;
77  typedef typename value_type::range_type range_type;
78 
79  // Make an empty result array
80  Array result(world, trange);
81 
82  // Iterate over local tiles of arg
83  for (const auto index : *result.pmap()) {
84  // Spawn a task to evaluate the tile
85  auto tile = world.taskq.add(
86  [=](const range_type& range) -> value_type {
87  value_type tile;
88  op(tile, range);
89  return tile;
90  },
91  trange.make_tile_range(index));
92 
93  // Store result tile
94  result.set(index, tile);
95  }
96 
97  return result;
98 }
99 
101 
135 template <typename Array, typename Op,
136  typename std::enable_if<!is_dense<Array>::value>::type* = nullptr>
137 inline Array make_array(World& world, const detail::trange_t<Array>& trange,
138  const std::shared_ptr<detail::pmap_t<Array> >& pmap,
139  Op&& op) {
140  typedef typename Array::value_type value_type;
141  typedef typename Array::ordinal_type ordinal_type;
142  typedef std::pair<ordinal_type, Future<value_type> > datum_type;
143 
144  // Create a vector to hold local tiles
145  std::vector<datum_type> tiles;
146  tiles.reserve(pmap->size());
147 
148  // Construct a tensor to hold updated tile norms for the result shape.
150  typename detail::shape_t<Array>::value_type,
152  tile_norms(trange.tiles_range(), 0);
153 
154  // Construct the task function used to construct the result tiles.
155  madness::AtomicInt counter;
156  counter = 0;
157  int task_count = 0;
158  auto task = [&](const ordinal_type index) -> value_type {
159  value_type tile;
160  tile_norms[index] = op(tile, trange.make_tile_range(index));
161  ++counter;
162  return tile;
163  };
164 
165  for (const auto index : *pmap) {
166  auto result_tile = world.taskq.add(task, index);
167  ++task_count;
168  tiles.emplace_back(index, std::move(result_tile));
169  }
170 
171  // Wait for tile norm data to be collected.
172  if (task_count > 0)
173  world.await(
174  [&counter, task_count]() -> bool { return counter == task_count; });
175 
176  // Construct the new array
177  Array result(world, trange,
178  typename Array::shape_type(world, tile_norms, trange), pmap);
179  for (auto& it : tiles) {
180  const auto index = it.first;
181  if (!result.is_zero(index)) result.set(it.first, it.second);
182  }
183 
184  return result;
185 }
186 
188 
221 template <typename Array, typename Op>
222 inline Array make_array(World& world, const detail::trange_t<Array>& trange,
223  Op&& op) {
224  return make_array<Array>(world, trange,
226  world, trange.tiles_range().volume()),
227  op);
228 }
229 
230 } // namespace TiledArray
231 
232 #endif // TILEDARRAY_CONVERSIONS_MAKE_ARRAY_H__INCLUDED
impl_type::value_type value_type
Tile type.
Definition: dist_array.h:86
::blas::Op Op
Definition: blas.h:46
Forward declarations.
Definition: foreach.h:34
typename T::pmap_interface pmap_t
Definition: type_traits.h:1177
void set(const Index &i, InIter first)
Definition: dist_array.h:619
typename T::policy_type policy_t
Definition: type_traits.h:1180
Array make_array(World &world, const detail::trange_t< Array > &trange, const std::shared_ptr< detail::pmap_t< Array > > &pmap, Op &&op)
Construct dense Array.
Definition: make_array.h:73
DistArray< Tile, Policy > Array
Forward declarations.
Definition: dist_array.h:57
typename T::trange_type trange_t
Definition: type_traits.h:1171
impl_type::ordinal_type ordinal_type
Ordinal type.
Definition: dist_array.h:85
An N-dimensional tensor object.
Definition: tensor.h:50
const std::shared_ptr< pmap_interface > & pmap() const
Process map accessor.
Definition: dist_array.h:1019
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:82
impl_type::shape_type shape_type
Shape type for array tiling.
Definition: dist_array.h:80