git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@13583 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2015-07-14 19:57:25 +00:00
parent 47e13d72a8
commit 61ec2f78ac
195 changed files with 68433 additions and 0 deletions

View File

@ -0,0 +1,146 @@
KOKKOS_PATH = ../..
GTEST_PATH = ../../TPL/gtest
vpath %.cpp ${KOKKOS_PATH}/core/unit_test
TEST_HEADERS = $(wildcard $(KOKKOS_PATH)/core/unit_test/*.hpp)
default: build_all
echo "End Build"
include $(KOKKOS_PATH)/Makefile.kokkos
ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1)
CXX = nvcc_wrapper
CXXFLAGS ?= -O3
LINK = $(CXX)
LDFLAGS ?= -lpthread
else
CXX ?= g++
CXXFLAGS ?= -O3
LINK ?= $(CXX)
LDFLAGS ?= -lpthread
endif
KOKKOS_CXXFLAGS += -I$(GTEST_PATH) -I${KOKKOS_PATH}/core/unit_test
TEST_TARGETS =
TARGETS =
ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1)
OBJ_CUDA = TestCuda.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_Cuda
TEST_TARGETS += test-cuda
endif
ifeq ($(KOKKOS_INTERNAL_USE_PTHREADS), 1)
OBJ_THREADS = TestThreads.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_Threads
TEST_TARGETS += test-threads
endif
ifeq ($(KOKKOS_INTERNAL_USE_OPENMP), 1)
OBJ_OPENMP = TestOpenMP.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_OpenMP
TEST_TARGETS += test-openmp
endif
ifeq ($(KOKKOS_INTERNAL_USE_SERIAL), 1)
OBJ_SERIAL = TestSerial.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_Serial
TEST_TARGETS += test-serial
endif
ifeq ($(KOKKOS_INTERNAL_USE_QTHREAD), 1)
OBJ_QTHREAD = TestQthread.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_Qthread
TEST_TARGETS += test-qthread
endif
OBJ_HWLOC = TestHWLOC.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_HWLOC
TEST_TARGETS += test-hwloc
OBJ_ALLOCATIONTRACKER = TestAllocationTracker.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_AllocationTracker
TEST_TARGETS += test-allocationtracker
OBJ_DEFAULT = TestDefaultDeviceType.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_Default
TEST_TARGETS += test-default
OBJ_DEFAULTINIT = TestDefaultDeviceTypeInit.o UnitTestMain.o gtest-all.o
TARGETS += KokkosCore_UnitTest_DefaultInit
TEST_TARGETS += test-default-init
KokkosCore_UnitTest_Cuda: $(OBJ_CUDA) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_CUDA) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_Cuda
KokkosCore_UnitTest_Threads: $(OBJ_THREADS) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_THREADS) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_Threads
KokkosCore_UnitTest_OpenMP: $(OBJ_OPENMP) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_OPENMP) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_OpenMP
KokkosCore_UnitTest_Serial: $(OBJ_SERIAL) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_SERIAL) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_Serial
KokkosCore_UnitTest_Qthread: $(OBJ_QTHREAD) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_QTHREAD) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_Qthread
KokkosCore_UnitTest_HWLOC: $(OBJ_HWLOC) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_HWLOC) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_HWLOC
KokkosCore_UnitTest_AllocationTracker: $(OBJ_ALLOCATIONTRACKER) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_ALLOCATIONTRACKER) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_AllocationTracker
KokkosCore_UnitTest_Default: $(OBJ_DEFAULT) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_DEFAULT) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_Default
KokkosCore_UnitTest_DefaultInit: $(OBJ_DEFAULTINIT) $(KOKKOS_LINK_DEPENDS)
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_DEFAULTINIT) $(KOKKOS_LIBS) $(LIB) -o KokkosCore_UnitTest_DefaultInit
test-cuda: KokkosCore_UnitTest_Cuda
./KokkosCore_UnitTest_Cuda
test-threads: KokkosCore_UnitTest_Threads
./KokkosCore_UnitTest_Threads
test-openmp: KokkosCore_UnitTest_OpenMP
./KokkosCore_UnitTest_OpenMP
test-serial: KokkosCore_UnitTest_Serial
./KokkosCore_UnitTest_Serial
test-qthread: KokkosCore_UnitTest_Qthread
./KokkosCore_UnitTest_Qthread
test-hwloc: KokkosCore_UnitTest_HWLOC
./KokkosCore_UnitTest_HWLOC
test-allocationtracker: KokkosCore_UnitTest_AllocationTracker
./KokkosCore_UnitTest_AllocationTracker
test-default: KokkosCore_UnitTest_Default
./KokkosCore_UnitTest_Default
test-default-init: KokkosCore_UnitTest_DefaultInit
./KokkosCore_UnitTest_DefaultInit
build_all: $(TARGETS)
test: $(TEST_TARGETS)
clean: kokkos-clean
rm -f *.o $(TARGETS)
# Compilation rules
%.o:%.cpp $(KOKKOS_CPP_DEPENDS) $(TEST_HEADERS)
$(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) $(EXTRA_INC) -c $<
gtest-all.o:$(GTEST_PATH)/gtest/gtest-all.cc
$(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) $(EXTRA_INC) -c $(GTEST_PATH)/gtest/gtest-all.cc

View File

@ -0,0 +1,716 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#ifndef TEST_AGGREGATE_HPP
#define TEST_AGGREGATE_HPP
#include <gtest/gtest.h>
#include <stdexcept>
#include <sstream>
#include <iostream>
/*--------------------------------------------------------------------------*/
namespace Test {
struct EmbedArray {};
struct ArrayProxyContiguous {};
struct ArrayProxyStrided {};
template< typename T , unsigned N = 0 , class Proxy = void >
struct Array ;
template< typename T >
struct Array<T,0,ArrayProxyContiguous>
{
public:
typedef T value_type ;
enum { StaticLength = 0 };
T * const value ;
const unsigned count ;
KOKKOS_INLINE_FUNCTION
Array( T * v , unsigned n ) : value(v), count(n) {}
template< class Proxy >
KOKKOS_INLINE_FUNCTION
Array & operator = ( const Array<T,0,Proxy> & rhs ) { return *this ; }
};
template< typename T , unsigned N >
struct Array<T,N,ArrayProxyContiguous>
{
public:
typedef T value_type ;
enum { StaticLength = N };
T * const value ;
KOKKOS_INLINE_FUNCTION
Array( T * v , unsigned ) : value(v) {}
template< class Proxy >
KOKKOS_INLINE_FUNCTION
Array & operator = ( const Array<T,N,Proxy> & rhs ) { return *this ; }
};
template< typename T , unsigned N >
struct Array<T,N,ArrayProxyStrided>
{
public:
typedef T value_type ;
enum { StaticLength = N };
T * const value ;
const unsigned stride ;
KOKKOS_INLINE_FUNCTION
Array( T * v , unsigned , unsigned s ) : value(v), stride(s) {}
template< class Proxy >
KOKKOS_INLINE_FUNCTION
Array & operator = ( const Array<T,N,Proxy> & rhs ) { return *this ; }
};
template< typename T >
struct Array<T,0,ArrayProxyStrided>
{
public:
typedef T value_type ;
enum { StaticLength = 0 };
T * const value ;
const unsigned count ;
const unsigned stride ;
KOKKOS_INLINE_FUNCTION
Array( T * v , unsigned n , unsigned s ) : value(v), count(n), stride(s) {}
template< class Proxy >
KOKKOS_INLINE_FUNCTION
Array & operator = ( const Array<T,0,Proxy> & rhs ) { return *this ; }
};
template< typename T >
struct Array<T,0,void>
{
public:
typedef T value_type ;
enum { StaticLength = 0 };
T * value ;
const unsigned count ;
KOKKOS_INLINE_FUNCTION
Array() : value(0) , count(0) {}
template< unsigned N , class Proxy >
KOKKOS_INLINE_FUNCTION
Array( const Array<T,N,Proxy> & rhs ) : value(rhs.value), count(N) {}
};
template< typename T , unsigned N >
struct Array<T,N,void>
{
public:
typedef T value_type ;
enum { StaticLength = N };
T value[N] ;
template< class Proxy >
KOKKOS_INLINE_FUNCTION
Array & operator = ( const Array<T,N,Proxy> & ) { return *this ; }
};
} // namespace Test
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
#if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
namespace Kokkos {
namespace Impl {
template< typename T , unsigned N >
struct AnalyzeShape< Test::Array< T , N > >
: public ShapeInsert< typename AnalyzeShape< T >::shape , N >::type
{
private:
typedef AnalyzeShape< T > nested ;
public:
typedef Test::EmbedArray specialize ;
typedef typename ShapeInsert< typename nested::shape , N >::type shape ;
typedef typename nested::array_intrinsic_type array_intrinsic_type[ N ];
typedef Test::Array< T , N > value_type ;
typedef Test::Array< T , N > type ;
typedef const array_intrinsic_type const_array_intrinsic_type ;
typedef const value_type const_value_type ;
typedef const type const_type ;
typedef typename nested::non_const_array_intrinsic_type non_const_array_intrinsic_type[ N ];
typedef Test::Array< typename nested::non_const_value_type , N > non_const_value_type ;
typedef Test::Array< typename nested::non_const_value_type , N > non_const_type ;
};
template< typename T >
struct AnalyzeShape< Test::Array< T , 0 > >
: public ShapeInsert< typename AnalyzeShape< T >::shape , 0 >::type
{
private:
typedef AnalyzeShape< T > nested ;
public:
typedef Test::EmbedArray specialize ;
typedef typename ShapeInsert< typename nested::shape , 0 >::type shape ;
typedef typename nested::array_intrinsic_type * array_intrinsic_type ;
typedef Test::Array< T , 0 > value_type ;
typedef Test::Array< T , 0 > type ;
typedef const array_intrinsic_type const_array_intrinsic_type ;
typedef const value_type const_value_type ;
typedef const type const_type ;
typedef typename nested::non_const_array_intrinsic_type * non_const_array_intrinsic_type ;
typedef Test::Array< typename nested::non_const_value_type , 0 > non_const_value_type ;
typedef Test::Array< typename nested::non_const_value_type , 0 > non_const_type ;
};
/*--------------------------------------------------------------------------*/
template< class ValueType , class MemorySpace , class MemoryTraits >
struct ViewSpecialize< ValueType
, Test::EmbedArray
, LayoutLeft
, MemorySpace
, MemoryTraits >
{ typedef Test::EmbedArray type ; };
template< class ValueType , class MemorySpace , class MemoryTraits >
struct ViewSpecialize< ValueType
, Test::EmbedArray
, LayoutRight
, MemorySpace
, MemoryTraits >
{ typedef Test::EmbedArray type ; };
/*--------------------------------------------------------------------------*/
template<>
struct ViewAssignment< Test::EmbedArray , Test::EmbedArray , void >
{
//------------------------------------
/** \brief Compatible value and shape */
template< class DT , class DL , class DD , class DM ,
class ST , class SL , class SD , class SM >
KOKKOS_INLINE_FUNCTION
ViewAssignment( View<DT,DL,DD,DM,Test::EmbedArray> & dst
, const View<ST,SL,SD,SM,Test::EmbedArray> & src
, const typename enable_if<(
ViewAssignable< ViewTraits<DT,DL,DD,DM> ,
ViewTraits<ST,SL,SD,SM> >::value
)>::type * = 0
)
{
dst.m_offset_map.assign( src.m_offset_map );
dst.m_ptr_on_device = src.m_ptr_on_device ;
dst.m_tracker = src.m_tracker;
}
};
template<>
struct ViewAssignment< ViewDefault , Test::EmbedArray , void >
{
//------------------------------------
/** \brief Compatible value and shape */
template< class ST , class SL , class SD , class SM >
KOKKOS_INLINE_FUNCTION
ViewAssignment( typename View<ST,SL,SD,SM,Test::EmbedArray>::array_type & dst
, const View<ST,SL,SD,SM,Test::EmbedArray> & src
)
{
dst.m_offset_map.assign( src.m_offset_map );
dst.m_ptr_on_device = src.m_ptr_on_device ;
dst.m_tracker = src.m_tracker;
}
};
} // namespace Impl
} // namespace Kokkos
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
namespace Kokkos {
template< class DataType ,
class Arg1Type ,
class Arg2Type ,
class Arg3Type >
class View< DataType , Arg1Type , Arg2Type , Arg3Type , Test::EmbedArray >
: public ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type >
{
public:
typedef ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type > traits ;
private:
// Assignment of compatible views requirement:
template< class , class , class , class , class > friend class View ;
// Assignment of compatible subview requirement:
template< class , class , class > friend struct Impl::ViewAssignment ;
typedef Impl::ViewOffset< typename traits::shape_type ,
typename traits::array_layout > offset_map_type ;
typedef Impl::ViewDataManagement< traits > view_data_management ;
// traits::value_type = Test::Array< T , N >
typename traits::value_type::value_type * m_ptr_on_device ;
offset_map_type m_offset_map ;
view_data_management m_management ;
Impl::AllocationTracker m_tracker ;
public:
typedef View< typename traits::array_intrinsic_type ,
typename traits::array_layout ,
typename traits::execution_space ,
typename traits::memory_traits > array_type ;
typedef View< typename traits::non_const_data_type ,
typename traits::array_layout ,
typename traits::execution_space ,
typename traits::memory_traits > non_const_type ;
typedef View< typename traits::const_data_type ,
typename traits::array_layout ,
typename traits::execution_space ,
typename traits::memory_traits > const_type ;
typedef View< typename traits::non_const_data_type ,
typename traits::array_layout ,
typename traits::host_mirror_space ,
void > HostMirror ;
//------------------------------------
// Shape
enum { Rank = traits::rank - 1 };
KOKKOS_INLINE_FUNCTION typename traits::shape_type shape() const { return m_offset_map ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_0() const { return m_offset_map.N0 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_1() const { return m_offset_map.N1 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_2() const { return m_offset_map.N2 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_3() const { return m_offset_map.N3 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_4() const { return m_offset_map.N4 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_5() const { return m_offset_map.N5 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_6() const { return m_offset_map.N6 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_7() const { return m_offset_map.N7 ; }
KOKKOS_INLINE_FUNCTION typename traits::size_type size() const
{
return m_offset_map.N0
* m_offset_map.N1
* m_offset_map.N2
* m_offset_map.N3
* m_offset_map.N4
* m_offset_map.N5
* m_offset_map.N6
* m_offset_map.N7
;
}
template< typename iType >
KOKKOS_INLINE_FUNCTION
typename traits::size_type dimension( const iType & i ) const
{ return Impl::dimension( m_offset_map , i ); }
//------------------------------------
// Destructor, constructors, assignment operators:
KOKKOS_INLINE_FUNCTION
~View() {}
KOKKOS_INLINE_FUNCTION
View()
: m_ptr_on_device(0)
, m_offset_map()
, m_management()
, m_tracker()
{ m_offset_map.assing(0,0,0,0,0,0,0,0); }
KOKKOS_INLINE_FUNCTION
View( const View & rhs )
: m_ptr_on_device(0)
, m_offset_map()
, m_management()
, m_tracker()
{
(void) Impl::ViewAssignment<
typename traits::specialize ,
typename traits::specialize >( *this , rhs );
}
KOKKOS_INLINE_FUNCTION
View & operator = ( const View & rhs )
{
(void) Impl::ViewAssignment<
typename traits::specialize ,
typename traits::specialize >( *this , rhs );
return *this ;
}
//------------------------------------
// Construct or assign compatible view:
template< class RT , class RL , class RD , class RM , class RS >
KOKKOS_INLINE_FUNCTION
View( const View<RT,RL,RD,RM,RS> & rhs )
: m_ptr_on_device(0)
, m_offset_map()
, m_management()
, m_tracker()
{
(void) Impl::ViewAssignment<
typename traits::specialize , RS >( *this , rhs );
}
template< class RT , class RL , class RD , class RM , class RS >
KOKKOS_INLINE_FUNCTION
View & operator = ( const View<RT,RL,RD,RM,RS> & rhs )
{
(void) Impl::ViewAssignment<
typename traits::specialize , RS >( *this , rhs );
return *this ;
}
//------------------------------------
// Allocation of a managed view with possible alignment padding.
template< class AllocationProperties >
explicit inline
View( const AllocationProperties & prop ,
const typename Impl::ViewAllocProp< traits , AllocationProperties >::size_type n0 = 0 ,
const size_t n1 = 0 ,
const size_t n2 = 0 ,
const size_t n3 = 0 ,
const size_t n4 = 0 ,
const size_t n5 = 0 ,
const size_t n6 = 0 ,
const size_t n7 = 0 )
: m_ptr_on_device(0)
, m_offset_map()
, m_management()
, m_tracker()
{
typedef Impl::ViewAllocProp< traits , AllocationProperties > Alloc ;
typedef typename traits::memory_space memory_space ;
typedef typename traits::value_type::value_type scalar_type ;
m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
m_offset_map.set_padding();
m_tracker = memory_space::allocate_and_track( Alloc::label( prop ), sizeof(scalar_type) * m_offset_map.capacity() );
m_ptr_on_device = reinterpret_cast<scalar_type *>(m_tracker.alloc_ptr());
(void) Impl::ViewDefaultConstruct< typename traits::execution_space , scalar_type , Alloc::Initialize >( m_ptr_on_device , m_offset_map.capacity() );
}
//------------------------------------
// Assign an unmanaged View from pointer, can be called in functors.
// No alignment padding is performed.
typedef Impl::if_c< ! traits::is_managed ,
typename traits::value_type::value_type * ,
Impl::ViewError::user_pointer_constructor_requires_unmanaged >
if_user_pointer_constructor ;
View( typename if_user_pointer_constructor::type ptr ,
const size_t n0 = 0 ,
const size_t n1 = 0 ,
const size_t n2 = 0 ,
const size_t n3 = 0 ,
const size_t n4 = 0 ,
const size_t n5 = 0 ,
const size_t n6 = 0 ,
const size_t n7 = 0 )
: m_ptr_on_device(0)
, m_offset_map()
, m_management()
, m_tracker()
{
m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
m_ptr_on_device = if_user_pointer_constructor::select( ptr );
m_management.set_unmanaged();
}
//------------------------------------
// Assign unmanaged View to portion of Device shared memory
typedef Impl::if_c< ! traits::is_managed ,
typename traits::execution_space ,
Impl::ViewError::device_shmem_constructor_requires_unmanaged >
if_device_shmem_constructor ;
explicit KOKKOS_INLINE_FUNCTION
View( typename if_device_shmem_constructor::type & dev ,
const unsigned n0 = 0 ,
const unsigned n1 = 0 ,
const unsigned n2 = 0 ,
const unsigned n3 = 0 ,
const unsigned n4 = 0 ,
const unsigned n5 = 0 ,
const unsigned n6 = 0 ,
const unsigned n7 = 0 )
: m_ptr_on_device(0)
, m_offset_map()
, m_management()
, m_tracker()
{
typedef typename traits::value_type::value_type scalar_type ;
enum { align = 8 };
enum { mask = align - 1 };
typedef Impl::if_c< ! traits::is_managed ,
scalar_type * ,
Impl::ViewError::device_shmem_constructor_requires_unmanaged >
if_device_shmem_pointer ;
m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
// Select the first argument:
m_ptr_on_device = if_device_shmem_pointer::select(
(scalar_type *) dev.get_shmem( unsigned( sizeof(scalar_type) * m_offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ) );
}
static inline
unsigned shmem_size( const unsigned n0 = 0 ,
const unsigned n1 = 0 ,
const unsigned n2 = 0 ,
const unsigned n3 = 0 ,
const unsigned n4 = 0 ,
const unsigned n5 = 0 ,
const unsigned n6 = 0 ,
const unsigned n7 = 0 )
{
enum { align = 8 };
enum { mask = align - 1 };
typedef typename traits::value_type::value_type scalar_type ;
offset_map_type offset_map ;
offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
return unsigned( sizeof(scalar_type) * offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ;
}
//------------------------------------
// Is not allocated
KOKKOS_INLINE_FUNCTION
bool is_null() const { return 0 == m_ptr_on_device ; }
//------------------------------------
// LayoutLeft, rank 2:
typedef Test::Array< typename traits::value_type::value_type ,
traits::value_type::StaticLength ,
Test::ArrayProxyStrided > LeftValue ;
template< typename iType0 >
KOKKOS_INLINE_FUNCTION
typename Impl::ViewEnableArrayOper< LeftValue , traits, LayoutLeft, 2, iType0 >::type
operator[] ( const iType0 & i0 ) const
{
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0, 0 );
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , m_ptr_on_device );
return LeftValue( m_ptr_on_device + i0 , m_offset_map.N1 , m_offset_map.S0 );
}
template< typename iType0 >
KOKKOS_INLINE_FUNCTION
typename Impl::ViewEnableArrayOper< LeftValue , traits, LayoutLeft, 2, iType0 >::type
operator() ( const iType0 & i0 ) const
{
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0, 0 );
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , m_ptr_on_device );
return LeftValue( m_ptr_on_device + i0 , m_offset_map.N1 , m_offset_map.S0 );
}
template< typename iType0 >
KOKKOS_INLINE_FUNCTION
typename Impl::ViewEnableArrayOper< LeftValue , traits, LayoutLeft, 2, iType0 >::type
at( const iType0 & i0 , const int , const int , const int ,
const int , const int , const int , const int ) const
{
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0, 0 );
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , m_ptr_on_device );
return LeftValue( m_ptr_on_device + i0 , m_offset_map.N1 , m_offset_map.S0 );
}
//------------------------------------
// LayoutRight, rank 2:
typedef Test::Array< typename traits::value_type::value_type ,
traits::value_type::StaticLength ,
Test::ArrayProxyContiguous > RightValue ;
template< typename iType0 >
KOKKOS_INLINE_FUNCTION
typename Impl::ViewEnableArrayOper< RightValue , traits, LayoutRight, 2, iType0 >::type
operator[] ( const iType0 & i0 ) const
{
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0, 0 );
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , m_ptr_on_device );
return RightValue( m_ptr_on_device + i0 , m_offset_map.N1 );
}
template< typename iType0 >
KOKKOS_INLINE_FUNCTION
typename Impl::ViewEnableArrayOper< RightValue , traits, LayoutRight, 2, iType0 >::type
operator() ( const iType0 & i0 ) const
{
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0, 0 );
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , m_ptr_on_device );
return RightValue( m_ptr_on_device + i0 , m_offset_map.N1 );
}
template< typename iType0 >
KOKKOS_INLINE_FUNCTION
typename Impl::ViewEnableArrayOper< RightValue , traits, LayoutRight, 2, iType0 >::type
at( const iType0 & i0 , const int , const int , const int ,
const int , const int , const int , const int ) const
{
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0, 0 );
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , m_ptr_on_device );
return RightValue( m_ptr_on_device + i0 , m_offset_map.N1 );
}
//------------------------------------
// Access to the underlying contiguous storage of this view specialization.
// These methods are specific to specialization of a view.
KOKKOS_INLINE_FUNCTION
typename traits::value_type::value_type * ptr_on_device() const { return m_ptr_on_device ; }
// Stride of physical storage, dimensioned to at least Rank
template< typename iType >
KOKKOS_INLINE_FUNCTION
void stride( iType * const s ) const
{ m_offset_map.stride( s ); }
// Count of contiguously allocated data members including padding.
KOKKOS_INLINE_FUNCTION
typename traits::size_type capacity() const
{ return m_offset_map.capacity(); }
};
} // namespace Kokkos
#endif /* #if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW ) */
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
namespace Test {
template< class DeviceType >
int TestViewAggregate()
{
#if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
typedef Kokkos::View< Test::Array<double,32> * , DeviceType > a32_type ;
typedef typename a32_type::array_type a32_base_type ;
typedef Kokkos::View< Test::Array<double> * , DeviceType > a0_type ;
typedef typename a0_type::array_type a0_base_type ;
a32_type a32("a32",100);
a32_base_type a32_base ;
a0_type a0("a0",100,32);
a0_base_type a0_base ;
a32_base = a32 ;
a0_base = a0 ;
#endif /* #if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW ) */
return 0 ;
}
}
#endif /* #ifndef TEST_AGGREGATE_HPP */

View File

@ -0,0 +1,189 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#ifndef TEST_AGGREGATE_REDUCTION_HPP
#define TEST_AGGREGATE_REDUCTION_HPP
#include <gtest/gtest.h>
#include <stdexcept>
#include <sstream>
#include <iostream>
namespace Test {
template< typename T , unsigned N >
struct StaticArray {
T value[N] ;
KOKKOS_INLINE_FUNCTION
StaticArray()
{ for ( unsigned i = 0 ; i < N ; ++i ) value[i] = T(); }
KOKKOS_INLINE_FUNCTION
StaticArray( const StaticArray & rhs )
{ for ( unsigned i = 0 ; i < N ; ++i ) value[i] = rhs.value[i]; }
KOKKOS_INLINE_FUNCTION
operator T () { return value[0]; }
KOKKOS_INLINE_FUNCTION
StaticArray & operator = ( const T & rhs )
{
for ( unsigned i = 0 ; i < N ; ++i ) value[i] = rhs ;
return *this ;
}
KOKKOS_INLINE_FUNCTION
StaticArray & operator = ( const StaticArray & rhs )
{
for ( unsigned i = 0 ; i < N ; ++i ) value[i] = rhs.value[i] ;
return *this ;
}
KOKKOS_INLINE_FUNCTION
StaticArray operator * ( const StaticArray & rhs )
{
StaticArray tmp ;
for ( unsigned i = 0 ; i < N ; ++i ) tmp.value[i] = value[i] * rhs.value[i] ;
return tmp ;
}
KOKKOS_INLINE_FUNCTION
StaticArray operator + ( const StaticArray & rhs )
{
StaticArray tmp ;
for ( unsigned i = 0 ; i < N ; ++i ) tmp.value[i] = value[i] + rhs.value[i] ;
return tmp ;
}
KOKKOS_INLINE_FUNCTION
StaticArray & operator += ( const StaticArray & rhs )
{
for ( unsigned i = 0 ; i < N ; ++i ) value[i] += rhs.value[i] ;
return *this ;
}
KOKKOS_INLINE_FUNCTION
void operator += ( const volatile StaticArray & rhs ) volatile
{
for ( unsigned i = 0 ; i < N ; ++i ) value[i] += rhs.value[i] ;
}
};
template< typename T , class Space >
struct DOT {
typedef T value_type ;
typedef Space execution_space ;
Kokkos::View< value_type * , Space > a ;
Kokkos::View< value_type * , Space > b ;
DOT( const Kokkos::View< value_type * , Space > arg_a
, const Kokkos::View< value_type * , Space > arg_b
)
: a( arg_a ), b( arg_b ) {}
KOKKOS_INLINE_FUNCTION
void operator()( const int i , value_type & update ) const
{
update += a(i) * b(i);
}
};
template< typename T , class Space >
struct FILL {
typedef T value_type ;
typedef Space execution_space ;
Kokkos::View< value_type * , Space > a ;
Kokkos::View< value_type * , Space > b ;
FILL( const Kokkos::View< value_type * , Space > & arg_a
, const Kokkos::View< value_type * , Space > & arg_b
)
: a( arg_a ), b( arg_b ) {}
KOKKOS_INLINE_FUNCTION
void operator()( const int i ) const
{
a(i) = i % 2 ? i + 1 : 1 ;
b(i) = i % 2 ? 1 : i + 1 ;
}
};
template< class Space >
void TestViewAggregateReduction()
{
const int count = 2 ;
const long result = count % 2 ? ( count * ( ( count + 1 ) / 2 ) )
: ( ( count / 2 ) * ( count + 1 ) );
Kokkos::View< long * , Space > a("a",count);
Kokkos::View< long * , Space > b("b",count);
Kokkos::View< StaticArray<long,4> * , Space > a4("a4",count);
Kokkos::View< StaticArray<long,4> * , Space > b4("b4",count);
Kokkos::View< StaticArray<long,10> * , Space > a10("a10",count);
Kokkos::View< StaticArray<long,10> * , Space > b10("b10",count);
Kokkos::parallel_for( count , FILL<long,Space>(a,b) );
Kokkos::parallel_for( count , FILL< StaticArray<long,4> , Space >(a4,b4) );
Kokkos::parallel_for( count , FILL< StaticArray<long,10> , Space >(a10,b10) );
long r = 0;
StaticArray<long,4> r4 ;
StaticArray<long,10> r10 ;
Kokkos::parallel_reduce( count , DOT<long,Space>(a,b) , r );
Kokkos::parallel_reduce( count , DOT< StaticArray<long,4> , Space >(a4,b4) , r4 );
Kokkos::parallel_reduce( count , DOT< StaticArray<long,10> , Space >(a10,b10) , r10 );
ASSERT_EQ( result , r );
for ( int i = 0 ; i < 10 ; ++i ) { ASSERT_EQ( result , r10.value[i] ); }
for ( int i = 0 ; i < 4 ; ++i ) { ASSERT_EQ( result , r4.value[i] ); }
}
}
#endif /* #ifndef TEST_AGGREGATE_REDUCTION_HPP */

View File

@ -0,0 +1,145 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <iostream>
#include <vector>
#include <Kokkos_Core.hpp>
#include <impl/Kokkos_AllocationTracker.hpp>
#include <impl/Kokkos_BasicAllocators.hpp>
namespace Test {
class alocation_tracker : public ::testing::Test {
protected:
static void SetUpTestCase()
{
Kokkos::initialize();
}
static void TearDownTestCase()
{
Kokkos::finalize();
}
};
TEST_F( alocation_tracker, simple)
{
using namespace Kokkos::Impl;
{
AllocationTracker tracker;
EXPECT_FALSE( tracker.is_valid() );
}
// test ref count and label
{
int size = 100;
std::vector<AllocationTracker> trackers(size);
trackers[0] = AllocationTracker( MallocAllocator(), 128,"Test");
for (int i=0; i<size; ++i) {
trackers[i] = trackers[0];
}
EXPECT_EQ(100u, trackers[0].ref_count());
EXPECT_EQ(std::string("Test"), std::string(trackers[0].label()));
}
// test circular list
{
int num_allocs = 3000;
unsigned ref_count = 100;
std::vector<AllocationTracker> trackers(num_allocs);
for (int i=0; i<num_allocs; ++i) {
trackers[i] = AllocationTracker( MallocAllocator(), 128, "Test");
std::vector<AllocationTracker> ref_trackers(ref_count);
for (unsigned j=0; j<ref_count; ++j) {
ref_trackers[j] = trackers[i];
}
EXPECT_EQ( ref_count + 1u, trackers[i].ref_count() );
}
for (int i=0; i<num_allocs; ++i) {
EXPECT_EQ( 1u, trackers[i].ref_count() );
}
}
}
TEST_F( alocation_tracker, force_leaks)
{
// uncomment to force memory leaks
#if 0
using namespace Kokkos::Impl;
Kokkos::kokkos_malloc("Forced Leak", 4096*10);
Kokkos::kokkos_malloc<Kokkos::HostSpace>("Forced Leak", 4096*10);
#endif
}
TEST_F( alocation_tracker, disable_reference_counting)
{
using namespace Kokkos::Impl;
// test ref count and label
{
int size = 100;
std::vector<AllocationTracker> trackers(size);
trackers[0] = AllocationTracker( MallocAllocator(), 128,"Test");
for (int i=1; i<size; ++i) {
trackers[i] = CopyWithoutTracking::apply(trackers[0]);
}
EXPECT_EQ(1u, trackers[0].ref_count());
EXPECT_EQ(std::string("Test"), std::string(trackers[0].label()));
}
}
} // namespace Test

View File

@ -0,0 +1,376 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
namespace TestAtomic {
// Struct for testing arbitrary size atomics
template<int N>
struct SuperScalar {
double val[N];
KOKKOS_INLINE_FUNCTION
SuperScalar() {
for(int i=0; i<N; i++)
val[i] = 0.0;
}
KOKKOS_INLINE_FUNCTION
SuperScalar(const SuperScalar& src) {
for(int i=0; i<N; i++)
val[i] = src.val[i];
}
KOKKOS_INLINE_FUNCTION
SuperScalar(const volatile SuperScalar& src) {
for(int i=0; i<N; i++)
val[i] = src.val[i];
}
KOKKOS_INLINE_FUNCTION
SuperScalar& operator = (const SuperScalar& src) {
for(int i=0; i<N; i++)
val[i] = src.val[i];
return *this;
}
KOKKOS_INLINE_FUNCTION
SuperScalar& operator = (const volatile SuperScalar& src) {
for(int i=0; i<N; i++)
val[i] = src.val[i];
return *this;
}
KOKKOS_INLINE_FUNCTION
volatile SuperScalar& operator = (const SuperScalar& src) volatile {
for(int i=0; i<N; i++)
val[i] = src.val[i];
return *this;
}
KOKKOS_INLINE_FUNCTION
SuperScalar operator + (const SuperScalar& src) {
SuperScalar tmp = *this;
for(int i=0; i<N; i++)
tmp.val[i] += src.val[i];
return tmp;
}
KOKKOS_INLINE_FUNCTION
SuperScalar& operator += (const double& src) {
for(int i=0; i<N; i++)
val[i] += 1.0*(i+1)*src;
return *this;
}
KOKKOS_INLINE_FUNCTION
SuperScalar& operator += (const SuperScalar& src) {
for(int i=0; i<N; i++)
val[i] += src.val[i];
return *this;
}
KOKKOS_INLINE_FUNCTION
bool operator == (const SuperScalar& src) {
bool compare = true;
for(int i=0; i<N; i++)
compare = compare && ( val[i] == src.val[i]);
return compare;
}
KOKKOS_INLINE_FUNCTION
bool operator != (const SuperScalar& src) {
bool compare = true;
for(int i=0; i<N; i++)
compare = compare && ( val[i] == src.val[i]);
return !compare;
}
KOKKOS_INLINE_FUNCTION
SuperScalar(const double& src) {
for(int i=0; i<N; i++)
val[i] = 1.0 * (i+1) * src;
}
};
template<int N>
std::ostream& operator<<(std::ostream& os, const SuperScalar<N>& dt)
{
os << "{ ";
for(int i=0;i<N-1;i++)
os << dt.val[i] << ", ";
os << dt.val[N-1] << "}";
return os;
}
template<class T,class DEVICE_TYPE>
struct ZeroFunctor {
typedef DEVICE_TYPE execution_space;
typedef typename Kokkos::View<T,execution_space> type;
typedef typename Kokkos::View<T,execution_space>::HostMirror h_type;
type data;
KOKKOS_INLINE_FUNCTION
void operator()(int) const {
data() = 0;
}
};
//---------------------------------------------------
//--------------atomic_fetch_add---------------------
//---------------------------------------------------
template<class T,class DEVICE_TYPE>
struct AddFunctor{
typedef DEVICE_TYPE execution_space;
typedef Kokkos::View<T,execution_space> type;
type data;
KOKKOS_INLINE_FUNCTION
void operator()(int) const {
Kokkos::atomic_fetch_add(&data(),(T)1);
}
};
template<class T, class execution_space >
T AddLoop(int loop) {
struct ZeroFunctor<T,execution_space> f_zero;
typename ZeroFunctor<T,execution_space>::type data("Data");
typename ZeroFunctor<T,execution_space>::h_type h_data("HData");
f_zero.data = data;
Kokkos::parallel_for(1,f_zero);
execution_space::fence();
struct AddFunctor<T,execution_space> f_add;
f_add.data = data;
Kokkos::parallel_for(loop,f_add);
execution_space::fence();
Kokkos::deep_copy(h_data,data);
T val = h_data();
return val;
}
template<class T>
T AddLoopSerial(int loop) {
T* data = new T[1];
data[0] = 0;
for(int i=0;i<loop;i++)
*data+=(T)1;
T val = *data;
delete data;
return val;
}
template<class T,class DEVICE_TYPE>
struct CASFunctor{
typedef DEVICE_TYPE execution_space;
typedef Kokkos::View<T,execution_space> type;
type data;
KOKKOS_INLINE_FUNCTION
void operator()(int) const {
T old = data();
T newval, assumed;
do {
assumed = old;
newval = assumed + (T)1;
old = Kokkos::atomic_compare_exchange(&data(), assumed, newval);
}
while( old != assumed );
}
};
template<class T, class execution_space >
T CASLoop(int loop) {
struct ZeroFunctor<T,execution_space> f_zero;
typename ZeroFunctor<T,execution_space>::type data("Data");
typename ZeroFunctor<T,execution_space>::h_type h_data("HData");
f_zero.data = data;
Kokkos::parallel_for(1,f_zero);
execution_space::fence();
struct CASFunctor<T,execution_space> f_cas;
f_cas.data = data;
Kokkos::parallel_for(loop,f_cas);
execution_space::fence();
Kokkos::deep_copy(h_data,data);
T val = h_data();
return val;
}
template<class T>
T CASLoopSerial(int loop) {
T* data = new T[1];
data[0] = 0;
for(int i=0;i<loop;i++) {
T assumed;
T newval;
T old;
do {
assumed = *data;
newval = assumed + (T)1;
old = *data;
*data = newval;
}
while(!(assumed==old));
}
T val = *data;
delete data;
return val;
}
template<class T,class DEVICE_TYPE>
struct ExchFunctor{
typedef DEVICE_TYPE execution_space;
typedef Kokkos::View<T,execution_space> type;
type data, data2;
KOKKOS_INLINE_FUNCTION
void operator()(int i) const {
T old = Kokkos::atomic_exchange(&data(),(T)i);
Kokkos::atomic_fetch_add(&data2(),old);
}
};
template<class T, class execution_space >
T ExchLoop(int loop) {
struct ZeroFunctor<T,execution_space> f_zero;
typename ZeroFunctor<T,execution_space>::type data("Data");
typename ZeroFunctor<T,execution_space>::h_type h_data("HData");
f_zero.data = data;
Kokkos::parallel_for(1,f_zero);
execution_space::fence();
typename ZeroFunctor<T,execution_space>::type data2("Data");
typename ZeroFunctor<T,execution_space>::h_type h_data2("HData");
f_zero.data = data2;
Kokkos::parallel_for(1,f_zero);
execution_space::fence();
struct ExchFunctor<T,execution_space> f_exch;
f_exch.data = data;
f_exch.data2 = data2;
Kokkos::parallel_for(loop,f_exch);
execution_space::fence();
Kokkos::deep_copy(h_data,data);
Kokkos::deep_copy(h_data2,data2);
T val = h_data() + h_data2();
return val;
}
template<class T>
T ExchLoopSerial(int loop) {
T* data = new T[1];
T* data2 = new T[1];
data[0] = 0;
data2[0] = 0;
for(int i=0;i<loop;i++) {
T old = *data;
*data=(T) i;
*data2+=old;
}
T val = *data2 + *data;
delete data;
delete data2;
return val;
}
template<class T, class DeviceType >
T LoopVariant(int loop, int test) {
switch (test) {
case 1: return AddLoop<T,DeviceType>(loop);
case 2: return CASLoop<T,DeviceType>(loop);
case 3: return ExchLoop<T,DeviceType>(loop);
}
return 0;
}
template<class T>
T LoopVariantSerial(int loop, int test) {
switch (test) {
case 1: return AddLoopSerial<T>(loop);
case 2: return CASLoopSerial<T>(loop);
case 3: return ExchLoopSerial<T>(loop);
}
return 0;
}
template<class T,class DeviceType>
bool Loop(int loop, int test)
{
T res = LoopVariant<T,DeviceType>(loop,test);
T resSerial = LoopVariantSerial<T>(loop,test);
bool passed = true;
if ( resSerial != res ) {
passed = false;
std::cout << "Loop<"
<< typeid(T).name()
<< ">( test = "
<< test << " FAILED : "
<< resSerial << " != " << res
<< std::endl ;
}
return passed ;
}
}

View File

@ -0,0 +1,319 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
namespace TestCXX11 {
template<class DeviceType>
struct FunctorAddTest{
typedef Kokkos::View<double**,DeviceType> view_type;
view_type a_, b_;
typedef DeviceType execution_space;
FunctorAddTest(view_type & a, view_type &b):a_(a),b_(b) {}
void operator() (const int& i) const {
b_(i,0) = a_(i,1) + a_(i,2);
b_(i,1) = a_(i,0) - a_(i,3);
b_(i,2) = a_(i,4) + a_(i,0);
b_(i,3) = a_(i,2) - a_(i,1);
b_(i,4) = a_(i,3) + a_(i,4);
}
typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ;
void operator() (const team_member & dev) const {
int i = dev.league_rank()*dev.team_size() + dev.team_rank();
b_(i,0) = a_(i,1) + a_(i,2);
b_(i,1) = a_(i,0) - a_(i,3);
b_(i,2) = a_(i,4) + a_(i,0);
b_(i,3) = a_(i,2) - a_(i,1);
b_(i,4) = a_(i,3) + a_(i,4);
}
};
template<class DeviceType, bool PWRTest>
double AddTestFunctor() {
typedef Kokkos::TeamPolicy<DeviceType> policy_type ;
Kokkos::View<double**,DeviceType> a("A",100,5);
Kokkos::View<double**,DeviceType> b("B",100,5);
typename Kokkos::View<double**,DeviceType>::HostMirror h_a = Kokkos::create_mirror_view(a);
typename Kokkos::View<double**,DeviceType>::HostMirror h_b = Kokkos::create_mirror_view(b);
for(int i=0;i<100;i++) {
for(int j=0;j<5;j++)
h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j;
}
Kokkos::deep_copy(a,h_a);
if(PWRTest==false)
Kokkos::parallel_for(100,FunctorAddTest<DeviceType>(a,b));
else
Kokkos::parallel_for(policy_type(25,4),FunctorAddTest<DeviceType>(a,b));
Kokkos::deep_copy(h_b,b);
double result = 0;
for(int i=0;i<100;i++) {
for(int j=0;j<5;j++)
result += h_b(i,j);
}
return result;
}
#if defined (KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA)
template<class DeviceType, bool PWRTest>
double AddTestLambda() {
typedef Kokkos::TeamPolicy<DeviceType> policy_type ;
Kokkos::View<double**,DeviceType> a("A",100,5);
Kokkos::View<double**,DeviceType> b("B",100,5);
typename Kokkos::View<double**,DeviceType>::HostMirror h_a = Kokkos::create_mirror_view(a);
typename Kokkos::View<double**,DeviceType>::HostMirror h_b = Kokkos::create_mirror_view(b);
for(int i=0;i<100;i++) {
for(int j=0;j<5;j++)
h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j;
}
Kokkos::deep_copy(a,h_a);
if(PWRTest==false) {
Kokkos::parallel_for(100,[=](const int& i) {
b(i,0) = a(i,1) + a(i,2);
b(i,1) = a(i,0) - a(i,3);
b(i,2) = a(i,4) + a(i,0);
b(i,3) = a(i,2) - a(i,1);
b(i,4) = a(i,3) + a(i,4);
});
} else {
typedef typename policy_type::member_type team_member ;
Kokkos::parallel_for(policy_type(25,4),[=](const team_member & dev) {
int i = dev.league_rank()*dev.team_size() + dev.team_rank();
b(i,0) = a(i,1) + a(i,2);
b(i,1) = a(i,0) - a(i,3);
b(i,2) = a(i,4) + a(i,0);
b(i,3) = a(i,2) - a(i,1);
b(i,4) = a(i,3) + a(i,4);
});
}
Kokkos::deep_copy(h_b,b);
double result = 0;
for(int i=0;i<100;i++) {
for(int j=0;j<5;j++)
result += h_b(i,j);
}
return result;
}
#else
template<class DeviceType, bool PWRTest>
double AddTestLambda() {
return AddTestFunctor<DeviceType,PWRTest>();
}
#endif
template<class DeviceType>
struct FunctorReduceTest{
typedef Kokkos::View<double**,DeviceType> view_type;
view_type a_;
typedef DeviceType execution_space;
typedef double value_type;
FunctorReduceTest(view_type & a):a_(a) {}
KOKKOS_INLINE_FUNCTION
void operator() (const int& i, value_type& sum) const {
sum += a_(i,1) + a_(i,2);
sum += a_(i,0) - a_(i,3);
sum += a_(i,4) + a_(i,0);
sum += a_(i,2) - a_(i,1);
sum += a_(i,3) + a_(i,4);
}
typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ;
KOKKOS_INLINE_FUNCTION
void operator() (const team_member & dev, value_type& sum) const {
int i = dev.league_rank()*dev.team_size() + dev.team_rank();
sum += a_(i,1) + a_(i,2);
sum += a_(i,0) - a_(i,3);
sum += a_(i,4) + a_(i,0);
sum += a_(i,2) - a_(i,1);
sum += a_(i,3) + a_(i,4);
}
KOKKOS_INLINE_FUNCTION
void init(value_type& update) const {update = 0.0;}
KOKKOS_INLINE_FUNCTION
void join(volatile value_type& update, volatile value_type const& input) const {update += input;}
};
template<class DeviceType, bool PWRTest>
double ReduceTestFunctor() {
typedef Kokkos::TeamPolicy<DeviceType> policy_type ;
typedef Kokkos::View<double**,DeviceType> view_type ;
typedef Kokkos::View<double,typename view_type::host_mirror_space,Kokkos::MemoryUnmanaged> unmanaged_result ;
view_type a("A",100,5);
typename view_type::HostMirror h_a = Kokkos::create_mirror_view(a);
for(int i=0;i<100;i++) {
for(int j=0;j<5;j++)
h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j;
}
Kokkos::deep_copy(a,h_a);
double result = 0.0;
if(PWRTest==false)
Kokkos::parallel_reduce(100,FunctorReduceTest<DeviceType>(a), unmanaged_result( & result ));
else
Kokkos::parallel_reduce(policy_type(25,4),FunctorReduceTest<DeviceType>(a), unmanaged_result( & result ));
return result;
}
#if defined (KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA)
template<class DeviceType, bool PWRTest>
double ReduceTestLambda() {
typedef Kokkos::TeamPolicy<DeviceType> policy_type ;
typedef Kokkos::View<double**,DeviceType> view_type ;
typedef Kokkos::View<double,typename view_type::host_mirror_space,Kokkos::MemoryUnmanaged> unmanaged_result ;
view_type a("A",100,5);
typename view_type::HostMirror h_a = Kokkos::create_mirror_view(a);
for(int i=0;i<100;i++) {
for(int j=0;j<5;j++)
h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j;
}
Kokkos::deep_copy(a,h_a);
double result = 0.0;
if(PWRTest==false) {
Kokkos::parallel_reduce(100,[=](const int& i, double& sum) {
sum += a(i,1) + a(i,2);
sum += a(i,0) - a(i,3);
sum += a(i,4) + a(i,0);
sum += a(i,2) - a(i,1);
sum += a(i,3) + a(i,4);
}, unmanaged_result( & result ) );
} else {
typedef typename policy_type::member_type team_member ;
Kokkos::parallel_reduce(policy_type(25,4),[=](const team_member & dev, double& sum) {
int i = dev.league_rank()*dev.team_size() + dev.team_rank();
sum += a(i,1) + a(i,2);
sum += a(i,0) - a(i,3);
sum += a(i,4) + a(i,0);
sum += a(i,2) - a(i,1);
sum += a(i,3) + a(i,4);
}, unmanaged_result( & result ) );
}
return result;
}
#else
template<class DeviceType, bool PWRTest>
double ReduceTestLambda() {
return ReduceTestFunctor<DeviceType,PWRTest>();
}
#endif
template<class DeviceType>
double TestVariantLambda(int test) {
switch (test) {
case 1: return AddTestLambda<DeviceType,false>();
case 2: return AddTestLambda<DeviceType,true>();
case 3: return ReduceTestLambda<DeviceType,false>();
case 4: return ReduceTestLambda<DeviceType,true>();
}
return 0;
}
template<class DeviceType>
double TestVariantFunctor(int test) {
switch (test) {
case 1: return AddTestFunctor<DeviceType,false>();
case 2: return AddTestFunctor<DeviceType,true>();
case 3: return ReduceTestFunctor<DeviceType,false>();
case 4: return ReduceTestFunctor<DeviceType,true>();
}
return 0;
}
template<class DeviceType>
bool Test(int test) {
#ifdef KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA
double res_functor = TestVariantFunctor<DeviceType>(test);
double res_lambda = TestVariantLambda<DeviceType>(test);
char testnames[5][256] = {" "
,"AddTest","AddTest TeamPolicy"
,"ReduceTest","ReduceTest TeamPolicy"
};
bool passed = true;
if ( res_functor != res_lambda ) {
passed = false;
std::cout << "CXX11 ( test = '"
<< testnames[test] << "' FAILED : "
<< res_functor << " != " << res_lambda
<< std::endl ;
}
return passed ;
#else
return true;
#endif
}
}

View File

@ -0,0 +1,103 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
#ifndef TESTCXX11DEDUCTION_HPP
#define TESTCXX11DEDUCTION_HPP
namespace TestCXX11 {
#if defined( KOKKOS_HAVE_CXX11 )
struct TestReductionDeductionTagA {};
struct TestReductionDeductionTagB {};
template < class ExecSpace >
struct TestReductionDeductionFunctor {
// KOKKOS_INLINE_FUNCTION
// void operator()( long i , long & value ) const
// { value += i + 1 ; }
KOKKOS_INLINE_FUNCTION
void operator()( TestReductionDeductionTagA , long i , long & value ) const
{ value += ( 2 * i + 1 ) + ( 2 * i + 2 ); }
KOKKOS_INLINE_FUNCTION
void operator()( const TestReductionDeductionTagB & , const long i , long & value ) const
{ value += ( 3 * i + 1 ) + ( 3 * i + 2 ) + ( 3 * i + 3 ) ; }
};
template< class ExecSpace >
void test_reduction_deduction()
{
typedef TestReductionDeductionFunctor< ExecSpace > Functor ;
const long N = 50 ;
// const long answer = N % 2 ? ( N * ((N+1)/2 )) : ( (N/2) * (N+1) );
const long answerA = N % 2 ? ( (2*N) * (((2*N)+1)/2 )) : ( ((2*N)/2) * ((2*N)+1) );
const long answerB = N % 2 ? ( (3*N) * (((3*N)+1)/2 )) : ( ((3*N)/2) * ((3*N)+1) );
long result = 0 ;
// Kokkos::parallel_reduce( Kokkos::RangePolicy<ExecSpace>(0,N) , Functor() , result );
// ASSERT_EQ( answer , result );
Kokkos::parallel_reduce( Kokkos::RangePolicy<ExecSpace,TestReductionDeductionTagA>(0,N) , Functor() , result );
ASSERT_EQ( answerA , result );
Kokkos::parallel_reduce( Kokkos::RangePolicy<ExecSpace,TestReductionDeductionTagB>(0,N) , Functor() , result );
ASSERT_EQ( answerB , result );
}
#else /* ! defined( KOKKOS_HAVE_CXX11 ) */
template< class ExecSpace >
void test_reduction_deduction() {}
#endif /* ! defined( KOKKOS_HAVE_CXX11 ) */
}
#endif

View File

@ -0,0 +1,93 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
#define KOKKOS_PRAGMA_UNROLL(a)
namespace TestCompilerMacros {
template<class DEVICE_TYPE>
struct AddFunctor {
typedef DEVICE_TYPE execution_space;
typedef typename Kokkos::View<int**,execution_space> type;
type a,b;
int length;
AddFunctor(type a_, type b_):a(a_),b(b_),length(a.dimension_1()) {}
KOKKOS_INLINE_FUNCTION
void operator()(int i) const {
#ifdef KOKKOS_HAVE_PRAGMA_UNROLL
#pragma unroll
#endif
#ifdef KOKKOS_HAVE_PRAGMA_IVDEP
#pragma ivdep
#endif
#ifdef KOKKOS_HAVE_PRAGMA_VECTOR
#pragma vector always
#endif
#ifdef KOKKOS_HAVE_PRAGMA_LOOPCOUNT
#pragma loop count(128)
#endif
#ifdef KOKKOS_HAVE_PRAGMA_SIMD
#pragma simd
#endif
for(int j=0;j<length;j++)
a(i,j) += b(i,j);
}
};
template<class DeviceType>
bool Test() {
typedef typename Kokkos::View<int**,DeviceType> type;
type a("A",1024,128);
type b("B",1024,128);
AddFunctor<DeviceType> f(a,b);
Kokkos::parallel_for(1024,f);
DeviceType::fence();
return true;
}
}

View File

@ -0,0 +1,495 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <iostream>
#include <Kokkos_Core.hpp>
//----------------------------------------------------------------------------
#include <impl/Kokkos_ViewTileLeft.hpp>
//----------------------------------------------------------------------------
#include <TestSharedAlloc.hpp>
#include <TestViewMapping.hpp>
#include <TestViewImpl.hpp>
#include <TestAtomic.hpp>
#include <TestViewAPI.hpp>
#include <TestViewSubview.hpp>
#include <TestTile.hpp>
#include <TestReduce.hpp>
#include <TestScan.hpp>
#include <TestRange.hpp>
#include <TestTeam.hpp>
#include <TestAggregate.hpp>
#include <TestAggregateReduction.hpp>
#include <TestCompilerMacros.hpp>
#include <TestMemorySpaceTracking.hpp>
#include <TestTeamVector.hpp>
#include <TestTemplateMetaFunctions.hpp>
#include <TestCXX11Deduction.hpp>
//----------------------------------------------------------------------------
class cuda : public ::testing::Test {
protected:
static void SetUpTestCase()
{
Kokkos::Cuda::print_configuration( std::cout );
Kokkos::HostSpace::execution_space::initialize();
Kokkos::Cuda::initialize( Kokkos::Cuda::SelectDevice(0) );
}
static void TearDownTestCase()
{
Kokkos::Cuda::finalize();
Kokkos::HostSpace::execution_space::finalize();
}
};
//----------------------------------------------------------------------------
namespace Test {
__global__
void test_abort()
{
Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<
Kokkos::CudaSpace ,
Kokkos::HostSpace >::verify();
}
__global__
void test_cuda_spaces_int_value( int * ptr )
{
if ( *ptr == 42 ) { *ptr = 2 * 42 ; }
}
TEST_F( cuda , compiler_macros )
{
ASSERT_TRUE( ( TestCompilerMacros::Test< Kokkos::Cuda >() ) );
}
TEST_F( cuda , memory_space )
{
TestMemorySpace< Kokkos::Cuda >();
}
TEST_F( cuda, spaces )
{
if ( Kokkos::CudaUVMSpace::available() ) {
Kokkos::Impl::AllocationTracker tracker = Kokkos::CudaUVMSpace::allocate_and_track("uvm_ptr",sizeof(int));
int * uvm_ptr = (int*) tracker.alloc_ptr();
*uvm_ptr = 42 ;
Kokkos::Cuda::fence();
test_cuda_spaces_int_value<<<1,1>>>(uvm_ptr);
Kokkos::Cuda::fence();
EXPECT_EQ( *uvm_ptr, int(2*42) );
}
}
//----------------------------------------------------------------------------
TEST_F( cuda , impl_shared_alloc )
{
test_shared_alloc< Kokkos::CudaSpace , Kokkos::HostSpace::execution_space >();
test_shared_alloc< Kokkos::CudaUVMSpace , Kokkos::HostSpace::execution_space >();
test_shared_alloc< Kokkos::CudaHostPinnedSpace , Kokkos::HostSpace::execution_space >();
}
TEST_F( cuda , impl_view_mapping )
{
test_view_mapping< Kokkos::Cuda >();
test_view_mapping_subview< Kokkos::Cuda >();
test_view_mapping_operator< Kokkos::Cuda >();
TestViewMappingAtomic< Kokkos::Cuda >::run();
}
template< class MemSpace >
struct TestViewCudaTexture {
enum { N = 1000 };
using V = Kokkos::Experimental::View<double*,MemSpace> ;
using T = Kokkos::Experimental::View<const double*, MemSpace, Kokkos::MemoryRandomAccess > ;
V m_base ;
T m_tex ;
struct TagInit {};
struct TagTest {};
KOKKOS_INLINE_FUNCTION
void operator()( const TagInit & , const int i ) const { m_base[i] = i + 1 ; }
KOKKOS_INLINE_FUNCTION
void operator()( const TagTest & , const int i , long & error_count ) const
{ if ( m_tex[i] != i + 1 ) ++error_count ; }
TestViewCudaTexture()
: m_base("base",N)
, m_tex( m_base )
{}
static void run()
{
EXPECT_TRUE( ( std::is_same< typename V::reference_type
, double &
>::value ) );
EXPECT_TRUE( ( std::is_same< typename T::reference_type
, const double
>::value ) );
EXPECT_TRUE( V::reference_type_is_lvalue_reference ); // An ordinary view
EXPECT_FALSE( T::reference_type_is_lvalue_reference ); // Texture fetch returns by value
TestViewCudaTexture self ;
Kokkos::parallel_for( Kokkos::RangePolicy< Kokkos::Cuda , TagInit >(0,N) , self );
long error_count = -1 ;
Kokkos::parallel_reduce( Kokkos::RangePolicy< Kokkos::Cuda , TagTest >(0,N) , self , error_count );
EXPECT_EQ( error_count , 0 );
}
};
TEST_F( cuda , impl_view_texture )
{
TestViewCudaTexture< Kokkos::CudaSpace >::run();
TestViewCudaTexture< Kokkos::CudaUVMSpace >::run();
}
template< class MemSpace , class ExecSpace >
struct TestViewCudaAccessible {
enum { N = 1000 };
using V = Kokkos::Experimental::View<double*,MemSpace> ;
V m_base ;
struct TagInit {};
struct TagTest {};
KOKKOS_INLINE_FUNCTION
void operator()( const TagInit & , const int i ) const { m_base[i] = i + 1 ; }
KOKKOS_INLINE_FUNCTION
void operator()( const TagTest & , const int i , long & error_count ) const
{ if ( m_base[i] != i + 1 ) ++error_count ; }
TestViewCudaAccessible()
: m_base("base",N)
{}
static void run()
{
TestViewCudaAccessible self ;
Kokkos::parallel_for( Kokkos::RangePolicy< typename MemSpace::execution_space , TagInit >(0,N) , self );
MemSpace::execution_space::fence();
// Next access is a different execution space, must complete prior kernel.
long error_count = -1 ;
Kokkos::parallel_reduce( Kokkos::RangePolicy< ExecSpace , TagTest >(0,N) , self , error_count );
EXPECT_EQ( error_count , 0 );
}
};
TEST_F( cuda , impl_view_accessible )
{
TestViewCudaAccessible< Kokkos::CudaSpace , Kokkos::Cuda >::run();
TestViewCudaAccessible< Kokkos::CudaUVMSpace , Kokkos::Cuda >::run();
TestViewCudaAccessible< Kokkos::CudaUVMSpace , Kokkos::HostSpace::execution_space >::run();
TestViewCudaAccessible< Kokkos::CudaHostPinnedSpace , Kokkos::Cuda >::run();
TestViewCudaAccessible< Kokkos::CudaHostPinnedSpace , Kokkos::HostSpace::execution_space >::run();
}
//----------------------------------------------------------------------------
TEST_F( cuda, view_impl )
{
// test_abort<<<32,32>>>(); // Aborts the kernel with CUDA version 4.1 or greater
test_view_impl< Kokkos::Cuda >();
}
TEST_F( cuda, view_api )
{
typedef Kokkos::View< const int * , Kokkos::Cuda , Kokkos::MemoryTraits< Kokkos::RandomAccess > > view_texture_managed ;
typedef Kokkos::View< const int * , Kokkos::Cuda , Kokkos::MemoryTraits< Kokkos::RandomAccess | Kokkos::Unmanaged > > view_texture_unmanaged ;
TestViewAPI< double , Kokkos::Cuda >();
#if 0
Kokkos::View<double, Kokkos::Cuda > x("x");
Kokkos::View<double[1], Kokkos::Cuda > y("y");
// *x = 10 ;
// x() = 10 ;
// y[0] = 10 ;
// y(0) = 10 ;
#endif
}
TEST_F( cuda, view_subview_auto_1d_left ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutLeft,Kokkos::Cuda >();
}
TEST_F( cuda, view_subview_auto_1d_right ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutRight,Kokkos::Cuda >();
}
TEST_F( cuda, view_subview_auto_1d_stride ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutStride,Kokkos::Cuda >();
}
TEST_F( cuda, view_subview_assign_strided ) {
TestViewSubview::test_1d_strided_assignment< Kokkos::Cuda >();
}
TEST_F( cuda, view_subview_left_0 ) {
TestViewSubview::test_left_0< Kokkos::CudaUVMSpace >();
}
TEST_F( cuda, view_subview_left_1 ) {
TestViewSubview::test_left_1< Kokkos::CudaUVMSpace >();
}
TEST_F( cuda, view_subview_left_2 ) {
TestViewSubview::test_left_2< Kokkos::CudaUVMSpace >();
}
TEST_F( cuda, view_subview_left_3 ) {
TestViewSubview::test_left_3< Kokkos::CudaUVMSpace >();
}
TEST_F( cuda, view_subview_right_0 ) {
TestViewSubview::test_right_0< Kokkos::CudaUVMSpace >();
}
TEST_F( cuda, view_subview_right_1 ) {
TestViewSubview::test_right_1< Kokkos::CudaUVMSpace >();
}
TEST_F( cuda, view_subview_right_3 ) {
TestViewSubview::test_right_3< Kokkos::CudaUVMSpace >();
}
TEST_F( cuda, range_tag )
{
TestRange< Kokkos::Cuda >::test_for(1000);
TestRange< Kokkos::Cuda >::test_reduce(1000);
TestRange< Kokkos::Cuda >::test_scan(1000);
}
TEST_F( cuda, team_tag )
{
TestTeamPolicy< Kokkos::Cuda >::test_for(1000);
TestTeamPolicy< Kokkos::Cuda >::test_reduce(1000);
}
TEST_F( cuda, reduce )
{
TestReduce< long , Kokkos::Cuda >( 10000000 );
TestReduce< double , Kokkos::Cuda >( 1000000 );
}
TEST_F( cuda, reduce_team )
{
TestReduceTeam< long , Kokkos::Cuda >( 10000000 );
TestReduceTeam< double , Kokkos::Cuda >( 1000000 );
}
TEST_F( cuda, shared_team )
{
TestSharedTeam< Kokkos::Cuda >();
}
TEST_F( cuda, reduce_dynamic )
{
TestReduceDynamic< long , Kokkos::Cuda >( 10000000 );
TestReduceDynamic< double , Kokkos::Cuda >( 1000000 );
}
TEST_F( cuda, reduce_dynamic_view )
{
TestReduceDynamicView< long , Kokkos::Cuda >( 10000000 );
TestReduceDynamicView< double , Kokkos::Cuda >( 1000000 );
}
TEST_F( cuda, atomic )
{
const int loop_count = 1e3 ;
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Cuda>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Cuda>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Cuda>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Cuda>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Cuda>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Cuda>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Cuda>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Cuda>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Cuda>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Cuda>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Cuda>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Cuda>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Cuda>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Cuda>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Cuda>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Cuda>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Cuda>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Cuda>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Cuda>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Cuda>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Cuda>(100,3) ) );
}
//----------------------------------------------------------------------------
TEST_F( cuda, tile_layout)
{
TestTile::test< Kokkos::Cuda , 1 , 1 >( 1 , 1 );
TestTile::test< Kokkos::Cuda , 1 , 1 >( 2 , 3 );
TestTile::test< Kokkos::Cuda , 1 , 1 >( 9 , 10 );
TestTile::test< Kokkos::Cuda , 2 , 2 >( 1 , 1 );
TestTile::test< Kokkos::Cuda , 2 , 2 >( 2 , 3 );
TestTile::test< Kokkos::Cuda , 2 , 2 >( 4 , 4 );
TestTile::test< Kokkos::Cuda , 2 , 2 >( 9 , 9 );
TestTile::test< Kokkos::Cuda , 2 , 4 >( 9 , 9 );
TestTile::test< Kokkos::Cuda , 4 , 4 >( 9 , 9 );
TestTile::test< Kokkos::Cuda , 4 , 4 >( 1 , 1 );
TestTile::test< Kokkos::Cuda , 4 , 4 >( 4 , 4 );
TestTile::test< Kokkos::Cuda , 4 , 4 >( 9 , 9 );
TestTile::test< Kokkos::Cuda , 4 , 4 >( 9 , 11 );
TestTile::test< Kokkos::Cuda , 8 , 8 >( 1 , 1 );
TestTile::test< Kokkos::Cuda , 8 , 8 >( 4 , 4 );
TestTile::test< Kokkos::Cuda , 8 , 8 >( 9 , 9 );
TestTile::test< Kokkos::Cuda , 8 , 8 >( 9 , 11 );
}
TEST_F( cuda , view_aggregate )
{
TestViewAggregate< Kokkos::Cuda >();
TestViewAggregateReduction< Kokkos::Cuda >();
}
TEST_F( cuda , scan )
{
TestScan< Kokkos::Cuda >::test_range( 1 , 1000 );
TestScan< Kokkos::Cuda >( 1000000 );
TestScan< Kokkos::Cuda >( 10000000 );
Kokkos::Cuda::fence();
}
TEST_F( cuda , team_scan )
{
TestScanTeam< Kokkos::Cuda >( 10 );
TestScanTeam< Kokkos::Cuda >( 10000 );
}
}
//----------------------------------------------------------------------------
TEST_F( cuda , template_meta_functions )
{
TestTemplateMetaFunctions<int, Kokkos::Cuda >();
}
//----------------------------------------------------------------------------
#ifdef KOKKOS_HAVE_CXX11
namespace Test {
TEST_F( cuda , reduction_deduction )
{
TestCXX11::test_reduction_deduction< Kokkos::Cuda >();
}
TEST_F( cuda , team_vector )
{
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(0) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(1) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(2) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(3) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(4) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(5) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(6) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(7) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(8) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(9) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Cuda >(10) ) );
}
}
#endif

View File

@ -0,0 +1,250 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#if !defined(KOKKOS_HAVE_CUDA) || defined(__CUDACC__)
//----------------------------------------------------------------------------
#include <TestViewImpl.hpp>
#include <TestAtomic.hpp>
#include <TestViewAPI.hpp>
#include <TestReduce.hpp>
#include <TestScan.hpp>
#include <TestTeam.hpp>
#include <TestAggregate.hpp>
#include <TestCompilerMacros.hpp>
#include <TestCXX11.hpp>
#include <TestTeamVector.hpp>
namespace Test {
class defaultdevicetype : public ::testing::Test {
protected:
static void SetUpTestCase()
{
Kokkos::initialize();
}
static void TearDownTestCase()
{
Kokkos::finalize();
}
};
TEST_F( defaultdevicetype, view_impl) {
test_view_impl< Kokkos::DefaultExecutionSpace >();
}
TEST_F( defaultdevicetype, view_api) {
TestViewAPI< double , Kokkos::DefaultExecutionSpace >();
}
TEST_F( defaultdevicetype, long_reduce) {
TestReduce< long , Kokkos::DefaultExecutionSpace >( 100000 );
}
TEST_F( defaultdevicetype, double_reduce) {
TestReduce< double , Kokkos::DefaultExecutionSpace >( 100000 );
}
TEST_F( defaultdevicetype, long_reduce_dynamic ) {
TestReduceDynamic< long , Kokkos::DefaultExecutionSpace >( 100000 );
}
TEST_F( defaultdevicetype, double_reduce_dynamic ) {
TestReduceDynamic< double , Kokkos::DefaultExecutionSpace >( 100000 );
}
TEST_F( defaultdevicetype, long_reduce_dynamic_view ) {
TestReduceDynamicView< long , Kokkos::DefaultExecutionSpace >( 100000 );
}
TEST_F( defaultdevicetype , atomics )
{
const int loop_count = 1e4 ;
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::DefaultExecutionSpace>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::DefaultExecutionSpace>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::DefaultExecutionSpace>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::DefaultExecutionSpace>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::DefaultExecutionSpace>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::DefaultExecutionSpace>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::DefaultExecutionSpace>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::DefaultExecutionSpace>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::DefaultExecutionSpace>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::DefaultExecutionSpace>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::DefaultExecutionSpace>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::DefaultExecutionSpace>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::DefaultExecutionSpace>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::DefaultExecutionSpace>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::DefaultExecutionSpace>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::DefaultExecutionSpace>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::DefaultExecutionSpace>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::DefaultExecutionSpace>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::DefaultExecutionSpace>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::DefaultExecutionSpace>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::DefaultExecutionSpace>(100,3) ) );
}
/*TEST_F( defaultdevicetype , view_remap )
{
enum { N0 = 3 , N1 = 2 , N2 = 8 , N3 = 9 };
typedef Kokkos::View< double*[N1][N2][N3] ,
Kokkos::LayoutRight ,
Kokkos::DefaultExecutionSpace > output_type ;
typedef Kokkos::View< int**[N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::DefaultExecutionSpace > input_type ;
typedef Kokkos::View< int*[N0][N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::DefaultExecutionSpace > diff_type ;
output_type output( "output" , N0 );
input_type input ( "input" , N0 , N1 );
diff_type diff ( "diff" , N0 );
int value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
input(i0,i1,i2,i3) = ++value ;
}}}}
// Kokkos::deep_copy( diff , input ); // throw with incompatible shape
Kokkos::deep_copy( output , input );
value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
++value ;
ASSERT_EQ( value , ((int) output(i0,i1,i2,i3) ) );
}}}}
}*/
//----------------------------------------------------------------------------
TEST_F( defaultdevicetype , view_aggregate )
{
TestViewAggregate< Kokkos::DefaultExecutionSpace >();
}
//----------------------------------------------------------------------------
TEST_F( defaultdevicetype , scan )
{
TestScan< Kokkos::DefaultExecutionSpace >::test_range( 1 , 1000 );
TestScan< Kokkos::DefaultExecutionSpace >( 1000000 );
TestScan< Kokkos::DefaultExecutionSpace >( 10000000 );
Kokkos::DefaultExecutionSpace::fence();
}
TEST_F( defaultdevicetype , team_scan )
{
TestScanTeam< Kokkos::DefaultExecutionSpace >( 10 );
TestScanTeam< Kokkos::DefaultExecutionSpace >( 10000 );
}
//----------------------------------------------------------------------------
TEST_F( defaultdevicetype , compiler_macros )
{
ASSERT_TRUE( ( TestCompilerMacros::Test< Kokkos::DefaultExecutionSpace >() ) );
}
//----------------------------------------------------------------------------
#if defined (KOKKOS_HAVE_CXX11)
TEST_F( defaultdevicetype , cxx11 )
{
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::DefaultExecutionSpace >(1) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::DefaultExecutionSpace >(2) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::DefaultExecutionSpace >(3) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::DefaultExecutionSpace >(4) ) );
}
#endif
#if defined (KOKKOS_HAVE_CXX11)
TEST_F( defaultdevicetype , team_vector )
{
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::DefaultExecutionSpace >(0) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::DefaultExecutionSpace >(1) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::DefaultExecutionSpace >(2) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::DefaultExecutionSpace >(3) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::DefaultExecutionSpace >(4) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::DefaultExecutionSpace >(5) ) );
}
#endif
#if defined (KOKKOS_HAVE_CXX11)
TEST_F( defaultdevicetype , malloc )
{
int* data = (int*) Kokkos::kokkos_malloc(100*sizeof(int));
ASSERT_NO_THROW(data = (int*) Kokkos::kokkos_realloc(data,120*sizeof(int)));
Kokkos::kokkos_free(data);
}
#endif
} // namespace test
#endif

View File

@ -0,0 +1,390 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#ifdef KOKKOS_HAVE_OPENMP
#include <omp.h>
#endif
#if !defined(KOKKOS_HAVE_CUDA) || defined(__CUDACC__)
//----------------------------------------------------------------------------
namespace Test {
namespace Impl {
char** init_kokkos_args(bool do_threads,bool do_numa,bool do_device,bool do_other, int& nargs, Kokkos::InitArguments& init_args) {
nargs = (do_threads?1:0) +
(do_numa?1:0) +
(do_device?1:0) +
(do_other?4:0);
char** args_kokkos = new char*[nargs];
for(int i = 0; i < nargs; i++)
args_kokkos[i] = new char[20];
int threads_idx = do_other?1:0;
int numa_idx = (do_other?3:0) + (do_threads?1:0);
int device_idx = (do_other?3:0) + (do_threads?1:0) + (do_numa?1:0);
if(do_threads) {
int nthreads = 3;
#ifdef KOKKOS_HAVE_OPENMP
if(omp_get_max_threads() < 3)
nthreads = omp_get_max_threads();
#endif
if(Kokkos::hwloc::available()) {
if(Kokkos::hwloc::get_available_threads_per_core()<3)
nthreads = Kokkos::hwloc::get_available_threads_per_core()
* Kokkos::hwloc::get_available_numa_count();
}
#ifdef KOKKOS_HAVE_SERIAL
if(Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultExecutionSpace>::value ||
Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultHostExecutionSpace>::value ) {
nthreads = 1;
}
#endif
init_args.num_threads = nthreads;
sprintf(args_kokkos[threads_idx],"--threads=%i",nthreads);
}
if(do_numa) {
int numa = 1;
if(Kokkos::hwloc::available())
numa = Kokkos::hwloc::get_available_numa_count();
#ifdef KOKKOS_HAVE_SERIAL
if(Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultExecutionSpace>::value ||
Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultHostExecutionSpace>::value ) {
numa = 1;
}
#endif
init_args.num_numa = numa;
sprintf(args_kokkos[numa_idx],"--numa=%i",numa);
}
if(do_device) {
init_args.device_id = 0;
sprintf(args_kokkos[device_idx],"--device=%i",0);
}
if(do_other) {
sprintf(args_kokkos[0],"--dummyarg=1");
sprintf(args_kokkos[threads_idx+(do_threads?1:0)],"--dummy2arg");
sprintf(args_kokkos[threads_idx+(do_threads?1:0)+1],"dummy3arg");
sprintf(args_kokkos[device_idx+(do_device?1:0)],"dummy4arg=1");
}
return args_kokkos;
}
Kokkos::InitArguments init_initstruct(bool do_threads, bool do_numa, bool do_device) {
Kokkos::InitArguments args;
if(do_threads) {
int nthreads = 3;
#ifdef KOKKOS_HAVE_OPENMP
if(omp_get_max_threads() < 3)
nthreads = omp_get_max_threads();
#endif
if(Kokkos::hwloc::available()) {
if(Kokkos::hwloc::get_available_threads_per_core()<3)
nthreads = Kokkos::hwloc::get_available_threads_per_core()
* Kokkos::hwloc::get_available_numa_count();
}
#ifdef KOKKOS_HAVE_SERIAL
if(Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultExecutionSpace>::value ||
Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultHostExecutionSpace>::value ) {
nthreads = 1;
}
#endif
args.num_threads = nthreads;
}
if(do_numa) {
int numa = 1;
if(Kokkos::hwloc::available())
numa = Kokkos::hwloc::get_available_numa_count();
#ifdef KOKKOS_HAVE_SERIAL
if(Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultExecutionSpace>::value ||
Kokkos::Impl::is_same<Kokkos::Serial,Kokkos::DefaultHostExecutionSpace>::value ) {
numa = 1;
}
#endif
args.num_numa = numa;
}
if(do_device) {
args.device_id = 0;
}
return args;
}
void check_correct_initialization(const Kokkos::InitArguments& argstruct) {
ASSERT_EQ( Kokkos::DefaultExecutionSpace::is_initialized(), 1);
ASSERT_EQ( Kokkos::HostSpace::execution_space::is_initialized(), 1);
//Figure out the number of threads the HostSpace ExecutionSpace should have initialized to
int expected_nthreads = argstruct.num_threads;
if(expected_nthreads<1) {
if(Kokkos::hwloc::available()) {
expected_nthreads = Kokkos::hwloc::get_available_numa_count()
* Kokkos::hwloc::get_available_cores_per_numa()
* Kokkos::hwloc::get_available_threads_per_core();
} else {
#ifdef KOKKOS_HAVE_OPENMP
if(Kokkos::Impl::is_same<Kokkos::HostSpace::execution_space,Kokkos::OpenMP>::value) {
expected_nthreads = omp_get_max_threads();
} else
#endif
expected_nthreads = 1;
}
#ifdef KOKKOS_HAVE_SERIAL
if(Kokkos::Impl::is_same<Kokkos::DefaultExecutionSpace,Kokkos::Serial>::value ||
Kokkos::Impl::is_same<Kokkos::DefaultHostExecutionSpace,Kokkos::Serial>::value )
expected_nthreads = 1;
#endif
}
int expected_numa = argstruct.num_numa;
if(expected_numa<1) {
if(Kokkos::hwloc::available()) {
expected_numa = Kokkos::hwloc::get_available_numa_count();
} else {
expected_numa = 1;
}
#ifdef KOKKOS_HAVE_SERIAL
if(Kokkos::Impl::is_same<Kokkos::DefaultExecutionSpace,Kokkos::Serial>::value ||
Kokkos::Impl::is_same<Kokkos::DefaultHostExecutionSpace,Kokkos::Serial>::value )
expected_numa = 1;
#endif
}
ASSERT_EQ(Kokkos::HostSpace::execution_space::thread_pool_size(),expected_nthreads);
#ifdef KOKKOS_HAVE_CUDA
if(Kokkos::Impl::is_same<Kokkos::DefaultExecutionSpace,Kokkos::Cuda>::value) {
int device;
cudaGetDevice( &device );
int expected_device = argstruct.device_id;
if(argstruct.device_id<0) {
expected_device = 0;
}
ASSERT_EQ(expected_device,device);
}
#endif
}
//ToDo: Add check whether correct number of threads are actually started
void test_no_arguments() {
Kokkos::initialize();
check_correct_initialization(Kokkos::InitArguments());
Kokkos::finalize();
}
void test_commandline_args(int nargs, char** args, const Kokkos::InitArguments& argstruct) {
Kokkos::initialize(nargs,args);
check_correct_initialization(argstruct);
Kokkos::finalize();
}
void test_initstruct_args(const Kokkos::InitArguments& args) {
Kokkos::initialize(args);
check_correct_initialization(args);
Kokkos::finalize();
}
}
class defaultdevicetypeinit : public ::testing::Test {
protected:
static void SetUpTestCase()
{
}
static void TearDownTestCase()
{
}
};
TEST_F( defaultdevicetypeinit, no_args) {
Impl::test_no_arguments();
}
TEST_F( defaultdevicetypeinit, commandline_args_empty) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(false,false,false,false,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_other) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(false,false,false,true,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_nthreads) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(true,false,false,false,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_nthreads_numa) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(true,true,false,false,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_nthreads_numa_device) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(true,true,true,false,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_nthreads_device) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(true,false,true,false,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_numa_device) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(false,true,true,false,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_device) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(false,false,true,false,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, commandline_args_nthreads_numa_device_other) {
Kokkos::InitArguments argstruct;
int nargs = 0;
char** args = Impl::init_kokkos_args(true,true,true,true,nargs, argstruct);
Impl::test_commandline_args(nargs,args,argstruct);
for(int i = 0; i < nargs; i++)
delete [] args[i];
delete [] args;
}
TEST_F( defaultdevicetypeinit, initstruct_default) {
Kokkos::InitArguments args;
Impl::test_initstruct_args(args);
}
TEST_F( defaultdevicetypeinit, initstruct_nthreads) {
Kokkos::InitArguments args = Impl::init_initstruct(true,false,false);
Impl::test_initstruct_args(args);
}
TEST_F( defaultdevicetypeinit, initstruct_nthreads_numa) {
Kokkos::InitArguments args = Impl::init_initstruct(true,true,false);
Impl::test_initstruct_args(args);
}
TEST_F( defaultdevicetypeinit, initstruct_device) {
Kokkos::InitArguments args = Impl::init_initstruct(false,false,true);
Impl::test_initstruct_args(args);
}
TEST_F( defaultdevicetypeinit, initstruct_nthreads_device) {
Kokkos::InitArguments args = Impl::init_initstruct(true,false,true);
Impl::test_initstruct_args(args);
}
TEST_F( defaultdevicetypeinit, initstruct_nthreads_numa_device) {
Kokkos::InitArguments args = Impl::init_initstruct(true,true,true);
Impl::test_initstruct_args(args);
}
} // namespace test
#endif

View File

@ -0,0 +1,69 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <iostream>
#include <Kokkos_hwloc.hpp>
namespace Test {
class hwloc : public ::testing::Test {
protected:
static void SetUpTestCase()
{}
static void TearDownTestCase()
{}
};
TEST_F( hwloc, query)
{
std::cout << " NUMA[" << Kokkos::hwloc::get_available_numa_count() << "]"
<< " CORE[" << Kokkos::hwloc::get_available_cores_per_numa() << "]"
<< " PU[" << Kokkos::hwloc::get_available_threads_per_core() << "]"
<< std::endl ;
}
}

View File

@ -0,0 +1,100 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <iostream>
#include <Kokkos_Core.hpp>
/*--------------------------------------------------------------------------*/
namespace {
template<class Arg1>
class TestMemorySpace {
public:
typedef typename Arg1::memory_space MemorySpace;
TestMemorySpace() { run_test(); }
void run_test()
{
#if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
Kokkos::View<int* ,Arg1> invalid;
ASSERT_EQ(0u, invalid.tracker().ref_count() );
{
Kokkos::View<int* ,Arg1> a("A",10);
ASSERT_EQ(1u, a.tracker().ref_count() );
{
Kokkos::View<int* ,Arg1> b = a;
ASSERT_EQ(2u, b.tracker().ref_count() );
Kokkos::View<int* ,Arg1> D("D",10);
ASSERT_EQ(1u, D.tracker().ref_count() );
{
Kokkos::View<int* ,Arg1> E("E",10);
ASSERT_EQ(1u, E.tracker().ref_count() );
}
ASSERT_EQ(2u, b.tracker().ref_count() );
}
ASSERT_EQ(1u, a.tracker().ref_count() );
}
#endif
}
};
}
/*--------------------------------------------------------------------------*/

View File

@ -0,0 +1,375 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
//----------------------------------------------------------------------------
#include <TestViewImpl.hpp>
#include <TestAtomic.hpp>
#include <TestViewAPI.hpp>
#include <TestViewSubview.hpp>
#include <TestSharedAlloc.hpp>
#include <TestViewMapping.hpp>
#include <TestRange.hpp>
#include <TestTeam.hpp>
#include <TestReduce.hpp>
#include <TestScan.hpp>
#include <TestAggregate.hpp>
#include <TestAggregateReduction.hpp>
#include <TestCompilerMacros.hpp>
#include <TestCXX11.hpp>
#include <TestCXX11Deduction.hpp>
#include <TestTeamVector.hpp>
#include <TestMemorySpaceTracking.hpp>
#include <TestTemplateMetaFunctions.hpp>
namespace Test {
class openmp : public ::testing::Test {
protected:
static void SetUpTestCase()
{
const unsigned numa_count = Kokkos::hwloc::get_available_numa_count();
const unsigned cores_per_numa = Kokkos::hwloc::get_available_cores_per_numa();
const unsigned threads_per_core = Kokkos::hwloc::get_available_threads_per_core();
const unsigned threads_count = std::max( 1u , numa_count ) *
std::max( 2u , ( cores_per_numa * threads_per_core ) / 2 );
Kokkos::OpenMP::initialize( threads_count );
Kokkos::OpenMP::print_configuration( std::cout , true );
}
static void TearDownTestCase()
{
Kokkos::OpenMP::finalize();
omp_set_num_threads(1);
ASSERT_EQ( 1 , omp_get_max_threads() );
}
};
TEST_F( openmp , impl_shared_alloc ) {
test_shared_alloc< Kokkos::HostSpace , Kokkos::OpenMP >();
}
TEST_F( openmp , impl_view_mapping ) {
test_view_mapping< Kokkos::OpenMP >();
test_view_mapping_subview< Kokkos::OpenMP >();
test_view_mapping_operator< Kokkos::OpenMP >();
TestViewMappingAtomic< Kokkos::OpenMP >::run();
}
TEST_F( openmp, view_impl) {
test_view_impl< Kokkos::OpenMP >();
}
TEST_F( openmp, view_api) {
TestViewAPI< double , Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_auto_1d_left ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutLeft,Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_auto_1d_right ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutRight,Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_auto_1d_stride ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutStride,Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_assign_strided ) {
TestViewSubview::test_1d_strided_assignment< Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_left_0 ) {
TestViewSubview::test_left_0< Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_left_1 ) {
TestViewSubview::test_left_1< Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_left_2 ) {
TestViewSubview::test_left_2< Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_left_3 ) {
TestViewSubview::test_left_3< Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_right_0 ) {
TestViewSubview::test_right_0< Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_right_1 ) {
TestViewSubview::test_right_1< Kokkos::OpenMP >();
}
TEST_F( openmp, view_subview_right_3 ) {
TestViewSubview::test_right_3< Kokkos::OpenMP >();
}
TEST_F( openmp , range_tag )
{
TestRange< Kokkos::OpenMP >::test_for(1000);
TestRange< Kokkos::OpenMP >::test_reduce(1000);
TestRange< Kokkos::OpenMP >::test_scan(1000);
}
TEST_F( openmp , team_tag )
{
TestTeamPolicy< Kokkos::OpenMP >::test_for(1000);
TestTeamPolicy< Kokkos::OpenMP >::test_reduce(1000);
}
TEST_F( openmp, long_reduce) {
TestReduce< long , Kokkos::OpenMP >( 1000000 );
}
TEST_F( openmp, double_reduce) {
TestReduce< double , Kokkos::OpenMP >( 1000000 );
}
TEST_F( openmp, long_reduce_dynamic ) {
TestReduceDynamic< long , Kokkos::OpenMP >( 1000000 );
}
TEST_F( openmp, double_reduce_dynamic ) {
TestReduceDynamic< double , Kokkos::OpenMP >( 1000000 );
}
TEST_F( openmp, long_reduce_dynamic_view ) {
TestReduceDynamicView< long , Kokkos::OpenMP >( 1000000 );
}
TEST_F( openmp, team_long_reduce) {
TestReduceTeam< long , Kokkos::OpenMP >( 100000 );
}
TEST_F( openmp, team_double_reduce) {
TestReduceTeam< double , Kokkos::OpenMP >( 100000 );
}
TEST_F( openmp, team_shared_request) {
TestSharedTeam< Kokkos::OpenMP >();
}
TEST_F( openmp , atomics )
{
const int loop_count = 1e4 ;
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::OpenMP>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::OpenMP>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::OpenMP>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::OpenMP>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::OpenMP>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::OpenMP>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::OpenMP>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::OpenMP>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::OpenMP>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::OpenMP>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::OpenMP>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::OpenMP>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::OpenMP>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::OpenMP>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::OpenMP>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::OpenMP>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::OpenMP>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::OpenMP>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::OpenMP>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::OpenMP>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::OpenMP>(100,3) ) );
#if defined( KOKKOS_ENABLE_ASM )
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::OpenMP>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::OpenMP>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::OpenMP>(100,3) ) );
#endif
}
TEST_F( openmp , view_remap )
{
enum { N0 = 3 , N1 = 2 , N2 = 8 , N3 = 9 };
typedef Kokkos::View< double*[N1][N2][N3] ,
Kokkos::LayoutRight ,
Kokkos::OpenMP > output_type ;
typedef Kokkos::View< int**[N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::OpenMP > input_type ;
typedef Kokkos::View< int*[N0][N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::OpenMP > diff_type ;
output_type output( "output" , N0 );
input_type input ( "input" , N0 , N1 );
diff_type diff ( "diff" , N0 );
int value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
input(i0,i1,i2,i3) = ++value ;
}}}}
// Kokkos::deep_copy( diff , input ); // throw with incompatible shape
Kokkos::deep_copy( output , input );
value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
++value ;
ASSERT_EQ( value , ((int) output(i0,i1,i2,i3) ) );
}}}}
}
//----------------------------------------------------------------------------
TEST_F( openmp , view_aggregate )
{
TestViewAggregate< Kokkos::OpenMP >();
TestViewAggregateReduction< Kokkos::OpenMP >();
}
//----------------------------------------------------------------------------
TEST_F( openmp , scan )
{
TestScan< Kokkos::OpenMP >::test_range( 1 , 1000 );
TestScan< Kokkos::OpenMP >( 1000000 );
TestScan< Kokkos::OpenMP >( 10000000 );
Kokkos::OpenMP::fence();
}
TEST_F( openmp , team_scan )
{
TestScanTeam< Kokkos::OpenMP >( 10000 );
TestScanTeam< Kokkos::OpenMP >( 10000 );
}
//----------------------------------------------------------------------------
TEST_F( openmp , compiler_macros )
{
ASSERT_TRUE( ( TestCompilerMacros::Test< Kokkos::OpenMP >() ) );
}
//----------------------------------------------------------------------------
TEST_F( openmp , memory_space )
{
TestMemorySpace< Kokkos::OpenMP >();
}
//----------------------------------------------------------------------------
TEST_F( openmp , template_meta_functions )
{
TestTemplateMetaFunctions<int, Kokkos::OpenMP >();
}
//----------------------------------------------------------------------------
#if defined( KOKKOS_HAVE_CXX11 ) && defined( KOKKOS_HAVE_DEFAULT_DEVICE_TYPE_OPENMP )
TEST_F( openmp , cxx11 )
{
if ( Kokkos::Impl::is_same< Kokkos::DefaultExecutionSpace , Kokkos::OpenMP >::value ) {
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::OpenMP >(1) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::OpenMP >(2) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::OpenMP >(3) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::OpenMP >(4) ) );
}
}
#endif
#if defined (KOKKOS_HAVE_CXX11)
TEST_F( openmp , reduction_deduction )
{
TestCXX11::test_reduction_deduction< Kokkos::OpenMP >();
}
TEST_F( openmp , team_vector )
{
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(0) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(1) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(2) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(3) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(4) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(5) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(6) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(7) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(8) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(9) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::OpenMP >(10) ) );
}
#endif
} // namespace test

View File

@ -0,0 +1,283 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#include <Kokkos_Qthread.hpp>
#include <Qthread/Kokkos_Qthread_TaskPolicy.hpp>
//----------------------------------------------------------------------------
#include <TestViewImpl.hpp>
#include <TestAtomic.hpp>
#include <TestViewAPI.hpp>
#include <TestTeam.hpp>
#include <TestRange.hpp>
#include <TestReduce.hpp>
#include <TestScan.hpp>
#include <TestAggregate.hpp>
#include <TestCompilerMacros.hpp>
#include <TestTaskPolicy.hpp>
// #include <TestTeamVector.hpp>
namespace Test {
class qthread : public ::testing::Test {
protected:
static void SetUpTestCase()
{
const unsigned numa_count = Kokkos::hwloc::get_available_numa_count();
const unsigned cores_per_numa = Kokkos::hwloc::get_available_cores_per_numa();
const unsigned threads_per_core = Kokkos::hwloc::get_available_threads_per_core();
int threads_count = std::max( 1u , numa_count )
* std::max( 2u , ( cores_per_numa * threads_per_core ) / 2 );
Kokkos::Qthread::initialize( threads_count );
Kokkos::Qthread::print_configuration( std::cout , true );
}
static void TearDownTestCase()
{
Kokkos::Qthread::finalize();
}
};
TEST_F( qthread , compiler_macros )
{
ASSERT_TRUE( ( TestCompilerMacros::Test< Kokkos::Qthread >() ) );
}
TEST_F( qthread, view_impl) {
test_view_impl< Kokkos::Qthread >();
}
TEST_F( qthread, view_api) {
TestViewAPI< double , Kokkos::Qthread >();
}
TEST_F( qthread , range_tag )
{
TestRange< Kokkos::Qthread >::test_for(1000);
TestRange< Kokkos::Qthread >::test_reduce(1000);
TestRange< Kokkos::Qthread >::test_scan(1000);
}
TEST_F( qthread , team_tag )
{
TestTeamPolicy< Kokkos::Qthread >::test_for( 1000 );
TestTeamPolicy< Kokkos::Qthread >::test_reduce( 1000 );
}
TEST_F( qthread, long_reduce) {
TestReduce< long , Kokkos::Qthread >( 1000000 );
}
TEST_F( qthread, double_reduce) {
TestReduce< double , Kokkos::Qthread >( 1000000 );
}
TEST_F( qthread, long_reduce_dynamic ) {
TestReduceDynamic< long , Kokkos::Qthread >( 1000000 );
}
TEST_F( qthread, double_reduce_dynamic ) {
TestReduceDynamic< double , Kokkos::Qthread >( 1000000 );
}
TEST_F( qthread, long_reduce_dynamic_view ) {
TestReduceDynamicView< long , Kokkos::Qthread >( 1000000 );
}
TEST_F( qthread, team_long_reduce) {
TestReduceTeam< long , Kokkos::Qthread >( 1000000 );
}
TEST_F( qthread, team_double_reduce) {
TestReduceTeam< double , Kokkos::Qthread >( 1000000 );
}
TEST_F( qthread , atomics )
{
const int loop_count = 1e4 ;
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Qthread>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Qthread>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Qthread>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Qthread>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Qthread>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Qthread>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Qthread>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Qthread>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Qthread>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Qthread>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Qthread>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Qthread>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Qthread>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Qthread>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Qthread>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Qthread>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Qthread>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Qthread>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Qthread>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Qthread>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Qthread>(100,3) ) );
#if defined( KOKKOS_ENABLE_ASM )
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Qthread>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Qthread>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Qthread>(100,3) ) );
#endif
}
TEST_F( qthread , view_remap )
{
enum { N0 = 3 , N1 = 2 , N2 = 8 , N3 = 9 };
typedef Kokkos::View< double*[N1][N2][N3] ,
Kokkos::LayoutRight ,
Kokkos::Qthread > output_type ;
typedef Kokkos::View< int**[N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::Qthread > input_type ;
typedef Kokkos::View< int*[N0][N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::Qthread > diff_type ;
output_type output( "output" , N0 );
input_type input ( "input" , N0 , N1 );
diff_type diff ( "diff" , N0 );
int value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
input(i0,i1,i2,i3) = ++value ;
}}}}
// Kokkos::deep_copy( diff , input ); // throw with incompatible shape
Kokkos::deep_copy( output , input );
value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
++value ;
ASSERT_EQ( value , ((int) output(i0,i1,i2,i3) ) );
}}}}
}
//----------------------------------------------------------------------------
TEST_F( qthread , view_aggregate )
{
TestViewAggregate< Kokkos::Qthread >();
}
//----------------------------------------------------------------------------
TEST_F( qthread , scan )
{
TestScan< Kokkos::Qthread >::test_range( 1 , 1000 );
TestScan< Kokkos::Qthread >( 1000000 );
TestScan< Kokkos::Qthread >( 10000000 );
Kokkos::Qthread::fence();
}
TEST_F( qthread, team_shared ) {
TestSharedTeam< Kokkos::Qthread >();
}
TEST_F( qthread , team_scan )
{
TestScanTeam< Kokkos::Qthread >( 10 );
TestScanTeam< Kokkos::Qthread >( 10000 );
}
#if defined (KOKKOS_HAVE_CXX11) && 0 /* disable */
TEST_F( qthread , team_vector )
{
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Qthread >(0) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Qthread >(1) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Qthread >(2) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Qthread >(3) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Qthread >(4) ) );
}
#endif
//----------------------------------------------------------------------------
TEST_F( qthread , task_policy )
{
TestTaskPolicy::test_task_dep< Kokkos::Qthread >( 10 );
for ( long i = 0 ; i < 25 ; ++i ) TestTaskPolicy::test_fib< Kokkos::Qthread >(i);
for ( long i = 0 ; i < 35 ; ++i ) TestTaskPolicy::test_fib2< Kokkos::Qthread >(i);
}
#if defined( KOKKOS_HAVE_CXX11 )
TEST_F( qthread , task_team )
{
std::cout << "qthread.task_team test disabled due to unresolved error causing the test to hang." << std::endl ;
// TestTaskPolicy::test_task_team< Kokkos::Qthread >(1000);
}
#endif
//----------------------------------------------------------------------------
} // namespace test

View File

@ -0,0 +1,171 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <stdio.h>
#include <Kokkos_Core.hpp>
/*--------------------------------------------------------------------------*/
namespace Test {
namespace {
template< class ExecSpace >
struct TestRange {
typedef int value_type ; ///< typedef required for the parallel_reduce
typedef Kokkos::View<int*,ExecSpace> view_type ;
view_type m_flags ;
struct VerifyInitTag {};
struct ResetTag {};
struct VerifyResetTag {};
TestRange( const size_t N )
: m_flags( Kokkos::ViewAllocateWithoutInitializing("flags"), N )
{}
static void test_for( const size_t N )
{
TestRange functor(N);
typename view_type::HostMirror host_flags = Kokkos::create_mirror_view( functor.m_flags );
Kokkos::parallel_for( Kokkos::RangePolicy<ExecSpace>(0,N) , functor );
Kokkos::parallel_for( Kokkos::RangePolicy<ExecSpace,VerifyInitTag>(0,N) , functor );
Kokkos::deep_copy( host_flags , functor.m_flags );
size_t error_count = 0 ;
for ( size_t i = 0 ; i < N ; ++i ) {
if ( int(i) != host_flags(i) ) ++error_count ;
}
ASSERT_EQ( error_count , size_t(0) );
Kokkos::parallel_for( Kokkos::RangePolicy<ExecSpace,ResetTag>(0,N) , functor );
Kokkos::parallel_for( std::string("TestKernelFor") , Kokkos::RangePolicy<ExecSpace,VerifyResetTag>(0,N) , functor );
Kokkos::deep_copy( host_flags , functor.m_flags );
error_count = 0 ;
for ( size_t i = 0 ; i < N ; ++i ) {
if ( int(2*i) != host_flags(i) ) ++error_count ;
}
ASSERT_EQ( error_count , size_t(0) );
}
KOKKOS_INLINE_FUNCTION
void operator()( const int i ) const
{ m_flags(i) = i ; }
KOKKOS_INLINE_FUNCTION
void operator()( const VerifyInitTag & , const int i ) const
{ if ( i != m_flags(i) ) { printf("TestRange::test_for error at %d != %d\n",i,m_flags(i)); } }
KOKKOS_INLINE_FUNCTION
void operator()( const ResetTag & , const int i ) const
{ m_flags(i) = 2 * m_flags(i); }
KOKKOS_INLINE_FUNCTION
void operator()( const VerifyResetTag & , const int i ) const
{ if ( 2 * i != m_flags(i) ) { printf("TestRange::test_for error at %d != %d\n",i,m_flags(i)); } }
//----------------------------------------
struct OffsetTag {};
static void test_reduce( const size_t N )
{
TestRange functor(N);
int total = 0 ;
Kokkos::parallel_for( Kokkos::RangePolicy<ExecSpace>(0,N) , functor );
Kokkos::parallel_reduce( "TestKernelReduce" , Kokkos::RangePolicy<ExecSpace>(0,N) , functor , total );
// sum( 0 .. N-1 )
ASSERT_EQ( size_t((N-1)*(N)/2) , size_t(total) );
Kokkos::parallel_reduce( Kokkos::RangePolicy<ExecSpace,OffsetTag>(0,N) , functor , total );
// sum( 1 .. N )
ASSERT_EQ( size_t((N)*(N+1)/2) , size_t(total) );
}
KOKKOS_INLINE_FUNCTION
void operator()( const int i , value_type & update ) const
{ update += m_flags(i); }
KOKKOS_INLINE_FUNCTION
void operator()( const OffsetTag & , const int i , value_type & update ) const
{ update += 1 + m_flags(i); }
//----------------------------------------
static void test_scan( const size_t N )
{
TestRange functor(N);
Kokkos::parallel_for( Kokkos::RangePolicy<ExecSpace>(0,N) , functor );
Kokkos::parallel_scan( "TestKernelScan" , Kokkos::RangePolicy<ExecSpace,OffsetTag>(0,N) , functor );
}
KOKKOS_INLINE_FUNCTION
void operator()( const OffsetTag & , const int i , value_type & update , bool final ) const
{
update += m_flags(i);
if ( final ) {
if ( update != (i*(i+1))/2 ) {
printf("TestRange::test_scan error %d : %d != %d\n",i,(i*(i+1))/2,m_flags(i));
}
}
}
};
} /* namespace */
} /* namespace Test */
/*--------------------------------------------------------------------------*/

View File

@ -0,0 +1,371 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <Kokkos_Core.hpp>
/*--------------------------------------------------------------------------*/
namespace Test {
template< typename ScalarType , class DeviceType >
class ReduceFunctor
{
public:
typedef DeviceType execution_space ;
typedef typename execution_space::size_type size_type ;
struct value_type {
ScalarType value[3] ;
};
const size_type nwork ;
ReduceFunctor( const size_type & arg_nwork ) : nwork( arg_nwork ) {}
ReduceFunctor( const ReduceFunctor & rhs )
: nwork( rhs.nwork ) {}
/*
KOKKOS_INLINE_FUNCTION
void init( value_type & dst ) const
{
dst.value[0] = 0 ;
dst.value[1] = 0 ;
dst.value[2] = 0 ;
}
*/
KOKKOS_INLINE_FUNCTION
void join( volatile value_type & dst ,
const volatile value_type & src ) const
{
dst.value[0] += src.value[0] ;
dst.value[1] += src.value[1] ;
dst.value[2] += src.value[2] ;
}
KOKKOS_INLINE_FUNCTION
void operator()( size_type iwork , value_type & dst ) const
{
dst.value[0] += 1 ;
dst.value[1] += iwork + 1 ;
dst.value[2] += nwork - iwork ;
}
};
template< class DeviceType >
class ReduceFunctorFinal : public ReduceFunctor< long , DeviceType > {
public:
typedef typename ReduceFunctor< long , DeviceType >::value_type value_type ;
ReduceFunctorFinal( const size_t n )
: ReduceFunctor<long,DeviceType>(n)
{}
KOKKOS_INLINE_FUNCTION
void final( value_type & dst ) const
{
dst.value[0] = - dst.value[0] ;
dst.value[1] = - dst.value[1] ;
dst.value[2] = - dst.value[2] ;
}
};
template< typename ScalarType , class DeviceType >
class RuntimeReduceFunctor
{
public:
// Required for functor:
typedef DeviceType execution_space ;
typedef ScalarType value_type[] ;
const unsigned value_count ;
// Unit test details:
typedef typename execution_space::size_type size_type ;
const size_type nwork ;
RuntimeReduceFunctor( const size_type arg_nwork ,
const size_type arg_count )
: value_count( arg_count )
, nwork( arg_nwork ) {}
/*
KOKKOS_INLINE_FUNCTION
void init( value_type dst ) const
{
for ( unsigned i = 0 ; i < value_count ; ++i ) dst[i] = 0 ;
}
*/
KOKKOS_INLINE_FUNCTION
void join( volatile ScalarType dst[] ,
const volatile ScalarType src[] ) const
{
for ( unsigned i = 0 ; i < value_count ; ++i ) dst[i] += src[i] ;
}
KOKKOS_INLINE_FUNCTION
void operator()( size_type iwork , ScalarType dst[] ) const
{
const size_type tmp[3] = { 1 , iwork + 1 , nwork - iwork };
for ( size_type i = 0 ; i < value_count ; ++i ) {
dst[i] += tmp[ i % 3 ];
}
}
};
template< class DeviceType >
class RuntimeReduceFunctorFinal : public RuntimeReduceFunctor< long , DeviceType > {
public:
typedef RuntimeReduceFunctor< long , DeviceType > base_type ;
typedef typename base_type::value_type value_type ;
typedef long scalar_type ;
RuntimeReduceFunctorFinal( const size_t theNwork , const size_t count ) : base_type(theNwork,count) {}
KOKKOS_INLINE_FUNCTION
void final( value_type dst ) const
{
for ( unsigned i = 0 ; i < base_type::value_count ; ++i ) {
dst[i] = - dst[i] ;
}
}
};
} // namespace Test
namespace {
template< typename ScalarType , class DeviceType >
class TestReduce
{
public:
typedef DeviceType execution_space ;
typedef typename execution_space::size_type size_type ;
//------------------------------------
TestReduce( const size_type & nwork )
{
run_test(nwork);
run_test_final(nwork);
}
void run_test( const size_type & nwork )
{
typedef Test::ReduceFunctor< ScalarType , execution_space > functor_type ;
typedef typename functor_type::value_type value_type ;
enum { Count = 3 };
enum { Repeat = 100 };
value_type result[ Repeat ];
const unsigned long nw = nwork ;
const unsigned long nsum = nw % 2 ? nw * (( nw + 1 )/2 )
: (nw/2) * ( nw + 1 );
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
Kokkos::parallel_reduce( nwork , functor_type(nwork) , result[i] );
}
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
for ( unsigned j = 0 ; j < Count ; ++j ) {
const unsigned long correct = 0 == j % 3 ? nw : nsum ;
ASSERT_EQ( (ScalarType) correct , result[i].value[j] );
}
}
}
void run_test_final( const size_type & nwork )
{
typedef Test::ReduceFunctorFinal< execution_space > functor_type ;
typedef typename functor_type::value_type value_type ;
enum { Count = 3 };
enum { Repeat = 100 };
value_type result[ Repeat ];
const unsigned long nw = nwork ;
const unsigned long nsum = nw % 2 ? nw * (( nw + 1 )/2 )
: (nw/2) * ( nw + 1 );
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
Kokkos::parallel_reduce( nwork , functor_type(nwork) , result[i] );
}
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
for ( unsigned j = 0 ; j < Count ; ++j ) {
const unsigned long correct = 0 == j % 3 ? nw : nsum ;
ASSERT_EQ( (ScalarType) correct , - result[i].value[j] );
}
}
}
};
template< typename ScalarType , class DeviceType >
class TestReduceDynamic
{
public:
typedef DeviceType execution_space ;
typedef typename execution_space::size_type size_type ;
//------------------------------------
TestReduceDynamic( const size_type nwork )
{
run_test_dynamic(nwork);
run_test_dynamic_final(nwork);
}
void run_test_dynamic( const size_type nwork )
{
typedef Test::RuntimeReduceFunctor< ScalarType , execution_space > functor_type ;
enum { Count = 3 };
enum { Repeat = 100 };
ScalarType result[ Repeat ][ Count ] ;
const unsigned long nw = nwork ;
const unsigned long nsum = nw % 2 ? nw * (( nw + 1 )/2 )
: (nw/2) * ( nw + 1 );
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
Kokkos::parallel_reduce( nwork , functor_type(nwork,Count) , result[i] );
}
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
for ( unsigned j = 0 ; j < Count ; ++j ) {
const unsigned long correct = 0 == j % 3 ? nw : nsum ;
ASSERT_EQ( (ScalarType) correct , result[i][j] );
}
}
}
void run_test_dynamic_final( const size_type nwork )
{
typedef Test::RuntimeReduceFunctorFinal< execution_space > functor_type ;
enum { Count = 3 };
enum { Repeat = 100 };
typename functor_type::scalar_type result[ Repeat ][ Count ] ;
const unsigned long nw = nwork ;
const unsigned long nsum = nw % 2 ? nw * (( nw + 1 )/2 )
: (nw/2) * ( nw + 1 );
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
Kokkos::parallel_reduce( "TestKernelReduce" , nwork , functor_type(nwork,Count) , result[i] );
}
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
for ( unsigned j = 0 ; j < Count ; ++j ) {
const unsigned long correct = 0 == j % 3 ? nw : nsum ;
ASSERT_EQ( (ScalarType) correct , - result[i][j] );
}
}
}
};
template< typename ScalarType , class DeviceType >
class TestReduceDynamicView
{
public:
typedef DeviceType execution_space ;
typedef typename execution_space::size_type size_type ;
//------------------------------------
TestReduceDynamicView( const size_type nwork )
{
run_test_dynamic_view(nwork);
}
void run_test_dynamic_view( const size_type nwork )
{
typedef Test::RuntimeReduceFunctor< ScalarType , execution_space > functor_type ;
typedef Kokkos::View< ScalarType* , DeviceType > result_type ;
typedef typename result_type::HostMirror result_host_type ;
const unsigned CountLimit = 23 ;
const unsigned long nw = nwork ;
const unsigned long nsum = nw % 2 ? nw * (( nw + 1 )/2 )
: (nw/2) * ( nw + 1 );
for ( unsigned count = 0 ; count < CountLimit ; ++count ) {
result_type result("result",count);
result_host_type host_result = Kokkos::create_mirror( result );
// Test result to host pointer:
std::string str("TestKernelReduce");
Kokkos::parallel_reduce( str , nw , functor_type(nw,count) , host_result.ptr_on_device() );
for ( unsigned j = 0 ; j < count ; ++j ) {
const unsigned long correct = 0 == j % 3 ? nw : nsum ;
ASSERT_EQ( host_result(j), (ScalarType) correct );
host_result(j) = 0 ;
}
}
}
};
}
/*--------------------------------------------------------------------------*/

View File

@ -0,0 +1,97 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
/*--------------------------------------------------------------------------*/
#include <stdio.h>
namespace Test {
template< class Device , class WorkSpec = size_t >
struct TestScan {
typedef Device execution_space ;
typedef long int value_type ;
KOKKOS_INLINE_FUNCTION
void operator()( const int iwork , value_type & update , const bool final_pass ) const
{
const value_type n = iwork + 1 ;
const value_type imbalance = ( (1000 <= n) && (0 == n % 1000) ) ? 1000 : 0 ;
// Insert an artificial load imbalance
for ( value_type i = 0 ; i < imbalance ; ++i ) { ++update ; }
update += n - imbalance ;
if ( final_pass ) {
const value_type answer = n & 1 ? ( n * ( ( n + 1 ) / 2 ) ) : ( ( n / 2 ) * ( n + 1 ) );
if ( answer != update ) {
printf("TestScan(%d,%ld) != %ld\n",iwork,update,answer);
}
}
}
KOKKOS_INLINE_FUNCTION
void init( value_type & update ) const { update = 0 ; }
KOKKOS_INLINE_FUNCTION
void join( volatile value_type & update ,
volatile const value_type & input ) const
{ update += input ; }
TestScan( const WorkSpec & N )
{ parallel_scan( N , *this ); }
static void test_range( const WorkSpec & begin , const WorkSpec & end )
{
for ( WorkSpec i = begin ; i < end ; ++i ) {
(void) TestScan( i );
}
}
};
}

View File

@ -0,0 +1,419 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
#include <impl/Kokkos_ViewTileLeft.hpp>
#include <TestTile.hpp>
#endif
#include <impl/Kokkos_Serial_TaskPolicy.hpp>
//----------------------------------------------------------------------------
#include <TestSharedAlloc.hpp>
#include <TestViewMapping.hpp>
#include <TestViewImpl.hpp>
#include <TestViewAPI.hpp>
#include <TestViewOfClass.hpp>
#include <TestViewSubview.hpp>
#include <TestAtomic.hpp>
#include <TestRange.hpp>
#include <TestTeam.hpp>
#include <TestReduce.hpp>
#include <TestScan.hpp>
#include <TestAggregate.hpp>
#include <TestAggregateReduction.hpp>
#include <TestCompilerMacros.hpp>
#include <TestTaskPolicy.hpp>
#include <TestCXX11.hpp>
#include <TestCXX11Deduction.hpp>
#include <TestTeamVector.hpp>
#include <TestMemorySpaceTracking.hpp>
#include <TestTemplateMetaFunctions.hpp>
namespace Test {
class serial : public ::testing::Test {
protected:
static void SetUpTestCase()
{
Kokkos::HostSpace::execution_space::initialize();
}
static void TearDownTestCase()
{
Kokkos::HostSpace::execution_space::finalize();
}
};
TEST_F( serial , impl_shared_alloc ) {
test_shared_alloc< Kokkos::HostSpace , Kokkos::Serial >();
}
TEST_F( serial , impl_view_mapping ) {
test_view_mapping< Kokkos::Serial >();
test_view_mapping_subview< Kokkos::Serial >();
test_view_mapping_operator< Kokkos::Serial >();
TestViewMappingAtomic< Kokkos::Serial >::run();
}
TEST_F( serial, view_impl) {
test_view_impl< Kokkos::Serial >();
}
TEST_F( serial, view_api) {
TestViewAPI< double , Kokkos::Serial >();
}
TEST_F( serial , view_nested_view )
{
::Test::view_nested_view< Kokkos::Serial >();
}
TEST_F( serial, view_subview_auto_1d_left ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutLeft,Kokkos::Serial >();
}
TEST_F( serial, view_subview_auto_1d_right ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutRight,Kokkos::Serial >();
}
TEST_F( serial, view_subview_auto_1d_stride ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutStride,Kokkos::Serial >();
}
TEST_F( serial, view_subview_assign_strided ) {
TestViewSubview::test_1d_strided_assignment< Kokkos::Serial >();
}
TEST_F( serial, view_subview_left_0 ) {
TestViewSubview::test_left_0< Kokkos::Serial >();
}
TEST_F( serial, view_subview_left_1 ) {
TestViewSubview::test_left_1< Kokkos::Serial >();
}
TEST_F( serial, view_subview_left_2 ) {
TestViewSubview::test_left_2< Kokkos::Serial >();
}
TEST_F( serial, view_subview_left_3 ) {
TestViewSubview::test_left_3< Kokkos::Serial >();
}
TEST_F( serial, view_subview_right_0 ) {
TestViewSubview::test_right_0< Kokkos::Serial >();
}
TEST_F( serial, view_subview_right_1 ) {
TestViewSubview::test_right_1< Kokkos::Serial >();
}
TEST_F( serial, view_subview_right_3 ) {
TestViewSubview::test_right_3< Kokkos::Serial >();
}
TEST_F( serial , range_tag )
{
TestRange< Kokkos::Serial >::test_for(1000);
TestRange< Kokkos::Serial >::test_reduce(1000);
TestRange< Kokkos::Serial >::test_scan(1000);
}
TEST_F( serial , team_tag )
{
TestTeamPolicy< Kokkos::Serial >::test_for( 1000 );
TestTeamPolicy< Kokkos::Serial >::test_reduce( 1000 );
}
TEST_F( serial, long_reduce) {
TestReduce< long , Kokkos::Serial >( 1000000 );
}
TEST_F( serial, double_reduce) {
TestReduce< double , Kokkos::Serial >( 1000000 );
}
TEST_F( serial, long_reduce_dynamic ) {
TestReduceDynamic< long , Kokkos::Serial >( 1000000 );
}
TEST_F( serial, double_reduce_dynamic ) {
TestReduceDynamic< double , Kokkos::Serial >( 1000000 );
}
TEST_F( serial, long_reduce_dynamic_view ) {
TestReduceDynamicView< long , Kokkos::Serial >( 1000000 );
}
TEST_F( serial , scan )
{
TestScan< Kokkos::Serial >::test_range( 1 , 1000 );
TestScan< Kokkos::Serial >( 10 );
TestScan< Kokkos::Serial >( 10000 );
}
TEST_F( serial , team_long_reduce) {
TestReduceTeam< long , Kokkos::Serial >( 100000 );
}
TEST_F( serial , team_double_reduce) {
TestReduceTeam< double , Kokkos::Serial >( 100000 );
}
TEST_F( serial , team_shared_request) {
TestSharedTeam< Kokkos::Serial >();
}
TEST_F( serial , team_scan )
{
TestScanTeam< Kokkos::Serial >( 10 );
TestScanTeam< Kokkos::Serial >( 10000 );
}
TEST_F( serial , view_remap )
{
enum { N0 = 3 , N1 = 2 , N2 = 8 , N3 = 9 };
typedef Kokkos::View< double*[N1][N2][N3] ,
Kokkos::LayoutRight ,
Kokkos::Serial > output_type ;
typedef Kokkos::View< int**[N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::Serial > input_type ;
typedef Kokkos::View< int*[N0][N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::Serial > diff_type ;
output_type output( "output" , N0 );
input_type input ( "input" , N0 , N1 );
diff_type diff ( "diff" , N0 );
int value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
input(i0,i1,i2,i3) = ++value ;
}}}}
// Kokkos::deep_copy( diff , input ); // throw with incompatible shape
Kokkos::deep_copy( output , input );
value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
++value ;
ASSERT_EQ( value , ((int) output(i0,i1,i2,i3) ) );
}}}}
}
//----------------------------------------------------------------------------
TEST_F( serial , view_aggregate )
{
TestViewAggregate< Kokkos::Serial >();
TestViewAggregateReduction< Kokkos::Serial >();
}
//----------------------------------------------------------------------------
TEST_F( serial , atomics )
{
const int loop_count = 1e6 ;
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Serial>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Serial>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Serial>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Serial>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Serial>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Serial>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Serial>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Serial>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Serial>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Serial>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Serial>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Serial>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Serial>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Serial>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Serial>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Serial>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Serial>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Serial>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Serial>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Serial>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Serial>(100,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Serial>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Serial>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Serial>(100,3) ) );
}
//----------------------------------------------------------------------------
#if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
TEST_F( serial, tile_layout )
{
TestTile::test< Kokkos::Serial , 1 , 1 >( 1 , 1 );
TestTile::test< Kokkos::Serial , 1 , 1 >( 2 , 3 );
TestTile::test< Kokkos::Serial , 1 , 1 >( 9 , 10 );
TestTile::test< Kokkos::Serial , 2 , 2 >( 1 , 1 );
TestTile::test< Kokkos::Serial , 2 , 2 >( 2 , 3 );
TestTile::test< Kokkos::Serial , 2 , 2 >( 4 , 4 );
TestTile::test< Kokkos::Serial , 2 , 2 >( 9 , 9 );
TestTile::test< Kokkos::Serial , 2 , 4 >( 9 , 9 );
TestTile::test< Kokkos::Serial , 4 , 2 >( 9 , 9 );
TestTile::test< Kokkos::Serial , 4 , 4 >( 1 , 1 );
TestTile::test< Kokkos::Serial , 4 , 4 >( 4 , 4 );
TestTile::test< Kokkos::Serial , 4 , 4 >( 9 , 9 );
TestTile::test< Kokkos::Serial , 4 , 4 >( 9 , 11 );
TestTile::test< Kokkos::Serial , 8 , 8 >( 1 , 1 );
TestTile::test< Kokkos::Serial , 8 , 8 >( 4 , 4 );
TestTile::test< Kokkos::Serial , 8 , 8 >( 9 , 9 );
TestTile::test< Kokkos::Serial , 8 , 8 >( 9 , 11 );
}
#endif
//----------------------------------------------------------------------------
TEST_F( serial , compiler_macros )
{
ASSERT_TRUE( ( TestCompilerMacros::Test< Kokkos::Serial >() ) );
}
//----------------------------------------------------------------------------
TEST_F( serial , memory_space )
{
TestMemorySpace< Kokkos::Serial >();
}
//----------------------------------------------------------------------------
TEST_F( serial , task_policy )
{
TestTaskPolicy::test_task_dep< Kokkos::Serial >( 10 );
// TestTaskPolicy::test_norm2< Kokkos::Serial >( 1000 );
// for ( long i = 0 ; i < 30 ; ++i ) TestTaskPolicy::test_fib< Kokkos::Serial >(i);
// for ( long i = 0 ; i < 40 ; ++i ) TestTaskPolicy::test_fib2< Kokkos::Serial >(i);
for ( long i = 0 ; i < 20 ; ++i ) TestTaskPolicy::test_fib< Kokkos::Serial >(i);
for ( long i = 0 ; i < 25 ; ++i ) TestTaskPolicy::test_fib2< Kokkos::Serial >(i);
}
#if defined( KOKKOS_HAVE_CXX11 )
TEST_F( serial , task_team )
{
TestTaskPolicy::test_task_team< Kokkos::Serial >(1000);
}
#endif
//----------------------------------------------------------------------------
TEST_F( serial , template_meta_functions )
{
TestTemplateMetaFunctions<int, Kokkos::Serial >();
}
//----------------------------------------------------------------------------
#if defined( KOKKOS_HAVE_CXX11 ) && defined( KOKKOS_HAVE_DEFAULT_DEVICE_TYPE_SERIAL )
TEST_F( serial , cxx11 )
{
if ( Kokkos::Impl::is_same< Kokkos::DefaultExecutionSpace , Kokkos::Serial >::value ) {
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Serial >(1) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Serial >(2) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Serial >(3) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Serial >(4) ) );
}
}
#endif
#if defined (KOKKOS_HAVE_CXX11)
TEST_F( serial , reduction_deduction )
{
TestCXX11::test_reduction_deduction< Kokkos::Serial >();
}
TEST_F( serial , team_vector )
{
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(0) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(1) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(2) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(3) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(4) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(5) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(6) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(7) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(8) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(9) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Serial >(10) ) );
}
#endif
} // namespace test

View File

@ -0,0 +1,204 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <Kokkos_Core.hpp>
/*--------------------------------------------------------------------------*/
namespace Test {
struct SharedAllocDestroy {
volatile int * count ;
SharedAllocDestroy() = default ;
SharedAllocDestroy( int * arg ) : count( arg ) {}
void destroy_shared_allocation()
{
Kokkos::atomic_fetch_add( count , 1 );
}
};
template< class MemorySpace , class ExecutionSpace >
void test_shared_alloc()
{
#if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
typedef const Kokkos::Experimental::Impl::SharedAllocationHeader Header ;
typedef Kokkos::Experimental::Impl::SharedAllocationTracker Tracker ;
typedef Kokkos::Experimental::Impl::SharedAllocationRecord< void , void > RecordBase ;
typedef Kokkos::Experimental::Impl::SharedAllocationRecord< MemorySpace , void > RecordMemS ;
typedef Kokkos::Experimental::Impl::SharedAllocationRecord< MemorySpace , SharedAllocDestroy > RecordFull ;
static_assert( sizeof(Tracker) == sizeof(int*), "SharedAllocationTracker has wrong size!" );
MemorySpace s ;
const size_t N = 1200 ;
const size_t size = 8 ;
RecordMemS * rarray[ N ];
Header * harray[ N ];
RecordMemS ** const r = rarray ;
Header ** const h = harray ;
Kokkos::RangePolicy< ExecutionSpace > range(0,N);
//----------------------------------------
{
Kokkos::parallel_for( range , [=]( size_t i ){
char name[64] ;
sprintf(name,"test_%.2d",int(i));
r[i] = RecordMemS::allocate( s , name , size * ( i + 1 ) );
h[i] = Header::get_header( r[i]->data() );
ASSERT_EQ( r[i]->use_count() , 0 );
for ( size_t j = 0 ; j < ( i / 10 ) + 1 ; ++j ) RecordBase::increment( r[i] );
ASSERT_EQ( r[i]->use_count() , ( i / 10 ) + 1 );
ASSERT_EQ( r[i] , RecordMemS::get_record( r[i]->data() ) );
});
// Sanity check for the whole set of allocation records to which this record belongs.
RecordBase::is_sane( r[0] );
// RecordMemS::print_records( std::cout , s , true );
Kokkos::parallel_for( range , [=]( size_t i ){
while ( 0 != ( r[i] = static_cast< RecordMemS *>( RecordBase::decrement( r[i] ) ) ) ) {
if ( r[i]->use_count() == 1 ) RecordBase::is_sane( r[i] );
}
});
}
//----------------------------------------
{
int destroy_count = 0 ;
SharedAllocDestroy counter( & destroy_count );
Kokkos::parallel_for( range , [=]( size_t i ){
char name[64] ;
sprintf(name,"test_%.2d",int(i));
RecordFull * rec = RecordFull::allocate( s , name , size * ( i + 1 ) );
rec->m_destroy = counter ;
r[i] = rec ;
h[i] = Header::get_header( r[i]->data() );
ASSERT_EQ( r[i]->use_count() , 0 );
for ( size_t j = 0 ; j < ( i / 10 ) + 1 ; ++j ) RecordBase::increment( r[i] );
ASSERT_EQ( r[i]->use_count() , ( i / 10 ) + 1 );
ASSERT_EQ( r[i] , RecordMemS::get_record( r[i]->data() ) );
});
RecordBase::is_sane( r[0] );
Kokkos::parallel_for( range , [=]( size_t i ){
while ( 0 != ( r[i] = static_cast< RecordMemS *>( RecordBase::decrement( r[i] ) ) ) ) {
if ( r[i]->use_count() == 1 ) RecordBase::is_sane( r[i] );
}
});
ASSERT_EQ( destroy_count , int(N) );
}
//----------------------------------------
{
int destroy_count = 0 ;
{
RecordFull * rec = RecordFull::allocate( s , "test" , size );
// ... Construction of the allocated { rec->data() , rec->size() }
// Copy destruction function object into the allocation record
rec->m_destroy = SharedAllocDestroy( & destroy_count );
// Start tracking, increments the use count from 0 to 1
Tracker track( rec );
ASSERT_EQ( rec->use_count() , 1 );
// Verify construction / destruction increment
for ( size_t i = 0 ; i < N ; ++i ) {
ASSERT_EQ( rec->use_count() , 1 );
{
Tracker local_tracker( rec );
ASSERT_EQ( rec->use_count() , 2 );
}
ASSERT_EQ( rec->use_count() , 1 );
}
Kokkos::parallel_for( range , [=]( size_t i ){
Tracker local_tracker( rec );
ASSERT_GT( rec->use_count() , 1 );
});
ASSERT_EQ( rec->use_count() , 1 );
// Destruction of 'track' object deallocates the 'rec' and invokes the destroy function object.
}
ASSERT_EQ( destroy_count , 1 );
}
#endif /* #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) */
}
}

View File

@ -0,0 +1,494 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#ifndef KOKKOS_UNITTEST_TASKPOLICY_HPP
#define KOKKOS_UNITTEST_TASKPOLICY_HPP
#include <stdio.h>
#include <iostream>
#include <cmath>
#include <Kokkos_TaskPolicy.hpp>
namespace TestTaskPolicy {
//----------------------------------------------------------------------------
template< class ExecSpace >
struct FibChild {
typedef long value_type ;
Kokkos::Experimental::TaskPolicy<ExecSpace> policy ;
const value_type n ;
int has_nested ;
FibChild( const Kokkos::Experimental::TaskPolicy<ExecSpace> & arg_policy
, const value_type arg_n )
: policy(arg_policy,2) /* default dependence capacity = 2 */
, n( arg_n ), has_nested(0) {}
inline
void apply( value_type & result )
{
if ( n < 2 ) {
has_nested = -1 ;
result = n ;
}
else {
if ( has_nested == 0 ) {
// Spawn new children and respawn myself to sum their results:
has_nested = 2 ;
Kokkos::Experimental::respawn
( policy
, this
, Kokkos::Experimental::spawn( policy , FibChild(policy,n-1) )
, Kokkos::Experimental::spawn( policy , FibChild(policy,n-2) )
);
}
else if ( has_nested == 2 ) {
has_nested = -1 ;
const Kokkos::Experimental::Future<long,ExecSpace> fib_1 = policy.get_dependence(this,0);
const Kokkos::Experimental::Future<long,ExecSpace> fib_2 = policy.get_dependence(this,1);
result = fib_1.get() + fib_2.get();
}
else {
fprintf(stderr,"FibChild(%ld) execution error\n",(long)n);
fflush(stderr);
}
}
}
};
template< class ExecSpace >
struct FibChild2 {
typedef long value_type ;
Kokkos::Experimental::TaskPolicy<ExecSpace> policy ;
const value_type n ;
int has_nested ;
FibChild2( const Kokkos::Experimental::TaskPolicy<ExecSpace> & arg_policy
, const value_type arg_n )
: policy(arg_policy,2) /* default dependence capacity = 2 */
, n( arg_n ), has_nested(0) {}
inline
void apply( value_type & result )
{
if ( 0 == has_nested ) {
if ( n < 2 ) {
has_nested = -1 ;
result = n ;
}
else if ( n < 4 ) {
// Spawn new children and respawn myself to sum their results:
// result = Fib(n-1) + Fib(n-2)
has_nested = 2 ;
// Kokkos::respawn implements the following steps:
policy.clear_dependence( this );
policy.add_dependence( this , Kokkos::Experimental::spawn( policy , FibChild2(policy,n-1) ) );
policy.add_dependence( this , Kokkos::Experimental::spawn( policy , FibChild2(policy,n-2) ) );
policy.respawn( this );
}
else {
// Spawn new children and respawn myself to sum their results:
// result = Fib(n-1) + Fib(n-2)
// result = ( Fib(n-2) + Fib(n-3) ) + ( Fib(n-3) + Fib(n-4) )
// result = ( ( Fib(n-3) + Fib(n-4) ) + Fib(n-3) ) + ( Fib(n-3) + Fib(n-4) )
// result = 3 * Fib(n-3) + 2 * Fib(n-4)
has_nested = 4 ;
// Kokkos::Experimental::respawn implements the following steps:
policy.clear_dependence( this );
policy.add_dependence( this , Kokkos::Experimental::spawn( policy , FibChild2(policy,n-3) ) );
policy.add_dependence( this , Kokkos::Experimental::spawn( policy , FibChild2(policy,n-4) ) );
policy.respawn( this );
}
}
else if ( 2 == has_nested || 4 == has_nested ) {
const Kokkos::Experimental::Future<long,ExecSpace> fib_a = policy.get_dependence(this,0);
const Kokkos::Experimental::Future<long,ExecSpace> fib_b = policy.get_dependence(this,1);
result = ( has_nested == 2 ) ? fib_a.get() + fib_b.get()
: 3 * fib_a.get() + 2 * fib_b.get() ;
has_nested = -1 ;
}
else {
fprintf(stderr,"FibChild2(%ld) execution error\n",(long)n);
fflush(stderr);
}
}
};
namespace {
long eval_fib( long n )
{
if ( n < 2 ) return n ;
std::vector<long> fib(n+1);
fib[0] = 0 ;
fib[1] = 1 ;
for ( long i = 2 ; i <= n ; ++i ) { fib[i] = fib[i-2] + fib[i-1]; }
return fib[n];
}
}
template< class ExecSpace >
void test_fib( long n )
{
Kokkos::Experimental::TaskPolicy<ExecSpace> policy(2);
Kokkos::Experimental::Future<long,ExecSpace> f = Kokkos::Experimental::spawn( policy , FibChild<ExecSpace>(policy,n) );
Kokkos::Experimental::wait( policy );
if ( f.get() != eval_fib(n) ) {
std::cout << "Fib(" << n << ") = " << f.get();
std::cout << " != " << eval_fib(n);
std::cout << std::endl ;
}
}
template< class ExecSpace >
void test_fib2( long n )
{
Kokkos::Experimental::TaskPolicy<ExecSpace> policy(2); // default dependence capacity
Kokkos::Experimental::Future<long,ExecSpace> f = Kokkos::Experimental::spawn( policy , FibChild2<ExecSpace>(policy,n) );
Kokkos::Experimental::wait( policy );
if ( f.get() != eval_fib(n) ) {
std::cout << "Fib2(" << n << ") = " << f.get();
std::cout << " != " << eval_fib(n);
std::cout << std::endl ;
}
}
//----------------------------------------------------------------------------
template< class ExecSpace >
struct Norm2 {
typedef double value_type ;
const double * const m_x ;
Norm2( const double * x ) : m_x(x) {}
inline
void init( double & val ) const { val = 0 ; }
inline
void operator()( int i , double & val ) const { val += m_x[i] * m_x[i] ; }
void apply( double & dst ) const { dst = std::sqrt( dst ); }
};
template< class ExecSpace >
void test_norm2( const int n )
{
Kokkos::Experimental::TaskPolicy< ExecSpace > policy ;
double * const x = new double[n];
for ( int i = 0 ; i < n ; ++i ) x[i] = 1 ;
Kokkos::RangePolicy<ExecSpace> r(0,n);
Kokkos::Experimental::Future<double,ExecSpace> f = Kokkos::Experimental::spawn_reduce( policy , r , Norm2<ExecSpace>(x) );
Kokkos::Experimental::wait( policy );
#if defined(PRINT)
std::cout << "Norm2: " << f.get() << std::endl ;
#endif
delete[] x ;
}
//----------------------------------------------------------------------------
template< class Space >
struct TaskDep {
typedef int value_type ;
typedef Kokkos::Experimental::TaskPolicy< Space > policy_type ;
const policy_type policy ;
const int input ;
TaskDep( const policy_type & arg_p , const int arg_i )
: policy( arg_p ), input( arg_i ) {}
void apply( int & val )
{
val = input ;
const int num = policy.get_dependence( this );
for ( int i = 0 ; i < num ; ++i ) {
Kokkos::Experimental::Future<int,Space> f = policy.get_dependence( this , i );
val += f.get();
}
}
};
template< class Space >
void test_task_dep( const int n )
{
enum { NTEST = 64 };
Kokkos::Experimental::TaskPolicy< Space > policy ;
Kokkos::Experimental::Future<int,Space> f[ NTEST ];
for ( int i = 0 ; i < NTEST ; ++i ) {
// Create task in the "constructing" state with capacity for 'n+1' dependences
f[i] = policy.create( TaskDep<Space>(policy,0) , n + 1 );
if ( f[i].get_task_state() != Kokkos::Experimental::TASK_STATE_CONSTRUCTING ) {
Kokkos::Impl::throw_runtime_exception("get_task_state() != Kokkos::Experimental::TASK_STATE_CONSTRUCTING");
}
// Only use 'n' dependences
for ( int j = 0 ; j < n ; ++j ) {
Kokkos::Experimental::Future<int,Space> nested = policy.create( TaskDep<Space>(policy,j+1) );
policy.spawn( nested );
// Add dependence to a "constructing" task
policy.add_dependence( f[i] , nested );
}
// Spawn task from the "constructing" to the "waiting" state
policy.spawn( f[i] );
}
const int answer = n % 2 ? n * ( ( n + 1 ) / 2 ) : ( n / 2 ) * ( n + 1 );
Kokkos::Experimental::wait( policy );
int error = 0 ;
for ( int i = 0 ; i < NTEST ; ++i ) {
if ( f[i].get_task_state() != Kokkos::Experimental::TASK_STATE_COMPLETE ) {
Kokkos::Impl::throw_runtime_exception("get_task_state() != Kokkos::Experimental::TASK_STATE_COMPLETE");
}
if ( answer != f[i].get() && 0 == error ) {
std::cout << "test_task_dep(" << n << ") ERROR at[" << i << "]"
<< " answer(" << answer << ") != result(" << f[i].get() << ")" << std::endl ;
}
}
}
//----------------------------------------------------------------------------
#if defined( KOKKOS_HAVE_CXX11 )
template< class ExecSpace >
struct TaskTeam {
enum { SPAN = 8 };
typedef void value_type ;
typedef Kokkos::Experimental::TaskPolicy<ExecSpace> policy_type ;
typedef Kokkos::Experimental::Future<ExecSpace> future_type ;
typedef Kokkos::View<long*,ExecSpace> view_type ;
policy_type policy ;
future_type future ;
view_type result ;
const long nvalue ;
TaskTeam( const policy_type & arg_policy
, const view_type & arg_result
, const long arg_nvalue )
: policy(arg_policy)
, future()
, result( arg_result )
, nvalue( arg_nvalue )
{}
inline
void apply( const typename policy_type::member_type & member )
{
const long end = nvalue + 1 ;
const long begin = 0 < end - SPAN ? end - SPAN : 0 ;
if ( 0 < begin && future.get_task_state() == Kokkos::Experimental::TASK_STATE_NULL ) {
if ( member.team_rank() == 0 ) {
future = policy.spawn( policy.create_team( TaskTeam( policy , result , begin - 1 ) ) );
policy.clear_dependence( this );
policy.add_dependence( this , future );
policy.respawn( this );
}
return ;
}
Kokkos::parallel_for( Kokkos::TeamThreadRange(member,begin,end)
, [&]( int i ) { result[i] = i + 1 ; }
);
}
};
template< class ExecSpace >
struct TaskTeamValue {
enum { SPAN = 8 };
typedef long value_type ;
typedef Kokkos::Experimental::TaskPolicy<ExecSpace> policy_type ;
typedef Kokkos::Experimental::Future<value_type,ExecSpace> future_type ;
typedef Kokkos::View<long*,ExecSpace> view_type ;
policy_type policy ;
future_type future ;
view_type result ;
const long nvalue ;
TaskTeamValue( const policy_type & arg_policy
, const view_type & arg_result
, const long arg_nvalue )
: policy(arg_policy)
, future()
, result( arg_result )
, nvalue( arg_nvalue )
{}
inline
void apply( const typename policy_type::member_type & member , value_type & final )
{
const long end = nvalue + 1 ;
const long begin = 0 < end - SPAN ? end - SPAN : 0 ;
if ( 0 < begin && future.get_task_state() == Kokkos::Experimental::TASK_STATE_NULL ) {
if ( member.team_rank() == 0 ) {
future = policy.spawn( policy.create_team( TaskTeamValue( policy , result , begin - 1 ) ) );
policy.clear_dependence( this );
policy.add_dependence( this , future );
policy.respawn( this );
}
return ;
}
Kokkos::parallel_for( Kokkos::TeamThreadRange(member,begin,end)
, [&]( int i ) { result[i] = i + 1 ; }
);
if ( member.team_rank() == 0 ) {
final = result[nvalue] ;
}
Kokkos::memory_fence();
}
};
template< class ExecSpace >
void test_task_team( long n )
{
typedef TaskTeam< ExecSpace > task_type ;
typedef TaskTeamValue< ExecSpace > task_value_type ;
typedef typename task_type::view_type view_type ;
typedef typename task_type::policy_type policy_type ;
typedef typename task_type::future_type future_type ;
typedef typename task_value_type::future_type future_value_type ;
policy_type policy ;
view_type result("result",n+1);
future_type f = policy.spawn( policy.create_team( task_type( policy , result , n ) ) );
Kokkos::Experimental::wait( policy );
for ( long i = 0 ; i <= n ; ++i ) {
const long answer = i + 1 ;
if ( result(i) != answer ) {
std::cerr << "test_task_team void ERROR result(" << i << ") = " << result(i) << " != " << answer << std::endl ;
}
}
future_value_type fv = policy.spawn( policy.create_team( task_value_type( policy , result , n ) ) );
Kokkos::Experimental::wait( policy );
if ( fv.get() != n + 1 ) {
std::cerr << "test_task_team value ERROR future = " << fv.get() << " != " << n + 1 << std::endl ;
}
for ( long i = 0 ; i <= n ; ++i ) {
const long answer = i + 1 ;
if ( result(i) != answer ) {
std::cerr << "test_task_team value ERROR result(" << i << ") = " << result(i) << " != " << answer << std::endl ;
}
}
}
#endif
//----------------------------------------------------------------------------
} // namespace TestTaskPolicy
#endif /* #ifndef KOKKOS_UNITTEST_TASKPOLICY_HPP */

View File

@ -0,0 +1,466 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <stdio.h>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <Kokkos_Core.hpp>
/*--------------------------------------------------------------------------*/
namespace Test {
namespace {
template< class ExecSpace >
struct TestTeamPolicy {
typedef typename Kokkos::TeamPolicy< ExecSpace >::member_type team_member ;
typedef Kokkos::View<int**,ExecSpace> view_type ;
view_type m_flags ;
TestTeamPolicy( const size_t league_size )
: m_flags( Kokkos::ViewAllocateWithoutInitializing("flags")
, Kokkos::TeamPolicy< ExecSpace >::team_size_max( *this )
, league_size )
{}
struct VerifyInitTag {};
KOKKOS_INLINE_FUNCTION
void operator()( const team_member & member ) const
{
const int tid = member.team_rank() + member.team_size() * member.league_rank();
m_flags( member.team_rank() , member.league_rank() ) = tid ;
}
KOKKOS_INLINE_FUNCTION
void operator()( const VerifyInitTag & , const team_member & member ) const
{
const int tid = member.team_rank() + member.team_size() * member.league_rank();
if ( tid != m_flags( member.team_rank() , member.league_rank() ) ) {
printf("TestTeamPolicy member(%d,%d) error %d != %d\n"
, member.league_rank() , member.team_rank()
, tid , m_flags( member.team_rank() , member.league_rank() ) );
}
}
static void test_for( const size_t league_size )
{
TestTeamPolicy functor( league_size );
const int team_size = Kokkos::TeamPolicy< ExecSpace >::team_size_max( functor );
Kokkos::parallel_for( Kokkos::TeamPolicy< ExecSpace >( league_size , team_size ) , functor );
Kokkos::parallel_for( Kokkos::TeamPolicy< ExecSpace , VerifyInitTag >( league_size , team_size ) , functor );
}
struct ReduceTag {};
typedef long value_type ;
KOKKOS_INLINE_FUNCTION
void operator()( const team_member & member , value_type & update ) const
{
update += member.team_rank() + member.team_size() * member.league_rank();
}
KOKKOS_INLINE_FUNCTION
void operator()( const ReduceTag & , const team_member & member , value_type & update ) const
{
update += 1 + member.team_rank() + member.team_size() * member.league_rank();
}
static void test_reduce( const size_t league_size )
{
TestTeamPolicy functor( league_size );
const int team_size = Kokkos::TeamPolicy< ExecSpace >::team_size_max( functor );
const long N = team_size * league_size ;
long total = 0 ;
Kokkos::parallel_reduce( Kokkos::TeamPolicy< ExecSpace >( league_size , team_size ) , functor , total );
ASSERT_EQ( size_t((N-1)*(N))/2 , size_t(total) );
Kokkos::parallel_reduce( Kokkos::TeamPolicy< ExecSpace , ReduceTag >( league_size , team_size ) , functor , total );
ASSERT_EQ( (size_t(N)*size_t(N+1))/2 , size_t(total) );
}
};
}
}
/*--------------------------------------------------------------------------*/
namespace Test {
template< typename ScalarType , class DeviceType >
class ReduceTeamFunctor
{
public:
typedef DeviceType execution_space ;
typedef Kokkos::TeamPolicy< execution_space > policy_type ;
typedef typename execution_space::size_type size_type ;
struct value_type {
ScalarType value[3] ;
};
const size_type nwork ;
ReduceTeamFunctor( const size_type & arg_nwork ) : nwork( arg_nwork ) {}
ReduceTeamFunctor( const ReduceTeamFunctor & rhs )
: nwork( rhs.nwork ) {}
KOKKOS_INLINE_FUNCTION
void init( value_type & dst ) const
{
dst.value[0] = 0 ;
dst.value[1] = 0 ;
dst.value[2] = 0 ;
}
KOKKOS_INLINE_FUNCTION
void join( volatile value_type & dst ,
const volatile value_type & src ) const
{
dst.value[0] += src.value[0] ;
dst.value[1] += src.value[1] ;
dst.value[2] += src.value[2] ;
}
KOKKOS_INLINE_FUNCTION
void operator()( const typename policy_type::member_type ind , value_type & dst ) const
{
const int thread_rank = ind.team_rank() + ind.team_size() * ind.league_rank();
const int thread_size = ind.team_size() * ind.league_size();
const int chunk = ( nwork + thread_size - 1 ) / thread_size ;
size_type iwork = chunk * thread_rank ;
const size_type iwork_end = iwork + chunk < nwork ? iwork + chunk : nwork ;
for ( ; iwork < iwork_end ; ++iwork ) {
dst.value[0] += 1 ;
dst.value[1] += iwork + 1 ;
dst.value[2] += nwork - iwork ;
}
}
};
} // namespace Test
namespace {
template< typename ScalarType , class DeviceType >
class TestReduceTeam
{
public:
typedef DeviceType execution_space ;
typedef Kokkos::TeamPolicy< execution_space > policy_type ;
typedef typename execution_space::size_type size_type ;
//------------------------------------
TestReduceTeam( const size_type & nwork )
{
run_test(nwork);
}
void run_test( const size_type & nwork )
{
typedef Test::ReduceTeamFunctor< ScalarType , execution_space > functor_type ;
typedef typename functor_type::value_type value_type ;
typedef Kokkos::View< value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged > result_type ;
enum { Count = 3 };
enum { Repeat = 100 };
value_type result[ Repeat ];
const unsigned long nw = nwork ;
const unsigned long nsum = nw % 2 ? nw * (( nw + 1 )/2 )
: (nw/2) * ( nw + 1 );
const unsigned team_size = policy_type::team_size_recommended( functor_type(nwork) );
const unsigned league_size = ( nwork + team_size - 1 ) / team_size ;
policy_type team_exec( league_size , team_size );
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
result_type tmp( & result[i] );
Kokkos::parallel_reduce( team_exec , functor_type(nwork) , tmp );
}
execution_space::fence();
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
for ( unsigned j = 0 ; j < Count ; ++j ) {
const unsigned long correct = 0 == j % 3 ? nw : nsum ;
ASSERT_EQ( (ScalarType) correct , result[i].value[j] );
}
}
}
};
}
/*--------------------------------------------------------------------------*/
namespace Test {
template< class DeviceType >
class ScanTeamFunctor
{
public:
typedef DeviceType execution_space ;
typedef Kokkos::TeamPolicy< execution_space > policy_type ;
typedef long int value_type ;
Kokkos::View< value_type , execution_space > accum ;
Kokkos::View< value_type , execution_space > total ;
ScanTeamFunctor() : accum("accum"), total("total") {}
KOKKOS_INLINE_FUNCTION
void init( value_type & error ) const { error = 0 ; }
KOKKOS_INLINE_FUNCTION
void join( value_type volatile & error ,
value_type volatile const & input ) const
{ if ( input ) error = 1 ; }
struct JoinMax {
typedef long int value_type ;
KOKKOS_INLINE_FUNCTION
void join( value_type volatile & dst
, value_type volatile const & input ) const
{ if ( dst < input ) dst = input ; }
};
KOKKOS_INLINE_FUNCTION
void operator()( const typename policy_type::member_type ind , value_type & error ) const
{
if ( 0 == ind.league_rank() && 0 == ind.team_rank() ) {
const long int thread_count = ind.league_size() * ind.team_size();
total() = ( thread_count * ( thread_count + 1 ) ) / 2 ;
}
// Team max:
const int long m = ind.team_reduce( (long int) ( ind.league_rank() + ind.team_rank() ) , JoinMax() );
if ( m != ind.league_rank() + ( ind.team_size() - 1 ) ) {
printf("ScanTeamFunctor[%d.%d of %d.%d] reduce_max_answer(%ld) != reduce_max(%ld)\n"
, ind.league_rank(), ind.team_rank()
, ind.league_size(), ind.team_size()
, (long int)(ind.league_rank() + ( ind.team_size() - 1 )) , m );
}
// Scan:
const long int answer =
( ind.league_rank() + 1 ) * ind.team_rank() +
( ind.team_rank() * ( ind.team_rank() + 1 ) ) / 2 ;
const long int result =
ind.team_scan( ind.league_rank() + 1 + ind.team_rank() + 1 );
const long int result2 =
ind.team_scan( ind.league_rank() + 1 + ind.team_rank() + 1 );
if ( answer != result || answer != result2 ) {
printf("ScanTeamFunctor[%d.%d of %d.%d] answer(%ld) != scan_first(%ld) or scan_second(%ld)\n",
ind.league_rank(), ind.team_rank(),
ind.league_size(), ind.team_size(),
answer,result,result2);
error = 1 ;
}
const long int thread_rank = ind.team_rank() +
ind.team_size() * ind.league_rank();
ind.team_scan( 1 + thread_rank , accum.ptr_on_device() );
}
};
template< class DeviceType >
class TestScanTeam
{
public:
typedef DeviceType execution_space ;
typedef long int value_type ;
typedef Kokkos::TeamPolicy< execution_space > policy_type ;
typedef Test::ScanTeamFunctor<DeviceType> functor_type ;
//------------------------------------
TestScanTeam( const size_t nteam )
{
run_test(nteam);
}
void run_test( const size_t nteam )
{
typedef Kokkos::View< long int , Kokkos::HostSpace , Kokkos::MemoryUnmanaged > result_type ;
const unsigned REPEAT = 100000 ;
const unsigned Repeat = ( REPEAT + nteam - 1 ) / nteam ;
functor_type functor ;
policy_type team_exec( nteam , policy_type::team_size_max( functor ) );
for ( unsigned i = 0 ; i < Repeat ; ++i ) {
long int accum = 0 ;
long int total = 0 ;
long int error = 0 ;
Kokkos::deep_copy( functor.accum , total );
Kokkos::parallel_reduce( team_exec , functor , result_type( & error ) );
DeviceType::fence();
Kokkos::deep_copy( accum , functor.accum );
Kokkos::deep_copy( total , functor.total );
ASSERT_EQ( error , 0 );
ASSERT_EQ( total , accum );
}
execution_space::fence();
}
};
} // namespace Test
/*--------------------------------------------------------------------------*/
namespace Test {
template< class ExecSpace >
struct SharedTeamFunctor {
typedef ExecSpace execution_space ;
typedef int value_type ;
typedef Kokkos::TeamPolicy< execution_space > policy_type ;
enum { SHARED_COUNT = 1000 };
typedef typename ExecSpace::scratch_memory_space shmem_space ;
// tbd: MemoryUnmanaged should be the default for shared memory space
typedef Kokkos::View<int*,shmem_space,Kokkos::MemoryUnmanaged> shared_int_array_type ;
// Tell how much shared memory will be required by this functor:
inline
unsigned team_shmem_size( int /* team_size */ ) const
{
return shared_int_array_type::shmem_size( SHARED_COUNT ) +
shared_int_array_type::shmem_size( SHARED_COUNT );
}
KOKKOS_INLINE_FUNCTION
void operator()( const typename policy_type::member_type & ind , value_type & update ) const
{
const shared_int_array_type shared_A( ind.team_shmem() , SHARED_COUNT );
const shared_int_array_type shared_B( ind.team_shmem() , SHARED_COUNT );
if ((shared_A.ptr_on_device () == NULL && SHARED_COUNT > 0) ||
(shared_B.ptr_on_device () == NULL && SHARED_COUNT > 0)) {
printf ("Failed to allocate shared memory of size %lu\n",
static_cast<unsigned long> (SHARED_COUNT));
++update; // failure to allocate is an error
}
else {
for ( int i = ind.team_rank() ; i < SHARED_COUNT ; i += ind.team_size() ) {
shared_A[i] = i + ind.league_rank();
shared_B[i] = 2 * i + ind.league_rank();
}
ind.team_barrier();
if ( ind.team_rank() + 1 == ind.team_size() ) {
for ( int i = 0 ; i < SHARED_COUNT ; ++i ) {
if ( shared_A[i] != i + ind.league_rank() ) {
++update ;
}
if ( shared_B[i] != 2 * i + ind.league_rank() ) {
++update ;
}
}
}
}
}
};
}
namespace {
template< class ExecSpace >
struct TestSharedTeam {
TestSharedTeam()
{ run(); }
void run()
{
typedef Test::SharedTeamFunctor<ExecSpace> Functor ;
typedef Kokkos::View< typename Functor::value_type , Kokkos::HostSpace , Kokkos::MemoryUnmanaged > result_type ;
const size_t team_size = Kokkos::TeamPolicy< ExecSpace >::team_size_max( Functor() );
Kokkos::TeamPolicy< ExecSpace > team_exec( 8192 / team_size , team_size );
typename Functor::value_type error_count = 0 ;
Kokkos::parallel_reduce( team_exec , Functor() , result_type( & error_count ) );
ASSERT_EQ( error_count , 0 );
}
};
}
/*--------------------------------------------------------------------------*/

View File

@ -0,0 +1,650 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
#include <impl/Kokkos_Timer.hpp>
#include <iostream>
#include <cstdlib>
namespace TestTeamVector {
struct my_complex {
double re,im;
int dummy;
KOKKOS_INLINE_FUNCTION
my_complex() {
re = 0.0;
im = 0.0;
dummy = 0;
}
KOKKOS_INLINE_FUNCTION
my_complex(const my_complex& src) {
re = src.re;
im = src.im;
dummy = src.dummy;
}
KOKKOS_INLINE_FUNCTION
my_complex(const volatile my_complex& src) {
re = src.re;
im = src.im;
dummy = src.dummy;
}
KOKKOS_INLINE_FUNCTION
my_complex(const double& val) {
re = val;
im = 0.0;
dummy = 0;
}
KOKKOS_INLINE_FUNCTION
my_complex& operator += (const my_complex& src) {
re += src.re;
im += src.im;
dummy += src.dummy;
return *this;
}
KOKKOS_INLINE_FUNCTION
void operator += (const volatile my_complex& src) volatile {
re += src.re;
im += src.im;
dummy += src.dummy;
}
KOKKOS_INLINE_FUNCTION
my_complex& operator *= (const my_complex& src) {
double re_tmp = re*src.re - im*src.im;
double im_tmp = re * src.im + im * src.re;
re = re_tmp;
im = im_tmp;
dummy *= src.dummy;
return *this;
}
KOKKOS_INLINE_FUNCTION
void operator *= (const volatile my_complex& src) volatile {
double re_tmp = re*src.re - im*src.im;
double im_tmp = re * src.im + im * src.re;
re = re_tmp;
im = im_tmp;
dummy *= src.dummy;
}
KOKKOS_INLINE_FUNCTION
bool operator == (const my_complex& src) {
return (re == src.re) && (im == src.im) && ( dummy == src.dummy );
}
KOKKOS_INLINE_FUNCTION
bool operator != (const my_complex& src) {
return (re != src.re) || (im != src.im) || ( dummy != src.dummy );
}
KOKKOS_INLINE_FUNCTION
bool operator != (const double& val) {
return (re != val) ||
(im != 0) || (dummy != 0);
}
KOKKOS_INLINE_FUNCTION
my_complex& operator= (const int& val) {
re = val;
im = 0.0;
dummy = 0;
return *this;
}
KOKKOS_INLINE_FUNCTION
my_complex& operator= (const double& val) {
re = val;
im = 0.0;
dummy = 0;
return *this;
}
KOKKOS_INLINE_FUNCTION
operator double() {
return re;
}
};
#if defined (KOKKOS_HAVE_CXX11)
template<typename Scalar, class ExecutionSpace>
struct functor_team_for {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_team_for(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
unsigned team_shmem_size(int team_size) const {return team_size*13*sizeof(Scalar)+8;}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
typedef typename ExecutionSpace::scratch_memory_space shmem_space ;
typedef Kokkos::View<Scalar*,shmem_space,Kokkos::MemoryUnmanaged> shared_int;
typedef typename shared_int::size_type size_type;
const size_type shmemSize = team.team_size () * 13;
shared_int values = shared_int (team.team_shmem (), shmemSize);
if (values.ptr_on_device () == NULL || values.dimension_0 () < shmemSize) {
printf ("FAILED to allocate shared memory of size %u\n",
static_cast<unsigned int> (shmemSize));
}
else {
// Initialize shared memory
values(team.team_rank ()) = 0;
// Accumulate value into per thread shared memory
// This is non blocking
Kokkos::parallel_for(Kokkos::TeamThreadRange(team,131),[&] (int i) {
values(team.team_rank ()) += i - team.league_rank () + team.league_size () + team.team_size ();
});
// Wait for all memory to be written
team.team_barrier ();
// One thread per team executes the comparison
Kokkos::single(Kokkos::PerTeam(team),[&]() {
Scalar test = 0;
Scalar value = 0;
for (int i = 0; i < 131; ++i) {
test += i - team.league_rank () + team.league_size () + team.team_size ();
}
for (int i = 0; i < team.team_size (); ++i) {
value += values(i);
}
if (test != value) {
printf ("FAILED team_parallel_for %i %i %f %f\n",
team.league_rank (), team.team_rank (),
static_cast<double> (test), static_cast<double> (value));
flag() = 1;
}
});
}
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_team_reduce {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_team_reduce(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
unsigned team_shmem_size(int team_size) const {return team_size*13*sizeof(Scalar)+8;}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
Scalar value = Scalar();
Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team,131),[&] (int i, Scalar& val) {
val += i - team.league_rank () + team.league_size () + team.team_size ();
},value);
team.team_barrier ();
Kokkos::single(Kokkos::PerTeam(team),[&]() {
Scalar test = 0;
for (int i = 0; i < 131; ++i) {
test += i - team.league_rank () + team.league_size () + team.team_size ();
}
if (test != value) {
if(team.league_rank() == 0)
printf ("FAILED team_parallel_reduce %i %i %f %f %lu\n",
team.league_rank (), team.team_rank (),
static_cast<double> (test), static_cast<double> (value),sizeof(Scalar));
flag() = 1;
}
});
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_team_reduce_join {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_team_reduce_join(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
unsigned team_shmem_size(int team_size) const {return team_size*13*sizeof(Scalar)+8;}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
Scalar value = 0;
Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team,131)
, [&] (int i, Scalar& val) {
val += i - team.league_rank () + team.league_size () + team.team_size ();
}
, [&] (volatile Scalar& val, const volatile Scalar& src) {val+=src;}
, value
);
team.team_barrier ();
Kokkos::single(Kokkos::PerTeam(team),[&]() {
Scalar test = 0;
for (int i = 0; i < 131; ++i) {
test += i - team.league_rank () + team.league_size () + team.team_size ();
}
if (test != value) {
printf ("FAILED team_vector_parallel_reduce_join %i %i %f %f\n",
team.league_rank (), team.team_rank (),
static_cast<double> (test), static_cast<double> (value));
flag() = 1;
}
});
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_team_vector_for {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_team_vector_for(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
unsigned team_shmem_size(int team_size) const {return team_size*13*sizeof(Scalar)+8;}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
typedef typename ExecutionSpace::scratch_memory_space shmem_space ;
typedef Kokkos::View<Scalar*,shmem_space,Kokkos::MemoryUnmanaged> shared_int;
typedef typename shared_int::size_type size_type;
const size_type shmemSize = team.team_size () * 13;
shared_int values = shared_int (team.team_shmem (), shmemSize);
if (values.ptr_on_device () == NULL || values.dimension_0 () < shmemSize) {
printf ("FAILED to allocate shared memory of size %u\n",
static_cast<unsigned int> (shmemSize));
}
else {
Kokkos::single(Kokkos::PerThread(team),[&] () {
values(team.team_rank ()) = 0;
});
Kokkos::parallel_for(Kokkos::TeamThreadRange(team,131),[&] (int i) {
Kokkos::single(Kokkos::PerThread(team),[&] () {
values(team.team_rank ()) += i - team.league_rank () + team.league_size () + team.team_size ();
});
});
team.team_barrier ();
Kokkos::single(Kokkos::PerTeam(team),[&]() {
Scalar test = 0;
Scalar value = 0;
for (int i = 0; i < 131; ++i) {
test += i - team.league_rank () + team.league_size () + team.team_size ();
}
for (int i = 0; i < team.team_size (); ++i) {
value += values(i);
}
if (test != value) {
printf ("FAILED team_vector_parallel_for %i %i %f %f\n",
team.league_rank (), team.team_rank (),
static_cast<double> (test), static_cast<double> (value));
flag() = 1;
}
});
}
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_team_vector_reduce {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_team_vector_reduce(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
unsigned team_shmem_size(int team_size) const {return team_size*13*sizeof(Scalar)+8;}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
Scalar value = Scalar();
Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team,131),[&] (int i, Scalar& val) {
val += i - team.league_rank () + team.league_size () + team.team_size ();
},value);
team.team_barrier ();
Kokkos::single(Kokkos::PerTeam(team),[&]() {
Scalar test = 0;
for (int i = 0; i < 131; ++i) {
test += i - team.league_rank () + team.league_size () + team.team_size ();
}
if (test != value) {
if(team.league_rank() == 0)
printf ("FAILED team_vector_parallel_reduce %i %i %f %f %lu\n",
team.league_rank (), team.team_rank (),
static_cast<double> (test), static_cast<double> (value),sizeof(Scalar));
flag() = 1;
}
});
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_team_vector_reduce_join {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_team_vector_reduce_join(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
unsigned team_shmem_size(int team_size) const {return team_size*13*sizeof(Scalar)+8;}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
Scalar value = 0;
Kokkos::parallel_reduce(Kokkos::TeamThreadRange(team,131)
, [&] (int i, Scalar& val) {
val += i - team.league_rank () + team.league_size () + team.team_size ();
}
, [&] (volatile Scalar& val, const volatile Scalar& src) {val+=src;}
, value
);
team.team_barrier ();
Kokkos::single(Kokkos::PerTeam(team),[&]() {
Scalar test = 0;
for (int i = 0; i < 131; ++i) {
test += i - team.league_rank () + team.league_size () + team.team_size ();
}
if (test != value) {
printf ("FAILED team_vector_parallel_reduce_join %i %i %f %f\n",
team.league_rank (), team.team_rank (),
static_cast<double> (test), static_cast<double> (value));
flag() = 1;
}
});
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_vec_single {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_vec_single(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
// Warning: this test case intentionally violates permissable semantics
// It is not valid to get references to members of the enclosing region
// inside a parallel_for and write to it.
Scalar value = 0;
Kokkos::parallel_for(Kokkos::ThreadVectorRange(team,13),[&] (int i) {
value = i; // This write is violating Kokkos semantics for nested parallelism
});
Kokkos::single(Kokkos::PerThread(team),[&] (Scalar& val) {
val = 1;
},value);
Scalar value2 = 0;
Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,13), [&] (int i, Scalar& val) {
val += value;
},value2);
if(value2!=(value*13)) {
printf("FAILED vector_single broadcast %i %i %f %f\n",team.league_rank(),team.team_rank(),(double) value2,(double) value);
flag()=1;
}
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_vec_for {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_vec_for(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
unsigned team_shmem_size(int team_size) const {return team_size*13*sizeof(Scalar)+8;}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
typedef typename ExecutionSpace::scratch_memory_space shmem_space ;
typedef Kokkos::View<Scalar*,shmem_space,Kokkos::MemoryUnmanaged> shared_int;
shared_int values = shared_int(team.team_shmem(),team.team_size()*13);
if (values.ptr_on_device () == NULL ||
values.dimension_0() < (unsigned) team.team_size() * 13) {
printf ("FAILED to allocate memory of size %i\n",
static_cast<int> (team.team_size () * 13));
flag() = 1;
}
else {
Kokkos::parallel_for(Kokkos::ThreadVectorRange(team,13), [&] (int i) {
values(13*team.team_rank() + i) = i - team.team_rank() - team.league_rank() + team.league_size() + team.team_size();
});
Kokkos::single(Kokkos::PerThread(team),[&] () {
Scalar test = 0;
Scalar value = 0;
for (int i = 0; i < 13; ++i) {
test += i - team.team_rank() - team.league_rank() + team.league_size() + team.team_size();
value += values(13*team.team_rank() + i);
}
if (test != value) {
printf ("FAILED vector_par_for %i %i %f %f\n",
team.league_rank (), team.team_rank (),
static_cast<double> (test), static_cast<double> (value));
flag() = 1;
}
});
}
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_vec_red {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_vec_red(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
Scalar value = 0;
Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,13),[&] (int i, Scalar& val) {
val += i;
}, value);
Kokkos::single(Kokkos::PerThread(team),[&] () {
Scalar test = 0;
for(int i = 0; i < 13; i++) {
test+=i;
}
if(test!=value) {
printf("FAILED vector_par_reduce %i %i %f %f\n",team.league_rank(),team.team_rank(),(double) test,(double) value);
flag()=1;
}
});
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_vec_red_join {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_vec_red_join(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
Scalar value = 1;
Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,13)
, [&] (int i, Scalar& val) { val *= i; }
, [&] (Scalar& val, const Scalar& src) {val*=src;}
, value
);
Kokkos::single(Kokkos::PerThread(team),[&] () {
Scalar test = 1;
for(int i = 0; i < 13; i++) {
test*=i;
}
if(test!=value) {
printf("FAILED vector_par_reduce_join %i %i %f %f\n",team.league_rank(),team.team_rank(),(double) test,(double) value);
flag()=1;
}
});
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_vec_scan {
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_vec_scan(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team) const {
Kokkos::parallel_scan(Kokkos::ThreadVectorRange(team,13),[&] (int i, Scalar& val, bool final) {
val += i;
if(final) {
Scalar test = 0;
for(int k = 0; k <= i; k++) {
test+=k;
}
if(test!=val) {
printf("FAILED vector_par_scan %i %i %f %f\n",team.league_rank(),team.team_rank(),(double) test,(double) val);
flag()=1;
}
}
});
}
};
template<typename Scalar, class ExecutionSpace>
struct functor_reduce {
typedef double value_type;
typedef Kokkos::TeamPolicy<ExecutionSpace> policy_type;
typedef ExecutionSpace execution_space;
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag;
functor_reduce(Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> flag_):flag(flag_) {}
KOKKOS_INLINE_FUNCTION
void operator() (typename policy_type::member_type team, double& sum) const {
sum += team.league_rank() * 100 + team.thread_rank();
}
};
#endif
template<typename Scalar,class ExecutionSpace>
bool test_scalar(int nteams, int team_size, int test) {
Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace> d_flag("flag");
typename Kokkos::View<int,Kokkos::LayoutLeft,ExecutionSpace>::HostMirror h_flag("h_flag");
h_flag() = 0 ;
Kokkos::deep_copy(d_flag,h_flag);
#ifdef KOKKOS_HAVE_CXX11
if(test==0)
Kokkos::parallel_for( std::string("A") , Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_vec_red<Scalar, ExecutionSpace>(d_flag));
if(test==1)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_vec_red_join<Scalar, ExecutionSpace>(d_flag));
if(test==2)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_vec_scan<Scalar, ExecutionSpace>(d_flag));
if(test==3)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_vec_for<Scalar, ExecutionSpace>(d_flag));
if(test==4)
Kokkos::parallel_for( "B" , Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_vec_single<Scalar, ExecutionSpace>(d_flag));
if(test==5)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size),
functor_team_for<Scalar, ExecutionSpace>(d_flag));
if(test==6)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size),
functor_team_reduce<Scalar, ExecutionSpace>(d_flag));
if(test==7)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size),
functor_team_reduce_join<Scalar, ExecutionSpace>(d_flag));
if(test==8)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_team_vector_for<Scalar, ExecutionSpace>(d_flag));
if(test==9)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_team_vector_reduce<Scalar, ExecutionSpace>(d_flag));
if(test==10)
Kokkos::parallel_for( Kokkos::TeamPolicy<ExecutionSpace>(nteams,team_size,8),
functor_team_vector_reduce_join<Scalar, ExecutionSpace>(d_flag));
#endif
Kokkos::deep_copy(h_flag,d_flag);
return (h_flag() == 0);
}
template<class ExecutionSpace>
bool Test(int test) {
bool passed = true;
passed = passed && test_scalar<int, ExecutionSpace>(317,33,test);
passed = passed && test_scalar<long long int, ExecutionSpace>(317,33,test);
passed = passed && test_scalar<float, ExecutionSpace>(317,33,test);
passed = passed && test_scalar<double, ExecutionSpace>(317,33,test);
passed = passed && test_scalar<my_complex, ExecutionSpace>(317,33,test);
return passed;
}
}

View File

@ -0,0 +1,219 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
#define KOKKOS_PRAGMA_UNROLL(a)
namespace {
template<class Scalar, class ExecutionSpace>
struct SumPlain {
typedef ExecutionSpace execution_space;
typedef typename Kokkos::View<Scalar*,execution_space> type;
type view;
SumPlain(type view_):view(view_) {}
KOKKOS_INLINE_FUNCTION
void operator() (int i, Scalar& val) {
val += Scalar();
}
};
template<class Scalar, class ExecutionSpace>
struct SumInitJoinFinalValueType {
typedef ExecutionSpace execution_space;
typedef typename Kokkos::View<Scalar*,execution_space> type;
type view;
typedef Scalar value_type;
SumInitJoinFinalValueType(type view_):view(view_) {}
KOKKOS_INLINE_FUNCTION
void init(value_type& val) const {
val = value_type();
}
KOKKOS_INLINE_FUNCTION
void join(volatile value_type& val, volatile value_type& src) const {
val += src;
}
KOKKOS_INLINE_FUNCTION
void operator() (int i, value_type& val) const {
val += value_type();
}
};
template<class Scalar, class ExecutionSpace>
struct SumInitJoinFinalValueType2 {
typedef ExecutionSpace execution_space;
typedef typename Kokkos::View<Scalar*,execution_space> type;
type view;
typedef Scalar value_type;
SumInitJoinFinalValueType2(type view_):view(view_) {}
KOKKOS_INLINE_FUNCTION
void init(volatile value_type& val) const {
val = value_type();
}
KOKKOS_INLINE_FUNCTION
void join(volatile value_type& val, const volatile value_type& src) const {
val += src;
}
KOKKOS_INLINE_FUNCTION
void operator() (int i, value_type& val) const {
val += value_type();
}
};
template<class Scalar, class ExecutionSpace>
struct SumInitJoinFinalValueTypeArray {
typedef ExecutionSpace execution_space;
typedef typename Kokkos::View<Scalar*,execution_space> type;
type view;
typedef Scalar value_type[];
int n;
SumInitJoinFinalValueTypeArray(type view_, int n_):view(view_),n(n_) {}
KOKKOS_INLINE_FUNCTION
void init(value_type val) const {
for(int k=0;k<n;k++)
val[k] = 0;
}
KOKKOS_INLINE_FUNCTION
void join(volatile value_type val, const volatile value_type src) const {
for(int k=0;k<n;k++)
val[k] += src[k];
}
KOKKOS_INLINE_FUNCTION
void operator() (int i, value_type val) const {
for(int k=0;k<n;k++)
val[k] += k*i;
}
};
template<class Scalar, class ExecutionSpace>
struct SumWrongInitJoinFinalValueType {
typedef ExecutionSpace execution_space;
typedef typename Kokkos::View<Scalar*,execution_space> type;
type view;
typedef Scalar value_type;
SumWrongInitJoinFinalValueType(type view_):view(view_) {}
KOKKOS_INLINE_FUNCTION
void init(double& val) const {
val = double();
}
KOKKOS_INLINE_FUNCTION
void join(volatile value_type& val, const value_type& src) const {
val += src;
}
KOKKOS_INLINE_FUNCTION
void operator() (int i, value_type& val) const {
val += value_type();
}
};
template<class Scalar, class ExecutionSpace>
void TestTemplateMetaFunctions() {
typedef typename Kokkos::View<Scalar*,ExecutionSpace> type;
type a("A",100);
/* #ifdef KOKKOS_HAVE_CXX11
int sum_plain_has_init_arg = Kokkos::Impl::FunctorHasInit<SumPlain<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_plain_has_init_arg,0);
int sum_initjoinfinalvaluetype_has_init_arg = Kokkos::Impl::FunctorHasInit<SumInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar >::value;
ASSERT_EQ(sum_initjoinfinalvaluetype_has_init_arg,1);
int sum_initjoinfinalvaluetype_has_init_arg2 = Kokkos::Impl::FunctorHasInit<SumInitJoinFinalValueType2<Scalar,ExecutionSpace>, Scalar >::value;
ASSERT_EQ(sum_initjoinfinalvaluetype_has_init_arg2,1);
int sum_wronginitjoinfinalvaluetype_has_init_arg = Kokkos::Impl::FunctorHasInit<SumWrongInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar >::value;
ASSERT_EQ(sum_wronginitjoinfinalvaluetype_has_init_arg,0);
//int sum_initjoinfinalvaluetypearray_has_init_arg = Kokkos::Impl::FunctorHasInit<SumInitJoinFinalValueTypeArray<Scalar,ExecutionSpace>, Scalar[] >::value;
//ASSERT_EQ(sum_initjoinfinalvaluetypearray_has_init_arg,1);
#else
int sum_plain_has_init_arg = Kokkos::Impl::FunctorHasInit<SumPlain<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_plain_has_init_arg,0);
int sum_initjoinfinalvaluetype_has_init_arg = Kokkos::Impl::FunctorHasInit<SumInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_initjoinfinalvaluetype_has_init_arg,1);
int sum_wronginitjoinfinalvaluetype_has_init_arg = Kokkos::Impl::FunctorHasInit<SumWrongInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_wronginitjoinfinalvaluetype_has_init_arg,1);
#endif
//printf("Values Init: %i %i %i\n",sum_plain_has_init_arg,sum_initjoinfinalvaluetype_has_init_arg,sum_wronginitjoinfinalvaluetype_has_init_arg);
#ifdef KOKKOS_HAVE_CXX11
int sum_plain_has_join_arg = Kokkos::Impl::FunctorHasJoin<SumPlain<Scalar,ExecutionSpace>, Scalar >::value;
ASSERT_EQ(sum_plain_has_join_arg,0);
int sum_initjoinfinalvaluetype_has_join_arg = Kokkos::Impl::FunctorHasJoin<SumInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar >::value;
ASSERT_EQ(sum_initjoinfinalvaluetype_has_join_arg,1);
int sum_initjoinfinalvaluetype_has_join_arg2 = Kokkos::Impl::FunctorHasJoin<SumInitJoinFinalValueType2<Scalar,ExecutionSpace>, Scalar >::value;
ASSERT_EQ(sum_initjoinfinalvaluetype_has_join_arg2,1);
int sum_wronginitjoinfinalvaluetype_has_join_arg = Kokkos::Impl::FunctorHasJoin<SumWrongInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar >::value;
ASSERT_EQ(sum_wronginitjoinfinalvaluetype_has_join_arg,0);
#else
int sum_plain_has_join_arg = Kokkos::Impl::FunctorHasJoin<SumPlain<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_plain_has_join_arg,0);
int sum_initjoinfinalvaluetype_has_join_arg = Kokkos::Impl::FunctorHasJoin<SumInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_initjoinfinalvaluetype_has_join_arg,1);
int sum_initjoinfinalvaluetype_has_join_arg2 = Kokkos::Impl::FunctorHasJoin<SumInitJoinFinalValueType2<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_initjoinfinalvaluetype_has_join_arg2,1);
int sum_wronginitjoinfinalvaluetype_has_join_arg = Kokkos::Impl::FunctorHasJoin<SumWrongInitJoinFinalValueType<Scalar,ExecutionSpace>, Scalar& >::value;
ASSERT_EQ(sum_wronginitjoinfinalvaluetype_has_join_arg,1);
#endif*/
//printf("Values Join: %i %i %i\n",sum_plain_has_join_arg,sum_initjoinfinalvaluetype_has_join_arg,sum_wronginitjoinfinalvaluetype_has_join_arg);
}
}

View File

@ -0,0 +1,443 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Macros.hpp>
#if defined( KOKKOS_HAVE_PTHREAD )
#include <Kokkos_Core.hpp>
#include <Threads/Kokkos_Threads_TaskPolicy.hpp>
//----------------------------------------------------------------------------
#include <TestSharedAlloc.hpp>
#include <TestViewMapping.hpp>
#include <TestViewImpl.hpp>
#include <TestViewAPI.hpp>
#include <TestViewSubview.hpp>
#include <TestAtomic.hpp>
#include <TestReduce.hpp>
#include <TestScan.hpp>
#include <TestRange.hpp>
#include <TestTeam.hpp>
#include <TestAggregate.hpp>
#include <TestAggregateReduction.hpp>
#include <TestCompilerMacros.hpp>
#include <TestCXX11.hpp>
#include <TestCXX11Deduction.hpp>
#include <TestTeamVector.hpp>
#include <TestMemorySpaceTracking.hpp>
#include <TestTemplateMetaFunctions.hpp>
#include <TestTaskPolicy.hpp>
namespace Test {
class threads : public ::testing::Test {
protected:
static void SetUpTestCase()
{
// Finalize without initialize is a no-op:
Kokkos::Threads::finalize();
const unsigned numa_count = Kokkos::hwloc::get_available_numa_count();
const unsigned cores_per_numa = Kokkos::hwloc::get_available_cores_per_numa();
const unsigned threads_per_core = Kokkos::hwloc::get_available_threads_per_core();
unsigned threads_count = 0 ;
// Initialize and finalize with no threads:
Kokkos::Threads::initialize( 1u );
Kokkos::Threads::finalize();
threads_count = std::max( 1u , numa_count )
* std::max( 2u , cores_per_numa * threads_per_core );
Kokkos::Threads::initialize( threads_count );
Kokkos::Threads::finalize();
threads_count = std::max( 1u , numa_count * 2 )
* std::max( 2u , ( cores_per_numa * threads_per_core ) / 2 );
Kokkos::Threads::initialize( threads_count );
Kokkos::Threads::finalize();
// Quick attempt to verify thread start/terminate don't have race condition:
threads_count = std::max( 1u , numa_count )
* std::max( 2u , ( cores_per_numa * threads_per_core ) / 2 );
for ( unsigned i = 0 ; i < 10 ; ++i ) {
Kokkos::Threads::initialize( threads_count );
Kokkos::Threads::sleep();
Kokkos::Threads::wake();
Kokkos::Threads::finalize();
}
Kokkos::Threads::initialize( threads_count );
Kokkos::Threads::print_configuration( std::cout , true /* detailed */ );
}
static void TearDownTestCase()
{
Kokkos::Threads::finalize();
}
};
TEST_F( threads , init ) {
;
}
TEST_F( threads , impl_shared_alloc ) {
test_shared_alloc< Kokkos::HostSpace , Kokkos::Threads >();
}
TEST_F( threads , impl_view_mapping ) {
test_view_mapping< Kokkos::Threads >();
test_view_mapping_subview< Kokkos::Threads >();
test_view_mapping_operator< Kokkos::Threads >();
TestViewMappingAtomic< Kokkos::Threads >::run();
}
TEST_F( threads, view_impl) {
test_view_impl< Kokkos::Threads >();
}
TEST_F( threads, view_api) {
TestViewAPI< double , Kokkos::Threads >();
}
TEST_F( threads, view_subview_auto_1d_left ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutLeft,Kokkos::Threads >();
}
TEST_F( threads, view_subview_auto_1d_right ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutRight,Kokkos::Threads >();
}
TEST_F( threads, view_subview_auto_1d_stride ) {
TestViewSubview::test_auto_1d< Kokkos::LayoutStride,Kokkos::Threads >();
}
TEST_F( threads, view_subview_assign_strided ) {
TestViewSubview::test_1d_strided_assignment< Kokkos::Threads >();
}
TEST_F( threads, view_subview_left_0 ) {
TestViewSubview::test_left_0< Kokkos::Threads >();
}
TEST_F( threads, view_subview_left_1 ) {
TestViewSubview::test_left_1< Kokkos::Threads >();
}
TEST_F( threads, view_subview_left_2 ) {
TestViewSubview::test_left_2< Kokkos::Threads >();
}
TEST_F( threads, view_subview_left_3 ) {
TestViewSubview::test_left_3< Kokkos::Threads >();
}
TEST_F( threads, view_subview_right_0 ) {
TestViewSubview::test_right_0< Kokkos::Threads >();
}
TEST_F( threads, view_subview_right_1 ) {
TestViewSubview::test_right_1< Kokkos::Threads >();
}
TEST_F( threads, view_subview_right_3 ) {
TestViewSubview::test_right_3< Kokkos::Threads >();
}
TEST_F( threads, view_aggregate ) {
TestViewAggregate< Kokkos::Threads >();
TestViewAggregateReduction< Kokkos::Threads >();
}
TEST_F( threads , range_tag )
{
TestRange< Kokkos::Threads >::test_for(1000);
TestRange< Kokkos::Threads >::test_reduce(1000);
TestRange< Kokkos::Threads >::test_scan(1000);
}
TEST_F( threads , team_tag )
{
TestTeamPolicy< Kokkos::Threads >::test_for(1000);
TestTeamPolicy< Kokkos::Threads >::test_reduce(1000);
}
TEST_F( threads, long_reduce) {
TestReduce< long , Kokkos::Threads >( 1000000 );
}
TEST_F( threads, double_reduce) {
TestReduce< double , Kokkos::Threads >( 1000000 );
}
TEST_F( threads, team_long_reduce) {
TestReduceTeam< long , Kokkos::Threads >( 100000 );
}
TEST_F( threads, team_double_reduce) {
TestReduceTeam< double , Kokkos::Threads >( 100000 );
}
TEST_F( threads, long_reduce_dynamic ) {
TestReduceDynamic< long , Kokkos::Threads >( 1000000 );
}
TEST_F( threads, double_reduce_dynamic ) {
TestReduceDynamic< double , Kokkos::Threads >( 1000000 );
}
TEST_F( threads, long_reduce_dynamic_view ) {
TestReduceDynamicView< long , Kokkos::Threads >( 1000000 );
}
TEST_F( threads, team_shared_request) {
TestSharedTeam< Kokkos::Threads >();
}
TEST_F( threads , view_remap )
{
enum { N0 = 3 , N1 = 2 , N2 = 8 , N3 = 9 };
typedef Kokkos::View< double*[N1][N2][N3] ,
Kokkos::LayoutRight ,
Kokkos::Threads > output_type ;
typedef Kokkos::View< int**[N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::Threads > input_type ;
typedef Kokkos::View< int*[N0][N2][N3] ,
Kokkos::LayoutLeft ,
Kokkos::Threads > diff_type ;
output_type output( "output" , N0 );
input_type input ( "input" , N0 , N1 );
diff_type diff ( "diff" , N0 );
int value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
input(i0,i1,i2,i3) = ++value ;
}}}}
// Kokkos::deep_copy( diff , input ); // throw with incompatible shape
Kokkos::deep_copy( output , input );
value = 0 ;
for ( size_t i3 = 0 ; i3 < N3 ; ++i3 ) {
for ( size_t i2 = 0 ; i2 < N2 ; ++i2 ) {
for ( size_t i1 = 0 ; i1 < N1 ; ++i1 ) {
for ( size_t i0 = 0 ; i0 < N0 ; ++i0 ) {
++value ;
ASSERT_EQ( value , ((int) output(i0,i1,i2,i3) ) );
}}}}
}
//----------------------------------------------------------------------------
TEST_F( threads , atomics )
{
const int loop_count = 1e6 ;
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Threads>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Threads>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<int,Kokkos::Threads>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Threads>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Threads>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned int,Kokkos::Threads>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Threads>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Threads>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long int,Kokkos::Threads>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Threads>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Threads>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<unsigned long int,Kokkos::Threads>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Threads>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Threads>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<long long int,Kokkos::Threads>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Threads>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Threads>(loop_count,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<double,Kokkos::Threads>(loop_count,3) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Threads>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Threads>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<float,Kokkos::Threads>(100,3) ) );
#if defined( KOKKOS_ENABLE_ASM )
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Threads>(100,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Threads>(100,2) ) );
ASSERT_TRUE( ( TestAtomic::Loop<Kokkos::complex<double> ,Kokkos::Threads>(100,3) ) );
#endif
ASSERT_TRUE( ( TestAtomic::Loop<TestAtomic::SuperScalar<3>, Kokkos::Threads>(loop_count,1) ) );
ASSERT_TRUE( ( TestAtomic::Loop<TestAtomic::SuperScalar<3>, Kokkos::Threads>(loop_count,2) ) );
}
//----------------------------------------------------------------------------
#if 0
TEST_F( threads , scan_small )
{
typedef TestScan< Kokkos::Threads , Kokkos::Impl::ThreadsExecUseScanSmall > TestScanFunctor ;
for ( int i = 0 ; i < 1000 ; ++i ) {
TestScanFunctor( 10 );
TestScanFunctor( 10000 );
}
TestScanFunctor( 1000000 );
TestScanFunctor( 10000000 );
Kokkos::Threads::fence();
}
#endif
TEST_F( threads , scan )
{
TestScan< Kokkos::Threads >::test_range( 1 , 1000 );
TestScan< Kokkos::Threads >( 1000000 );
TestScan< Kokkos::Threads >( 10000000 );
Kokkos::Threads::fence();
}
//----------------------------------------------------------------------------
TEST_F( threads , team_scan )
{
TestScanTeam< Kokkos::Threads >( 10 );
TestScanTeam< Kokkos::Threads >( 10000 );
}
//----------------------------------------------------------------------------
TEST_F( threads , compiler_macros )
{
ASSERT_TRUE( ( TestCompilerMacros::Test< Kokkos::Threads >() ) );
}
TEST_F( threads , memory_space )
{
TestMemorySpace< Kokkos::Threads >();
}
//----------------------------------------------------------------------------
TEST_F( threads , template_meta_functions )
{
TestTemplateMetaFunctions<int, Kokkos::Threads >();
}
//----------------------------------------------------------------------------
#if defined( KOKKOS_HAVE_CXX11 ) && defined( KOKKOS_HAVE_DEFAULT_DEVICE_TYPE_THREADS )
TEST_F( threads , cxx11 )
{
if ( Kokkos::Impl::is_same< Kokkos::DefaultExecutionSpace , Kokkos::Threads >::value ) {
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Threads >(1) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Threads >(2) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Threads >(3) ) );
ASSERT_TRUE( ( TestCXX11::Test< Kokkos::Threads >(4) ) );
}
}
#endif
#if defined (KOKKOS_HAVE_CXX11)
TEST_F( threads , reduction_deduction )
{
TestCXX11::test_reduction_deduction< Kokkos::Threads >();
}
TEST_F( threads , team_vector )
{
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(0) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(1) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(2) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(3) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(4) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(5) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(6) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(7) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(8) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(9) ) );
ASSERT_TRUE( ( TestTeamVector::Test< Kokkos::Threads >(10) ) );
}
#endif
TEST_F( threads , task_policy )
{
TestTaskPolicy::test_task_dep< Kokkos::Threads >( 10 );
for ( long i = 0 ; i < 25 ; ++i ) TestTaskPolicy::test_fib< Kokkos::Threads >(i);
for ( long i = 0 ; i < 35 ; ++i ) TestTaskPolicy::test_fib2< Kokkos::Threads >(i);
}
#if defined( KOKKOS_HAVE_CXX11 )
TEST_F( threads , task_team )
{
TestTaskPolicy::test_task_team< Kokkos::Threads >(1000);
}
#endif
} // namespace Test
#endif /* #if defined( KOKKOS_HAVE_PTHREAD ) */

View File

@ -0,0 +1,153 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
#ifndef TEST_TILE_HPP
#define TEST_TILE_HPP
#include <Kokkos_Core.hpp>
namespace TestTile {
template < typename Device , typename TileLayout>
struct ReduceTileErrors
{
typedef Device execution_space ;
typedef Kokkos::View< ptrdiff_t**, TileLayout, Device> array_type;
typedef Kokkos::View< ptrdiff_t[ TileLayout::N0 ][ TileLayout::N1 ], Kokkos::LayoutLeft , Device > tile_type ;
array_type m_array ;
typedef ptrdiff_t value_type;
ReduceTileErrors( array_type a )
: m_array(a)
{}
KOKKOS_INLINE_FUNCTION
static void init( value_type & errors )
{
errors = 0;
}
KOKKOS_INLINE_FUNCTION
static void join( volatile value_type & errors ,
const volatile value_type & src_errors )
{
errors += src_errors;
}
// Initialize
KOKKOS_INLINE_FUNCTION
void operator()( size_t iwork ) const
{
const size_t i = iwork % m_array.dimension_0();
const size_t j = iwork / m_array.dimension_0();
if ( j < m_array.dimension_1() ) {
m_array(i,j) = & m_array(i,j) - & m_array(0,0);
// printf("m_array(%d,%d) = %d\n",int(i),int(j),int(m_array(i,j)));
}
}
// Verify:
KOKKOS_INLINE_FUNCTION
void operator()( size_t iwork , value_type & errors ) const
{
const size_t tile_dim0 = ( m_array.dimension_0() + TileLayout::N0 - 1 ) / TileLayout::N0 ;
const size_t tile_dim1 = ( m_array.dimension_1() + TileLayout::N1 - 1 ) / TileLayout::N1 ;
const size_t itile = iwork % tile_dim0 ;
const size_t jtile = iwork / tile_dim0 ;
if ( jtile < tile_dim1 ) {
tile_type tile = Kokkos::tile_subview( m_array , itile , jtile );
if ( tile(0,0) != ptrdiff_t(( itile + jtile * tile_dim0 ) * TileLayout::N0 * TileLayout::N1 ) ) {
++errors ;
}
else {
for ( size_t j = 0 ; j < size_t(TileLayout::N1) ; ++j ) {
for ( size_t i = 0 ; i < size_t(TileLayout::N0) ; ++i ) {
const size_t iglobal = i + itile * TileLayout::N0 ;
const size_t jglobal = j + jtile * TileLayout::N1 ;
if ( iglobal < m_array.dimension_0() && jglobal < m_array.dimension_1() ) {
if ( tile(i,j) != ptrdiff_t( tile(0,0) + i + j * TileLayout::N0 ) ) ++errors ;
// printf("tile(%d,%d)(%d,%d) = %d\n",int(itile),int(jtile),int(i),int(j),int(tile(i,j)));
}
}
}
}
}
}
};
template< class Space , unsigned N0 , unsigned N1 >
void test( const size_t dim0 , const size_t dim1 )
{
typedef Kokkos::LayoutTileLeft<N0,N1> array_layout ;
typedef ReduceTileErrors< Space , array_layout > functor_type ;
const size_t tile_dim0 = ( dim0 + N0 - 1 ) / N0 ;
const size_t tile_dim1 = ( dim1 + N1 - 1 ) / N1 ;
typename functor_type::array_type array("",dim0,dim1);
Kokkos::parallel_for( Kokkos::RangePolicy<Space,size_t>(0,dim0*dim1) , functor_type( array ) );
ptrdiff_t error = 0 ;
Kokkos::parallel_reduce( Kokkos::RangePolicy<Space,size_t>(0,tile_dim0*tile_dim1) , functor_type( array ) , error );
EXPECT_EQ( error , ptrdiff_t(0) );
}
} /* namespace TestTile */
#endif //TEST_TILE_HPP

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,289 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <Kokkos_Core.hpp>
/*--------------------------------------------------------------------------*/
#if defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
namespace Test {
template < class Device >
void test_view_impl() {}
}
#else
/*--------------------------------------------------------------------------*/
namespace Test {
struct DummyMemorySpace
{
typedef DummyMemorySpace memory_space ;
typedef unsigned size_type ;
};
/*--------------------------------------------------------------------------*/
template< class Type >
struct DefineShape {
typedef typename Kokkos::Impl::AnalyzeShape<Type>::shape type ;
};
template< class Type >
struct ExtractValueType {
typedef typename Kokkos::Impl::AnalyzeShape<Type>::value_type type ;
};
template< class Type >
struct ArrayType { typedef Type type ; };
template < class Device >
void test_view_impl()
{
//typedef typename Device::memory_space memory_space ; // unused
typedef ArrayType< int[100] >::type type_01 ;
typedef ArrayType< int* >::type type_11 ;
typedef ArrayType< int[5][6][700] >::type type_03 ;
typedef ArrayType< double*[8][9][900] >::type type_14 ;
typedef ArrayType< long** >::type type_22 ;
typedef ArrayType< short **[5][6][7] >::type type_25 ;
typedef ArrayType< const short **[5][6][7] >::type const_type_25 ;
typedef ArrayType< short***[5][6][7] >::type type_36 ;
typedef ArrayType< const short***[5][6][7] >::type const_type_36 ;
// mfh 14 Feb 2014: With gcc 4.8.2 -Wall, this emits a warning:
//
// typedef ok_const_25 locally defined but not used [-Wunused-local-typedefs]
//
// It's unfortunate that this is the case, because the typedef is
// being used for a compile-time check! We deal with this by
// declaring an instance of ok_const_25, and marking it with
// "(void)" so that instance doesn't emit an "unused variable"
// warning.
//
// typedef typename Kokkos::Impl::StaticAssertSame<
// typename Kokkos::Impl::AnalyzeShape<type_25>::const_type ,
// typename Kokkos::Impl::AnalyzeShape<const_type_25>::type
// > ok_const_25 ;
typedef typename Kokkos::Impl::StaticAssertSame<
typename Kokkos::Impl::AnalyzeShape<type_25>::const_type,
typename Kokkos::Impl::AnalyzeShape<const_type_25>::type
> ok_const_25 ;
typedef typename Kokkos::Impl::StaticAssertSame<
typename Kokkos::Impl::AnalyzeShape<type_36>::const_type,
typename Kokkos::Impl::AnalyzeShape<const_type_36>::type
> ok_const_36 ;
{
ok_const_25 thing_25 ;
ok_const_36 thing_36 ;
(void) thing_25 ; // silence warning for unused variable
(void) thing_36 ; // silence warning for unused variable
}
ASSERT_TRUE( ( Kokkos::Impl::is_same< ExtractValueType<type_03>::type , int >::value ) );
ASSERT_TRUE( ( Kokkos::Impl::is_same< ExtractValueType<type_14>::type , double >::value ) );
ASSERT_TRUE( ( Kokkos::Impl::is_same< ExtractValueType<type_22>::type , long >::value ) );
ASSERT_TRUE( ( Kokkos::Impl::is_same< ExtractValueType<type_36>::type , short >::value ) );
ASSERT_FALSE( ( Kokkos::Impl::is_same< ExtractValueType<type_36>::type , int >::value ) );
typedef typename DefineShape< type_01 >::type shape_01_type ;
typedef typename DefineShape< type_11 >::type shape_11_type ;
typedef typename DefineShape< type_03 >::type shape_03_type ;
typedef typename DefineShape< type_14 >::type shape_14_type ;
typedef typename DefineShape< type_22 >::type shape_22_type ;
typedef typename DefineShape< type_36 >::type shape_36_type ;
ASSERT_TRUE( ( Kokkos::Impl::StaticAssert< shape_36_type::rank == 6 >::value ) );
ASSERT_TRUE( ( Kokkos::Impl::StaticAssert< shape_03_type::rank == 3 >::value ) );
shape_01_type shape_01 ; shape_01_type::assign( shape_01 );
shape_11_type shape_11 ; shape_11_type::assign( shape_11, 1000 );
shape_03_type shape_03 ; shape_03_type::assign( shape_03 );
shape_14_type shape_14 ; shape_14_type::assign( shape_14 , 0 );
shape_22_type shape_22 ; shape_22_type::assign( shape_22 , 0 , 0 );
shape_36_type shape_36 ; shape_36_type::assign( shape_36 , 10 , 20 , 30 );
ASSERT_TRUE( shape_01.rank_dynamic == 0u );
ASSERT_TRUE( shape_01.rank == 1u );
ASSERT_TRUE( shape_01.N0 == 100u );
ASSERT_TRUE( shape_11.rank_dynamic == 1u );
ASSERT_TRUE( shape_11.rank == 1u );
ASSERT_TRUE( shape_11.N0 == 1000u );
ASSERT_TRUE( shape_03.rank_dynamic == 0u );
ASSERT_TRUE( shape_03.rank == 3u );
ASSERT_TRUE( shape_03.N0 == 5u );
ASSERT_TRUE( shape_03.N1 == 6u );
ASSERT_TRUE( shape_03.N2 == 700u );
ASSERT_TRUE( shape_14.rank_dynamic == 1u );
ASSERT_TRUE( shape_14.rank == 4u );
ASSERT_TRUE( shape_14.N0 == 0u );
ASSERT_TRUE( shape_14.N1 == 8u );
ASSERT_TRUE( shape_14.N2 == 9u );
ASSERT_TRUE( shape_14.N3 == 900u );
ASSERT_TRUE( shape_22.rank_dynamic == 2u );
ASSERT_TRUE( shape_22.rank == 2u );
ASSERT_TRUE( shape_22.N0 == 0u );
ASSERT_TRUE( shape_22.N1 == 0u );
ASSERT_TRUE( shape_36.rank_dynamic == 3u );
ASSERT_TRUE( shape_36.rank == 6u );
ASSERT_TRUE( shape_36.N0 == 10u );
ASSERT_TRUE( shape_36.N1 == 20u );
ASSERT_TRUE( shape_36.N2 == 30u );
ASSERT_TRUE( shape_36.N3 == 5u );
ASSERT_TRUE( shape_36.N4 == 6u );
ASSERT_TRUE( shape_36.N5 == 7u );
ASSERT_TRUE( shape_01 == shape_01 );
ASSERT_TRUE( shape_11 == shape_11 );
ASSERT_TRUE( shape_36 == shape_36 );
ASSERT_TRUE( shape_01 != shape_36 );
ASSERT_TRUE( shape_22 != shape_36 );
//------------------------------------------------------------------------
typedef Kokkos::Impl::ViewOffset< shape_01_type , Kokkos::LayoutLeft > shape_01_left_offset ;
typedef Kokkos::Impl::ViewOffset< shape_11_type , Kokkos::LayoutLeft > shape_11_left_offset ;
typedef Kokkos::Impl::ViewOffset< shape_03_type , Kokkos::LayoutLeft > shape_03_left_offset ;
typedef Kokkos::Impl::ViewOffset< shape_14_type , Kokkos::LayoutLeft > shape_14_left_offset ;
typedef Kokkos::Impl::ViewOffset< shape_22_type , Kokkos::LayoutLeft > shape_22_left_offset ;
typedef Kokkos::Impl::ViewOffset< shape_36_type , Kokkos::LayoutLeft > shape_36_left_offset ;
typedef Kokkos::Impl::ViewOffset< shape_01_type , Kokkos::LayoutRight > shape_01_right_offset ;
typedef Kokkos::Impl::ViewOffset< shape_11_type , Kokkos::LayoutRight > shape_11_right_offset ;
typedef Kokkos::Impl::ViewOffset< shape_03_type , Kokkos::LayoutRight > shape_03_right_offset ;
typedef Kokkos::Impl::ViewOffset< shape_14_type , Kokkos::LayoutRight > shape_14_right_offset ;
typedef Kokkos::Impl::ViewOffset< shape_22_type , Kokkos::LayoutRight > shape_22_right_offset ;
typedef Kokkos::Impl::ViewOffset< shape_36_type , Kokkos::LayoutRight > shape_36_right_offset ;
ASSERT_TRUE( ! shape_01_left_offset::has_padding );
ASSERT_TRUE( ! shape_11_left_offset::has_padding );
ASSERT_TRUE( ! shape_03_left_offset::has_padding );
ASSERT_TRUE( shape_14_left_offset::has_padding );
ASSERT_TRUE( shape_22_left_offset::has_padding );
ASSERT_TRUE( shape_36_left_offset::has_padding );
ASSERT_TRUE( ! shape_01_right_offset::has_padding );
ASSERT_TRUE( ! shape_11_right_offset::has_padding );
ASSERT_TRUE( ! shape_03_right_offset::has_padding );
ASSERT_TRUE( ! shape_14_right_offset::has_padding );
ASSERT_TRUE( shape_22_right_offset::has_padding );
ASSERT_TRUE( shape_36_right_offset::has_padding );
//------------------------------------------------------------------------
typedef Kokkos::Impl::ViewOffset< shape_01_type , Kokkos::LayoutStride > shape_01_stride_offset ;
typedef Kokkos::Impl::ViewOffset< shape_36_type , Kokkos::LayoutStride > shape_36_stride_offset ;
{
shape_01_stride_offset stride_offset_01 ;
stride_offset_01.assign( 1, stride_offset_01.N0, 0,0,0,0,0,0,0 );
ASSERT_EQ( int(stride_offset_01.S[0]) , int(1) );
ASSERT_EQ( int(stride_offset_01.S[1]) , int(stride_offset_01.N0) );
}
{
shape_36_stride_offset stride_offset_36 ;
size_t str[7] ;
str[5] = 1 ;
str[4] = str[5] * stride_offset_36.N5 ;
str[3] = str[4] * stride_offset_36.N4 ;
str[2] = str[3] * stride_offset_36.N3 ;
str[1] = str[2] * 100 ;
str[0] = str[1] * 200 ;
str[6] = str[0] * 300 ;
stride_offset_36.assign( str[0] , str[1] , str[2] , str[3] , str[4] , str[5] , str[6] , 0 , 0 );
ASSERT_EQ( size_t(stride_offset_36.S[6]) , size_t(str[6]) );
ASSERT_EQ( size_t(stride_offset_36.N2) , size_t(100) );
ASSERT_EQ( size_t(stride_offset_36.N1) , size_t(200) );
ASSERT_EQ( size_t(stride_offset_36.N0) , size_t(300) );
}
//------------------------------------------------------------------------
{
const int rank = 6 ;
const int order[] = { 5 , 3 , 1 , 0 , 2 , 4 };
const unsigned dim[] = { 2 , 3 , 5 , 7 , 11 , 13 };
Kokkos::LayoutStride stride_6 = Kokkos::LayoutStride::order_dimensions( rank , order , dim );
size_t n = 1 ;
for ( int i = 0 ; i < rank ; ++i ) {
ASSERT_EQ( size_t(dim[i]) , size_t( stride_6.dimension[i] ) );
ASSERT_EQ( size_t(n) , size_t( stride_6.stride[ order[i] ] ) );
n *= dim[order[i]] ;
}
}
//------------------------------------------------------------------------
}
} /* namespace Test */
#endif
/*--------------------------------------------------------------------------*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,126 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#include <stdexcept>
#include <sstream>
#include <iostream>
/*--------------------------------------------------------------------------*/
namespace Test {
namespace {
volatile int nested_view_count ;
}
template< class Space >
class NestedView {
private:
Kokkos::View<int*,Space> member ;
public:
KOKKOS_INLINE_FUNCTION
NestedView()
#if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
: member("member",2)
{ Kokkos::atomic_increment( & nested_view_count ); }
#else
: member(){}
#endif
~NestedView()
#if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
{ Kokkos::atomic_decrement( & nested_view_count ); }
#else
{}
#endif
};
template< class Space >
void view_nested_view()
{
ASSERT_EQ( 0 , nested_view_count );
{
Kokkos::View< NestedView<Space> * , Space > a("a_nested_view",2);
ASSERT_EQ( 2 , nested_view_count );
Kokkos::View< NestedView<Space> * , Space > b("b_nested_view",2);
ASSERT_EQ( 4 , nested_view_count );
}
// ASSERT_EQ( 0 , nested_view_count );
}
}
namespace Kokkos {
namespace Impl {
template< class ExecSpace , class S >
struct ViewDefaultConstruct< ExecSpace , Test::NestedView<S> , true >
{
typedef Test::NestedView<S> type ;
type * const m_ptr ;
KOKKOS_FORCEINLINE_FUNCTION
void operator()( const typename ExecSpace::size_type& i ) const
{ new(m_ptr+i) type(); }
ViewDefaultConstruct( type * pointer , size_t capacity )
: m_ptr( pointer )
{
Kokkos::RangePolicy< ExecSpace > range( 0 , capacity );
parallel_for( range , *this );
ExecSpace::fence();
}
};
} // namespace Impl
} // namespace Kokkos
/*--------------------------------------------------------------------------*/

View File

@ -0,0 +1,632 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#include <stdexcept>
#include <sstream>
#include <iostream>
/*--------------------------------------------------------------------------*/
namespace TestViewSubview {
#if defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
using Kokkos::Experimental::ALL ;
#else
namespace {
const Kokkos::ALL ALL ;
}
#endif
template<class Layout, class Space>
struct getView {
static
Kokkos::View<double**,Layout,Space> get(int n, int m) {
return Kokkos::View<double**,Layout,Space>("G",n,m);
}
};
template<class Space>
struct getView<Kokkos::LayoutStride,Space> {
static
Kokkos::View<double**,Kokkos::LayoutStride,Space> get(int n, int m) {
const int rank = 2 ;
const int order[] = { 0, 1 };
const unsigned dim[] = { unsigned(n), unsigned(m) };
Kokkos::LayoutStride stride = Kokkos::LayoutStride::order_dimensions( rank , order , dim );
return Kokkos::View<double**,Kokkos::LayoutStride,Space>("G",stride);
}
};
template<class ViewType, class Space>
struct fill_1D {
typedef typename Space::execution_space execution_space;
typedef typename ViewType::size_type size_type;
ViewType a;
double val;
fill_1D(ViewType a_, double val_):a(a_),val(val_) {
}
KOKKOS_INLINE_FUNCTION
void operator() (const int i) const {
a(i) = val;
}
};
template<class ViewType, class Space>
struct fill_2D {
typedef typename Space::execution_space execution_space;
typedef typename ViewType::size_type size_type;
ViewType a;
double val;
fill_2D(ViewType a_, double val_):a(a_),val(val_) {
}
KOKKOS_INLINE_FUNCTION
void operator() (const int i) const{
for(int j = 0; j < static_cast<int>(a.dimension_1()); j++)
a(i,j) = val;
}
};
template<class Layout, class Space>
void test_auto_1d ()
{
typedef Kokkos::View<double**, Layout, Space> mv_type;
typedef typename mv_type::size_type size_type;
const double ZERO = 0.0;
const double ONE = 1.0;
const double TWO = 2.0;
const size_type numRows = 10;
const size_type numCols = 3;
mv_type X = getView<Layout,Space>::get(numRows, numCols);
typename mv_type::HostMirror X_h = Kokkos::create_mirror_view (X);
fill_2D<mv_type,Space> f1(X, ONE);
Kokkos::parallel_for(X.dimension_0(),f1);
Kokkos::deep_copy (X_h, X);
for (size_type j = 0; j < numCols; ++j) {
for (size_type i = 0; i < numRows; ++i) {
ASSERT_TRUE(X_h(i,j) == ONE);
}
}
fill_2D<mv_type,Space> f2(X, 0.0);
Kokkos::parallel_for(X.dimension_0(),f2);
Kokkos::deep_copy (X_h, X);
for (size_type j = 0; j < numCols; ++j) {
for (size_type i = 0; i < numRows; ++i) {
ASSERT_TRUE(X_h(i,j) == ZERO);
}
}
fill_2D<mv_type,Space> f3(X, TWO);
Kokkos::parallel_for(X.dimension_0(),f3);
Kokkos::deep_copy (X_h, X);
for (size_type j = 0; j < numCols; ++j) {
for (size_type i = 0; i < numRows; ++i) {
ASSERT_TRUE(X_h(i,j) == TWO);
}
}
for (size_type j = 0; j < numCols; ++j) {
auto X_j = Kokkos::subview (X, TestViewSubview::ALL, j);
fill_1D<decltype(X_j),Space> f4(X_j, ZERO);
Kokkos::parallel_for(X_j.dimension_0(),f4);
Kokkos::deep_copy (X_h, X);
for (size_type i = 0; i < numRows; ++i) {
ASSERT_TRUE(X_h(i,j) == ZERO);
}
for (size_type jj = 0; jj < numCols; ++jj) {
auto X_jj = Kokkos::subview (X, TestViewSubview::ALL, jj);
fill_1D<decltype(X_jj),Space> f5(X_jj, ONE);
Kokkos::parallel_for(X_jj.dimension_0(),f5);
Kokkos::deep_copy (X_h, X);
for (size_type i = 0; i < numRows; ++i) {
ASSERT_TRUE(X_h(i,jj) == ONE);
}
}
}
}
template<class LD, class LS, class Space>
void test_1d_strided_assignment_impl(bool a, bool b, bool c, bool d, int n, int m) {
Kokkos::View<double**,LS,Space> l2d("l2d",n,m);
int col = n>2?2:0;
int row = m>2?2:0;
if(Kokkos::Impl::VerifyExecutionCanAccessMemorySpace<Kokkos::HostSpace,Space>::value) {
if(a) {
Kokkos::View<double*,LD,Space> l1da = Kokkos::subview(l2d,TestViewSubview::ALL,row);
ASSERT_TRUE( & l1da(0) == & l2d(0,row) );
if(n>1)
ASSERT_TRUE( & l1da(1) == & l2d(1,row) );
}
if(b && n>13) {
Kokkos::View<double*,LD,Space> l1db = Kokkos::subview(l2d,std::pair<unsigned,unsigned>(2,13),row);
ASSERT_TRUE( & l1db(0) == & l2d(2,row) );
ASSERT_TRUE( & l1db(1) == & l2d(3,row) );
}
if(c) {
Kokkos::View<double*,LD,Space> l1dc = Kokkos::subview(l2d,col,TestViewSubview::ALL);
ASSERT_TRUE( & l1dc(0) == & l2d(col,0) );
if(m>1)
ASSERT_TRUE( & l1dc(1) == & l2d(col,1) );
}
if(d && m>13) {
Kokkos::View<double*,LD,Space> l1dd = Kokkos::subview(l2d,col,std::pair<unsigned,unsigned>(2,13));
ASSERT_TRUE( & l1dd(0) == & l2d(col,2) );
ASSERT_TRUE( & l1dd(1) == & l2d(col,3) );
}
}
}
template<class Space >
void test_1d_strided_assignment() {
test_1d_strided_assignment_impl<Kokkos::LayoutStride,Kokkos::LayoutLeft,Space>(true,true,true,true,17,3);
test_1d_strided_assignment_impl<Kokkos::LayoutStride,Kokkos::LayoutRight,Space>(true,true,true,true,17,3);
test_1d_strided_assignment_impl<Kokkos::LayoutLeft,Kokkos::LayoutLeft,Space>(true,true,false,false,17,3);
test_1d_strided_assignment_impl<Kokkos::LayoutRight,Kokkos::LayoutLeft,Space>(true,true,false,false,17,3);
test_1d_strided_assignment_impl<Kokkos::LayoutLeft,Kokkos::LayoutRight,Space>(false,false,true,true,17,3);
test_1d_strided_assignment_impl<Kokkos::LayoutRight,Kokkos::LayoutRight,Space>(false,false,true,true,17,3);
test_1d_strided_assignment_impl<Kokkos::LayoutLeft,Kokkos::LayoutLeft,Space>(true,true,false,false,17,1);
test_1d_strided_assignment_impl<Kokkos::LayoutLeft,Kokkos::LayoutLeft,Space>(true,true,true,true,1,17);
test_1d_strided_assignment_impl<Kokkos::LayoutRight,Kokkos::LayoutLeft,Space>(true,true,true,true,1,17);
test_1d_strided_assignment_impl<Kokkos::LayoutRight,Kokkos::LayoutLeft,Space>(true,true,false,false,17,1);
test_1d_strided_assignment_impl<Kokkos::LayoutLeft,Kokkos::LayoutRight,Space>(true,true,true,true,17,1);
test_1d_strided_assignment_impl<Kokkos::LayoutLeft,Kokkos::LayoutRight,Space>(false,false,true,true,1,17);
test_1d_strided_assignment_impl<Kokkos::LayoutRight,Kokkos::LayoutRight,Space>(false,false,true,true,1,17);
test_1d_strided_assignment_impl<Kokkos::LayoutRight,Kokkos::LayoutRight,Space>(true,true,true,true,17,1);
}
template< class Space >
void test_left_0()
{
typedef Kokkos::View< int [2][3][4][5][2][3][4][5] , Kokkos::LayoutLeft , Space >
view_static_8_type ;
view_static_8_type x_static_8("x_static_left_8");
ASSERT_TRUE( x_static_8.is_contiguous() );
Kokkos::View<int,Kokkos::LayoutLeft,Space> x0 = Kokkos::subview( x_static_8 , 0, 0, 0, 0, 0, 0, 0, 0 );
ASSERT_TRUE( x0.is_contiguous() );
ASSERT_TRUE( & x0() == & x_static_8(0,0,0,0,0,0,0,0) );
Kokkos::View<int*,Kokkos::LayoutLeft,Space> x1 =
Kokkos::subview( x_static_8, Kokkos::pair<int,int>(0,2), 1, 2, 3, 0, 1, 2, 3 );
ASSERT_TRUE( x1.is_contiguous() );
ASSERT_TRUE( & x1(0) == & x_static_8(0,1,2,3,0,1,2,3) );
ASSERT_TRUE( & x1(1) == & x_static_8(1,1,2,3,0,1,2,3) );
Kokkos::View<int**,Kokkos::LayoutLeft,Space> x2 =
Kokkos::subview( x_static_8, Kokkos::pair<int,int>(0,2), 1, 2, 3
, Kokkos::pair<int,int>(0,2), 1, 2, 3 );
ASSERT_TRUE( ! x2.is_contiguous() );
ASSERT_TRUE( & x2(0,0) == & x_static_8(0,1,2,3,0,1,2,3) );
ASSERT_TRUE( & x2(1,0) == & x_static_8(1,1,2,3,0,1,2,3) );
ASSERT_TRUE( & x2(0,1) == & x_static_8(0,1,2,3,1,1,2,3) );
ASSERT_TRUE( & x2(1,1) == & x_static_8(1,1,2,3,1,1,2,3) );
// Kokkos::View<int**,Kokkos::LayoutLeft,Space> error_2 =
Kokkos::View<int**,Kokkos::LayoutStride,Space> sx2 =
Kokkos::subview( x_static_8, 1, Kokkos::pair<int,int>(0,2), 2, 3
, Kokkos::pair<int,int>(0,2), 1, 2, 3 );
ASSERT_TRUE( ! sx2.is_contiguous() );
ASSERT_TRUE( & sx2(0,0) == & x_static_8(1,0,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(1,0) == & x_static_8(1,1,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(0,1) == & x_static_8(1,0,2,3,1,1,2,3) );
ASSERT_TRUE( & sx2(1,1) == & x_static_8(1,1,2,3,1,1,2,3) );
Kokkos::View<int****,Kokkos::LayoutStride,Space> sx4 =
Kokkos::subview( x_static_8, 0, Kokkos::pair<int,int>(0,2) /* of [3] */
, 1, Kokkos::pair<int,int>(1,3) /* of [5] */
, 1, Kokkos::pair<int,int>(0,2) /* of [3] */
, 2, Kokkos::pair<int,int>(2,4) /* of [5] */
);
ASSERT_TRUE( ! sx4.is_contiguous() );
for ( int i0 = 0 ; i0 < (int) sx4.dimension_0() ; ++i0 )
for ( int i1 = 0 ; i1 < (int) sx4.dimension_1() ; ++i1 )
for ( int i2 = 0 ; i2 < (int) sx4.dimension_2() ; ++i2 )
for ( int i3 = 0 ; i3 < (int) sx4.dimension_3() ; ++i3 ) {
ASSERT_TRUE( & sx4(i0,i1,i2,i3) == & x_static_8(0,0+i0, 1,1+i1, 1,0+i2, 2,2+i3) );
}
}
template< class Space >
void test_left_1()
{
typedef Kokkos::View< int ****[2][3][4][5] , Kokkos::LayoutLeft , Space >
view_type ;
view_type x8("x_left_8",2,3,4,5);
ASSERT_TRUE( x8.is_contiguous() );
Kokkos::View<int,Kokkos::LayoutLeft,Space> x0 = Kokkos::subview( x8 , 0, 0, 0, 0, 0, 0, 0, 0 );
ASSERT_TRUE( x0.is_contiguous() );
ASSERT_TRUE( & x0() == & x8(0,0,0,0,0,0,0,0) );
Kokkos::View<int*,Kokkos::LayoutLeft,Space> x1 =
Kokkos::subview( x8, Kokkos::pair<int,int>(0,2), 1, 2, 3, 0, 1, 2, 3 );
ASSERT_TRUE( x1.is_contiguous() );
ASSERT_TRUE( & x1(0) == & x8(0,1,2,3,0,1,2,3) );
ASSERT_TRUE( & x1(1) == & x8(1,1,2,3,0,1,2,3) );
Kokkos::View<int**,Kokkos::LayoutLeft,Space> x2 =
Kokkos::subview( x8, Kokkos::pair<int,int>(0,2), 1, 2, 3
, Kokkos::pair<int,int>(0,2), 1, 2, 3 );
ASSERT_TRUE( ! x2.is_contiguous() );
ASSERT_TRUE( & x2(0,0) == & x8(0,1,2,3,0,1,2,3) );
ASSERT_TRUE( & x2(1,0) == & x8(1,1,2,3,0,1,2,3) );
ASSERT_TRUE( & x2(0,1) == & x8(0,1,2,3,1,1,2,3) );
ASSERT_TRUE( & x2(1,1) == & x8(1,1,2,3,1,1,2,3) );
// Kokkos::View<int**,Kokkos::LayoutLeft,Space> error_2 =
Kokkos::View<int**,Kokkos::LayoutStride,Space> sx2 =
Kokkos::subview( x8, 1, Kokkos::pair<int,int>(0,2), 2, 3
, Kokkos::pair<int,int>(0,2), 1, 2, 3 );
ASSERT_TRUE( ! sx2.is_contiguous() );
ASSERT_TRUE( & sx2(0,0) == & x8(1,0,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(1,0) == & x8(1,1,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(0,1) == & x8(1,0,2,3,1,1,2,3) );
ASSERT_TRUE( & sx2(1,1) == & x8(1,1,2,3,1,1,2,3) );
Kokkos::View<int****,Kokkos::LayoutStride,Space> sx4 =
Kokkos::subview( x8, 0, Kokkos::pair<int,int>(0,2) /* of [3] */
, 1, Kokkos::pair<int,int>(1,3) /* of [5] */
, 1, Kokkos::pair<int,int>(0,2) /* of [3] */
, 2, Kokkos::pair<int,int>(2,4) /* of [5] */
);
ASSERT_TRUE( ! sx4.is_contiguous() );
for ( int i0 = 0 ; i0 < (int) sx4.dimension_0() ; ++i0 )
for ( int i1 = 0 ; i1 < (int) sx4.dimension_1() ; ++i1 )
for ( int i2 = 0 ; i2 < (int) sx4.dimension_2() ; ++i2 )
for ( int i3 = 0 ; i3 < (int) sx4.dimension_3() ; ++i3 ) {
ASSERT_TRUE( & sx4(i0,i1,i2,i3) == & x8(0,0+i0, 1,1+i1, 1,0+i2, 2,2+i3) );
}
}
template< class Space >
void test_left_2()
{
typedef Kokkos::View< int **** , Kokkos::LayoutLeft , Space > view_type ;
view_type x4("x4",2,3,4,5);
ASSERT_TRUE( x4.is_contiguous() );
Kokkos::View<int,Kokkos::LayoutLeft,Space> x0 = Kokkos::subview( x4 , 0, 0, 0, 0 );
ASSERT_TRUE( x0.is_contiguous() );
ASSERT_TRUE( & x0() == & x4(0,0,0,0) );
Kokkos::View<int*,Kokkos::LayoutLeft,Space> x1 =
Kokkos::subview( x4, Kokkos::pair<int,int>(0,2), 1, 2, 3 );
ASSERT_TRUE( x1.is_contiguous() );
ASSERT_TRUE( & x1(0) == & x4(0,1,2,3) );
ASSERT_TRUE( & x1(1) == & x4(1,1,2,3) );
Kokkos::View<int**,Kokkos::LayoutLeft,Space> x2 =
Kokkos::subview( x4, Kokkos::pair<int,int>(0,2), 1, Kokkos::pair<int,int>(1,3), 2 );
ASSERT_TRUE( ! x2.is_contiguous() );
ASSERT_TRUE( & x2(0,0) == & x4(0,1,1,2) );
ASSERT_TRUE( & x2(1,0) == & x4(1,1,1,2) );
ASSERT_TRUE( & x2(0,1) == & x4(0,1,2,2) );
ASSERT_TRUE( & x2(1,1) == & x4(1,1,2,2) );
// Kokkos::View<int**,Kokkos::LayoutLeft,Space> error_2 =
Kokkos::View<int**,Kokkos::LayoutStride,Space> sx2 =
Kokkos::subview( x4, 1, Kokkos::pair<int,int>(0,2)
, 2, Kokkos::pair<int,int>(1,4) );
ASSERT_TRUE( ! sx2.is_contiguous() );
ASSERT_TRUE( & sx2(0,0) == & x4(1,0,2,1) );
ASSERT_TRUE( & sx2(1,0) == & x4(1,1,2,1) );
ASSERT_TRUE( & sx2(0,1) == & x4(1,0,2,2) );
ASSERT_TRUE( & sx2(1,1) == & x4(1,1,2,2) );
ASSERT_TRUE( & sx2(0,2) == & x4(1,0,2,3) );
ASSERT_TRUE( & sx2(1,2) == & x4(1,1,2,3) );
Kokkos::View<int****,Kokkos::LayoutStride,Space> sx4 =
Kokkos::subview( x4, Kokkos::pair<int,int>(1,2) /* of [2] */
, Kokkos::pair<int,int>(1,3) /* of [3] */
, Kokkos::pair<int,int>(0,4) /* of [4] */
, Kokkos::pair<int,int>(2,4) /* of [5] */
);
ASSERT_TRUE( ! sx4.is_contiguous() );
for ( int i0 = 0 ; i0 < (int) sx4.dimension_0() ; ++i0 )
for ( int i1 = 0 ; i1 < (int) sx4.dimension_1() ; ++i1 )
for ( int i2 = 0 ; i2 < (int) sx4.dimension_2() ; ++i2 )
for ( int i3 = 0 ; i3 < (int) sx4.dimension_3() ; ++i3 ) {
ASSERT_TRUE( & sx4(i0,i1,i2,i3) == & x4( 1+i0, 1+i1, 0+i2, 2+i3 ) );
}
}
template< class Space >
void test_left_3()
{
typedef Kokkos::View< int ** , Kokkos::LayoutLeft , Space > view_type ;
view_type xm("x4",10,5);
ASSERT_TRUE( xm.is_contiguous() );
Kokkos::View<int,Kokkos::LayoutLeft,Space> x0 = Kokkos::subview( xm , 5, 3 );
ASSERT_TRUE( x0.is_contiguous() );
ASSERT_TRUE( & x0() == & xm(5,3) );
Kokkos::View<int*,Kokkos::LayoutLeft,Space> x1 =
Kokkos::subview( xm, TestViewSubview::ALL, 3 );
ASSERT_TRUE( x1.is_contiguous() );
for ( int i = 0 ; i < int(xm.dimension_0()) ; ++i ) {
ASSERT_TRUE( & x1(i) == & xm(i,3) );
}
Kokkos::View<int**,Kokkos::LayoutLeft,Space> x2 =
Kokkos::subview( xm, Kokkos::pair<int,int>(1,9), TestViewSubview::ALL );
ASSERT_TRUE( ! x2.is_contiguous() );
for ( int j = 0 ; j < int(x2.dimension_1()) ; ++j )
for ( int i = 0 ; i < int(x2.dimension_0()) ; ++i ) {
ASSERT_TRUE( & x2(i,j) == & xm(1+i,j) );
}
Kokkos::View<int**,Kokkos::LayoutLeft,Space> x2c =
Kokkos::subview( xm, TestViewSubview::ALL, std::pair<int,int>(2,4) );
ASSERT_TRUE( x2c.is_contiguous() );
for ( int j = 0 ; j < int(x2c.dimension_1()) ; ++j )
for ( int i = 0 ; i < int(x2c.dimension_0()) ; ++i ) {
ASSERT_TRUE( & x2c(i,j) == & xm(i,2+j) );
}
Kokkos::View<int**,Kokkos::LayoutLeft,Space> x2_n1 =
Kokkos::subview( xm , std::pair<int,int>(1,1) , TestViewSubview::ALL );
ASSERT_TRUE( x2_n1.dimension_0() == 0 );
ASSERT_TRUE( x2_n1.dimension_1() == xm.dimension_1() );
Kokkos::View<int**,Kokkos::LayoutLeft,Space> x2_n2 =
Kokkos::subview( xm , TestViewSubview::ALL , std::pair<int,int>(1,1) );
ASSERT_TRUE( x2_n2.dimension_0() == xm.dimension_0() );
ASSERT_TRUE( x2_n2.dimension_1() == 0 );
}
//----------------------------------------------------------------------------
template< class Space >
void test_right_0()
{
typedef Kokkos::View< int [2][3][4][5][2][3][4][5] , Kokkos::LayoutRight , Space >
view_static_8_type ;
view_static_8_type x_static_8("x_static_right_8");
Kokkos::View<int,Kokkos::LayoutRight,Space> x0 = Kokkos::subview( x_static_8 , 0, 0, 0, 0, 0, 0, 0, 0 );
ASSERT_TRUE( & x0() == & x_static_8(0,0,0,0,0,0,0,0) );
Kokkos::View<int*,Kokkos::LayoutRight,Space> x1 =
Kokkos::subview( x_static_8, 0, 1, 2, 3, 0, 1, 2, Kokkos::pair<int,int>(1,3) );
ASSERT_TRUE( & x1(0) == & x_static_8(0,1,2,3,0,1,2,1) );
ASSERT_TRUE( & x1(1) == & x_static_8(0,1,2,3,0,1,2,2) );
Kokkos::View<int**,Kokkos::LayoutRight,Space> x2 =
Kokkos::subview( x_static_8, 0, 1, 2, Kokkos::pair<int,int>(1,3)
, 0, 1, 2, Kokkos::pair<int,int>(1,3) );
ASSERT_TRUE( & x2(0,0) == & x_static_8(0,1,2,1,0,1,2,1) );
ASSERT_TRUE( & x2(1,0) == & x_static_8(0,1,2,2,0,1,2,1) );
ASSERT_TRUE( & x2(0,1) == & x_static_8(0,1,2,1,0,1,2,2) );
ASSERT_TRUE( & x2(1,1) == & x_static_8(0,1,2,2,0,1,2,2) );
// Kokkos::View<int**,Kokkos::LayoutRight,Space> error_2 =
Kokkos::View<int**,Kokkos::LayoutStride,Space> sx2 =
Kokkos::subview( x_static_8, 1, Kokkos::pair<int,int>(0,2), 2, 3
, Kokkos::pair<int,int>(0,2), 1, 2, 3 );
ASSERT_TRUE( & sx2(0,0) == & x_static_8(1,0,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(1,0) == & x_static_8(1,1,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(0,1) == & x_static_8(1,0,2,3,1,1,2,3) );
ASSERT_TRUE( & sx2(1,1) == & x_static_8(1,1,2,3,1,1,2,3) );
Kokkos::View<int****,Kokkos::LayoutStride,Space> sx4 =
Kokkos::subview( x_static_8, 0, Kokkos::pair<int,int>(0,2) /* of [3] */
, 1, Kokkos::pair<int,int>(1,3) /* of [5] */
, 1, Kokkos::pair<int,int>(0,2) /* of [3] */
, 2, Kokkos::pair<int,int>(2,4) /* of [5] */
);
for ( int i0 = 0 ; i0 < (int) sx4.dimension_0() ; ++i0 )
for ( int i1 = 0 ; i1 < (int) sx4.dimension_1() ; ++i1 )
for ( int i2 = 0 ; i2 < (int) sx4.dimension_2() ; ++i2 )
for ( int i3 = 0 ; i3 < (int) sx4.dimension_3() ; ++i3 ) {
ASSERT_TRUE( & sx4(i0,i1,i2,i3) == & x_static_8(0, 0+i0, 1, 1+i1, 1, 0+i2, 2, 2+i3) );
}
}
template< class Space >
void test_right_1()
{
typedef Kokkos::View< int ****[2][3][4][5] , Kokkos::LayoutRight , Space >
view_type ;
view_type x8("x_right_8",2,3,4,5);
Kokkos::View<int,Kokkos::LayoutRight,Space> x0 = Kokkos::subview( x8 , 0, 0, 0, 0, 0, 0, 0, 0 );
ASSERT_TRUE( & x0() == & x8(0,0,0,0,0,0,0,0) );
Kokkos::View<int*,Kokkos::LayoutRight,Space> x1 =
Kokkos::subview( x8, 0, 1, 2, 3, 0, 1, 2, Kokkos::pair<int,int>(1,3) );
ASSERT_TRUE( & x1(0) == & x8(0,1,2,3,0,1,2,1) );
ASSERT_TRUE( & x1(1) == & x8(0,1,2,3,0,1,2,2) );
Kokkos::View<int**,Kokkos::LayoutRight,Space> x2 =
Kokkos::subview( x8, 0, 1, 2, Kokkos::pair<int,int>(1,3)
, 0, 1, 2, Kokkos::pair<int,int>(1,3) );
ASSERT_TRUE( & x2(0,0) == & x8(0,1,2,1,0,1,2,1) );
ASSERT_TRUE( & x2(1,0) == & x8(0,1,2,2,0,1,2,1) );
ASSERT_TRUE( & x2(0,1) == & x8(0,1,2,1,0,1,2,2) );
ASSERT_TRUE( & x2(1,1) == & x8(0,1,2,2,0,1,2,2) );
// Kokkos::View<int**,Kokkos::LayoutRight,Space> error_2 =
Kokkos::View<int**,Kokkos::LayoutStride,Space> sx2 =
Kokkos::subview( x8, 1, Kokkos::pair<int,int>(0,2), 2, 3
, Kokkos::pair<int,int>(0,2), 1, 2, 3 );
ASSERT_TRUE( & sx2(0,0) == & x8(1,0,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(1,0) == & x8(1,1,2,3,0,1,2,3) );
ASSERT_TRUE( & sx2(0,1) == & x8(1,0,2,3,1,1,2,3) );
ASSERT_TRUE( & sx2(1,1) == & x8(1,1,2,3,1,1,2,3) );
Kokkos::View<int****,Kokkos::LayoutStride,Space> sx4 =
Kokkos::subview( x8, 0, Kokkos::pair<int,int>(0,2) /* of [3] */
, 1, Kokkos::pair<int,int>(1,3) /* of [5] */
, 1, Kokkos::pair<int,int>(0,2) /* of [3] */
, 2, Kokkos::pair<int,int>(2,4) /* of [5] */
);
for ( int i0 = 0 ; i0 < (int) sx4.dimension_0() ; ++i0 )
for ( int i1 = 0 ; i1 < (int) sx4.dimension_1() ; ++i1 )
for ( int i2 = 0 ; i2 < (int) sx4.dimension_2() ; ++i2 )
for ( int i3 = 0 ; i3 < (int) sx4.dimension_3() ; ++i3 ) {
ASSERT_TRUE( & sx4(i0,i1,i2,i3) == & x8(0,0+i0, 1,1+i1, 1,0+i2, 2,2+i3) );
}
}
template< class Space >
void test_right_3()
{
typedef Kokkos::View< int ** , Kokkos::LayoutRight , Space > view_type ;
view_type xm("x4",10,5);
ASSERT_TRUE( xm.is_contiguous() );
Kokkos::View<int,Kokkos::LayoutRight,Space> x0 = Kokkos::subview( xm , 5, 3 );
ASSERT_TRUE( x0.is_contiguous() );
ASSERT_TRUE( & x0() == & xm(5,3) );
Kokkos::View<int*,Kokkos::LayoutRight,Space> x1 =
Kokkos::subview( xm, 3, TestViewSubview::ALL );
ASSERT_TRUE( x1.is_contiguous() );
for ( int i = 0 ; i < int(xm.dimension_1()) ; ++i ) {
ASSERT_TRUE( & x1(i) == & xm(3,i) );
}
Kokkos::View<int**,Kokkos::LayoutRight,Space> x2c =
Kokkos::subview( xm, Kokkos::pair<int,int>(1,9), TestViewSubview::ALL );
ASSERT_TRUE( x2c.is_contiguous() );
for ( int j = 0 ; j < int(x2c.dimension_1()) ; ++j )
for ( int i = 0 ; i < int(x2c.dimension_0()) ; ++i ) {
ASSERT_TRUE( & x2c(i,j) == & xm(1+i,j) );
}
Kokkos::View<int**,Kokkos::LayoutRight,Space> x2 =
Kokkos::subview( xm, TestViewSubview::ALL, std::pair<int,int>(2,4) );
ASSERT_TRUE( ! x2.is_contiguous() );
for ( int j = 0 ; j < int(x2.dimension_1()) ; ++j )
for ( int i = 0 ; i < int(x2.dimension_0()) ; ++i ) {
ASSERT_TRUE( & x2(i,j) == & xm(i,2+j) );
}
Kokkos::View<int**,Kokkos::LayoutRight,Space> x2_n1 =
Kokkos::subview( xm , std::pair<int,int>(1,1) , TestViewSubview::ALL );
ASSERT_TRUE( x2_n1.dimension_0() == 0 );
ASSERT_TRUE( x2_n1.dimension_1() == xm.dimension_1() );
Kokkos::View<int**,Kokkos::LayoutRight,Space> x2_n2 =
Kokkos::subview( xm , TestViewSubview::ALL , std::pair<int,int>(1,1) );
ASSERT_TRUE( x2_n2.dimension_0() == xm.dimension_0() );
ASSERT_TRUE( x2_n2.dimension_1() == 0 );
}
//----------------------------------------------------------------------------
}

View File

@ -0,0 +1,50 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc,argv);
return RUN_ALL_TESTS();
}