git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@13583 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
146
lib/kokkos/core/unit_test/Makefile
Executable file
146
lib/kokkos/core/unit_test/Makefile
Executable 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
|
||||
|
||||
716
lib/kokkos/core/unit_test/TestAggregate.hpp
Executable file
716
lib/kokkos/core/unit_test/TestAggregate.hpp
Executable 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 */
|
||||
189
lib/kokkos/core/unit_test/TestAggregateReduction.hpp
Executable file
189
lib/kokkos/core/unit_test/TestAggregateReduction.hpp
Executable 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 */
|
||||
|
||||
145
lib/kokkos/core/unit_test/TestAllocationTracker.cpp
Executable file
145
lib/kokkos/core/unit_test/TestAllocationTracker.cpp
Executable 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
|
||||
376
lib/kokkos/core/unit_test/TestAtomic.hpp
Executable file
376
lib/kokkos/core/unit_test/TestAtomic.hpp
Executable 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 ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
319
lib/kokkos/core/unit_test/TestCXX11.hpp
Executable file
319
lib/kokkos/core/unit_test/TestCXX11.hpp
Executable 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
|
||||
}
|
||||
|
||||
}
|
||||
103
lib/kokkos/core/unit_test/TestCXX11Deduction.hpp
Executable file
103
lib/kokkos/core/unit_test/TestCXX11Deduction.hpp
Executable 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
|
||||
|
||||
93
lib/kokkos/core/unit_test/TestCompilerMacros.hpp
Executable file
93
lib/kokkos/core/unit_test/TestCompilerMacros.hpp
Executable 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;
|
||||
}
|
||||
|
||||
}
|
||||
495
lib/kokkos/core/unit_test/TestCuda.cpp
Executable file
495
lib/kokkos/core/unit_test/TestCuda.cpp
Executable 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
|
||||
|
||||
250
lib/kokkos/core/unit_test/TestDefaultDeviceType.cpp
Executable file
250
lib/kokkos/core/unit_test/TestDefaultDeviceType.cpp
Executable 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
|
||||
390
lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.cpp
Executable file
390
lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.cpp
Executable 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
|
||||
69
lib/kokkos/core/unit_test/TestHWLOC.cpp
Executable file
69
lib/kokkos/core/unit_test/TestHWLOC.cpp
Executable 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 ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
100
lib/kokkos/core/unit_test/TestMemorySpaceTracking.hpp
Executable file
100
lib/kokkos/core/unit_test/TestMemorySpaceTracking.hpp
Executable 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
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
375
lib/kokkos/core/unit_test/TestOpenMP.cpp
Executable file
375
lib/kokkos/core/unit_test/TestOpenMP.cpp
Executable 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
|
||||
|
||||
283
lib/kokkos/core/unit_test/TestQthread.cpp
Executable file
283
lib/kokkos/core/unit_test/TestQthread.cpp
Executable 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
|
||||
|
||||
171
lib/kokkos/core/unit_test/TestRange.hpp
Executable file
171
lib/kokkos/core/unit_test/TestRange.hpp
Executable 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 */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
371
lib/kokkos/core/unit_test/TestReduce.hpp
Executable file
371
lib/kokkos/core/unit_test/TestReduce.hpp
Executable 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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
97
lib/kokkos/core/unit_test/TestScan.hpp
Executable file
97
lib/kokkos/core/unit_test/TestScan.hpp
Executable 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 );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
419
lib/kokkos/core/unit_test/TestSerial.cpp
Executable file
419
lib/kokkos/core/unit_test/TestSerial.cpp
Executable 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
|
||||
|
||||
204
lib/kokkos/core/unit_test/TestSharedAlloc.hpp
Executable file
204
lib/kokkos/core/unit_test/TestSharedAlloc.hpp
Executable 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 ) */
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
494
lib/kokkos/core/unit_test/TestTaskPolicy.hpp
Executable file
494
lib/kokkos/core/unit_test/TestTaskPolicy.hpp
Executable 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 */
|
||||
|
||||
|
||||
466
lib/kokkos/core/unit_test/TestTeam.hpp
Executable file
466
lib/kokkos/core/unit_test/TestTeam.hpp
Executable 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 );
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
650
lib/kokkos/core/unit_test/TestTeamVector.hpp
Executable file
650
lib/kokkos/core/unit_test/TestTeamVector.hpp
Executable 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
219
lib/kokkos/core/unit_test/TestTemplateMetaFunctions.hpp
Executable file
219
lib/kokkos/core/unit_test/TestTemplateMetaFunctions.hpp
Executable 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);
|
||||
}
|
||||
|
||||
}
|
||||
443
lib/kokkos/core/unit_test/TestThreads.cpp
Executable file
443
lib/kokkos/core/unit_test/TestThreads.cpp
Executable 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 ) */
|
||||
153
lib/kokkos/core/unit_test/TestTile.hpp
Executable file
153
lib/kokkos/core/unit_test/TestTile.hpp
Executable 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
|
||||
|
||||
1305
lib/kokkos/core/unit_test/TestViewAPI.hpp
Executable file
1305
lib/kokkos/core/unit_test/TestViewAPI.hpp
Executable file
File diff suppressed because it is too large
Load Diff
289
lib/kokkos/core/unit_test/TestViewImpl.hpp
Executable file
289
lib/kokkos/core/unit_test/TestViewImpl.hpp
Executable 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
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
1018
lib/kokkos/core/unit_test/TestViewMapping.hpp
Executable file
1018
lib/kokkos/core/unit_test/TestViewMapping.hpp
Executable file
File diff suppressed because it is too large
Load Diff
126
lib/kokkos/core/unit_test/TestViewOfClass.hpp
Executable file
126
lib/kokkos/core/unit_test/TestViewOfClass.hpp
Executable 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
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
632
lib/kokkos/core/unit_test/TestViewSubview.hpp
Executable file
632
lib/kokkos/core/unit_test/TestViewSubview.hpp
Executable 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 );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
50
lib/kokkos/core/unit_test/UnitTestMain.cpp
Executable file
50
lib/kokkos/core/unit_test/UnitTestMain.cpp
Executable 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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user