Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FadMPAssembly/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_send_node_box[PROC_NEIGH_MAX][3][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
unsigned m_owns_node[PROC_NEIGH_MAX][2]
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])
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])
KOKKOS_INLINE_FUNCTION void local_node_coord(size_t lid, unsigned coord[]) const
void box_partition(const unsigned global_size, const unsigned global_rank, const unsigned global_box[][2], unsigned box[][2])
KOKKOS_INLINE_FUNCTION void box_intersect(unsigned box[][2], const unsigned boxA[][2], const unsigned boxB[][2])
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
KOKKOS_INLINE_FUNCTION unsigned send_node_msg_count() const
KOKKOS_INLINE_FUNCTION unsigned send_node_rank(unsigned msg) const
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.
unsigned m_owns_node_box[PROC_NEIGH_MAX][3][2]
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
unsigned m_send_node[PROC_NEIGH_MAX][2]