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_FUNCTORADAPTER_HPP
45
#define KOKKOS_FUNCTORADAPTER_HPP
48
#include <Kokkos_Core_fwd.hpp>
49
#include <impl/Kokkos_Traits.hpp>
50
#include <impl/Kokkos_Tags.hpp>
52
//----------------------------------------------------------------------------
53
//----------------------------------------------------------------------------
58
template< class FunctorType , class ArgTag , class Enable = void >
59
struct FunctorDeclaresValueType : public Impl::false_type {};
61
template< class FunctorType , class ArgTag >
62
struct FunctorDeclaresValueType< FunctorType , ArgTag
63
, typename Impl::enable_if_type< typename FunctorType::value_type >::type >
64
: public Impl::true_type {};
67
/** \brief Query Functor and execution policy argument tag for value type.
69
* If C++11 enabled and 'value_type' is not explicitly declared then attempt
70
* to deduce the type from FunctorType::operator().
72
template< class FunctorType , class ArgTag , bool Dec = FunctorDeclaresValueType<FunctorType,ArgTag>::value >
73
struct FunctorValueTraits
75
typedef void value_type ;
76
typedef void pointer_type ;
77
typedef void reference_type ;
79
enum { StaticValueSize = 0 };
81
KOKKOS_FORCEINLINE_FUNCTION static
82
unsigned value_count( const FunctorType & ) { return 0 ; }
84
KOKKOS_FORCEINLINE_FUNCTION static
85
unsigned value_size( const FunctorType & ) { return 0 ; }
88
/** \brief FunctorType::value_type is explicitly declared so use it.
90
* Two options for declaration
92
* 1) A plain-old-data (POD) type
93
* typedef {pod_type} value_type ;
95
* 2) An array of POD of a runtime specified count.
96
* typedef {pod_type} value_type[] ;
97
* const unsigned value_count ;
99
template< class FunctorType , class ArgTag >
100
struct FunctorValueTraits< FunctorType , ArgTag , true /* exists FunctorType::value_type */ >
102
typedef typename Impl::remove_extent< typename FunctorType::value_type >::type value_type ;
104
// If not an array then what is the sizeof(value_type)
105
enum { StaticValueSize = Impl::is_array< typename FunctorType::value_type >::value ? 0 : sizeof(value_type) };
107
typedef value_type * pointer_type ;
109
// The reference_type for an array is 'value_type *'
110
// The reference_type for a single value is 'value_type &'
112
typedef typename Impl::if_c< ! StaticValueSize , value_type *
113
, value_type & >::type reference_type ;
115
// Number of values if single value
117
KOKKOS_FORCEINLINE_FUNCTION static
118
typename Impl::enable_if< Impl::is_same<F,FunctorType>::value && StaticValueSize , unsigned >::type
119
value_count( const F & ) { return 1 ; }
121
// Number of values if an array, protect via templating because 'f.value_count'
122
// will only exist when the functor declares the value_type to be an array.
124
KOKKOS_FORCEINLINE_FUNCTION static
125
typename Impl::enable_if< Impl::is_same<F,FunctorType>::value && ! StaticValueSize , unsigned >::type
126
value_count( const F & f ) { return f.value_count ; }
128
// Total size of the value
129
KOKKOS_INLINE_FUNCTION static
130
unsigned value_size( const FunctorType & f ) { return value_count( f ) * sizeof(value_type) ; }
134
#if defined( KOKKOS_HAVE_CXX11 )
136
// If have C++11 and functor does not explicitly specify a value type
137
// then try to deduce the value type from FunctorType::operator().
138
// Can only deduce single value type since array length cannot be deduced.
139
template< class FunctorType >
140
struct FunctorValueTraits< FunctorType
141
, void /* == ArgTag */
142
, false /* == exists FunctorType::value_type */
149
// parallel_for operator without a tag:
150
template< class ArgMember >
151
KOKKOS_INLINE_FUNCTION
152
static VOID deduce( void (FunctorType::*)( ArgMember ) const ) {}
154
// parallel_reduce operator without a tag:
155
template< class ArgMember , class T >
156
KOKKOS_INLINE_FUNCTION
157
static T deduce( void (FunctorType::*)( ArgMember , T & ) const ) {}
159
// parallel_scan operator without a tag:
160
template< class ArgMember , class T >
161
KOKKOS_INLINE_FUNCTION
162
static T deduce( void (FunctorType::*)( ArgMember , T & , bool ) const ) {}
164
typedef decltype( deduce( & FunctorType::operator() ) ) ValueType ;
166
enum { IS_VOID = Impl::is_same<VOID,ValueType>::value };
170
typedef typename Impl::if_c< IS_VOID , void , ValueType >::type value_type ;
171
typedef typename Impl::if_c< IS_VOID , void , ValueType * >::type pointer_type ;
172
typedef typename Impl::if_c< IS_VOID , void , ValueType & >::type reference_type ;
174
enum { StaticValueSize = IS_VOID ? 0 : sizeof(ValueType) };
176
KOKKOS_FORCEINLINE_FUNCTION static
177
unsigned value_size( const FunctorType & ) { return StaticValueSize ; }
179
KOKKOS_FORCEINLINE_FUNCTION static
180
unsigned value_count( const FunctorType & ) { return IS_VOID ? 0 : 1 ; }
184
template< class FunctorType , class ArgTag >
185
struct FunctorValueTraits< FunctorType
186
, ArgTag /* != void */
187
, false /* == exists FunctorType::value_type */
192
//----------------------------------------
193
// parallel_for operator with a tag:
195
struct VOID {}; // to allow valid sizeof(ValueType)
197
template< class ArgMember >
198
KOKKOS_INLINE_FUNCTION
199
static VOID deduce( void (FunctorType::*)( ArgTag , ArgMember ) const ) {}
201
template< class ArgMember >
202
KOKKOS_INLINE_FUNCTION
203
static VOID deduce( void (FunctorType::*)( const ArgTag & , ArgMember ) const ) {}
205
//----------------------------------------
206
// parallel_reduce operator with a tag:
208
template< class ArgMember , class T >
209
KOKKOS_INLINE_FUNCTION
210
static T deduce( void (FunctorType::*)( ArgTag , ArgMember , T & ) const ) {}
212
template< class ArgMember , class T >
213
KOKKOS_INLINE_FUNCTION
214
static T deduce( void (FunctorType::*)( const ArgTag & , ArgMember , T & ) const ) {}
216
//----------------------------------------
217
// parallel_scan operator with a tag:
219
template< class ArgMember , class T >
220
KOKKOS_INLINE_FUNCTION
221
static T deduce( void (FunctorType::*)( ArgTag , ArgMember , T & , bool ) const ) {}
223
template< class ArgMember , class T >
224
KOKKOS_INLINE_FUNCTION
225
static T deduce( void (FunctorType::*)( const ArgTag & , ArgMember , T & , bool ) const ) {}
227
//----------------------------------------
229
typedef decltype( deduce( & FunctorType::operator() ) ) ValueType ;
231
enum { IS_VOID = Impl::is_same<VOID,ValueType>::value };
235
typedef typename Impl::if_c< IS_VOID , void , ValueType >::type value_type ;
236
typedef typename Impl::if_c< IS_VOID , void , ValueType * >::type pointer_type ;
237
typedef typename Impl::if_c< IS_VOID , void , ValueType & >::type reference_type ;
239
enum { StaticValueSize = IS_VOID ? 0 : sizeof(ValueType) };
241
KOKKOS_FORCEINLINE_FUNCTION static
242
unsigned value_size( const FunctorType & ) { return StaticValueSize ; }
244
KOKKOS_FORCEINLINE_FUNCTION static
245
unsigned value_count( const FunctorType & ) { return IS_VOID ? 0 : 1 ; }
248
#endif /* #if defined( KOKKOS_HAVE_CXX11 ) */
251
} // namespace Kokkos
253
//----------------------------------------------------------------------------
254
//----------------------------------------------------------------------------
259
// Function signatures for FunctorType::init function with a tag and not an array
260
template< class FunctorType , class ArgTag , bool IsArray = 0 == FunctorValueTraits<FunctorType,ArgTag>::StaticValueSize >
261
struct FunctorValueInitFunction {
263
typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
265
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type & ) const );
266
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type & ) const );
267
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type & ) );
268
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type & ) );
270
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type volatile & ) const );
271
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile & ) const );
272
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type volatile & ) );
273
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type volatile & ) );
276
// Function signatures for FunctorType::init function with a tag and is an array
277
template< class FunctorType , class ArgTag >
278
struct FunctorValueInitFunction< FunctorType , ArgTag , true > {
280
typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
282
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type * ) const );
283
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type * ) const );
284
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type * ) );
285
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type * ) );
287
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type volatile * ) const );
288
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile * ) const );
289
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type volatile * ) );
290
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type volatile * ) );
293
// Function signatures for FunctorType::init function without a tag and not an array
294
template< class FunctorType >
295
struct FunctorValueInitFunction< FunctorType , void , false > {
297
typedef typename FunctorValueTraits<FunctorType,void>::reference_type value_type ;
299
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type & ) const );
300
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( value_type & ) );
302
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type volatile & ) const );
303
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( value_type volatile & ) );
306
// Function signatures for FunctorType::init function without a tag and is an array
307
template< class FunctorType >
308
struct FunctorValueInitFunction< FunctorType , void , true > {
310
typedef typename FunctorValueTraits<FunctorType,void>::reference_type value_type ;
312
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type * ) const );
313
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( value_type * ) );
315
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type volatile * ) const );
316
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( value_type volatile * ) );
319
// Adapter for value initialization function.
320
// If a proper FunctorType::init is declared then use it,
321
// otherwise use default constructor.
322
template< class FunctorType , class ArgTag
323
, class T = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type
324
, class Enable = void >
325
struct FunctorValueInit ;
327
/* No 'init' function provided for single value */
328
template< class FunctorType , class ArgTag , class T , class Enable >
329
struct FunctorValueInit< FunctorType , ArgTag , T & , Enable >
331
KOKKOS_FORCEINLINE_FUNCTION static
332
T & init( const FunctorType & f , void * p )
333
{ return *( new(p) T() ); };
336
/* No 'init' function provided for array value */
337
template< class FunctorType , class ArgTag , class T , class Enable >
338
struct FunctorValueInit< FunctorType , ArgTag , T * , Enable >
340
KOKKOS_FORCEINLINE_FUNCTION static
341
T * init( const FunctorType & f , void * p )
343
const int n = FunctorValueTraits< FunctorType , ArgTag >::value_count(f);
344
for ( int i = 0 ; i < n ; ++i ) { new( ((T*)p) + i ) T(); }
349
/* 'init' function provided for single value */
350
template< class FunctorType , class ArgTag , class T >
351
struct FunctorValueInit
355
// First substitution failure when FunctorType::init does not exist.
356
#if defined( KOKKOS_HAVE_CXX11 )
357
// Second substitution failure when FunctorType::init is not compatible.
358
, decltype( FunctorValueInitFunction< FunctorType , ArgTag >::enable_if( & FunctorType::init ) )
360
, typename Impl::enable_if< 0 < sizeof( & FunctorType::init ) >::type
364
KOKKOS_FORCEINLINE_FUNCTION static
365
T & init( const FunctorType & f , void * p )
366
{ f.init( *((T*)p) ); return *((T*)p) ; }
369
/* 'init' function provided for array value */
370
template< class FunctorType , class ArgTag , class T >
371
struct FunctorValueInit
375
// First substitution failure when FunctorType::init does not exist.
376
#if defined( KOKKOS_HAVE_CXX11 )
377
// Second substitution failure when FunctorType::init is not compatible
378
, decltype( FunctorValueInitFunction< FunctorType , ArgTag >::enable_if( & FunctorType::init ) )
380
, typename Impl::enable_if< 0 < sizeof( & FunctorType::init ) >::type
384
KOKKOS_FORCEINLINE_FUNCTION static
385
T * init( const FunctorType & f , void * p )
386
{ f.init( (T*)p ); return (T*)p ; }
390
} // namespace Kokkos
392
//----------------------------------------------------------------------------
393
//----------------------------------------------------------------------------
398
// Signatures for compatible FunctorType::join with tag and not an array
399
template< class FunctorType , class ArgTag , bool IsArray = 0 == FunctorValueTraits<FunctorType,ArgTag>::StaticValueSize >
400
struct FunctorValueJoinFunction {
402
typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
404
typedef volatile value_type & vref_type ;
405
typedef const volatile value_type & cvref_type ;
407
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , vref_type , cvref_type ) const );
408
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , vref_type , cvref_type ) const );
409
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , vref_type , cvref_type ) );
410
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , vref_type , cvref_type ) );
413
// Signatures for compatible FunctorType::join with tag and is an array
414
template< class FunctorType , class ArgTag >
415
struct FunctorValueJoinFunction< FunctorType , ArgTag , true > {
417
typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
419
typedef volatile value_type * vptr_type ;
420
typedef const volatile value_type * cvptr_type ;
422
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , vptr_type , cvptr_type ) const );
423
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , vptr_type , cvptr_type ) const );
424
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , vptr_type , cvptr_type ) );
425
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , vptr_type , cvptr_type ) );
428
// Signatures for compatible FunctorType::join without tag and not an array
429
template< class FunctorType >
430
struct FunctorValueJoinFunction< FunctorType , void , false > {
432
typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
434
typedef volatile value_type & vref_type ;
435
typedef const volatile value_type & cvref_type ;
437
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( vref_type , cvref_type ) const );
438
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( vref_type , cvref_type ) );
441
// Signatures for compatible FunctorType::join without tag and is an array
442
template< class FunctorType >
443
struct FunctorValueJoinFunction< FunctorType , void , true > {
445
typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
447
typedef volatile value_type * vptr_type ;
448
typedef const volatile value_type * cvptr_type ;
450
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( vptr_type , cvptr_type ) const );
451
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( vptr_type , cvptr_type ) );
455
template< class FunctorType , class ArgTag
456
, class T = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type
457
, class Enable = void >
458
struct FunctorValueJoin ;
460
/* No 'join' function provided, single value */
461
template< class FunctorType , class ArgTag , class T , class Enable >
462
struct FunctorValueJoin< FunctorType , ArgTag , T & , Enable >
464
KOKKOS_FORCEINLINE_FUNCTION static
465
void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
467
*((volatile T*)lhs) += *((const volatile T*)rhs);
471
/* No 'join' function provided, array of values */
472
template< class FunctorType , class ArgTag , class T , class Enable >
473
struct FunctorValueJoin< FunctorType , ArgTag , T * , Enable >
475
KOKKOS_FORCEINLINE_FUNCTION static
476
void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
478
const int n = FunctorValueTraits<FunctorType,ArgTag>::value_count(f);
480
for ( int i = 0 ; i < n ; ++i ) { ((volatile T*)lhs)[i] += ((const volatile T*)rhs)[i]; }
484
/* 'join' function provided, single value */
485
template< class FunctorType , class ArgTag , class T >
486
struct FunctorValueJoin
490
// First substitution failure when FunctorType::join does not exist.
491
#if defined( KOKKOS_HAVE_CXX11 )
492
// Second substitution failure when enable_if( & Functor::join ) does not exist
493
, decltype( FunctorValueJoinFunction< FunctorType , ArgTag >::enable_if( & FunctorType::join ) )
495
, typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
499
KOKKOS_FORCEINLINE_FUNCTION static
500
void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
502
f.join( ArgTag() , *((volatile T *)lhs) , *((const volatile T *)rhs) );
506
/* 'join' function provided, no tag, single value */
507
template< class FunctorType , class T >
508
struct FunctorValueJoin
512
// First substitution failure when FunctorType::join does not exist.
513
#if defined( KOKKOS_HAVE_CXX11 )
514
// Second substitution failure when enable_if( & Functor::join ) does not exist
515
, decltype( FunctorValueJoinFunction< FunctorType , void >::enable_if( & FunctorType::join ) )
517
, typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
521
KOKKOS_FORCEINLINE_FUNCTION static
522
void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
524
f.join( *((volatile T *)lhs) , *((const volatile T *)rhs) );
528
/* 'join' function provided for array value */
529
template< class FunctorType , class ArgTag , class T >
530
struct FunctorValueJoin
534
// First substitution failure when FunctorType::join does not exist.
535
#if defined( KOKKOS_HAVE_CXX11 )
536
// Second substitution failure when enable_if( & Functor::join ) does not exist
537
, decltype( FunctorValueJoinFunction< FunctorType , ArgTag >::enable_if( & FunctorType::join ) )
539
, typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
543
KOKKOS_FORCEINLINE_FUNCTION static
544
void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
546
f.join( ArgTag() , (volatile T *)lhs , (const volatile T *)rhs );
550
/* 'join' function provided, no tag, array value */
551
template< class FunctorType , class T >
552
struct FunctorValueJoin
556
// First substitution failure when FunctorType::join does not exist.
557
#if defined( KOKKOS_HAVE_CXX11 )
558
// Second substitution failure when enable_if( & Functor::join ) does not exist
559
, decltype( FunctorValueJoinFunction< FunctorType , void >::enable_if( & FunctorType::join ) )
561
, typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
565
KOKKOS_FORCEINLINE_FUNCTION static
566
void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
568
f.join( (volatile T *)lhs , (const volatile T *)rhs );
573
} // namespace Kokkos
575
#ifdef KOKKOS_HAVE_CXX11
580
template<typename ValueType, class JoinOp, class Enable = void>
581
struct JoinLambdaAdapter {
582
typedef ValueType value_type;
583
const JoinOp& lambda;
584
KOKKOS_INLINE_FUNCTION
585
JoinLambdaAdapter(const JoinOp& lambda_):lambda(lambda_) {}
587
KOKKOS_INLINE_FUNCTION
588
void join(volatile value_type& dst, const volatile value_type& src) const {
592
KOKKOS_INLINE_FUNCTION
593
void join(value_type& dst, const value_type& src) const {
597
KOKKOS_INLINE_FUNCTION
598
void operator() (volatile value_type& dst, const volatile value_type& src) const {
602
KOKKOS_INLINE_FUNCTION
603
void operator() (value_type& dst, const value_type& src) const {
608
template<typename ValueType, class JoinOp>
609
struct JoinLambdaAdapter<ValueType, JoinOp, decltype( FunctorValueJoinFunction< JoinOp , void >::enable_if( & JoinOp::join ) )> {
610
typedef ValueType value_type;
611
typedef StaticAssertSame<ValueType,typename JoinOp::value_type> assert_value_types_match;
612
const JoinOp& lambda;
613
KOKKOS_INLINE_FUNCTION
614
JoinLambdaAdapter(const JoinOp& lambda_):lambda(lambda_) {}
616
KOKKOS_INLINE_FUNCTION
617
void join(volatile value_type& dst, const volatile value_type& src) const {
618
lambda.join(dst,src);
621
KOKKOS_INLINE_FUNCTION
622
void join(value_type& dst, const value_type& src) const {
623
lambda.join(dst,src);
626
KOKKOS_INLINE_FUNCTION
627
void operator() (volatile value_type& dst, const volatile value_type& src) const {
628
lambda.join(dst,src);
631
KOKKOS_INLINE_FUNCTION
632
void operator() (value_type& dst, const value_type& src) const {
633
lambda.join(dst,src);
637
template<typename ValueType>
639
typedef ValueType value_type;
641
KOKKOS_INLINE_FUNCTION
644
KOKKOS_INLINE_FUNCTION
645
void join(volatile value_type& dst, const volatile value_type& src) const {
648
KOKKOS_INLINE_FUNCTION
649
void operator() (value_type& dst, const value_type& src) const {
652
KOKKOS_INLINE_FUNCTION
653
void operator() (volatile value_type& dst, const volatile value_type& src) const {
662
//----------------------------------------------------------------------------
663
//----------------------------------------------------------------------------
668
template< class FunctorType , class ArgTag
669
, class T = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type >
670
struct FunctorValueOps ;
672
template< class FunctorType , class ArgTag , class T >
673
struct FunctorValueOps< FunctorType , ArgTag , T & >
675
KOKKOS_FORCEINLINE_FUNCTION static
676
T * pointer( T & r ) { return & r ; }
678
KOKKOS_FORCEINLINE_FUNCTION static
679
T & reference( void * p ) { return *((T*)p); }
681
KOKKOS_FORCEINLINE_FUNCTION static
682
void copy( const FunctorType & , void * const lhs , const void * const rhs )
683
{ *((T*)lhs) = *((const T*)rhs); }
686
/* No 'join' function provided, array of values */
687
template< class FunctorType , class ArgTag , class T >
688
struct FunctorValueOps< FunctorType , ArgTag , T * >
690
KOKKOS_FORCEINLINE_FUNCTION static
691
T * pointer( T * p ) { return p ; }
693
KOKKOS_FORCEINLINE_FUNCTION static
694
T * reference( void * p ) { return ((T*)p); }
696
KOKKOS_FORCEINLINE_FUNCTION static
697
void copy( const FunctorType & f , void * const lhs , const void * const rhs )
699
const int n = FunctorValueTraits<FunctorType,ArgTag>::value_count(f);
700
for ( int i = 0 ; i < n ; ++i ) { ((T*)lhs)[i] = ((const T*)rhs)[i]; }
705
} // namespace Kokkos
707
//----------------------------------------------------------------------------
708
//----------------------------------------------------------------------------
713
// Compatible functions for 'final' function and value_type not an array
714
template< class FunctorType , class ArgTag , bool IsArray = 0 == FunctorValueTraits<FunctorType,ArgTag>::StaticValueSize >
715
struct FunctorFinalFunction {
717
typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
719
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type & ) const );
720
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type & ) const );
721
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type & ) );
722
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type & ) );
723
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type & ) );
724
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type & ) );
726
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type volatile & ) const );
727
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile & ) const );
728
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type volatile & ) );
729
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile & ) );
730
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type volatile & ) );
731
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type volatile & ) );
733
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const & ) const );
734
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const & ) const );
735
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const & ) );
736
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const & ) );
737
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type const & ) );
738
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type const & ) );
740
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const volatile & ) const );
741
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile & ) const );
742
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const volatile & ) );
743
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile & ) );
744
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type const volatile & ) );
745
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type const volatile & ) );
748
// Compatible functions for 'final' function and value_type is an array
749
template< class FunctorType , class ArgTag >
750
struct FunctorFinalFunction< FunctorType , ArgTag , true > {
752
typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
754
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type * ) const );
755
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type * ) const );
756
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type * ) );
757
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type * ) );
758
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type * ) );
759
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type * ) );
761
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type volatile * ) const );
762
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile * ) const );
763
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type volatile * ) );
764
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile * ) );
765
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type volatile * ) );
766
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type volatile * ) );
768
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const * ) const );
769
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const * ) const );
770
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const * ) );
771
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const * ) );
772
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type const * ) );
773
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type const * ) );
775
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const volatile * ) const );
776
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile * ) const );
777
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , value_type const volatile * ) );
778
// KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile * ) );
779
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , value_type const volatile * ) );
780
// KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , value_type const volatile * ) );
783
template< class FunctorType >
784
struct FunctorFinalFunction< FunctorType , void , false > {
786
typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
788
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type & ) const );
789
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type & ) );
790
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( value_type & ) );
792
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type & ) const );
793
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type & ) );
794
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( const value_type & ) );
797
template< class FunctorType >
798
struct FunctorFinalFunction< FunctorType , void , true > {
800
typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
802
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type * ) const );
803
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type * ) );
804
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( value_type * ) );
806
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type * ) const );
807
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type * ) );
808
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( const value_type * ) );
811
/* No 'final' function provided */
812
template< class FunctorType , class ArgTag
813
, class ResultType = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type
814
, class Enable = void >
817
KOKKOS_FORCEINLINE_FUNCTION static
818
void final( const FunctorType & , void * ) {}
821
/* 'final' function provided */
822
template< class FunctorType , class ArgTag , class T >
827
// First substitution failure when FunctorType::final does not exist.
828
#if defined( KOKKOS_HAVE_CXX11 )
829
// Second substitution failure when enable_if( & Functor::final ) does not exist
830
, decltype( FunctorFinalFunction< FunctorType , ArgTag >::enable_if( & FunctorType::final ) )
832
, typename Impl::enable_if< 0 < sizeof( & FunctorType::final ) >::type
836
KOKKOS_FORCEINLINE_FUNCTION static
837
void final( const FunctorType & f , void * p ) { f.final( *((T*)p) ); }
839
KOKKOS_FORCEINLINE_FUNCTION static
840
void final( FunctorType & f , void * p ) { f.final( *((T*)p) ); }
843
/* 'final' function provided for array value */
844
template< class FunctorType , class ArgTag , class T >
849
// First substitution failure when FunctorType::final does not exist.
850
#if defined( KOKKOS_HAVE_CXX11 )
851
// Second substitution failure when enable_if( & Functor::final ) does not exist
852
, decltype( FunctorFinalFunction< FunctorType , ArgTag >::enable_if( & FunctorType::final ) )
854
, typename Impl::enable_if< 0 < sizeof( & FunctorType::final ) >::type
858
KOKKOS_FORCEINLINE_FUNCTION static
859
void final( const FunctorType & f , void * p ) { f.final( (T*)p ); }
861
KOKKOS_FORCEINLINE_FUNCTION static
862
void final( FunctorType & f , void * p ) { f.final( (T*)p ); }
866
} // namespace Kokkos
868
//----------------------------------------------------------------------------
869
//----------------------------------------------------------------------------
874
template< class FunctorType , class ArgTag
875
, class ReferenceType = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type >
876
struct FunctorApplyFunction {
878
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , ReferenceType ) const );
879
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , ReferenceType ) const );
880
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag , ReferenceType ) );
881
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , ReferenceType ) );
882
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag , ReferenceType ) );
883
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ArgTag const & , ReferenceType ) );
886
template< class FunctorType , class ReferenceType >
887
struct FunctorApplyFunction< FunctorType , void , ReferenceType > {
889
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ReferenceType ) const );
890
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ReferenceType ) );
891
KOKKOS_INLINE_FUNCTION static void enable_if( void ( *)( ReferenceType ) );
894
template< class FunctorType >
895
struct FunctorApplyFunction< FunctorType , void , void > {
897
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)() const );
898
KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)() );
901
template< class FunctorType , class ArgTag , class ReferenceType
902
, class Enable = void >
905
KOKKOS_FORCEINLINE_FUNCTION static
906
void apply( const FunctorType & , void * ) {}
909
/* 'apply' function provided for void value */
910
template< class FunctorType , class ArgTag >
915
// First substitution failure when FunctorType::apply does not exist.
916
#if defined( KOKKOS_HAVE_CXX11 )
917
// Second substitution failure when enable_if( & Functor::apply ) does not exist
918
, decltype( FunctorApplyFunction< FunctorType , ArgTag , void >::enable_if( & FunctorType::apply ) )
920
, typename Impl::enable_if< 0 < sizeof( & FunctorType::apply ) >::type
924
KOKKOS_FORCEINLINE_FUNCTION static
925
void apply( FunctorType & f ) { f.apply(); }
927
KOKKOS_FORCEINLINE_FUNCTION static
928
void apply( const FunctorType & f ) { f.apply(); }
931
/* 'apply' function provided for single value */
932
template< class FunctorType , class ArgTag , class T >
937
// First substitution failure when FunctorType::apply does not exist.
938
#if defined( KOKKOS_HAVE_CXX11 )
939
// Second substitution failure when enable_if( & Functor::apply ) does not exist
940
, decltype( FunctorApplyFunction< FunctorType , ArgTag >::enable_if( & FunctorType::apply ) )
942
, typename Impl::enable_if< 0 < sizeof( & FunctorType::apply ) >::type
946
KOKKOS_FORCEINLINE_FUNCTION static
947
void apply( const FunctorType & f , void * p ) { f.apply( *((T*)p) ); }
949
KOKKOS_FORCEINLINE_FUNCTION static
950
void apply( FunctorType & f , void * p ) { f.apply( *((T*)p) ); }
954
} // namespace Kokkos
956
//----------------------------------------------------------------------------
957
//----------------------------------------------------------------------------
959
#endif /* KOKKOS_FUNCTORADAPTER_HPP */