Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
fenl_assembly/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
53namespace Kokkos {
54namespace Example {
55
56KOKKOS_INLINE_FUNCTION
57void 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
68KOKKOS_INLINE_FUNCTION
69size_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
76KOKKOS_INLINE_FUNCTION
77void 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
88void 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
98namespace Kokkos {
99namespace Example {
100
111public:
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
124 KOKKOS_INLINE_FUNCTION
127
128 KOKKOS_INLINE_FUNCTION
131
132 KOKKOS_INLINE_FUNCTION
135
136 KOKKOS_INLINE_FUNCTION
137 size_t owns_node_count() const
139
140 KOKKOS_INLINE_FUNCTION
143
144 //----------------------------------------
145
146 KOKKOS_INLINE_FUNCTION
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
156 KOKKOS_INLINE_FUNCTION
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
169 KOKKOS_INLINE_FUNCTION
170 unsigned global_coord_max( unsigned axis ) const
171 { return m_global_node_box[axis][1] - 1 ; }
172
173 //----------------------------------------
174
175 KOKKOS_INLINE_FUNCTION
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
191 KOKKOS_INLINE_FUNCTION
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
212 KOKKOS_INLINE_FUNCTION
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
222 KOKKOS_INLINE_FUNCTION
223 unsigned recv_node_msg_count() const { return m_owns_node_count - 1 ; }
224
225 KOKKOS_INLINE_FUNCTION
226 unsigned recv_node_rank( unsigned msg ) const { return m_owns_node[msg+1][0] ; }
227
228 KOKKOS_INLINE_FUNCTION
229 unsigned recv_node_count( unsigned msg ) const { return m_owns_node[msg+1][1] ; }
230
231 //----------------------------------------
232
233 KOKKOS_INLINE_FUNCTION
234 unsigned send_node_msg_count() const { return m_send_node_count ; }
235
236 KOKKOS_INLINE_FUNCTION
237 unsigned send_node_rank( unsigned msg ) const { return m_send_node[msg][0] ; }
238
239 KOKKOS_INLINE_FUNCTION
240 unsigned send_node_count( unsigned msg ) const { return m_send_node[msg][1] ; }
241
242 KOKKOS_INLINE_FUNCTION
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
252 KOKKOS_INLINE_FUNCTION
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
279private:
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] ;
303
304 unsigned m_send_node_box[ PROC_NEIGH_MAX ][3][2] ;
307};
308
309} // namespace Example
310} // namespace Kokkos
311
312//----------------------------------------------------------------------------
313
314#endif /* #ifndef KOKKOS_BOXELEMPART_HPP */
315
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
Partition a box of hexahedral elements among subdomains.
KOKKOS_INLINE_FUNCTION unsigned send_node_id_count() const
KOKKOS_INLINE_FUNCTION unsigned recv_node_msg_count() const
KOKKOS_INLINE_FUNCTION unsigned local_node_id(const unsigned c[]) const
KOKKOS_INLINE_FUNCTION unsigned send_node_id(unsigned item) const
KOKKOS_INLINE_FUNCTION void uses_elem_coord(size_t lid, unsigned c[]) 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_elem_count() const
unsigned m_send_node_box[PROC_NEIGH_MAX][3][2]
KOKKOS_INLINE_FUNCTION void local_node_coord(size_t lid, unsigned coord[]) const
KOKKOS_INLINE_FUNCTION unsigned global_coord_max(unsigned axis) const
KOKKOS_INLINE_FUNCTION unsigned send_node_msg_count() const
unsigned m_owns_node_box[PROC_NEIGH_MAX][3][2]
unsigned m_send_node[PROC_NEIGH_MAX][2]
KOKKOS_INLINE_FUNCTION unsigned recv_node_rank(unsigned msg) const
KOKKOS_INLINE_FUNCTION size_t uses_node_count() const
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
KOKKOS_INLINE_FUNCTION size_t uses_elem_count() const
KOKKOS_INLINE_FUNCTION unsigned send_node_rank(unsigned msg) const
KOKKOS_INLINE_FUNCTION unsigned send_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION unsigned recv_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION size_t uses_elem_offset(const unsigned ix, const unsigned iy, const unsigned iz) const
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_owns_node[PROC_NEIGH_MAX][2]
KOKKOS_INLINE_FUNCTION size_t global_node_id(const unsigned c[]) const
int * count
KOKKOS_INLINE_FUNCTION void box_intersect(unsigned box[][2], const unsigned boxA[][2], const unsigned boxB[][2])
KOKKOS_INLINE_FUNCTION size_t box_count(const unsigned box[][2])
void box_partition(const unsigned global_size, const unsigned global_rank, const unsigned global_box[][2], unsigned box[][2])
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])