Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BoxElemPart.hpp
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos: Manycore Performance-Portable Multidimensional Arrays
6 // Copyright (2012) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_BOXELEMPART_HPP
45 #define KOKKOS_BOXELEMPART_HPP
46 
47 #include <utility>
48 #include <ostream>
49 #include <Kokkos_Macros.hpp>
50 
51 //----------------------------------------------------------------------------
52 
53 namespace Kokkos {
54 namespace Example {
55 
57 void box_intersect( unsigned box[][2] ,
58  const unsigned boxA[][2] ,
59  const unsigned boxB[][2] )
60 {
61  for ( unsigned i = 0 ; i < 3 ; ++i ) {
62  box[i][0] = boxA[i][0] > boxB[i][0] ? boxA[i][0] : boxB[i][0] ;
63  box[i][1] = boxA[i][1] < boxB[i][1] ? boxA[i][1] : boxB[i][1] ;
64  if ( box[i][0] > box[i][1] ) box[i][1] = box[i][0] ;
65  }
66 }
67 
69 size_t box_count( const unsigned box[][2] )
70 {
71  return size_t( box[0][1] - box[0][0] ) *
72  size_t( box[1][1] - box[1][0] ) *
73  size_t( box[2][1] - box[2][0] );
74 }
75 
77 void box_ghost_layer( const unsigned global_box[][2] ,
78  const unsigned local_box[][2] ,
79  const unsigned ghost_layer ,
80  unsigned ghost_box[][2] )
81 {
82  for ( unsigned i = 0 ; i < 3 ; ++i ) {
83  ghost_box[i][0] = global_box[i][0] + ghost_layer > local_box[i][0] ? global_box[i][0] : local_box[i][0] - ghost_layer ;
84  ghost_box[i][1] = global_box[i][1] < local_box[i][1] + ghost_layer ? global_box[i][1] : local_box[i][1] + ghost_layer ;
85  }
86 }
87 
88 void box_partition( const unsigned global_size ,
89  const unsigned global_rank ,
90  const unsigned global_box[][2] ,
91  unsigned box[][2] );
92 
93 } // namespace Example
94 } // namespace Kokkos
95 
96 //----------------------------------------------------------------------------
97 
98 namespace Kokkos {
99 namespace Example {
100 
110 class BoxElemPart {
111 public:
112 
115 
116  BoxElemPart( const ElemOrder elem_order ,
117  const Decompose decompose ,
118  const unsigned global_size ,
119  const unsigned global_rank ,
120  const unsigned elem_nx ,
121  const unsigned elem_ny ,
122  const unsigned elem_nz );
123 
125  size_t global_elem_count() const
127 
129  size_t global_node_count() const
131 
133  size_t uses_elem_count() const
135 
137  size_t owns_node_count() const
139 
141  size_t uses_node_count() const
143 
144  //----------------------------------------
145 
147  size_t uses_elem_offset( const unsigned ix ,
148  const unsigned iy ,
149  const unsigned iz ) const
150  {
151  return size_t( ix - m_uses_elem_box[0][0] ) + size_t( m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ) * (
152  size_t( iy - m_uses_elem_box[1][0] ) + size_t( m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ) * (
153  size_t( iz - m_uses_elem_box[2][0] ) ) );
154  }
155 
157  void uses_elem_coord( size_t lid , unsigned c[] ) const
158  {
159  const unsigned nx = m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ;
160  const unsigned ny = m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ;
161 
162  c[0] = m_uses_elem_box[0][0] + lid % nx ; lid /= nx ;
163  c[1] = m_uses_elem_box[1][0] + lid % ny ; lid /= ny ;
164  c[2] = m_uses_elem_box[2][0] + lid ;
165  }
166 
167  //----------------------------------------
168 
170  unsigned global_coord_max( unsigned axis ) const
171  { return m_global_node_box[axis][1] - 1 ; }
172 
173  //----------------------------------------
174 
176  void local_node_coord( size_t lid , unsigned coord[] ) const
177  {
178  // Local id within an 'owns' block (has sentinal)
179  unsigned j = 0 ;
180  while ( m_owns_node[j][1] <= lid ) { lid -= m_owns_node[j][1] ; ++j ; }
181 
182  // Map to global coordinates:
183  const unsigned nx = m_owns_node_box[j][0][1] - m_owns_node_box[j][0][0] ;
184  const unsigned ny = m_owns_node_box[j][1][1] - m_owns_node_box[j][1][0] ;
185 
186  coord[0] = m_owns_node_box[j][0][0] + lid % nx ; lid /= nx ;
187  coord[1] = m_owns_node_box[j][1][0] + lid % ny ; lid /= ny ;
188  coord[2] = m_owns_node_box[j][2][0] + lid ;
189  }
190 
192  unsigned local_node_id( const unsigned c[] ) const
193  {
194  // Find which 'owns' block and accumulate the offset of this block:
195  size_t lid = 0 ;
196  unsigned j = 0 ;
197  while ( ! ( m_owns_node_box[j][0][0] <= c[0] && c[0] < m_owns_node_box[j][0][1] &&
198  m_owns_node_box[j][1][0] <= c[1] && c[1] < m_owns_node_box[j][1][1] &&
199  m_owns_node_box[j][2][0] <= c[2] && c[2] < m_owns_node_box[j][2][1] ) ) {
200 
201  lid += m_owns_node[j][1] ;
202  ++j ;
203  }
204 
205  // Map offset to the block plus offset within the block:
206  return lid +
207  size_t( c[0] - m_owns_node_box[j][0][0] ) + size_t( m_owns_node_box[j][0][1] - m_owns_node_box[j][0][0] ) * (
208  size_t( c[1] - m_owns_node_box[j][1][0] ) + size_t( m_owns_node_box[j][1][1] - m_owns_node_box[j][1][0] ) * (
209  size_t( c[2] - m_owns_node_box[j][2][0] ) ) );
210  }
211 
213  size_t global_node_id( const unsigned c[] ) const
214  {
215  return size_t( c[0] - m_global_node_box[0][0] ) + size_t( m_global_node_box[0][1] - m_global_node_box[0][0] ) * (
216  size_t( c[1] - m_global_node_box[1][0] ) + size_t( m_global_node_box[1][1] - m_global_node_box[1][0] ) * (
217  size_t( c[2] - m_global_node_box[2][0] ) ) );
218  }
219 
220  //----------------------------------------
221 
223  unsigned recv_node_msg_count() const { return m_owns_node_count - 1 ; }
224 
226  unsigned recv_node_rank( unsigned msg ) const { return m_owns_node[msg+1][0] ; }
227 
229  unsigned recv_node_count( unsigned msg ) const { return m_owns_node[msg+1][1] ; }
230 
231  //----------------------------------------
232 
234  unsigned send_node_msg_count() const { return m_send_node_count ; }
235 
237  unsigned send_node_rank( unsigned msg ) const { return m_send_node[msg][0] ; }
238 
240  unsigned send_node_count( unsigned msg ) const { return m_send_node[msg][1] ; }
241 
243  unsigned send_node_id_count() const
244  {
245  unsigned count = 0 ;
246  for ( unsigned i = 0 ; i < m_send_node_count ; ++i ) {
247  count += m_send_node[i][1] ;
248  }
249  return count ;
250  }
251 
253  unsigned send_node_id( unsigned item ) const
254  {
255  // Find which send list this send item is in:
256  unsigned j = 0 ;
257  while ( m_send_node[j][1] <= item ) { item -= m_send_node[j][1] ; ++j ; }
258 
259  // Map to global coordinate:
260  const unsigned nx = m_send_node_box[j][0][1] - m_send_node_box[j][0][0] ;
261  const unsigned ny = m_send_node_box[j][1][1] - m_send_node_box[j][1][0] ;
262 
263  unsigned c[3] ;
264 
265  c[0] = m_send_node_box[j][0][0] + item % nx ; item /= nx ;
266  c[1] = m_send_node_box[j][1][0] + item % ny ; item /= ny ;
267  c[2] = m_send_node_box[j][2][0] + item ;
268 
269  // Map to local id:
270  return size_t( c[0] - m_owns_node_box[0][0][0] ) + size_t( m_owns_node_box[0][0][1] - m_owns_node_box[0][0][0] ) * (
271  size_t( c[1] - m_owns_node_box[0][1][0] ) + size_t( m_owns_node_box[0][1][1] - m_owns_node_box[0][1][0] ) * (
272  size_t( c[2] - m_owns_node_box[0][2][0] ) ) );
273  }
274 
275  //----------------------------------------
276 
277  void print( std::ostream & s ) const ;
278 
279 private:
280 
281  // Maximum number of processes in a neighborhood, including this process
282  enum { PROC_NEIGH_MAX = 32 };
283 
284  void local( const unsigned rank ,
285  unsigned uses_elem[][2] ,
286  unsigned owns_node[][2] ,
287  unsigned uses_node[][2] ) const ;
288 
289  unsigned m_global_size ;
290  unsigned m_global_rank ;
293 
294  unsigned m_global_elem_box[3][2] ;
295  unsigned m_global_node_box[3][2] ;
296  unsigned m_uses_elem_box[3][2] ;
297  unsigned m_uses_node_box[3][2] ;
298 
299  // [ processor rank , count ]
300  unsigned m_owns_node_box[ PROC_NEIGH_MAX ][3][2] ;
301  unsigned m_owns_node[ PROC_NEIGH_MAX ][2] ;
302  unsigned m_owns_node_count ;
303 
304  unsigned m_send_node_box[ PROC_NEIGH_MAX ][3][2] ;
305  unsigned m_send_node[ PROC_NEIGH_MAX ][2] ;
306  unsigned m_send_node_count ;
307 };
308 
309 } // namespace Example
310 } // namespace Kokkos
311 
312 //----------------------------------------------------------------------------
313 
314 #endif /* #ifndef KOKKOS_BOXELEMPART_HPP */
315 
unsigned m_owns_node[PROC_NEIGH_MAX][2]
KOKKOS_INLINE_FUNCTION void uses_elem_coord(size_t lid, unsigned c[]) const
KOKKOS_INLINE_FUNCTION size_t uses_elem_count() const
KOKKOS_INLINE_FUNCTION unsigned send_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION unsigned local_node_id(const unsigned c[]) const
KOKKOS_INLINE_FUNCTION size_t global_node_id(const unsigned c[]) const
KOKKOS_INLINE_FUNCTION size_t global_elem_count() const
KOKKOS_INLINE_FUNCTION unsigned send_node_id_count() const
void print(std::ostream &s) const
KOKKOS_INLINE_FUNCTION unsigned send_node_id(unsigned item) const
BoxElemPart(const ElemOrder elem_order, const Decompose decompose, const unsigned global_size, const unsigned global_rank, const unsigned elem_nx, const unsigned elem_ny, const unsigned elem_nz)
KOKKOS_INLINE_FUNCTION size_t uses_elem_offset(const unsigned ix, const unsigned iy, const unsigned iz) const
KOKKOS_INLINE_FUNCTION unsigned recv_node_msg_count() const
KOKKOS_INLINE_FUNCTION size_t box_count(const unsigned box[][2])
Definition: BoxElemPart.hpp:69
KOKKOS_INLINE_FUNCTION size_t uses_node_count() const
KOKKOS_INLINE_FUNCTION void box_ghost_layer(const unsigned global_box[][2], const unsigned local_box[][2], const unsigned ghost_layer, unsigned ghost_box[][2])
Definition: BoxElemPart.hpp:77
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION void local_node_coord(size_t lid, unsigned coord[]) const
unsigned m_send_node_box[PROC_NEIGH_MAX][3][2]
void box_partition(const unsigned global_size, const unsigned global_rank, const unsigned global_box[][2], unsigned box[][2])
Definition: BoxElemPart.cpp:56
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
KOKKOS_INLINE_FUNCTION void box_intersect(unsigned box[][2], const unsigned boxA[][2], const unsigned boxB[][2])
Definition: BoxElemPart.hpp:57
unsigned m_send_node[PROC_NEIGH_MAX][2]
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
unsigned m_owns_node_box[PROC_NEIGH_MAX][3][2]
KOKKOS_INLINE_FUNCTION unsigned send_node_msg_count() const
unsigned m_global_elem_box[3][2]
KOKKOS_INLINE_FUNCTION unsigned send_node_rank(unsigned msg) const
unsigned m_global_node_box[3][2]
KOKKOS_INLINE_FUNCTION unsigned recv_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION unsigned global_coord_max(unsigned axis) const
KOKKOS_INLINE_FUNCTION unsigned recv_node_rank(unsigned msg) const
Partition a box of hexahedral elements among subdomains.
void local(const unsigned rank, unsigned uses_elem[][2], unsigned owns_node[][2], unsigned uses_node[][2]) const
KOKKOS_INLINE_FUNCTION size_t global_node_count() const