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 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_BOXELEMPART_HPP
18 #define KOKKOS_BOXELEMPART_HPP
19 
20 #include <utility>
21 #include <ostream>
22 #include <Kokkos_Macros.hpp>
23 
24 //----------------------------------------------------------------------------
25 
26 namespace Kokkos {
27 namespace Example {
28 
29 KOKKOS_INLINE_FUNCTION
30 void box_intersect( unsigned box[][2] ,
31  const unsigned boxA[][2] ,
32  const unsigned boxB[][2] )
33 {
34  for ( unsigned i = 0 ; i < 3 ; ++i ) {
35  box[i][0] = boxA[i][0] > boxB[i][0] ? boxA[i][0] : boxB[i][0] ;
36  box[i][1] = boxA[i][1] < boxB[i][1] ? boxA[i][1] : boxB[i][1] ;
37  if ( box[i][0] > box[i][1] ) box[i][1] = box[i][0] ;
38  }
39 }
40 
41 KOKKOS_INLINE_FUNCTION
42 size_t box_count( const unsigned box[][2] )
43 {
44  return size_t( box[0][1] - box[0][0] ) *
45  size_t( box[1][1] - box[1][0] ) *
46  size_t( box[2][1] - box[2][0] );
47 }
48 
49 KOKKOS_INLINE_FUNCTION
50 void box_ghost_layer( const unsigned global_box[][2] ,
51  const unsigned local_box[][2] ,
52  const unsigned ghost_layer ,
53  unsigned ghost_box[][2] )
54 {
55  for ( unsigned i = 0 ; i < 3 ; ++i ) {
56  ghost_box[i][0] = global_box[i][0] + ghost_layer > local_box[i][0] ? global_box[i][0] : local_box[i][0] - ghost_layer ;
57  ghost_box[i][1] = global_box[i][1] < local_box[i][1] + ghost_layer ? global_box[i][1] : local_box[i][1] + ghost_layer ;
58  }
59 }
60 
61 void box_partition( const unsigned global_size ,
62  const unsigned global_rank ,
63  const unsigned global_box[][2] ,
64  unsigned box[][2] );
65 
66 } // namespace Example
67 } // namespace Kokkos
68 
69 //----------------------------------------------------------------------------
70 
71 namespace Kokkos {
72 namespace Example {
73 
83 class BoxElemPart {
84 public:
85 
88 
89  BoxElemPart( const ElemOrder elem_order ,
90  const Decompose decompose ,
91  const unsigned global_size ,
92  const unsigned global_rank ,
93  const unsigned elem_nx ,
94  const unsigned elem_ny ,
95  const unsigned elem_nz );
96 
97  KOKKOS_INLINE_FUNCTION
98  size_t global_elem_count() const
100 
101  KOKKOS_INLINE_FUNCTION
102  size_t global_node_count() const
104 
105  KOKKOS_INLINE_FUNCTION
106  size_t uses_elem_count() const
108 
109  KOKKOS_INLINE_FUNCTION
110  size_t owns_node_count() const
112 
113  KOKKOS_INLINE_FUNCTION
114  size_t uses_node_count() const
116 
117  //----------------------------------------
118 
119  KOKKOS_INLINE_FUNCTION
120  size_t uses_elem_offset( const unsigned ix ,
121  const unsigned iy ,
122  const unsigned iz ) const
123  {
124  return size_t( ix - m_uses_elem_box[0][0] ) + size_t( m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ) * (
125  size_t( iy - m_uses_elem_box[1][0] ) + size_t( m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ) * (
126  size_t( iz - m_uses_elem_box[2][0] ) ) );
127  }
128 
129  KOKKOS_INLINE_FUNCTION
130  void uses_elem_coord( size_t lid , unsigned c[] ) const
131  {
132  const unsigned nx = m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ;
133  const unsigned ny = m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ;
134 
135  c[0] = m_uses_elem_box[0][0] + lid % nx ; lid /= nx ;
136  c[1] = m_uses_elem_box[1][0] + lid % ny ; lid /= ny ;
137  c[2] = m_uses_elem_box[2][0] + lid ;
138  }
139 
140  //----------------------------------------
141 
142  KOKKOS_INLINE_FUNCTION
143  unsigned global_coord_max( unsigned axis ) const
144  { return m_global_node_box[axis][1] - 1 ; }
145 
146  //----------------------------------------
147 
148  KOKKOS_INLINE_FUNCTION
149  void local_node_coord( size_t lid , unsigned coord[] ) const
150  {
151  // Local id within an 'owns' block (has sentinal)
152  unsigned j = 0 ;
153  while ( m_owns_node[j][1] <= lid ) { lid -= m_owns_node[j][1] ; ++j ; }
154 
155  // Map to global coordinates:
156  const unsigned nx = m_owns_node_box[j][0][1] - m_owns_node_box[j][0][0] ;
157  const unsigned ny = m_owns_node_box[j][1][1] - m_owns_node_box[j][1][0] ;
158 
159  coord[0] = m_owns_node_box[j][0][0] + lid % nx ; lid /= nx ;
160  coord[1] = m_owns_node_box[j][1][0] + lid % ny ; lid /= ny ;
161  coord[2] = m_owns_node_box[j][2][0] + lid ;
162  }
163 
164  KOKKOS_INLINE_FUNCTION
165  unsigned local_node_id( const unsigned c[] ) const
166  {
167  // Find which 'owns' block and accumulate the offset of this block:
168  size_t lid = 0 ;
169  unsigned j = 0 ;
170  while ( ! ( m_owns_node_box[j][0][0] <= c[0] && c[0] < m_owns_node_box[j][0][1] &&
171  m_owns_node_box[j][1][0] <= c[1] && c[1] < m_owns_node_box[j][1][1] &&
172  m_owns_node_box[j][2][0] <= c[2] && c[2] < m_owns_node_box[j][2][1] ) ) {
173 
174  lid += m_owns_node[j][1] ;
175  ++j ;
176  }
177 
178  // Map offset to the block plus offset within the block:
179  return lid +
180  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] ) * (
181  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] ) * (
182  size_t( c[2] - m_owns_node_box[j][2][0] ) ) );
183  }
184 
185  KOKKOS_INLINE_FUNCTION
186  size_t global_node_id( const unsigned c[] ) const
187  {
188  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] ) * (
189  size_t( c[1] - m_global_node_box[1][0] ) + size_t( m_global_node_box[1][1] - m_global_node_box[1][0] ) * (
190  size_t( c[2] - m_global_node_box[2][0] ) ) );
191  }
192 
193  //----------------------------------------
194 
195  KOKKOS_INLINE_FUNCTION
196  unsigned recv_node_msg_count() const { return m_owns_node_count - 1 ; }
197 
198  KOKKOS_INLINE_FUNCTION
199  unsigned recv_node_rank( unsigned msg ) const { return m_owns_node[msg+1][0] ; }
200 
201  KOKKOS_INLINE_FUNCTION
202  unsigned recv_node_count( unsigned msg ) const { return m_owns_node[msg+1][1] ; }
203 
204  //----------------------------------------
205 
206  KOKKOS_INLINE_FUNCTION
207  unsigned send_node_msg_count() const { return m_send_node_count ; }
208 
209  KOKKOS_INLINE_FUNCTION
210  unsigned send_node_rank( unsigned msg ) const { return m_send_node[msg][0] ; }
211 
212  KOKKOS_INLINE_FUNCTION
213  unsigned send_node_count( unsigned msg ) const { return m_send_node[msg][1] ; }
214 
215  KOKKOS_INLINE_FUNCTION
216  unsigned send_node_id_count() const
217  {
218  unsigned count = 0 ;
219  for ( unsigned i = 0 ; i < m_send_node_count ; ++i ) {
220  count += m_send_node[i][1] ;
221  }
222  return count ;
223  }
224 
225  KOKKOS_INLINE_FUNCTION
226  unsigned send_node_id( unsigned item ) const
227  {
228  // Find which send list this send item is in:
229  unsigned j = 0 ;
230  while ( m_send_node[j][1] <= item ) { item -= m_send_node[j][1] ; ++j ; }
231 
232  // Map to global coordinate:
233  const unsigned nx = m_send_node_box[j][0][1] - m_send_node_box[j][0][0] ;
234  const unsigned ny = m_send_node_box[j][1][1] - m_send_node_box[j][1][0] ;
235 
236  unsigned c[3] ;
237 
238  c[0] = m_send_node_box[j][0][0] + item % nx ; item /= nx ;
239  c[1] = m_send_node_box[j][1][0] + item % ny ; item /= ny ;
240  c[2] = m_send_node_box[j][2][0] + item ;
241 
242  // Map to local id:
243  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] ) * (
244  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] ) * (
245  size_t( c[2] - m_owns_node_box[0][2][0] ) ) );
246  }
247 
248  //----------------------------------------
249 
250  void print( std::ostream & s ) const ;
251 
252 private:
253 
254  // Maximum number of processes in a neighborhood, including this process
255  enum { PROC_NEIGH_MAX = 32 };
256 
257  void local( const unsigned rank ,
258  unsigned uses_elem[][2] ,
259  unsigned owns_node[][2] ,
260  unsigned uses_node[][2] ) const ;
261 
262  unsigned m_global_size ;
263  unsigned m_global_rank ;
266 
267  unsigned m_global_elem_box[3][2] ;
268  unsigned m_global_node_box[3][2] ;
269  unsigned m_uses_elem_box[3][2] ;
270  unsigned m_uses_node_box[3][2] ;
271 
272  // [ processor rank , count ]
273  unsigned m_owns_node_box[ PROC_NEIGH_MAX ][3][2] ;
274  unsigned m_owns_node[ PROC_NEIGH_MAX ][2] ;
275  unsigned m_owns_node_count ;
276 
277  unsigned m_send_node_box[ PROC_NEIGH_MAX ][3][2] ;
278  unsigned m_send_node[ PROC_NEIGH_MAX ][2] ;
279  unsigned m_send_node_count ;
280 };
281 
282 } // namespace Example
283 } // namespace Kokkos
284 
285 //----------------------------------------------------------------------------
286 
287 #endif /* #ifndef KOKKOS_BOXELEMPART_HPP */
288 
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
int * count
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
Definition: BoxElemPart.hpp:98
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:42
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:50
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:29
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:30
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.
Definition: BoxElemPart.hpp:83
void local(const unsigned rank, unsigned uses_elem[][2], unsigned owns_node[][2], unsigned uses_node[][2]) const
Definition: BoxElemPart.cpp:89
KOKKOS_INLINE_FUNCTION size_t global_node_count() const