TiledArray  0.7.0
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 
29 #include <TiledArray/madness.h>
30 #include <TiledArray/type_traits.h>
31 
33 namespace Eigen {
34  template <typename> class aligned_allocator;
35 } // namespace Eigen
36 
37 namespace TiledArray {
38 
40 
68  template <typename Array, typename Op,
69  typename std::enable_if<is_dense<Array>::value>::type* = nullptr>
70  inline Array
71  make_array(World& world, const detail::trange_t<Array>& trange,
72  const std::shared_ptr<detail::pmap_t<Array> >& pmap, Op&& op)
73  {
74  typedef typename Array::value_type value_type;
75  typedef typename value_type::range_type range_type;
76 
77  // Make an empty result array
78  Array result(world, trange);
79 
80  // Iterate over local tiles of arg
81  for(const auto index : * result.pmap()) {
82 
83  // Spawn a task to evaluate the tile
84  auto tile =
85  world.taskq.add([=] (const range_type& range) -> value_type {
86  value_type tile;
87  op(tile, range);
88  return tile;
89  }, trange.make_tile_range(index));
90 
91  // Store result tile
92  result.set(index, tile);
93  }
94 
95  return result;
96  }
97 
99 
132  template <typename Array, typename Op,
133  typename std::enable_if<! is_dense<Array>::value>::type* = nullptr>
134  inline Array
135  make_array(World& world, const detail::trange_t<Array>& trange,
136  const std::shared_ptr<detail::pmap_t<Array> >& pmap, Op&& op)
137  {
138  typedef typename Array::value_type value_type;
139  typedef typename Array::size_type size_type;
140  typedef std::pair<size_type, Future<value_type> > datum_type;
141 
142  // Create a vector to hold local tiles
143  std::vector<datum_type> tiles;
144  tiles.reserve(pmap->size());
145 
146  // Construct a tensor to hold updated tile norms for the result shape.
149  tile_norms(trange.tiles_range(), 0);
150 
151  // Construct the task function used to construct the result tiles.
152  madness::AtomicInt counter; counter = 0;
153  int task_count = 0;
154  auto task = [&](const size_type index) -> value_type {
155  value_type tile;
156  tile_norms[index] = op(tile, trange.make_tile_range(index));
157  ++counter;
158  return tile;
159  };
160 
161  for(const auto index : *pmap) {
162  auto result_tile = world.taskq.add(task, index);
163  ++task_count;
164  tiles.emplace_back(index, std::move(result_tile));
165  }
166 
167  // Wait for tile norm data to be collected.
168  if(task_count > 0)
169  world.await([&counter,task_count] () -> bool { return counter == task_count; });
170 
171  // Construct the new array
172  Array result(world, trange,
173  typename Array::shape_type(world, tile_norms, trange), pmap);
174  for(auto& it : tiles) {
175  const size_type index = it.first;
176  if(! result.is_zero(index))
177  result.set(it.first, it.second);
178  }
179 
180  return result;
181  }
182 
183 
185 
217  template <typename Array, typename Op>
218  inline Array
219  make_array(World& world, const detail::trange_t<Array>& trange, Op&& op) {
220  return make_array<Array>(world, trange,
222  trange.tiles_range().volume()), op);
223  }
224 
225 } // namespace TiledArray
226 
227 #endif // TILEDARRAY_CONVERSIONS_MAKE_ARRAY_H__INCLUDED
std::enable_if< detail::is_input_iterator< InIter >::value >::type set(const Index &i, InIter first)
Set a tile and fill it using a sequence.
Definition: dist_array.h:348
impl_type::shape_type shape_type
Shape type for array tiling.
Definition: dist_array.h:61
An N-dimensional tensor object.
Definition: foreach.h:40
Forward declarations.
Definition: foreach.h:32
typename T::pmap_interface pmap_t
Definition: type_traits.h:770
impl_type::value_type value_type
Tile type.
Definition: dist_array.h:64
typename T::trange_type trange_t
Definition: type_traits.h:764
Forward declarations.
Definition: clone.h:32
Tensor_ add(const Right &right) const
Add this and other to construct a new tensors.
Definition: tensor.h:694
typename T::policy_type policy_t
Definition: type_traits.h:773
impl_type::size_type size_type
Size type.
Definition: dist_array.h:63
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:71
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:80
DistArray< Tile, Policy > Array
const std::shared_ptr< pmap_interface > & pmap() const
Process map accessor.
Definition: dist_array.h:647