3
// ************************************************************************
5
// Kokkos: Manycore Performance-Portable Multidimensional Arrays
6
// Copyright (2012) Sandia Corporation
8
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9
// the U.S. Government retains certain rights in this software.
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are
15
// 1. Redistributions of source code must retain the above copyright
16
// notice, this list of conditions and the following disclaimer.
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.
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.
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.
38
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
40
// ************************************************************************
44
#ifndef KOKKOS_VIEWSUPPORT_HPP
45
#define KOKKOS_VIEWSUPPORT_HPP
47
#include <Kokkos_ExecPolicy.hpp>
48
#include <impl/Kokkos_Shape.hpp>
50
//----------------------------------------------------------------------------
51
//----------------------------------------------------------------------------
56
/** \brief Evaluate if LHS = RHS view assignment is allowed. */
57
template< class ViewLHS , class ViewRHS >
62
// Compatible 'const' qualifier
63
// Cannot assign managed = unmannaged
64
enum { assignable_value =
65
( is_same< typename ViewLHS::value_type ,
66
typename ViewRHS::value_type >::value
68
is_same< typename ViewLHS::value_type ,
69
typename ViewRHS::const_value_type >::value )
71
is_same< typename ViewLHS::memory_space ,
72
typename ViewRHS::memory_space >::value
74
( ! ( ViewLHS::is_managed && ! ViewRHS::is_managed ) )
77
enum { assignable_shape =
78
// Compatible shape and matching layout:
79
( ShapeCompatible< typename ViewLHS::shape_type ,
80
typename ViewRHS::shape_type >::value
82
is_same< typename ViewLHS::array_layout ,
83
typename ViewRHS::array_layout >::value )
85
// Matching layout, same rank, and LHS dynamic rank
86
( is_same< typename ViewLHS::array_layout ,
87
typename ViewRHS::array_layout >::value
89
int(ViewLHS::rank) == int(ViewRHS::rank)
91
int(ViewLHS::rank) == int(ViewLHS::rank_dynamic) )
93
// Both rank-0, any shape and layout
94
( int(ViewLHS::rank) == 0 && int(ViewRHS::rank) == 0 )
96
// Both rank-1 and LHS is dynamic rank-1, any shape and layout
97
( int(ViewLHS::rank) == 1 && int(ViewRHS::rank) == 1 &&
98
int(ViewLHS::rank_dynamic) == 1 )
101
enum { value = assignable_value && assignable_shape };
105
} // namespace Kokkos
107
//----------------------------------------------------------------------------
108
//----------------------------------------------------------------------------
113
template< class ExecSpace , class Type , bool Initialize >
114
struct ViewDefaultConstruct
115
{ ViewDefaultConstruct( Type * , size_t ) {} };
118
/** \brief ViewDataHandle provides the type of the 'data handle' which the view
119
* uses to access data with the [] operator. It also provides
120
* an allocate function and a function to extract a raw ptr from the
121
* data handle. ViewDataHandle also defines an enum ReferenceAble which
122
* specifies whether references/pointers to elements can be taken and a
123
* 'return_type' which is what the view operators will give back.
124
* Specialisation of this object allows three things depending
125
* on ViewTraits and compiler options:
126
* (i) Use special allocator (e.g. huge pages/small pages and pinned memory)
127
* (ii) Use special data handle type (e.g. add Cuda Texture Object)
128
* (iii) Use special access intrinsics (e.g. texture fetch and non-caching loads)
130
template< class StaticViewTraits , class Enable = void >
131
struct ViewDataHandle {
133
enum { ReturnTypeIsReference = true };
135
typedef typename StaticViewTraits::value_type * handle_type;
136
typedef typename StaticViewTraits::value_type & return_type;
139
template< class StaticViewTraits , class Enable = void >
140
class ViewDataManagement : public ViewDataHandle< StaticViewTraits > {
143
template< class , class > friend class ViewDataManagement ;
145
struct PotentiallyManaged {};
146
struct StaticallyUnmanaged {};
148
/* Statically unmanaged if traits or not executing in host-accessible memory space */
150
Impl::if_c< StaticViewTraits::is_managed &&
151
Impl::is_same< Kokkos::HostSpace
152
, Kokkos::Impl::ActiveExecutionMemorySpace >::value
154
, StaticallyUnmanaged
155
>::type StaticManagementTag ;
157
enum { Unmanaged = 0x01
158
, Noncontiguous = 0x02
161
enum { DefaultTraits = Impl::is_same< StaticManagementTag , StaticallyUnmanaged >::value ? Unmanaged : 0 };
163
unsigned m_traits ; ///< Runtime traits
168
unsigned assign( const ViewDataManagement<T> & rhs , const PotentiallyManaged & )
169
{ return rhs.m_traits | ( rhs.is_managed() && Kokkos::HostSpace::in_parallel() ? unsigned(Unmanaged) : 0u ); }
172
KOKKOS_INLINE_FUNCTION static
173
unsigned assign( const ViewDataManagement<T> & rhs , const StaticallyUnmanaged & )
174
{ return rhs.m_traits | Unmanaged ; }
177
void increment( const void * ptr , const PotentiallyManaged & ) const
178
{ if ( is_managed() ) StaticViewTraits::memory_space::increment( ptr ); }
181
void decrement( const void * ptr , const PotentiallyManaged & ) const
182
{ if ( is_managed() ) StaticViewTraits::memory_space::decrement( ptr ); }
184
KOKKOS_INLINE_FUNCTION
185
void increment( const void * , const StaticallyUnmanaged & ) const {}
187
KOKKOS_INLINE_FUNCTION
188
void decrement( const void * , const StaticallyUnmanaged & ) const {}
192
typedef typename ViewDataHandle< StaticViewTraits >::handle_type handle_type;
194
KOKKOS_INLINE_FUNCTION
195
ViewDataManagement() : m_traits( DefaultTraits ) {}
197
KOKKOS_INLINE_FUNCTION
198
ViewDataManagement( const ViewDataManagement & rhs )
199
: m_traits( assign( rhs , StaticManagementTag() ) ) {}
201
KOKKOS_INLINE_FUNCTION
202
ViewDataManagement & operator = ( const ViewDataManagement & rhs )
203
{ m_traits = assign( rhs , StaticManagementTag() ); return *this ; }
205
template< class SVT >
206
KOKKOS_INLINE_FUNCTION
207
ViewDataManagement( const ViewDataManagement<SVT> & rhs )
208
: m_traits( assign( rhs , StaticManagementTag() ) ) {}
210
template< class SVT >
211
KOKKOS_INLINE_FUNCTION
212
ViewDataManagement & operator = ( const ViewDataManagement<SVT> & rhs )
213
{ m_traits = assign( rhs , StaticManagementTag() ); return *this ; }
215
KOKKOS_INLINE_FUNCTION
216
bool is_managed() const { return ! ( m_traits & Unmanaged ); }
218
KOKKOS_INLINE_FUNCTION
219
bool is_contiguous() const { return ! ( m_traits & Noncontiguous ); }
221
KOKKOS_INLINE_FUNCTION
222
void set_unmanaged() { m_traits |= Unmanaged ; }
224
KOKKOS_INLINE_FUNCTION
225
void set_noncontiguous() { m_traits |= Noncontiguous ; }
228
KOKKOS_INLINE_FUNCTION
229
void increment( handle_type handle ) const
230
{ increment( ( typename StaticViewTraits::value_type *) handle , StaticManagementTag() ); }
232
KOKKOS_INLINE_FUNCTION
233
void decrement( handle_type handle ) const
234
{ decrement( ( typename StaticViewTraits::value_type *) handle , StaticManagementTag() ); }
237
KOKKOS_INLINE_FUNCTION
238
void increment( const void * ptr ) const
239
{ increment( ptr , StaticManagementTag() ); }
241
KOKKOS_INLINE_FUNCTION
242
void decrement( const void * ptr ) const
243
{ decrement( ptr , StaticManagementTag() ); }
246
template< bool Initialize >
248
handle_type allocate( const std::string & label
249
, const Impl::ViewOffset< typename StaticViewTraits::shape_type
250
, typename StaticViewTraits::array_layout > & offset_map )
252
typedef typename StaticViewTraits::execution_space execution_space ;
253
typedef typename StaticViewTraits::memory_space memory_space ;
254
typedef typename StaticViewTraits::value_type value_type ;
256
const size_t count = offset_map.capacity();
258
value_type * ptr = (value_type*) memory_space::allocate( label , sizeof(value_type) * count );
260
// Default construct within the view's execution space.
261
(void) ViewDefaultConstruct< execution_space , value_type , Initialize >( ptr , count );
263
return typename ViewDataHandle< StaticViewTraits >::handle_type(ptr);
268
} // namespace Kokkos
270
//----------------------------------------------------------------------------
271
//----------------------------------------------------------------------------
276
template< class OutputView , class InputView , unsigned Rank = OutputView::Rank >
279
typedef typename OutputView::size_type size_type ;
281
const OutputView output ;
282
const InputView input ;
292
ViewRemap( const OutputView & arg_out , const InputView & arg_in )
293
: output( arg_out ), input( arg_in )
294
, n0( std::min( (size_t)arg_out.dimension_0() , (size_t)arg_in.dimension_0() ) )
295
, n1( std::min( (size_t)arg_out.dimension_1() , (size_t)arg_in.dimension_1() ) )
296
, n2( std::min( (size_t)arg_out.dimension_2() , (size_t)arg_in.dimension_2() ) )
297
, n3( std::min( (size_t)arg_out.dimension_3() , (size_t)arg_in.dimension_3() ) )
298
, n4( std::min( (size_t)arg_out.dimension_4() , (size_t)arg_in.dimension_4() ) )
299
, n5( std::min( (size_t)arg_out.dimension_5() , (size_t)arg_in.dimension_5() ) )
300
, n6( std::min( (size_t)arg_out.dimension_6() , (size_t)arg_in.dimension_6() ) )
301
, n7( std::min( (size_t)arg_out.dimension_7() , (size_t)arg_in.dimension_7() ) )
303
typedef typename OutputView::execution_space execution_space ;
304
Kokkos::RangePolicy< execution_space > range( 0 , n0 );
305
parallel_for( range , *this );
308
KOKKOS_INLINE_FUNCTION
309
void operator()( const size_type i0 ) const
311
for ( size_type i1 = 0 ; i1 < n1 ; ++i1 ) {
312
for ( size_type i2 = 0 ; i2 < n2 ; ++i2 ) {
313
for ( size_type i3 = 0 ; i3 < n3 ; ++i3 ) {
314
for ( size_type i4 = 0 ; i4 < n4 ; ++i4 ) {
315
for ( size_type i5 = 0 ; i5 < n5 ; ++i5 ) {
316
for ( size_type i6 = 0 ; i6 < n6 ; ++i6 ) {
317
for ( size_type i7 = 0 ; i7 < n7 ; ++i7 ) {
318
output.at(i0,i1,i2,i3,i4,i5,i6,i7) = input.at(i0,i1,i2,i3,i4,i5,i6,i7);
323
template< class OutputView , class InputView >
324
struct ViewRemap< OutputView , InputView , 0 >
326
typedef typename OutputView::value_type value_type ;
327
typedef typename OutputView::memory_space dst_space ;
328
typedef typename InputView ::memory_space src_space ;
330
ViewRemap( const OutputView & arg_out , const InputView & arg_in )
332
DeepCopy< dst_space , src_space >( arg_out.ptr_on_device() ,
333
arg_in.ptr_on_device() ,
334
sizeof(value_type) );
338
//----------------------------------------------------------------------------
340
template< class ExecSpace , class Type >
341
struct ViewDefaultConstruct< ExecSpace , Type , true >
345
KOKKOS_INLINE_FUNCTION
346
void operator()( const typename ExecSpace::size_type i ) const
347
{ new( m_ptr + i ) Type(); }
349
ViewDefaultConstruct( Type * pointer , size_t capacity )
352
Kokkos::RangePolicy< ExecSpace > range( 0 , capacity );
353
parallel_for( range , *this );
358
template< class OutputView , unsigned Rank = OutputView::Rank >
361
typedef typename OutputView::const_value_type const_value_type ;
362
typedef typename OutputView::size_type size_type ;
364
const OutputView output ;
365
const_value_type input ;
367
ViewFill( const OutputView & arg_out , const_value_type & arg_in )
368
: output( arg_out ), input( arg_in )
370
typedef typename OutputView::execution_space execution_space ;
371
Kokkos::RangePolicy< execution_space > range( 0 , output.dimension_0() );
372
parallel_for( range , *this );
373
execution_space::fence();
376
KOKKOS_INLINE_FUNCTION
377
void operator()( const size_type i0 ) const
379
for ( size_type i1 = 0 ; i1 < output.dimension_1() ; ++i1 ) {
380
for ( size_type i2 = 0 ; i2 < output.dimension_2() ; ++i2 ) {
381
for ( size_type i3 = 0 ; i3 < output.dimension_3() ; ++i3 ) {
382
for ( size_type i4 = 0 ; i4 < output.dimension_4() ; ++i4 ) {
383
for ( size_type i5 = 0 ; i5 < output.dimension_5() ; ++i5 ) {
384
for ( size_type i6 = 0 ; i6 < output.dimension_6() ; ++i6 ) {
385
for ( size_type i7 = 0 ; i7 < output.dimension_7() ; ++i7 ) {
386
output.at(i0,i1,i2,i3,i4,i5,i6,i7) = input ;
391
template< class OutputView >
392
struct ViewFill< OutputView , 0 >
394
typedef typename OutputView::const_value_type const_value_type ;
395
typedef typename OutputView::memory_space dst_space ;
397
ViewFill( const OutputView & arg_out , const_value_type & arg_in )
399
DeepCopy< dst_space , dst_space >( arg_out.ptr_on_device() , & arg_in ,
400
sizeof(const_value_type) );
405
} // namespace Kokkos
407
//----------------------------------------------------------------------------
408
//----------------------------------------------------------------------------
412
struct ViewAllocateWithoutInitializing {
414
const std::string label ;
416
ViewAllocateWithoutInitializing() : label() {}
417
ViewAllocateWithoutInitializing( const std::string & arg_label ) : label( arg_label ) {}
418
ViewAllocateWithoutInitializing( const char * const arg_label ) : label( arg_label ) {}
421
struct ViewAllocate {
423
const std::string label ;
425
ViewAllocate() : label() {}
426
ViewAllocate( const std::string & arg_label ) : label( arg_label ) {}
427
ViewAllocate( const char * const arg_label ) : label( arg_label ) {}
435
template< class Traits , class AllocationProperties , class Enable = void >
436
struct ViewAllocProp : public Kokkos::Impl::false_type {};
438
template< class Traits >
439
struct ViewAllocProp< Traits , Kokkos::ViewAllocate
440
, typename Kokkos::Impl::enable_if<(
441
Traits::is_managed && ! Kokkos::Impl::is_const< typename Traits::value_type >::value
443
: public Kokkos::Impl::true_type
445
typedef size_t size_type ;
446
typedef const ViewAllocate & property_type ;
448
enum { Initialize = true };
449
enum { AllowPadding = false };
452
static const std::string & label( property_type p ) { return p.label ; }
455
template< class Traits >
456
struct ViewAllocProp< Traits , std::string
457
, typename Kokkos::Impl::enable_if<(
458
Traits::is_managed && ! Kokkos::Impl::is_const< typename Traits::value_type >::value
460
: public Kokkos::Impl::true_type
462
typedef size_t size_type ;
463
typedef const std::string & property_type ;
465
enum { Initialize = true };
466
enum { AllowPadding = false };
469
static const std::string & label( property_type s ) { return s ; }
472
template< class Traits , unsigned N >
473
struct ViewAllocProp< Traits , char[N]
474
, typename Kokkos::Impl::enable_if<(
475
Traits::is_managed && ! Kokkos::Impl::is_const< typename Traits::value_type >::value
477
: public Kokkos::Impl::true_type
480
typedef char label_type[N] ;
483
typedef size_t size_type ;
484
typedef const label_type & property_type ;
486
enum { Initialize = true };
487
enum { AllowPadding = false };
490
static std::string label( property_type s ) { return std::string(s) ; }
493
template< class Traits >
494
struct ViewAllocProp< Traits , Kokkos::ViewAllocateWithoutInitializing
495
, typename Kokkos::Impl::enable_if<(
496
Traits::is_managed && ! Kokkos::Impl::is_const< typename Traits::value_type >::value
498
: public Kokkos::Impl::true_type
500
typedef size_t size_type ;
501
typedef const Kokkos::ViewAllocateWithoutInitializing & property_type ;
503
enum { Initialize = false };
504
enum { AllowPadding = false };
507
static std::string label( property_type s ) { return s.label ; }
511
} // namespace Kokkos
513
//----------------------------------------------------------------------------
514
//----------------------------------------------------------------------------
519
template< class Traits , class PointerProperties , class Enable = void >
520
struct ViewRawPointerProp : public Kokkos::Impl::false_type {};
522
template< class Traits , typename T >
523
struct ViewRawPointerProp< Traits , T ,
524
typename Kokkos::Impl::enable_if<(
525
Impl::is_same< T , typename Traits::value_type >::value ||
526
Impl::is_same< T , typename Traits::non_const_value_type >::value
528
: public Kokkos::Impl::true_type
530
typedef size_t size_type ;
534
} // namespace Kokkos
536
//----------------------------------------------------------------------------
537
//----------------------------------------------------------------------------
539
#endif /* #ifndef KOKKOS_VIEWSUPPORT_HPP */