Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MPAssembly/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( size_t box[][2] ,
31  const size_t boxA[][2] ,
32  const size_t boxB[][2] )
33 {
34  for ( int 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 size_t 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 size_t global_box[][2] ,
51  const size_t local_box[][2] ,
52  const size_t ghost_layer ,
53  size_t ghost_box[][2] )
54 {
55  for ( int 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 size_t global_size ,
62  const size_t global_rank ,
63  const size_t global_box[][2] ,
64  size_t 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  bool ok() const { return m_ok ; }
90 
91  BoxElemPart( const ElemOrder elem_order ,
92  const Decompose decompose ,
93  const size_t global_size ,
94  const size_t global_rank ,
95  const size_t elem_nx ,
96  const size_t elem_ny ,
97  const size_t elem_nz );
98 
99  KOKKOS_INLINE_FUNCTION
100  size_t global_elem_count() const
102 
103  KOKKOS_INLINE_FUNCTION
104  size_t global_node_count() const
106 
107  KOKKOS_INLINE_FUNCTION
108  size_t uses_elem_count() const
110 
111  KOKKOS_INLINE_FUNCTION
112  size_t owns_node_count() const
114 
115  KOKKOS_INLINE_FUNCTION
116  size_t uses_node_count() const
118 
119  //----------------------------------------
120 
121  KOKKOS_INLINE_FUNCTION
122  size_t uses_elem_offset( const size_t ix ,
123  const size_t iy ,
124  const size_t iz ) const
125  {
126  return size_t( ix - m_uses_elem_box[0][0] ) + size_t( m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ) * (
127  size_t( iy - m_uses_elem_box[1][0] ) + size_t( m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ) * (
128  size_t( iz - m_uses_elem_box[2][0] ) ) );
129  }
130 
131  KOKKOS_INLINE_FUNCTION
132  void uses_elem_coord( size_t lid , size_t c[] ) const
133  {
134  const size_t nx = m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ;
135  const size_t ny = m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ;
136 
137  c[0] = m_uses_elem_box[0][0] + lid % nx ; lid /= nx ;
138  c[1] = m_uses_elem_box[1][0] + lid % ny ; lid /= ny ;
139  c[2] = m_uses_elem_box[2][0] + lid ;
140  }
141 
142  //----------------------------------------
143 
144  KOKKOS_INLINE_FUNCTION
145  size_t global_coord_max( size_t axis ) const
146  { return m_global_node_box[axis][1] - 1 ; }
147 
148  //----------------------------------------
149 
150  KOKKOS_INLINE_FUNCTION
151  void local_node_coord( size_t lid , size_t coord[] ) const
152  {
153  // Local id within an 'owns' block (has sentinal)
154  size_t j = 0 ;
155  while ( m_owns_node[j][1] <= lid ) { lid -= m_owns_node[j][1] ; ++j ; }
156 
157  // Map to global coordinates:
158  const size_t nx = m_owns_node_box[j][0][1] - m_owns_node_box[j][0][0] ;
159  const size_t ny = m_owns_node_box[j][1][1] - m_owns_node_box[j][1][0] ;
160 
161  coord[0] = m_owns_node_box[j][0][0] + lid % nx ; lid /= nx ;
162  coord[1] = m_owns_node_box[j][1][0] + lid % ny ; lid /= ny ;
163  coord[2] = m_owns_node_box[j][2][0] + lid ;
164  }
165 
166  KOKKOS_INLINE_FUNCTION
167  size_t local_node_id( const size_t c[] ) const
168  {
169  // Find which 'owns' block and accumulate the offset of this block:
170  size_t lid = 0 ;
171  size_t j = 0 ;
172  while ( ! ( m_owns_node_box[j][0][0] <= c[0] && c[0] < m_owns_node_box[j][0][1] &&
173  m_owns_node_box[j][1][0] <= c[1] && c[1] < m_owns_node_box[j][1][1] &&
174  m_owns_node_box[j][2][0] <= c[2] && c[2] < m_owns_node_box[j][2][1] ) ) {
175 
176  lid += m_owns_node[j][1] ;
177  ++j ;
178  }
179 
180  // Map offset to the block plus offset within the block:
181  return lid +
182  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] ) * (
183  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] ) * (
184  size_t( c[2] - m_owns_node_box[j][2][0] ) ) );
185  }
186 
187  KOKKOS_INLINE_FUNCTION
188  size_t global_node_id( const size_t c[] ) const
189  {
190  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] ) * (
191  size_t( c[1] - m_global_node_box[1][0] ) + size_t( m_global_node_box[1][1] - m_global_node_box[1][0] ) * (
192  size_t( c[2] - m_global_node_box[2][0] ) ) );
193  }
194 
195  //----------------------------------------
196 
197  KOKKOS_INLINE_FUNCTION
198  size_t recv_node_msg_count() const { return m_owns_node_count - 1 ; }
199 
200  KOKKOS_INLINE_FUNCTION
201  size_t recv_node_rank( size_t msg ) const { return m_owns_node[msg+1][0] ; }
202 
203  KOKKOS_INLINE_FUNCTION
204  size_t recv_node_count( size_t msg ) const { return m_owns_node[msg+1][1] ; }
205 
206  //----------------------------------------
207 
208  KOKKOS_INLINE_FUNCTION
209  size_t send_node_msg_count() const { return m_send_node_count ; }
210 
211  KOKKOS_INLINE_FUNCTION
212  size_t send_node_rank( size_t msg ) const { return m_send_node[msg][0] ; }
213 
214  KOKKOS_INLINE_FUNCTION
215  size_t send_node_count( size_t msg ) const { return m_send_node[msg][1] ; }
216 
217  KOKKOS_INLINE_FUNCTION
218  size_t send_node_id_count() const
219  {
220  size_t count = 0 ;
221  for ( size_t i = 0 ; i < m_send_node_count ; ++i ) {
222  count += m_send_node[i][1] ;
223  }
224  return count ;
225  }
226 
227  KOKKOS_INLINE_FUNCTION
228  size_t send_node_id( size_t item ) const
229  {
230  // Find which send list this send item is in:
231  size_t j = 0 ;
232  while ( m_send_node[j][1] <= item ) { item -= m_send_node[j][1] ; ++j ; }
233 
234  // Map to global coordinate:
235  const size_t nx = m_send_node_box[j][0][1] - m_send_node_box[j][0][0] ;
236  const size_t ny = m_send_node_box[j][1][1] - m_send_node_box[j][1][0] ;
237 
238  size_t c[3] ;
239 
240  c[0] = m_send_node_box[j][0][0] + item % nx ; item /= nx ;
241  c[1] = m_send_node_box[j][1][0] + item % ny ; item /= ny ;
242  c[2] = m_send_node_box[j][2][0] + item ;
243 
244  // Map to local id:
245  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] ) * (
246  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] ) * (
247  size_t( c[2] - m_owns_node_box[0][2][0] ) ) );
248  }
249 
250  //----------------------------------------
251 
252  void print( std::ostream & s ) const ;
253 
254 private:
255 
256  // Maximum number of processes in a neighborhood, including this process
257  enum { PROC_NEIGH_MAX = 64 };
258 
259  void local( const size_t rank ,
260  size_t uses_elem[][2] ,
261  size_t owns_node[][2] ,
262  size_t uses_node[][2] ) const ;
263 
264  size_t m_global_size ;
265  size_t m_global_rank ;
266 
269 
270  size_t m_global_elem_box[3][2] ;
271  size_t m_global_node_box[3][2] ;
272  size_t m_uses_elem_box[3][2] ;
273  size_t m_uses_node_box[3][2] ;
274 
275  // [ processor rank , count ]
276  size_t m_owns_node_box[ PROC_NEIGH_MAX ][3][2] ;
279 
280  size_t m_send_node_box[ PROC_NEIGH_MAX ][3][2] ;
283 
284  bool m_ok ;
285 };
286 
287 } // namespace Example
288 } // namespace Kokkos
289 
290 //----------------------------------------------------------------------------
291 
292 #endif /* #ifndef KOKKOS_BOXELEMPART_HPP */
293 
KOKKOS_INLINE_FUNCTION size_t local_node_id(const size_t c[]) const
unsigned m_send_node_box[PROC_NEIGH_MAX][3][2]
KOKKOS_INLINE_FUNCTION size_t send_node_rank(size_t msg) const
KOKKOS_INLINE_FUNCTION size_t uses_elem_count() const
KOKKOS_INLINE_FUNCTION size_t global_coord_max(size_t axis) const
KOKKOS_INLINE_FUNCTION size_t global_elem_count() const
KOKKOS_INLINE_FUNCTION size_t uses_elem_offset(const size_t ix, const size_t iy, const size_t iz) const
unsigned m_owns_node[PROC_NEIGH_MAX][2]
void print(std::ostream &s) const
KOKKOS_INLINE_FUNCTION size_t send_node_msg_count() 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 global_node_id(const size_t c[]) const
KOKKOS_INLINE_FUNCTION size_t recv_node_rank(size_t msg) 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 size_t recv_node_count(size_t msg) const
KOKKOS_INLINE_FUNCTION void local_node_coord(size_t lid, size_t 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 send_node_id_count() const
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
KOKKOS_INLINE_FUNCTION size_t send_node_count(size_t msg) const
KOKKOS_INLINE_FUNCTION size_t send_node_id(size_t item) const
KOKKOS_INLINE_FUNCTION size_t recv_node_msg_count() const
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
KOKKOS_INLINE_FUNCTION void uses_elem_coord(size_t lid, size_t c[]) const
unsigned m_send_node[PROC_NEIGH_MAX][2]