Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_Grid_IndexSpace.hpp
Go to the documentation of this file.
1/****************************************************************************
2 * Copyright (c) 2018-2023 by the Cabana authors *
3 * All rights reserved. *
4 * *
5 * This file is part of the Cabana library. Cabana is distributed under a *
6 * BSD 3-clause license. For the licensing terms see the LICENSE file in *
7 * the top-level directory. *
8 * *
9 * SPDX-License-Identifier: BSD-3-Clause *
10 ****************************************************************************/
11
16#ifndef CABANA_GRID_INDEXSPACE_HPP
17#define CABANA_GRID_INDEXSPACE_HPP
18
19#include <Cabana_Utils.hpp> // FIXME: remove after next release.
20
21#include <Kokkos_Core.hpp>
22
23#include <algorithm>
24#include <array>
25#include <string>
26
27namespace Cabana
28{
29namespace Grid
30{
31//---------------------------------------------------------------------------//
35template <long N>
37{
38 public:
40 static constexpr long Rank = N;
41
44 {
45 std::fill( _min.data(), _min.data() + Rank, -1 );
46 std::fill( _max.data(), _max.data() + Rank, -1 );
47 }
48
52 template <typename Scalar>
53 IndexSpace( const std::initializer_list<Scalar>& size )
54 {
55 std::fill( _min.data(), _min.data() + Rank, 0 );
56 std::copy( size.begin(), size.end(), _max.data() );
57 }
58
62 template <typename Scalar>
63 IndexSpace( const std::initializer_list<Scalar>& min,
64 const std::initializer_list<Scalar>& max )
65 {
66 std::copy( min.begin(), min.end(), _min.data() );
67 std::copy( max.begin(), max.end(), _max.data() );
68 }
69
73 IndexSpace( const std::array<long, N>& size )
74 {
75 std::fill( _min.data(), _min.data() + Rank, 0 );
76 std::copy( size.begin(), size.end(), _max.data() );
77 }
78
82 IndexSpace( const std::array<long, N>& min, const std::array<long, N>& max )
83 {
84 std::copy( min.begin(), min.end(), _min.data() );
85 std::copy( max.begin(), max.end(), _max.data() );
86 }
87
89 KOKKOS_INLINE_FUNCTION
90 bool operator==( const IndexSpace<N>& rhs ) const
91 {
92 for ( long i = 0; i < N; ++i )
93 {
94 if ( min( i ) != rhs.min( i ) || max( i ) != rhs.max( i ) )
95 return false;
96 }
97 return true;
98 }
99
101 KOKKOS_INLINE_FUNCTION
102 bool operator!=( const IndexSpace<N>& rhs ) const
103 {
104 return !( operator==( rhs ) );
105 }
106
108 KOKKOS_INLINE_FUNCTION
109 long min( const long dim ) const { return _min[dim]; }
110
112 KOKKOS_INLINE_FUNCTION
113 Kokkos::Array<long, Rank> min() const { return _min; }
114
116 KOKKOS_INLINE_FUNCTION
117 long max( const long dim ) const { return _max[dim]; }
118
120 KOKKOS_INLINE_FUNCTION
121 Kokkos::Array<long, Rank> max() const { return _max; }
122
124 KOKKOS_INLINE_FUNCTION
125 Kokkos::pair<long, long> range( const long dim ) const
126 {
127 return Kokkos::tie( _min[dim], _max[dim] );
128 }
129
131 KOKKOS_INLINE_FUNCTION
132 long rank() const { return Rank; }
133
135 KOKKOS_INLINE_FUNCTION
136 long extent( const long dim ) const { return _max[dim] - _min[dim]; }
137
139 KOKKOS_INLINE_FUNCTION
140 long size() const
141 {
142 long size = 1;
143 for ( long d = 0; d < Rank; ++d )
144 size *= extent( d );
145 return size;
146 }
147
149 KOKKOS_INLINE_FUNCTION
150 bool inRange( const long index[N] ) const
151 {
152 bool result = true;
153 for ( long i = 0; i < N; ++i )
154 result =
155 result && ( _min[i] <= index[i] ) && ( index[i] < _max[i] );
156 return result;
157 }
158
159 protected:
161 Kokkos::Array<long, Rank> _min;
162
164 Kokkos::Array<long, Rank> _max;
165};
166
167//---------------------------------------------------------------------------//
173template <class ExecutionSpace>
174Kokkos::RangePolicy<ExecutionSpace>
176 const ExecutionSpace& exec_space )
177{
178 return Kokkos::RangePolicy<ExecutionSpace>(
179 exec_space, index_space.min( 0 ), index_space.max( 0 ) );
180}
181
182//---------------------------------------------------------------------------//
189template <class ExecutionSpace, class WorkTag>
190Kokkos::RangePolicy<ExecutionSpace, WorkTag>
192 const ExecutionSpace& exec_space, const WorkTag& )
193{
194 return Kokkos::RangePolicy<ExecutionSpace, WorkTag>(
195 exec_space, index_space.min( 0 ), index_space.max( 0 ) );
196}
197
198//---------------------------------------------------------------------------//
203template <class IndexSpace_t, class ExecutionSpace>
204Kokkos::MDRangePolicy<ExecutionSpace, Kokkos::Rank<IndexSpace_t::Rank>>
205createExecutionPolicy( const IndexSpace_t& index_space,
206 const ExecutionSpace& exec_space )
207{
208 return Kokkos::MDRangePolicy<ExecutionSpace,
209 Kokkos::Rank<IndexSpace_t::Rank>>(
210 exec_space, index_space.min(), index_space.max() );
211}
212
213//---------------------------------------------------------------------------//
219template <class IndexSpace_t, class ExecutionSpace, class WorkTag>
220Kokkos::MDRangePolicy<ExecutionSpace, WorkTag, Kokkos::Rank<IndexSpace_t::Rank>>
221createExecutionPolicy( const IndexSpace_t& index_space,
222 const ExecutionSpace& exec_space, const WorkTag& )
223{
224 return Kokkos::MDRangePolicy<ExecutionSpace, WorkTag,
225 Kokkos::Rank<IndexSpace_t::Rank>>(
226 exec_space, index_space.min(), index_space.max() );
227}
228
229//---------------------------------------------------------------------------//
236template <class Scalar, class... Params>
237Kokkos::View<Scalar*, Params...> createView( const std::string& label,
238 const IndexSpace<1>& index_space )
239{
240 return Kokkos::View<Scalar*, Params...>(
241 Kokkos::ViewAllocateWithoutInitializing( label ),
242 index_space.extent( 0 ) );
243}
244
245//---------------------------------------------------------------------------//
253template <class Scalar, class... Params>
254Kokkos::View<Scalar*, Params..., Kokkos::MemoryUnmanaged>
255createView( const IndexSpace<1>& index_space, Scalar* data )
256{
257 return Kokkos::View<Scalar*, Params..., Kokkos::MemoryUnmanaged>(
258 data, index_space.extent( 0 ) );
259}
260
261//---------------------------------------------------------------------------//
269template <class Scalar, class... Params>
270Kokkos::View<Scalar**, Params...> createView( const std::string& label,
271 const IndexSpace<2>& index_space )
272{
273 return Kokkos::View<Scalar**, Params...>(
274 Kokkos::ViewAllocateWithoutInitializing( label ),
275 index_space.extent( 0 ), index_space.extent( 1 ) );
276}
277
278//---------------------------------------------------------------------------//
286template <class Scalar, class... Params>
287Kokkos::View<Scalar**, Params..., Kokkos::MemoryUnmanaged>
288createView( const IndexSpace<2>& index_space, Scalar* data )
289{
290 return Kokkos::View<Scalar**, Params..., Kokkos::MemoryUnmanaged>(
291 data, index_space.extent( 0 ), index_space.extent( 1 ) );
292}
293
294//---------------------------------------------------------------------------//
302template <class Scalar, class... Params>
303Kokkos::View<Scalar***, Params...>
304createView( const std::string& label, const IndexSpace<3>& index_space )
305{
306 return Kokkos::View<Scalar***, Params...>(
307 Kokkos::ViewAllocateWithoutInitializing( label ),
308 index_space.extent( 0 ), index_space.extent( 1 ),
309 index_space.extent( 2 ) );
310}
311
312//---------------------------------------------------------------------------//
320template <class Scalar, class... Params>
321Kokkos::View<Scalar***, Params..., Kokkos::MemoryUnmanaged>
322createView( const IndexSpace<3>& index_space, Scalar* data )
323{
324 return Kokkos::View<Scalar***, Params..., Kokkos::MemoryUnmanaged>(
325 data, index_space.extent( 0 ), index_space.extent( 1 ),
326 index_space.extent( 2 ) );
327}
328
329//---------------------------------------------------------------------------//
336template <class Scalar, class... Params>
337Kokkos::View<Scalar****, Params...>
338createView( const std::string& label, const IndexSpace<4>& index_space )
339{
340 return Kokkos::View<Scalar****, Params...>(
341 Kokkos::ViewAllocateWithoutInitializing( label ),
342 index_space.extent( 0 ), index_space.extent( 1 ),
343 index_space.extent( 2 ), index_space.extent( 3 ) );
344}
345
346//---------------------------------------------------------------------------//
354template <class Scalar, class... Params>
355Kokkos::View<Scalar****, Params..., Kokkos::MemoryUnmanaged>
356createView( const IndexSpace<4>& index_space, Scalar* data )
357{
358 return Kokkos::View<Scalar****, Params..., Kokkos::MemoryUnmanaged>(
359 data, index_space.extent( 0 ), index_space.extent( 1 ),
360 index_space.extent( 2 ), index_space.extent( 3 ) );
361}
362
363//---------------------------------------------------------------------------//
370template <class ViewType>
371KOKKOS_INLINE_FUNCTION auto createSubview( const ViewType& view,
372 const IndexSpace<1>& index_space )
373 -> decltype( Kokkos::subview( view, index_space.range( 0 ) ) )
374{
375 static_assert( 1 == ViewType::rank, "Incorrect view rank" );
376 return Kokkos::subview( view, index_space.range( 0 ) );
377}
378
379//---------------------------------------------------------------------------//
386template <class ViewType>
387KOKKOS_INLINE_FUNCTION auto createSubview( const ViewType& view,
388 const IndexSpace<2>& index_space )
389 -> decltype( Kokkos::subview( view, index_space.range( 0 ),
390 index_space.range( 1 ) ) )
391{
392 static_assert( 2 == ViewType::rank, "Incorrect view rank" );
393 return Kokkos::subview( view, index_space.range( 0 ),
394 index_space.range( 1 ) );
395}
396
397//---------------------------------------------------------------------------//
404template <class ViewType>
405KOKKOS_INLINE_FUNCTION auto createSubview( const ViewType& view,
406 const IndexSpace<3>& index_space )
407 -> decltype( Kokkos::subview( view, index_space.range( 0 ),
408 index_space.range( 1 ),
409 index_space.range( 2 ) ) )
410{
411 static_assert( 3 == ViewType::rank, "Incorrect view rank" );
412 return Kokkos::subview( view, index_space.range( 0 ),
413 index_space.range( 1 ), index_space.range( 2 ) );
414}
415
416//---------------------------------------------------------------------------//
423template <class ViewType>
424KOKKOS_INLINE_FUNCTION auto createSubview( const ViewType& view,
425 const IndexSpace<4>& index_space )
426 -> decltype( Kokkos::subview( view, index_space.range( 0 ),
427 index_space.range( 1 ),
428 index_space.range( 2 ),
429 index_space.range( 3 ) ) )
430{
431 static_assert( 4 == ViewType::rank, "Incorrect view rank" );
432 return Kokkos::subview( view, index_space.range( 0 ),
433 index_space.range( 1 ), index_space.range( 2 ),
434 index_space.range( 3 ) );
435}
436
437//---------------------------------------------------------------------------//
443template <long N>
445 const long size )
446{
447 std::array<long, N + 1> min;
448 for ( int d = 0; d < N; ++d )
449 min[d] = index_space.min( d );
450 min[N] = 0;
451
452 std::array<long, N + 1> max;
453 for ( int d = 0; d < N; ++d )
454 max[d] = index_space.max( d );
455 max[N] = size;
456
457 return IndexSpace<N + 1>( min, max );
458}
459
460//---------------------------------------------------------------------------//
466template <long N>
468 const long min, const long max )
469{
470 std::array<long, N + 1> range_min;
471 for ( int d = 0; d < N; ++d )
472 range_min[d] = index_space.min( d );
473 range_min[N] = min;
474
475 std::array<long, N + 1> range_max;
476 for ( int d = 0; d < N; ++d )
477 range_max[d] = index_space.max( d );
478 range_max[N] = max;
479
480 return IndexSpace<N + 1>( range_min, range_max );
481}
482
483//---------------------------------------------------------------------------//
484
485} // namespace Grid
486} // namespace Cabana
487
488#endif // end CABANA_GRID_INDEXSPACE_HPP
KOKKOS_INLINE_FUNCTION auto createSubview(const ViewType &view, const IndexSpace< 1 > &index_space) -> decltype(Kokkos::subview(view, index_space.range(0)))
Given a view create a subview over the given index space.
Definition Cabana_Grid_IndexSpace.hpp:371
Kokkos::View< Scalar *, Params... > createView(const std::string &label, const IndexSpace< 1 > &index_space)
Given an index space create a view over the extent of that index space.
Definition Cabana_Grid_IndexSpace.hpp:237
Kokkos::RangePolicy< ExecutionSpace > createExecutionPolicy(const IndexSpace< 1 > &index_space, const ExecutionSpace &exec_space)
Create a multi-dimensional execution policy over an index space.
Definition Cabana_Grid_IndexSpace.hpp:175
IndexSpace< N+1 > appendDimension(const IndexSpace< N > &index_space, const long size)
Given an N-dimensional index space append an additional dimension with the given size.
Definition Cabana_Grid_IndexSpace.hpp:444
Cabana utilities.
Structured index space.
Definition Cabana_Grid_IndexSpace.hpp:37
KOKKOS_INLINE_FUNCTION bool inRange(const long index[N]) const
Determine if a set of indices is within the range of the index space.
Definition Cabana_Grid_IndexSpace.hpp:150
KOKKOS_INLINE_FUNCTION Kokkos::Array< long, Rank > max() const
Get the maximum indices in all dimensions.
Definition Cabana_Grid_IndexSpace.hpp:121
KOKKOS_INLINE_FUNCTION Kokkos::Array< long, Rank > min() const
Get the minimum indices in all dimensions.
Definition Cabana_Grid_IndexSpace.hpp:113
Kokkos::Array< long, Rank > _max
Maximum index bounds.
Definition Cabana_Grid_IndexSpace.hpp:164
IndexSpace(const std::array< long, N > &min, const std::array< long, N > &max)
Vector range constructor.
Definition Cabana_Grid_IndexSpace.hpp:82
KOKKOS_INLINE_FUNCTION long max(const long dim) const
Get the maximum index in a given dimension.
Definition Cabana_Grid_IndexSpace.hpp:117
KOKKOS_INLINE_FUNCTION long min(const long dim) const
Get the minimum index in a given dimension.
Definition Cabana_Grid_IndexSpace.hpp:109
KOKKOS_INLINE_FUNCTION bool operator==(const IndexSpace< N > &rhs) const
Comparison operator.
Definition Cabana_Grid_IndexSpace.hpp:90
static constexpr long Rank
Number of dimensions.
Definition Cabana_Grid_IndexSpace.hpp:40
KOKKOS_INLINE_FUNCTION Kokkos::pair< long, long > range(const long dim) const
Get the range of a given dimension.
Definition Cabana_Grid_IndexSpace.hpp:125
Kokkos::Array< long, Rank > _min
Minimum index bounds.
Definition Cabana_Grid_IndexSpace.hpp:161
KOKKOS_INLINE_FUNCTION bool operator!=(const IndexSpace< N > &rhs) const
Comparison operator.
Definition Cabana_Grid_IndexSpace.hpp:102
KOKKOS_INLINE_FUNCTION long size() const
Get the total size of the index space.
Definition Cabana_Grid_IndexSpace.hpp:140
KOKKOS_INLINE_FUNCTION long rank() const
Get the number of dimensions.
Definition Cabana_Grid_IndexSpace.hpp:132
KOKKOS_INLINE_FUNCTION long extent(const long dim) const
Get the extent of a given dimension.
Definition Cabana_Grid_IndexSpace.hpp:136
IndexSpace(const std::initializer_list< Scalar > &min, const std::initializer_list< Scalar > &max)
Initializer list range constructor.
Definition Cabana_Grid_IndexSpace.hpp:63
IndexSpace()
Default constructor.
Definition Cabana_Grid_IndexSpace.hpp:43
IndexSpace(const std::initializer_list< Scalar > &size)
Initializer list size constructor.
Definition Cabana_Grid_IndexSpace.hpp:53
IndexSpace(const std::array< long, N > &size)
Vector size constructor.
Definition Cabana_Grid_IndexSpace.hpp:73
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
auto size(SliceType slice, typename std::enable_if< is_slice< SliceType >::value, int >::type *=0)
Check slice size (differs from Kokkos View).
Definition Cabana_Slice.hpp:1019