@@ -99,10 +99,6 @@ auto Field::get_view () const
99
99
// Make sure input field is allocated
100
100
EKAT_REQUIRE_MSG (is_allocated (),
101
101
" Error! Cannot extract a field's view before allocation happens.\n " );
102
- // FIXME: add check
103
- // EKAT_REQUIRE_MSG(true /*is_multiSlice_subview()*/,
104
- // "Error! Multi-sliced subfield is incompatible--must employ "
105
- // "get_strided_view().\n")
106
102
107
103
EKAT_REQUIRE_MSG (not m_is_read_only || std::is_const<DstValueType>::value,
108
104
" Error! Cannot get a view to non-const data if the field is read-only.\n " );
@@ -207,26 +203,26 @@ auto Field::get_strided_view () const
207
203
return DstView (get_ND_view<HD,DstValueType,1 >());
208
204
}
209
205
210
- template <typename DT, HostOrDevice HD>
211
- Kokkos::View<Real****, Kokkos::LayoutStride> Field::get_strided_view (bool special) const
206
+ // NOTE: multi-slicing a view is only supported for strided view return type
207
+ template <typename DT, int N, HostOrDevice HD>
208
+ auto Field::get_multi_sliced_view () const
209
+ -> get_strided_view_type<data_nd_t<DT, N>, HD>
212
210
{
213
211
// The destination view type on correct mem space
214
- using DstView = get_strided_view_type<DT,HD>;
212
+ using DstView = get_strided_view_type<data_nd_t < DT, N>, HD>;
215
213
// The dst value types
216
214
using DstValueType = typename DstView::traits::value_type;
217
- // We only allow to reshape to a view of the correct rank
218
- constexpr int DstRank = DstView::rank;
219
- constexpr int DstRankDynamic = DstView::rank_dynamic;
220
215
221
216
// Get src details
222
217
const auto & alloc_prop = m_header->get_alloc_properties ();
223
218
const auto & fl = m_header->get_identifier ().get_layout ();
224
219
225
220
// Checks
226
- // EKAT_REQUIRE_MSG (DstRank==1 && fl.rank()==1,
227
- // "Error! Strided view only available for rank-1 fields.\n");
228
- // EKAT_REQUIRE_MSG (DstRankDynamic==1,
221
+ // TODO: decide whether a dynamic-rank view is ok
222
+ // EKAT_REQUIRE_MSG (DstRankDynamic == 1,
229
223
// "Error! Strided view not allowed with compile-time dimensions.\n");
224
+ EKAT_REQUIRE_MSG (N == fl.rank (),
225
+ " Error! Input Rank must be equal to parent view's rank for multi-sliced subview.\n " );
230
226
EKAT_REQUIRE_MSG (is_allocated (),
231
227
" Error! Cannot extract a field's view before allocation happens.\n " );
232
228
EKAT_REQUIRE_MSG (not m_is_read_only || std::is_const<DstValueType>::value,
@@ -236,51 +232,23 @@ Kokkos::View<Real****, Kokkos::LayoutStride> Field::get_strided_view (bool speci
236
232
237
233
// Check if this field is a subview of another field
238
234
const auto parent = m_header->get_parent ().lock ();
239
- if (parent!=nullptr ) {
240
- // Parent field has correct layout to reinterpret the view into N+1-dim view
241
- // So create the parent field on the fly, use it to get the N+1-dim view, then subview it.
242
- // NOTE: we can set protected members, since f is the same type of this class.
235
+ if (parent != nullptr ) {
243
236
Field f;
244
237
f.m_header = parent;
245
238
f.m_data = m_data;
246
239
247
- // // Take 2 dimensional view with normal LayoutRight
248
- // auto v_np1 = f.get_ND_view<HD,DstValueType,2>();
249
- // const auto vfs_rank = f.get_header().get_identifier().get_layout().rank();
250
- auto v_fullsize = f.get_ND_view <HD, DstValueType, 4 >();
240
+ auto v_fullsize = f.get_ND_view <HD, DstValueType, N>();
251
241
252
242
// Now we can subview v_np1 at the correct slice
253
243
const auto & info = m_header->get_alloc_properties ().get_subview_info ();
254
- const int idim = info.dim_idx ;
255
- const int k = info.slice_idx ;
256
- const int k_end = info.slice_idx_end ;
257
-
258
- // // So far we can only subview at first or second dimension.
259
- // EKAT_REQUIRE_MSG (idim==0 || idim==1,
260
- // "Error! Subview dimension index is out of bounds.\n");
261
-
262
- // Use correct subview utility
263
- if (idim==0 ) {
264
- // FIXME: what's a better way to do this? can't use v_fullsize after the
265
- // logic block b/c of scoping, and it's also not easy to know what type of
266
- // exotic
267
- // we know it's a subview, so if it has the same rank as its parent, then
268
- // we know that it's a multi-slice subview
269
- if (fl.rank () == f.get_header ().get_identifier ().get_layout ().rank ()) {
270
- auto svs = ekat::subview (v_fullsize, Kokkos::make_pair<int , int >(k, k_end), idim);
271
- // for (size_t i = 0; i < 4; i++)
272
- // {
273
- // std::cout << "i = " << i << "\n";
274
- // std::cout << "svs.stride(i) = " << svs.stride(i) << "\n";
275
- // std::cout << "svs.extent(i) = " << svs.extent(i) << "\n";
276
- // }
277
- return svs;
278
- } else {
279
- // return DstView(ekat::subview(v_np1,k));
280
- }
281
- } else {
282
- // return DstView(ekat::subview_1(v_np1,k));
283
- }
244
+ const int idim = info.dim_idx ;
245
+ const int k = info.slice_idx ;
246
+ const int k_end = info.slice_idx_end ;
247
+
248
+ // this version of ekat::subview overloaded conveniently, so only the single
249
+ // version of the call is required here
250
+ return DstView (ekat::subview (v_fullsize,
251
+ Kokkos::make_pair<int , int >(k, k_end), idim));
284
252
}
285
253
}
286
254
@@ -838,7 +806,6 @@ auto Field::get_ND_view () const ->
838
806
return ret_type (ptr,kl);
839
807
}
840
808
841
- // TODO: will need to set this up for multi-sliced subfield
842
809
template <HostOrDevice HD,typename T,int N>
843
810
auto Field::get_ND_view () const ->
844
811
if_t<N==MaxRank,get_view_type<data_nd_t<T,N>,HD>>
@@ -848,7 +815,6 @@ auto Field::get_ND_view () const ->
848
815
" Error! Input Rank must either be 1 (flat array) or the actual field rank.\n " );
849
816
850
817
// Given that N==MaxRank, this field cannot be a subview of another field
851
- // NOTE: this will not be true for multi-slice
852
818
EKAT_REQUIRE_MSG (m_header->get_parent ().expired (),
853
819
" Error! A view of rank " + std::to_string (MaxRank) + " should not be the subview of another field.\n " );
854
820
0 commit comments