Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
Stokhos_Sparse3TensorPartition.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef STOKHOS_SPARSE_3_TENSOR_PARTITION_HPP
43 #define STOKHOS_SPARSE_3_TENSOR_PARTITION_HPP
44 
46 
47 #include "Teuchos_ArrayRCP.hpp"
48 #include "Teuchos_Array.hpp"
49 
50 namespace Stokhos {
51 
52  template <typename TupleType>
53  class RCB {
54  public:
57  typedef typename TupleType::id_type id_type;
58 
59  struct CoordCompare {
61  CoordCompare(const size_type& d_) : d(d_) {}
62  bool operator() (const TupleType& a, const TupleType& b) const {
63  return a(d) < b(d);
64  }
65  };
66 
67  struct Box {
73 
74  Box(const Teuchos::ArrayView<TupleType>& c) : coords(c.begin(), c.end()) {
77  }
78 
79  // Compute bounding box around points
81  xmin = coords[0](0); xmax = coords[0](0);
82  ymin = coords[0](1); ymax = coords[0](1);
83  zmin = coords[0](2); zmax = coords[0](2);
84  for (size_type i=0; i<coords.size(); ++i) {
85  coord_type x = coords[i](0);
86  coord_type y = coords[i](1);
87  coord_type z = coords[i](2);
88  if (x < xmin) xmin = x;
89  if (y < ymin) ymin = y;
90  if (z < zmin) zmin = z;
91  if (x > xmax) xmax = x;
92  if (y > ymax) ymax = y;
93  if (z > zmax) zmax = z;
94  }
95  delta_x = xmax - xmin + 1;
96  delta_y = ymax - ymin + 1;
97  delta_z = zmax - zmin + 1;
98 
99  // std::cout << "delta_x = " << delta_x
100  // << " delta_y = " << delta_y
101  // << " delta_z = " << delta_z << std::endl;
102  }
103 
104  // Compute dimension to split
106  split_dim = 0;
107  if (delta_y >= delta_x && delta_y >= delta_z) split_dim = 1;
108  if (delta_z >= delta_x && delta_z >= delta_y) split_dim = 2;
109 
110  //std::cout << "splitting dimension = " << split_dim << std::endl;
111  }
112 
113  // Split box into two pieces with roughly equal numbers of points
114  void split() {
115  // Sort points based on splitting dimension
116  CoordCompare cmp(split_dim);
117  std::sort(coords.begin(), coords.end(), cmp);
118 
119  // Divide coords into two bins of roughly equal size, keeping
120  // coords with equal values for split dimension together
121  size_type n = coords.size();
122  size_type s = n / 2;
123 
124  while (s < n-1 && coords[s](split_dim) == coords[s+1](split_dim)) ++s;
125  //std::cout << "n = " << n << " s = " << s << std::endl;
126 
127  if (s > 0)
128  left = Teuchos::rcp(new Box(coords.view(0, s)));
129  if (s < n)
130  right = Teuchos::rcp(new Box(coords.view(s, n-s)));
131 
132  // Clear my coordinate array since we aren't a leaf
133  //Teuchos::Array<TupleType>().swap(coords);
134  //coords.resize(0);
135  }
136 
137  };
138 
140  RCB(const coord_type& max_length_,
141  const size_type& max_parts_,
142  const Teuchos::ArrayView<TupleType>& coords_) :
143  max_length(max_length_),
144  max_parts(max_parts_),
145  coords(coords_.begin(), coords_.end()) {
146  partition();
147  }
148 
150  ~RCB() {}
151 
153  size_type get_num_parts() const { return num_parts; }
154 
157 
160  return parts; }
161 
162  // Create list of part IDs for each tuple
165  for (size_type part=0; part<num_parts; ++part) {
166  Teuchos::RCP<Box> box = (*parts)[part];
167  size_type n = box->coords.size();
168  for (size_type i=0; i<n; ++i)
169  part_ids[ box->coords[i].ID() ] = part;
170  }
171  return part_ids;
172  }
173 
174  private:
175 
181 
183  void partition() {
184 
185  // Create root bounding box
186  root = Teuchos::rcp(new Box(coords()));
187  num_parts = 1;
189 
190  // Create array of boxes that are too big
191  Teuchos::Array< Teuchos::RCP<Box> > boxes_to_split;
192  if (root->delta_x > max_length ||
193  root->delta_y > max_length ||
194  root->delta_z > max_length)
195  boxes_to_split.push_back(root);
196  else
197  parts->push_back(root);
198 
199  // Split each box until all boxes are less than tolerance
200  while(boxes_to_split.size() > 0 && num_parts < max_parts) {
201  Teuchos::RCP<Box> box = boxes_to_split.back();
202  boxes_to_split.pop_back();
203  box->split();
204  ++num_parts;
205  if (box->left != Teuchos::null) {
206  if (box->left->delta_x > max_length ||
207  box->left->delta_y > max_length ||
208  box->left->delta_z > max_length)
209  boxes_to_split.push_back(box->left);
210  else
211  parts->push_back(box->left);
212  }
213  if (box->right != Teuchos::null) {
214  if (box->right->delta_x > max_length ||
215  box->right->delta_y > max_length ||
216  box->right->delta_z > max_length)
217  boxes_to_split.push_back(box->right);
218  else
219  parts->push_back(box->right);
220  }
221  }
222 
223  TEUCHOS_ASSERT(parts->size() == num_parts);
224  }
225 
226  };
227 
228  template <typename ordinal_type, typename scalar_type>
229  struct CijkData {
235 
237  if (d == 0) return i;
238  if (d == 1) return j;
239  if (d == 2) return k;
240  return -1;
241  }
242 
243  ordinal_type ID() const { return gid; }
244  };
245 
250  };
251 
252  template <typename ordinal_type, typename scalar_type>
256  CijkSymmetryType symmetry_type) {
258  typedef typename Cijk_type::k_iterator k_iterator;
259  typedef typename Cijk_type::kj_iterator kj_iterator;
260  typedef typename Cijk_type::kji_iterator kji_iterator;
261 
262  ordinal_type num_cijk = Cijk.num_entries();
264  num_cijk);
265  ordinal_type idx = 0;
266  k_iterator k_begin = Cijk.k_begin();
267  k_iterator k_end = Cijk.k_end();
268  for (k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
269  ordinal_type k = index(k_it);
270  kj_iterator j_begin = Cijk.j_begin(k_it);
271  kj_iterator j_end = Cijk.j_end(k_it);
272  for (kj_iterator j_it = j_begin; j_it != j_end; ++j_it) {
273  ordinal_type j = index(j_it);
274  kji_iterator i_begin = Cijk.i_begin(j_it);
275  kji_iterator i_end = Cijk.i_end(j_it);
276  for (kji_iterator i_it = i_begin; i_it != i_end; ++i_it) {
277  ordinal_type i = index(i_it);
278  if (symmetry_type == CIJK_NO_SYMMETRY) {
279  coordinate_list[idx].i = i;
280  coordinate_list[idx].j = j;
281  coordinate_list[idx].k = k;
282  coordinate_list[idx].c = value(i_it);
283  coordinate_list[idx].gid = idx;
284  ++idx;
285  }
286  else if (symmetry_type == CIJK_TWO_WAY_SYMMETRY && j >= k) {
287  coordinate_list[idx].i = i;
288  coordinate_list[idx].j = j;
289  coordinate_list[idx].k = k;
290  if (j == k)
291  coordinate_list[idx].c = 0.5*value(i_it);
292  else
293  coordinate_list[idx].c = value(i_it);
294  coordinate_list[idx].gid = idx;
295  ++idx;
296  }
297  else if (symmetry_type == CIJK_SIX_WAY_SYMMETRY && i >= j && j >= k) {
298  coordinate_list[idx].i = i;
299  coordinate_list[idx].j = j;
300  coordinate_list[idx].k = k;
301  if (i == j && j == k)
302  coordinate_list[idx].c = (1.0/6.0)*value(i_it);
303  else
304  coordinate_list[idx].c = value(i_it);
305  coordinate_list[idx].gid = idx;
306  ++idx;
307  }
308  }
309  }
310  }
311  coordinate_list.resize(idx);
312 
313  return coordinate_list;
314  }
315 
316 } // namespace Stokhos
317 
318 #endif // STOKHOS_SPARSE_3_TENSOR_PARTITION_HPP
Teuchos::Array::size
size_type size() const
Stokhos::CijkData::k
ordinal_type k
Definition: Stokhos_Sparse3TensorPartition.hpp:233
Stokhos::RCB::Box::right
Teuchos::RCP< Box > right
Definition: Stokhos_Sparse3TensorPartition.hpp:71
Teuchos::Array::end
iterator end()
Stokhos::RCB::partition
void partition()
Partition.
Definition: Stokhos_Sparse3TensorPartition.hpp:183
Stokhos::Sparse3Tensor::i_begin
kji_iterator i_begin(const kj_iterator &j) const
Iterator pointing to first i entry for given j and k.
Definition: Stokhos_Sparse3TensorImp.hpp:383
Stokhos::RCB::Box::xmax
coord_type xmax
Definition: Stokhos_Sparse3TensorPartition.hpp:68
Teuchos::Array::back
reference back()
Stokhos::CijkData::value_type
ordinal_type value_type
Definition: Stokhos_Sparse3TensorPartition.hpp:230
Stokhos::Sparse3Tensor::j_end
kj_iterator j_end(const k_iterator &k) const
Iterator pointing to last j entry for given k.
Definition: Stokhos_Sparse3TensorImp.hpp:347
Stokhos::RCB::parts
Teuchos::RCP< Teuchos::Array< Teuchos::RCP< Box > > > parts
Definition: Stokhos_Sparse3TensorPartition.hpp:180
Teuchos::ArrayView::size_type
Ordinal size_type
Stokhos::RCB::num_parts
size_type num_parts
Definition: Stokhos_Sparse3TensorPartition.hpp:177
Stokhos::RCB::CoordCompare::d
size_type d
Definition: Stokhos_Sparse3TensorPartition.hpp:60
Teuchos_ArrayRCP.hpp
Teuchos::Array::push_back
void push_back(const value_type &x)
TotalOrderBasisUnitTest::value_type
double value_type
Definition: Stokhos_LexicographicTreeBasisUnitTest.cpp:70
SDMUtilsUnitTest::scalar_type
double scalar_type
Definition: Stokhos_SDMUtilsUnitTest.cpp:57
TEUCHOS_ASSERT
#define TEUCHOS_ASSERT(assertion_test)
Teuchos::rcp
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Stokhos::Sparse3Tensor::num_entries
ordinal_type num_entries() const
Return number of non-zero entries.
Definition: Stokhos_Sparse3TensorImp.hpp:195
Teuchos_Array.hpp
Stokhos::Sparse3Tensor::j_begin
kj_iterator j_begin(const k_iterator &k) const
Iterator pointing to first j entry for given k.
Definition: Stokhos_Sparse3TensorImp.hpp:335
Stokhos::RCB::coords
Teuchos::Array< TupleType > coords
Definition: Stokhos_Sparse3TensorPartition.hpp:178
Stokhos::Sparse3Tensor
Data structure storing a sparse 3-tensor C(i,j,k) in a a compressed format.
Definition: Stokhos_Sparse3Tensor.hpp:56
Sparse3TensorUnitTest::Cijk_type
Stokhos::Sparse3Tensor< int, double > Cijk_type
Definition: Stokhos_Sparse3TensorUnitTest.cpp:52
Teuchos::ArrayView< TupleType >
Stokhos::RCB::get_partition_root
Teuchos::RCP< Box > get_partition_root() const
Get root of partition.
Definition: Stokhos_Sparse3TensorPartition.hpp:156
Teuchos::RCP
Stokhos::RCB::Box::zmin
coord_type zmin
Definition: Stokhos_Sparse3TensorPartition.hpp:68
Stokhos::RCB::max_length
coord_type max_length
Definition: Stokhos_Sparse3TensorPartition.hpp:176
Teuchos::Array< TupleType >
Stokhos::CijkData::ID
ordinal_type ID() const
Definition: Stokhos_Sparse3TensorPartition.hpp:243
Stokhos::RCB::CoordCompare::operator()
bool operator()(const TupleType &a, const TupleType &b) const
Definition: Stokhos_Sparse3TensorPartition.hpp:62
Stokhos_Sparse3Tensor.hpp
Teuchos::Array::begin
iterator begin()
TotalOrderBasisUnitTest::ordinal_type
int ordinal_type
Definition: Stokhos_LexicographicTreeBasisUnitTest.cpp:69
Teuchos::ArrayRCP
Stokhos::RCB::get_num_parts
size_type get_num_parts() const
Get number of parts.
Definition: Stokhos_Sparse3TensorPartition.hpp:153
Stokhos::RCB::root
Teuchos::RCP< Box > root
Definition: Stokhos_Sparse3TensorPartition.hpp:179
Stokhos::RCB::Box::left
Teuchos::RCP< Box > left
Definition: Stokhos_Sparse3TensorPartition.hpp:71
Stokhos::RCB::Box::ymin
coord_type ymin
Definition: Stokhos_Sparse3TensorPartition.hpp:68
Stokhos::RCB::coord_type
TupleType::value_type coord_type
Definition: Stokhos_Sparse3TensorPartition.hpp:55
Stokhos::RCB::~RCB
~RCB()
Destructor.
Definition: Stokhos_Sparse3TensorPartition.hpp:150
Stokhos::RCB::CoordCompare::CoordCompare
CoordCompare(const size_type &d_)
Definition: Stokhos_Sparse3TensorPartition.hpp:61
Teuchos::Array::pop_back
void pop_back()
Stokhos
Top-level namespace for Stokhos classes and functions.
Definition: Stokhos_AbstractPreconditionerFactory.hpp:48
Stokhos::RCB::Box::split
void split()
Definition: Stokhos_Sparse3TensorPartition.hpp:114
j
j
Definition: Sacado_Fad_Exp_MP_Vector.hpp:527
Teuchos::Array::view
ArrayView< T > view(size_type offset, size_type size)
Stokhos::CijkSymmetryType
CijkSymmetryType
Definition: Stokhos_Sparse3TensorPartition.hpp:246
Stokhos::RCB::max_parts
size_type max_parts
Definition: Stokhos_Sparse3TensorPartition.hpp:177
Stokhos::CijkData
Definition: Stokhos_Sparse3TensorPartition.hpp:229
Stokhos::CIJK_SIX_WAY_SYMMETRY
Definition: Stokhos_Sparse3TensorPartition.hpp:249
Stokhos::RCB::size_type
Teuchos::ArrayView< TupleType >::size_type size_type
Definition: Stokhos_Sparse3TensorPartition.hpp:56
Teuchos::ArrayRCP::resize
void resize(const size_type n, const T &val=T())
Stokhos::RCB::Box::xmin
coord_type xmin
Definition: Stokhos_Sparse3TensorPartition.hpp:68
Stokhos::RCB::get_part_IDs
Teuchos::ArrayRCP< id_type > get_part_IDs() const
Definition: Stokhos_Sparse3TensorPartition.hpp:163
cusp::detail::device::x
const IndexType const IndexType const IndexType const IndexType const ValueType const ValueType * x
Definition: csr_vector.h:260
Stokhos::RCB::Box::Box
Box(const Teuchos::ArrayView< TupleType > &c)
Definition: Stokhos_Sparse3TensorPartition.hpp:74
Stokhos::RCB::Box::zmax
coord_type zmax
Definition: Stokhos_Sparse3TensorPartition.hpp:68
Stokhos::CijkData::id_type
ordinal_type id_type
Definition: Stokhos_Sparse3TensorPartition.hpp:231
Stokhos::CijkData::operator()
ordinal_type operator()(ordinal_type d) const
Definition: Stokhos_Sparse3TensorPartition.hpp:236
Stokhos::CijkData::gid
ordinal_type gid
Definition: Stokhos_Sparse3TensorPartition.hpp:232
Stokhos::RCB::Box::delta_y
coord_type delta_y
Definition: Stokhos_Sparse3TensorPartition.hpp:69
Stokhos::RCB::Box::coords
Teuchos::Array< TupleType > coords
Definition: Stokhos_Sparse3TensorPartition.hpp:72
Stokhos::CIJK_TWO_WAY_SYMMETRY
Definition: Stokhos_Sparse3TensorPartition.hpp:248
Stokhos::build_cijk_coordinate_list
Teuchos::ArrayRCP< CijkData< ordinal_type, scalar_type > > build_cijk_coordinate_list(const Sparse3Tensor< ordinal_type, scalar_type > &Cijk, CijkSymmetryType symmetry_type)
Definition: Stokhos_Sparse3TensorPartition.hpp:254
Stokhos::CijkData::j
ordinal_type j
Definition: Stokhos_Sparse3TensorPartition.hpp:233
Stokhos::RCB::RCB
RCB(const coord_type &max_length_, const size_type &max_parts_, const Teuchos::ArrayView< TupleType > &coords_)
Constructor.
Definition: Stokhos_Sparse3TensorPartition.hpp:140
Stokhos::CijkData::c
scalar_type c
Definition: Stokhos_Sparse3TensorPartition.hpp:234
Stokhos::RCB::get_parts
Teuchos::RCP< Teuchos::Array< Teuchos::RCP< Box > > > get_parts() const
Get parts array.
Definition: Stokhos_Sparse3TensorPartition.hpp:159
Stokhos::RCB::Box::split_dim
size_type split_dim
Definition: Stokhos_Sparse3TensorPartition.hpp:70
Stokhos::RCB
Definition: Stokhos_Sparse3TensorPartition.hpp:53
Stokhos::CijkData::i
ordinal_type i
Definition: Stokhos_Sparse3TensorPartition.hpp:233
Stokhos::RCB::Box::delta_x
coord_type delta_x
Definition: Stokhos_Sparse3TensorPartition.hpp:69
Stokhos::Sparse3Tensor::k_begin
k_iterator k_begin() const
Iterator pointing to first k entry.
Definition: Stokhos_Sparse3TensorImp.hpp:287
Stokhos::RCB::Box::computeSplittingDimension
void computeSplittingDimension()
Definition: Stokhos_Sparse3TensorPartition.hpp:105
Stokhos::RCB::Box::ymax
coord_type ymax
Definition: Stokhos_Sparse3TensorPartition.hpp:68
Stokhos::CIJK_NO_SYMMETRY
Definition: Stokhos_Sparse3TensorPartition.hpp:247
n
int n
cusp::detail::device::y
const IndexType const IndexType const IndexType const IndexType const ValueType const ValueType ValueType * y
Definition: csr_vector.h:267
Stokhos::RCB::Box::computeBoundingBox
void computeBoundingBox()
Definition: Stokhos_Sparse3TensorPartition.hpp:80
Stokhos::RCB::Box::delta_z
coord_type delta_z
Definition: Stokhos_Sparse3TensorPartition.hpp:69
Stokhos::RCB::id_type
TupleType::id_type id_type
Definition: Stokhos_Sparse3TensorPartition.hpp:57
Stokhos::RCB::Box
Definition: Stokhos_Sparse3TensorPartition.hpp:67
Stokhos::Sparse3Tensor::i_end
kji_iterator i_end(const kj_iterator &j) const
Iterator pointing to last i entry for given j and k.
Definition: Stokhos_Sparse3TensorImp.hpp:395
Stokhos::Sparse3Tensor::k_end
k_iterator k_end() const
Iterator pointing to last k entry.
Definition: Stokhos_Sparse3TensorImp.hpp:299
Stokhos::RCB::CoordCompare
Definition: Stokhos_Sparse3TensorPartition.hpp:59