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 /*
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 
56 KOKKOS_INLINE_FUNCTION
57 void box_intersect( size_t box[][2] ,
58  const size_t boxA[][2] ,
59  const size_t boxB[][2] )
60 {
61  for ( int 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 
68 KOKKOS_INLINE_FUNCTION
69 size_t box_count( const size_t 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 
76 KOKKOS_INLINE_FUNCTION
77 void box_ghost_layer( const size_t global_box[][2] ,
78  const size_t local_box[][2] ,
79  const size_t ghost_layer ,
80  size_t ghost_box[][2] )
81 {
82  for ( int 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 size_t global_size ,
89  const size_t global_rank ,
90  const size_t global_box[][2] ,
91  size_t 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  bool ok() const { return m_ok ; }
117 
118  BoxElemPart( const ElemOrder elem_order ,
119  const Decompose decompose ,
120  const size_t global_size ,
121  const size_t global_rank ,
122  const size_t elem_nx ,
123  const size_t elem_ny ,
124  const size_t elem_nz );
125 
126  KOKKOS_INLINE_FUNCTION
127  size_t global_elem_count() const
129 
130  KOKKOS_INLINE_FUNCTION
131  size_t global_node_count() const
133 
134  KOKKOS_INLINE_FUNCTION
135  size_t uses_elem_count() const
137 
138  KOKKOS_INLINE_FUNCTION
139  size_t owns_node_count() const
141 
142  KOKKOS_INLINE_FUNCTION
143  size_t uses_node_count() const
145 
146  //----------------------------------------
147 
148  KOKKOS_INLINE_FUNCTION
149  size_t uses_elem_offset( const size_t ix ,
150  const size_t iy ,
151  const size_t iz ) const
152  {
153  return size_t( ix - m_uses_elem_box[0][0] ) + size_t( m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ) * (
154  size_t( iy - m_uses_elem_box[1][0] ) + size_t( m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ) * (
155  size_t( iz - m_uses_elem_box[2][0] ) ) );
156  }
157 
158  KOKKOS_INLINE_FUNCTION
159  void uses_elem_coord( size_t lid , size_t c[] ) const
160  {
161  const size_t nx = m_uses_elem_box[0][1] - m_uses_elem_box[0][0] ;
162  const size_t ny = m_uses_elem_box[1][1] - m_uses_elem_box[1][0] ;
163 
164  c[0] = m_uses_elem_box[0][0] + lid % nx ; lid /= nx ;
165  c[1] = m_uses_elem_box[1][0] + lid % ny ; lid /= ny ;
166  c[2] = m_uses_elem_box[2][0] + lid ;
167  }
168 
169  //----------------------------------------
170 
171  KOKKOS_INLINE_FUNCTION
172  size_t global_coord_max( size_t axis ) const
173  { return m_global_node_box[axis][1] - 1 ; }
174 
175  //----------------------------------------
176 
177  KOKKOS_INLINE_FUNCTION
178  void local_node_coord( size_t lid , size_t coord[] ) const
179  {
180  // Local id within an 'owns' block (has sentinal)
181  size_t j = 0 ;
182  while ( m_owns_node[j][1] <= lid ) { lid -= m_owns_node[j][1] ; ++j ; }
183 
184  // Map to global coordinates:
185  const size_t nx = m_owns_node_box[j][0][1] - m_owns_node_box[j][0][0] ;
186  const size_t ny = m_owns_node_box[j][1][1] - m_owns_node_box[j][1][0] ;
187 
188  coord[0] = m_owns_node_box[j][0][0] + lid % nx ; lid /= nx ;
189  coord[1] = m_owns_node_box[j][1][0] + lid % ny ; lid /= ny ;
190  coord[2] = m_owns_node_box[j][2][0] + lid ;
191  }
192 
193  KOKKOS_INLINE_FUNCTION
194  size_t local_node_id( const size_t c[] ) const
195  {
196  // Find which 'owns' block and accumulate the offset of this block:
197  size_t lid = 0 ;
198  size_t j = 0 ;
199  while ( ! ( m_owns_node_box[j][0][0] <= c[0] && c[0] < m_owns_node_box[j][0][1] &&
200  m_owns_node_box[j][1][0] <= c[1] && c[1] < m_owns_node_box[j][1][1] &&
201  m_owns_node_box[j][2][0] <= c[2] && c[2] < m_owns_node_box[j][2][1] ) ) {
202 
203  lid += m_owns_node[j][1] ;
204  ++j ;
205  }
206 
207  // Map offset to the block plus offset within the block:
208  return lid +
209  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] ) * (
210  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] ) * (
211  size_t( c[2] - m_owns_node_box[j][2][0] ) ) );
212  }
213 
214  KOKKOS_INLINE_FUNCTION
215  size_t global_node_id( const size_t c[] ) const
216  {
217  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] ) * (
218  size_t( c[1] - m_global_node_box[1][0] ) + size_t( m_global_node_box[1][1] - m_global_node_box[1][0] ) * (
219  size_t( c[2] - m_global_node_box[2][0] ) ) );
220  }
221 
222  //----------------------------------------
223 
224  KOKKOS_INLINE_FUNCTION
225  size_t recv_node_msg_count() const { return m_owns_node_count - 1 ; }
226 
227  KOKKOS_INLINE_FUNCTION
228  size_t recv_node_rank( size_t msg ) const { return m_owns_node[msg+1][0] ; }
229 
230  KOKKOS_INLINE_FUNCTION
231  size_t recv_node_count( size_t msg ) const { return m_owns_node[msg+1][1] ; }
232 
233  //----------------------------------------
234 
235  KOKKOS_INLINE_FUNCTION
236  size_t send_node_msg_count() const { return m_send_node_count ; }
237 
238  KOKKOS_INLINE_FUNCTION
239  size_t send_node_rank( size_t msg ) const { return m_send_node[msg][0] ; }
240 
241  KOKKOS_INLINE_FUNCTION
242  size_t send_node_count( size_t msg ) const { return m_send_node[msg][1] ; }
243 
244  KOKKOS_INLINE_FUNCTION
245  size_t send_node_id_count() const
246  {
247  size_t count = 0 ;
248  for ( size_t i = 0 ; i < m_send_node_count ; ++i ) {
249  count += m_send_node[i][1] ;
250  }
251  return count ;
252  }
253 
254  KOKKOS_INLINE_FUNCTION
255  size_t send_node_id( size_t item ) const
256  {
257  // Find which send list this send item is in:
258  size_t j = 0 ;
259  while ( m_send_node[j][1] <= item ) { item -= m_send_node[j][1] ; ++j ; }
260 
261  // Map to global coordinate:
262  const size_t nx = m_send_node_box[j][0][1] - m_send_node_box[j][0][0] ;
263  const size_t ny = m_send_node_box[j][1][1] - m_send_node_box[j][1][0] ;
264 
265  size_t c[3] ;
266 
267  c[0] = m_send_node_box[j][0][0] + item % nx ; item /= nx ;
268  c[1] = m_send_node_box[j][1][0] + item % ny ; item /= ny ;
269  c[2] = m_send_node_box[j][2][0] + item ;
270 
271  // Map to local id:
272  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] ) * (
273  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] ) * (
274  size_t( c[2] - m_owns_node_box[0][2][0] ) ) );
275  }
276 
277  //----------------------------------------
278 
279  void print( std::ostream & s ) const ;
280 
281 private:
282 
283  // Maximum number of processes in a neighborhood, including this process
284  enum { PROC_NEIGH_MAX = 64 };
285 
286  void local( const size_t rank ,
287  size_t uses_elem[][2] ,
288  size_t owns_node[][2] ,
289  size_t uses_node[][2] ) const ;
290 
291  size_t m_global_size ;
292  size_t m_global_rank ;
293 
296 
297  size_t m_global_elem_box[3][2] ;
298  size_t m_global_node_box[3][2] ;
299  size_t m_uses_elem_box[3][2] ;
300  size_t m_uses_node_box[3][2] ;
301 
302  // [ processor rank , count ]
303  size_t m_owns_node_box[ PROC_NEIGH_MAX ][3][2] ;
306 
307  size_t m_send_node_box[ PROC_NEIGH_MAX ][3][2] ;
310 
311  bool m_ok ;
312 };
313 
314 } // namespace Example
315 } // namespace Kokkos
316 
317 //----------------------------------------------------------------------------
318 
319 #endif /* #ifndef KOKKOS_BOXELEMPART_HPP */
320 
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]