Update Kokkos library in LAMMPS to v3.6.0

This commit is contained in:
Stan Gerald Moore
2022-05-05 11:44:47 -06:00
parent bd4bbbddbe
commit b79c0bc7b4
380 changed files with 41928 additions and 8786 deletions

View File

@ -2,28 +2,32 @@
# Add test-only library for gtest to be reused by all the subpackages
#
IF(NOT GTest_FOUND) # fallback to internal gtest
SET(GTEST_SOURCE_DIR ${${PARENT_PACKAGE_NAME}_SOURCE_DIR}/tpls/gtest)
SET(GTEST_SOURCE_DIR ${${PARENT_PACKAGE_NAME}_SOURCE_DIR}/tpls/gtest)
#need here for tribits
KOKKOS_INCLUDE_DIRECTORIES(${GTEST_SOURCE_DIR})
KOKKOS_ADD_TEST_LIBRARY(
kokkos_gtest
HEADERS ${GTEST_SOURCE_DIR}/gtest/gtest.h
SOURCES ${GTEST_SOURCE_DIR}/gtest/gtest-all.cc
)
#need here for tribits
KOKKOS_INCLUDE_DIRECTORIES(${GTEST_SOURCE_DIR})
KOKKOS_ADD_TEST_LIBRARY(
kokkos_gtest
HEADERS ${GTEST_SOURCE_DIR}/gtest/gtest.h
SOURCES ${GTEST_SOURCE_DIR}/gtest/gtest-all.cc
)
TARGET_INCLUDE_DIRECTORIES(kokkos_gtest PUBLIC ${GTEST_SOURCE_DIR})
IF((NOT (Kokkos_ENABLE_CUDA AND WIN32)) AND (NOT ("${KOKKOS_CXX_COMPILER_ID}" STREQUAL "Fujitsu")))
TARGET_COMPILE_FEATURES(kokkos_gtest PUBLIC cxx_std_14)
ENDIF()
# avoid deprecation warnings from MSVC
TARGET_COMPILE_DEFINITIONS(kokkos_gtest PUBLIC GTEST_HAS_TR1_TUPLE=0 GTEST_HAS_PTHREAD=0)
# Suppress clang-tidy diagnostics on code that we do not have control over
IF(CMAKE_CXX_CLANG_TIDY)
SET_TARGET_PROPERTIES(kokkos_gtest PROPERTIES CXX_CLANG_TIDY "")
ENDIF()
TARGET_INCLUDE_DIRECTORIES(kokkos_gtest PUBLIC ${GTEST_SOURCE_DIR})
IF((NOT (Kokkos_ENABLE_CUDA AND WIN32)) AND (NOT ("${KOKKOS_CXX_COMPILER_ID}" STREQUAL "Fujitsu")))
TARGET_COMPILE_FEATURES(kokkos_gtest PUBLIC cxx_std_14)
ENDIF()
# Suppress clang-tidy diagnostics on code that we do not have control over
IF(CMAKE_CXX_CLANG_TIDY)
SET_TARGET_PROPERTIES(kokkos_gtest PROPERTIES CXX_CLANG_TIDY "")
FIND_PACKAGE(Threads QUIET)
IF(TARGET Threads::Threads)
SET_TARGET_PROPERTIES(kokkos_gtest PROPERTIES
INTERFACE_LINK_LIBRARIES Threads::Threads)
ENDIF()
ENDIF()
#
@ -81,12 +85,7 @@ KOKKOS_ADD_EXECUTABLE(
)
foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;HIP;SYCL)
# Because there is always an exception to the rule
if(Tag STREQUAL "Threads")
set(DEVICE "PTHREAD")
else()
string(TOUPPER ${Tag} DEVICE)
endif()
string(TOUPPER ${Tag} DEVICE)
string(TOLOWER ${Tag} dir)
if(Kokkos_ENABLE_${DEVICE})
@ -106,6 +105,7 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;HIP;SYCL)
AtomicOperations_float
AtomicOperations_complexdouble
AtomicOperations_complexfloat
AtomicOperations_shared
AtomicViews
Atomics
BlockSizeDeduction
@ -117,6 +117,8 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;HIP;SYCL)
FunctorAnalysis
Init
LocalDeepCopy
MinMaxClamp
MathematicalConstants
MathematicalFunctions
MDRange_a
MDRange_b
@ -143,6 +145,7 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;HIP;SYCL)
MDRange_d
MDRange_e
MDRange_f
MDRange_g
NumericTraits
Other
RangePolicy
@ -152,6 +155,7 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;HIP;SYCL)
Reducers_b
Reducers_c
Reducers_d
Reducers_e
Reductions_DeviceView
Scan
SharedAlloc
@ -258,6 +262,7 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;HIP;SYCL)
SubView_c12
SubView_c13
SubView_c14
WithoutInitializing
)
set(file ${dir}/Test${Tag}_${Name}.cpp)
# Write to a temporary intermediate file and call configure_file to avoid
@ -331,6 +336,16 @@ if(Kokkos_ENABLE_OPENMPTARGET)
)
endif()
# FIXME_OPENMPTARGET - Comment non-passing tests with amdclang++
IF(KOKKOS_ARCH_VEGA906 OR KOKKOS_ARCH_VEGA908 OR KOKKOS_ARCH_VEGA90A)
SET(KOKKOS_AMDGPU_ARCH TRUE)
ENDIF()
IF(KOKKOS_ENABLE_OPENMPTARGET AND KOKKOS_CXX_COMPILER_ID STREQUAL Clang AND KOKKOS_AMDGPU_ARCH)
LIST(REMOVE_ITEM OpenMPTarget_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_Reducers_e.cpp
)
ENDIF()
# FIXME_OPENMPTARGET - Comment non-passing tests with the NVIDIA HPC compiler nvc++
IF(KOKKOS_ENABLE_OPENMPTARGET AND KOKKOS_CXX_COMPILER_ID STREQUAL NVHPC)
list(REMOVE_ITEM OpenMPTarget_SOURCES
@ -364,6 +379,7 @@ IF(KOKKOS_ENABLE_OPENMPTARGET AND KOKKOS_CXX_COMPILER_ID STREQUAL NVHPC)
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_Reducers_b.cpp
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_Reducers_c.cpp
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_Reducers_d.cpp
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_Reducers_e.cpp
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_ViewMapping_b.cpp
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_TeamBasic.cpp
${CMAKE_CURRENT_BINARY_DIR}/openmptarget/TestOpenMPTarget_Scan.cpp
@ -423,7 +439,7 @@ if(Kokkos_ENABLE_SERIAL)
)
endif()
if(Kokkos_ENABLE_PTHREAD)
if(Kokkos_ENABLE_THREADS)
KOKKOS_ADD_EXECUTABLE_AND_TEST(
UnitTest_Threads
SOURCES ${Threads_SOURCES}
@ -514,6 +530,7 @@ if(Kokkos_ENABLE_CUDA)
SOURCES
UnitTestMainInit.cpp
${Cuda_SOURCES1}
cuda/TestCuda_ReducerViewSizeLimit.cpp
)
KOKKOS_ADD_EXECUTABLE_AND_TEST(
@ -690,6 +707,7 @@ else()
default/TestDefaultDeviceType_c3.cpp
default/TestDefaultDeviceType_d.cpp
default/TestDefaultDeviceTypeResize.cpp
default/TestDefaultDeviceTypeViewAPI.cpp
)
endif()
@ -730,7 +748,6 @@ KOKKOS_ADD_ADVANCED_TEST( UnitTest_PushFinalizeHook_terminate
"PASSED: I am the custom std::terminate handler."
ALWAYS_FAIL_ON_ZERO_RETURN
)
if(KOKKOS_ENABLE_TUNING)
KOKKOS_ADD_EXECUTABLE_AND_TEST(
UnitTest_TuningBuiltins
@ -755,13 +772,26 @@ KOKKOS_ADD_ADVANCED_TEST( UnitTest_PushFinalizeHook_terminate
tools/TestLogicalSpaces.cpp
)
endif()
if(NOT (KOKKOS_CXX_COMPILER_ID STREQUAL Intel AND KOKKOS_CXX_COMPILER_VERSION VERSION_LESS 18.0.0))
KOKKOS_ADD_EXECUTABLE_AND_TEST(
UnitTest_EventCorrectness
UnitTest_KokkosP
SOURCES
UnitTestMainInit.cpp
tools/TestEventCorrectness.cpp
tools/TestWithoutInitializing.cpp
tools/TestProfilingSection.cpp
)
endif()
if(KOKKOS_ENABLE_LIBDL)
KOKKOS_ADD_EXECUTABLE_AND_TEST(
UnitTest_ToolIndependence
SOURCES
tools/TestIndependence.cpp
)
TARGET_COMPILE_DEFINITIONS(
KokkosCore_UnitTest_ToolIndependence PUBLIC
KOKKOS_TOOLS_INDEPENDENT_BUILD
)
KOKKOS_ADD_TEST_LIBRARY(
kokkosprinter-tool SHARED
SOURCES tools/printing-tool.cpp
@ -807,7 +837,7 @@ KOKKOS_ADD_ADVANCED_TEST( UnitTest_PushFinalizeHook_terminate
EXE ProfilingAllCalls
TOOL kokkosprinter-tool
ARGS --kokkos-tools-args="-c test delimit"
PASS_REGULAR_EXPRESSION "kokkosp_init_library::kokkosp_parse_args:4:KokkosCore_ProfilingAllCalls:-c:test:delimit::.*::kokkosp_allocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]source] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_allocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]destination] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_begin_deep_copy:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_end_deep_copy::kokkosp_begin_parallel_for:parallel_for:${SIZE_REGEX}:0::kokkosp_end_parallel_for:0::kokkosp_begin_parallel_reduce:parallel_reduce:${SIZE_REGEX}:1${SKIP_SCRATCH_INITIALIZATION_REGEX}::kokkosp_end_parallel_reduce:1::kokkosp_begin_parallel_scan:parallel_scan:${SIZE_REGEX}:2::kokkosp_end_parallel_scan:2::kokkosp_push_profile_region:push_region::kokkosp_pop_profile_region::kokkosp_create_profile_section:created_section:3::kokkosp_start_profile_section:3::kokkosp_stop_profile_section:3::kokkosp_destroy_profile_section:3::kokkosp_profile_event:profiling_event::kokkosp_declare_metadata:dogs:good::kokkosp_deallocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_deallocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_finalize_library::"
PASS_REGULAR_EXPRESSION "kokkosp_init_library::kokkosp_parse_args:4:KokkosCore_ProfilingAllCalls:-c:test:delimit::.*::kokkosp_allocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]source] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_allocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]destination] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_begin_deep_copy:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::.*kokkosp_end_deep_copy::kokkosp_begin_parallel_for:parallel_for:${SIZE_REGEX}:0::kokkosp_end_parallel_for:0::kokkosp_begin_parallel_reduce:parallel_reduce:${SIZE_REGEX}:1${SKIP_SCRATCH_INITIALIZATION_REGEX}::kokkosp_end_parallel_reduce:1::kokkosp_begin_parallel_scan:parallel_scan:${SIZE_REGEX}:2::kokkosp_end_parallel_scan:2::kokkosp_push_profile_region:push_region::kokkosp_pop_profile_region::kokkosp_create_profile_section:created_section:3::kokkosp_start_profile_section:3::kokkosp_stop_profile_section:3::kokkosp_destroy_profile_section:3::kokkosp_profile_event:profiling_event::kokkosp_declare_metadata:dogs:good::kokkosp_deallocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_deallocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_finalize_library::"
)
# Above will test that leading/trailing quotes are stripped bc ctest cmd args is:
@ -824,7 +854,7 @@ KOKKOS_ADD_ADVANCED_TEST( UnitTest_PushFinalizeHook_terminate
EXE ProfilingAllCalls
ARGS [=[--kokkos-tools-args=-c test delimit]=]
--kokkos-tools-library=$<TARGET_FILE:kokkosprinter-tool>
PASS_REGULAR_EXPRESSION "kokkosp_init_library::kokkosp_parse_args:4:KokkosCore_ProfilingAllCalls:-c:test:delimit::.*::kokkosp_allocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]source] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_allocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]destination] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_begin_deep_copy:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_end_deep_copy::kokkosp_begin_parallel_for:parallel_for:${SIZE_REGEX}:0::kokkosp_end_parallel_for:0::kokkosp_begin_parallel_reduce:parallel_reduce:${SIZE_REGEX}:1${SKIP_SCRATCH_INITIALIZATION_REGEX}::kokkosp_end_parallel_reduce:1::kokkosp_begin_parallel_scan:parallel_scan:${SIZE_REGEX}:2::kokkosp_end_parallel_scan:2::kokkosp_push_profile_region:push_region::kokkosp_pop_profile_region::kokkosp_create_profile_section:created_section:3::kokkosp_start_profile_section:3::kokkosp_stop_profile_section:3::kokkosp_destroy_profile_section:3::kokkosp_profile_event:profiling_event::kokkosp_declare_metadata:dogs:good::kokkosp_deallocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_deallocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_finalize_library::"
PASS_REGULAR_EXPRESSION "kokkosp_init_library::kokkosp_parse_args:4:KokkosCore_ProfilingAllCalls:-c:test:delimit::.*::kokkosp_allocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]source] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_allocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_begin_parallel_for:Kokkos::View::initialization [[]destination] via memset:[0-9]+:0::kokkosp_end_parallel_for:0::kokkosp_begin_deep_copy:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::.*kokkosp_end_deep_copy::kokkosp_begin_parallel_for:parallel_for:${SIZE_REGEX}:0::kokkosp_end_parallel_for:0::kokkosp_begin_parallel_reduce:parallel_reduce:${SIZE_REGEX}:1${SKIP_SCRATCH_INITIALIZATION_REGEX}::kokkosp_end_parallel_reduce:1::kokkosp_begin_parallel_scan:parallel_scan:${SIZE_REGEX}:2::kokkosp_end_parallel_scan:2::kokkosp_push_profile_region:push_region::kokkosp_pop_profile_region::kokkosp_create_profile_section:created_section:3::kokkosp_start_profile_section:3::kokkosp_stop_profile_section:3::kokkosp_destroy_profile_section:3::kokkosp_profile_event:profiling_event::kokkosp_declare_metadata:dogs:good::kokkosp_deallocate_data:${MEMSPACE_REGEX}:destination:${ADDRESS_REGEX}:40::kokkosp_deallocate_data:${MEMSPACE_REGEX}:source:${ADDRESS_REGEX}:40::kokkosp_finalize_library::"
)
endif() #KOKKOS_ENABLE_LIBDL
if(NOT KOKKOS_HAS_TRILINOS)
@ -923,6 +953,6 @@ KOKKOS_ADD_EXECUTABLE_AND_TEST(
ARGS "one 2 THREE"
)
if (KOKKOS_ENABLE_HEADER_SELF_CONTAINMENT_TESTS AND NOT KOKKOS_HAS_TRILINOS)
if (KOKKOS_ENABLE_HEADER_SELF_CONTAINMENT_TESTS AND NOT KOKKOS_HAS_TRILINOS AND NOT WIN32)
add_subdirectory(headers_self_contained)
endif()

View File

@ -62,7 +62,7 @@ else
STACK_TRACE_TERMINATE_FILTER :=
endif
TESTS = AtomicOperations_int AtomicOperations_unsignedint AtomicOperations_longint AtomicOperations_unsignedlongint AtomicOperations_longlongint AtomicOperations_double AtomicOperations_float AtomicOperations_complexdouble AtomicOperations_complexfloat AtomicViews Atomics BlockSizeDeduction Concepts Complex Crs DeepCopyAlignment FunctorAnalysis Init LocalDeepCopy MDRange_a MDRange_b MDRange_c MDRange_d MDRange_e MDRange_f Other RangePolicy RangePolicyRequire Reductions Reducers_a Reducers_b Reducers_c Reducers_d Reductions_DeviceView Scan SharedAlloc TeamBasic TeamReductionScan TeamScratch TeamTeamSize TeamVectorRange UniqueToken ViewAPI_a ViewAPI_b ViewAPI_c ViewAPI_d ViewAPI_e ViewCopy_a ViewCopy_b ViewLayoutStrideAssignment ViewMapping_a ViewMapping_b ViewMapping_subview ViewOfClass WorkGraph View_64bit ViewResize
TESTS = AtomicOperations_int AtomicOperations_unsignedint AtomicOperations_longint AtomicOperations_unsignedlongint AtomicOperations_longlongint AtomicOperations_double AtomicOperations_float AtomicOperations_complexdouble AtomicOperations_complexfloat AtomicViews Atomics BlockSizeDeduction Concepts Complex Crs DeepCopyAlignment FunctorAnalysis Init LocalDeepCopy MDRange_a MDRange_b MDRange_c MDRange_d MDRange_e MDRange_f Other RangePolicy RangePolicyRequire Reductions Reducers_a Reducers_b Reducers_c Reducers_d Reducers_e Reductions_DeviceView Scan SharedAlloc TeamBasic TeamReductionScan TeamScratch TeamTeamSize TeamVectorRange UniqueToken ViewAPI_a ViewAPI_b ViewAPI_c ViewAPI_d ViewAPI_e ViewCopy_a ViewCopy_b ViewLayoutStrideAssignment ViewMapping_a ViewMapping_b ViewMapping_subview ViewOfClass WorkGraph View_64bit ViewResize
tmp := $(foreach device, $(KOKKOS_DEVICELIST), \
tmp2 := $(foreach test, $(TESTS), \
@ -129,7 +129,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1)
OBJ_CUDA += TestCuda_SubView_c13.o
OBJ_CUDA += TestCuda_Reductions.o TestCuda_Scan.o
OBJ_CUDA += TestCuda_Reductions_DeviceView.o
OBJ_CUDA += TestCuda_Reducers_a.o TestCuda_Reducers_b.o TestCuda_Reducers_c.o TestCuda_Reducers_d.o
OBJ_CUDA += TestCuda_Reducers_a.o TestCuda_Reducers_b.o TestCuda_Reducers_c.o TestCuda_Reducers_d.o TestCuda_Reducers_e.o
OBJ_CUDA += TestCuda_Complex.o
OBJ_CUDA += TestCuda_AtomicOperations_int.o TestCuda_AtomicOperations_unsignedint.o TestCuda_AtomicOperations_longint.o
OBJ_CUDA += TestCuda_AtomicOperations_unsignedlongint.o TestCuda_AtomicOperations_longlongint.o TestCuda_AtomicOperations_double.o TestCuda_AtomicOperations_float.o
@ -155,7 +155,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1)
TEST_TARGETS += test-cuda
endif
ifeq ($(KOKKOS_INTERNAL_USE_PTHREADS), 1)
ifeq ($(KOKKOS_INTERNAL_USE_THREADS), 1)
OBJ_THREADS = UnitTestMainInit.o gtest-all.o
OBJ_THREADS += TestThreads_Init.o
OBJ_THREADS += TestThreads_SharedAlloc.o
@ -173,7 +173,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_PTHREADS), 1)
OBJ_THREADS += TestThreads_SubView_c10.o TestThreads_SubView_c11.o TestThreads_SubView_c12.o
OBJ_THREADS += TestThreads_Reductions.o TestThreads_Scan.o
OBJ_THREADS += TestThreads_Reductions_DeviceView.o
OBJ_THREADS += TestThreads_Reducers_a.o TestThreads_Reducers_b.o TestThreads_Reducers_c.o TestThreads_Reducers_d.o
OBJ_THREADS += TestThreads_Reducers_a.o TestThreads_Reducers_b.o TestThreads_Reducers_c.o TestThreads_Reducers_d.o TestThreads_Reducers_e.o
OBJ_THREADS += TestThreads_Complex.o
OBJ_THREADS += TestThreads_AtomicOperations_int.o TestThreads_AtomicOperations_unsignedint.o TestThreads_AtomicOperations_longint.o
OBJ_THREADS += TestThreads_AtomicOperations_unsignedlongint.o TestThreads_AtomicOperations_longlongint.o TestThreads_AtomicOperations_double.o TestThreads_AtomicOperations_float.o
@ -209,7 +209,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_OPENMP), 1)
OBJ_OPENMP += TestOpenMP_SubView_c13.o
OBJ_OPENMP += TestOpenMP_Reductions.o TestOpenMP_Scan.o
OBJ_OPENMP += TestOpenMP_Reductions_DeviceView.o
OBJ_OPENMP += TestOpenMP_Reducers_a.o TestOpenMP_Reducers_b.o TestOpenMP_Reducers_c.o TestOpenMP_Reducers_d.o
OBJ_OPENMP += TestOpenMP_Reducers_a.o TestOpenMP_Reducers_b.o TestOpenMP_Reducers_c.o TestOpenMP_Reducers_d.o TestOpenMP_Reducers_e.o
OBJ_OPENMP += TestOpenMP_Complex.o
OBJ_OPENMP += TestOpenMP_AtomicOperations_int.o TestOpenMP_AtomicOperations_unsignedint.o TestOpenMP_AtomicOperations_longint.o
OBJ_OPENMP += TestOpenMP_AtomicOperations_unsignedlongint.o TestOpenMP_AtomicOperations_longlongint.o TestOpenMP_AtomicOperations_double.o TestOpenMP_AtomicOperations_float.o
@ -250,7 +250,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_OPENMPTARGET), 1)
#OBJ_OPENMPTARGET += TestOpenMPTarget_SubView_c07.o TestOpenMPTarget_SubView_c08.o TestOpenMPTarget_SubView_c09.o
#OBJ_OPENMPTARGET += TestOpenMPTarget_SubView_c10.o TestOpenMPTarget_SubView_c11.o TestOpenMPTarget_SubView_c12.o
#OBJ_OPENMPTARGET += TestOpenMPTarget_Reductions.o # Need custom reductions
OBJ_OPENMPTARGET += TestOpenMPTarget_Reducers_a.o TestOpenMPTarget_Reducers_b.o TestOpenMPTarget_Reducers_c.o TestOpenMPTarget_Reducers_d.o
OBJ_OPENMPTARGET += TestOpenMPTarget_Reducers_a.o TestOpenMPTarget_Reducers_b.o TestOpenMPTarget_Reducers_c.o TestOpenMPTarget_Reducers_d.o TestOpenMPTarget_Reducers_e.o
#OBJ_OPENMPTARGET += TestOpenMPTarget_Scan.o
OBJ_OPENMPTARGET += TestOpenMPTarget_Complex.o
OBJ_OPENMPTARGET += TestOpenMPTarget_AtomicOperations_int.o TestOpenMPTarget_AtomicOperations_unsignedint.o TestOpenMPTarget_AtomicOperations_longint.o
@ -285,7 +285,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_HIP), 1)
OBJ_HIP = UnitTestMainInit.o gtest-all.o
OBJ_HIP += TestHIP_Init.o
OBJ_HIP += TestHIP_Reducers_a.o TestHIP_Reducers_b.o TestHIP_Reducers_c.o TestHIP_Reducers_d.o
OBJ_HIP += TestHIP_Reducers_a.o TestHIP_Reducers_b.o TestHIP_Reducers_c.o TestHIP_Reducers_d.o TestHIP_Reducers_e.o
OBJ_HIP += TestHIP_Reductions.o
OBJ_HIP += TestHIP_MDRange_a.o TestHIP_MDRange_b.o TestHIP_MDRange_c.o TestHIP_MDRange_d.o TestHIP_MDRange_e.o
OBJ_HIP += TestHIP_Spaces.o
@ -316,7 +316,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_HPX), 1)
OBJ_HPX += TestHPX_SubView_c13.o
OBJ_HPX += TestHPX_Reductions.o
OBJ_HPX += TestHPX_Scan.o
OBJ_HPX += TestHPX_Reducers_a.o TestHPX_Reducers_b.o TestHPX_Reducers_c.o TestHPX_Reducers_d.o
OBJ_HPX += TestHPX_Reducers_a.o TestHPX_Reducers_b.o TestHPX_Reducers_c.o TestHPX_Reducers_d.o TestHPX_Reducers_e.o
OBJ_HPX += TestHPX_Complex.o
OBJ_HPX += TestHPX_AtomicOperations_int.o TestHPX_AtomicOperations_unsignedint.o TestHPX_AtomicOperations_longint.o
OBJ_HPX += TestHPX_AtomicOperations_unsignedlongint.o TestHPX_AtomicOperations_longlongint.o TestHPX_AtomicOperations_double.o TestHPX_AtomicOperations_float.o
@ -356,7 +356,7 @@ ifeq ($(KOKKOS_INTERNAL_USE_SERIAL), 1)
OBJ_SERIAL += TestSerial_SubView_c13.o
OBJ_SERIAL += TestSerial_Reductions.o TestSerial_Scan.o
OBJ_SERIAL += TestSerial_Reductions_DeviceView.o
OBJ_SERIAL += TestSerial_Reducers_a.o TestSerial_Reducers_b.o TestSerial_Reducers_c.o TestSerial_Reducers_d.o
OBJ_SERIAL += TestSerial_Reducers_a.o TestSerial_Reducers_b.o TestSerial_Reducers_c.o TestSerial_Reducers_d.o TestSerial_Reducers_e.o
OBJ_SERIAL += TestSerial_Complex.o
OBJ_SERIAL += TestSerial_AtomicOperations_int.o TestSerial_AtomicOperations_unsignedint.o TestSerial_AtomicOperations_longint.o
OBJ_SERIAL += TestSerial_AtomicOperations_unsignedlongint.o TestSerial_AtomicOperations_longlongint.o TestSerial_AtomicOperations_double.o TestSerial_AtomicOperations_float.o

View File

@ -97,11 +97,11 @@ void TestViewAggregate() {
a32_type x("test", 4, 5);
a32_flat_type y(x);
ASSERT_EQ(x.extent(0), 4);
ASSERT_EQ(x.extent(1), 5);
ASSERT_EQ(y.extent(0), 4);
ASSERT_EQ(y.extent(1), 5);
ASSERT_EQ(y.extent(2), 32);
ASSERT_EQ(x.extent(0), 4u);
ASSERT_EQ(x.extent(1), 5u);
ASSERT_EQ(y.extent(0), 4u);
ASSERT_EQ(y.extent(1), 5u);
ASSERT_EQ(y.extent(2), 32u);
// Initialize arrays from brace-init-list as for std::array.
//

View File

@ -345,6 +345,84 @@ bool IncAtomicTest(T i0) {
return passed;
}
//---------------------------------------------------
//-------------atomic_wrapping_increment-------------
//---------------------------------------------------
template <class T, class DEVICE_TYPE>
struct WrappingIncFunctor {
using execution_space = DEVICE_TYPE;
using type = Kokkos::View<T, execution_space>;
type data;
T i0;
T i1;
KOKKOS_INLINE_FUNCTION
void operator()(int) const {
#ifdef KOKKOS_ENABLE_IMPL_DESUL_ATOMICS
desul::atomic_fetch_inc_mod(&data(), (T)i1, desul::MemoryOrderRelaxed(),
desul::MemoryScopeDevice());
#endif
}
WrappingIncFunctor(T _i0, T _i1) : i0(_i0), i1(_i1) {}
};
template <class T, class execution_space>
T WrappingIncAtomic(T i0, T i1) {
struct InitFunctor<T, execution_space> f_init(i0);
typename InitFunctor<T, execution_space>::type data("Data");
typename InitFunctor<T, execution_space>::h_type h_data("HData");
f_init.data = data;
Kokkos::parallel_for(1, f_init);
execution_space().fence();
struct WrappingIncFunctor<T, execution_space> f(i0, i1);
f.data = data;
Kokkos::parallel_for(1, f);
execution_space().fence();
Kokkos::deep_copy(h_data, data);
T val = h_data();
return val;
}
template <class T>
T WrappingIncAtomicCheck(T i0, T i1) {
T* data = new T[1];
data[0] = 0;
// Wraps to 0 when i0 >= i1
*data = ((i0 >= i1) ? (T)0 : i0 + (T)1);
T val = *data;
delete[] data;
return val;
}
template <class T, class DeviceType>
bool WrappingIncAtomicTest(T i0, T i1) {
T res = WrappingIncAtomic<T, DeviceType>(i0, i1);
T resSerial = WrappingIncAtomicCheck<T>(i0, i1);
bool passed = true;
if (resSerial != res) {
passed = false;
std::cout << "Loop<" << typeid(T).name()
<< ">( test = WrappingIncAtomicTest"
<< " FAILED : " << resSerial << " != " << res << std::endl;
}
return passed;
}
//---------------------------------------------------
//--------------atomic_decrement---------------------
//---------------------------------------------------
@ -415,6 +493,85 @@ bool DecAtomicTest(T i0) {
return passed;
}
//---------------------------------------------------
//-------------atomic_wrapping_decrement-------------
//---------------------------------------------------
template <class T, class DEVICE_TYPE>
struct WrappingDecFunctor {
using execution_space = DEVICE_TYPE;
using type = Kokkos::View<T, execution_space>;
type data;
T i0;
T i1;
KOKKOS_INLINE_FUNCTION
void operator()(int) const {
#ifdef KOKKOS_ENABLE_IMPL_DESUL_ATOMICS
desul::atomic_fetch_dec_mod(&data(), (T)i1, desul::MemoryOrderRelaxed(),
desul::MemoryScopeDevice());
#endif
}
WrappingDecFunctor(T _i0, T _i1) : i0(_i0), i1(_i1) {}
};
template <class T, class execution_space>
T WrappingDecAtomic(T i0, T i1) {
struct InitFunctor<T, execution_space> f_init(i0);
typename InitFunctor<T, execution_space>::type data("Data");
typename InitFunctor<T, execution_space>::h_type h_data("HData");
f_init.data = data;
Kokkos::parallel_for(1, f_init);
execution_space().fence();
struct WrappingDecFunctor<T, execution_space> f(i0, i1);
f.data = data;
Kokkos::parallel_for(1, f);
execution_space().fence();
Kokkos::deep_copy(h_data, data);
T val = h_data();
return val;
}
template <class T>
T WrappingDecAtomicCheck(T i0, T i1) {
T* data = new T[1];
data[0] = 0;
// Wraps to i1 when i0 <= 0
// i0 should never be negative
*data = ((i0 <= (T)0) ? i1 : i0 - (T)1);
T val = *data;
delete[] data;
return val;
}
template <class T, class DeviceType>
bool WrappingDecAtomicTest(T i0, T i1) {
T res = WrappingDecAtomic<T, DeviceType>(i0, i1);
T resSerial = WrappingDecAtomicCheck<T>(i0, i1);
bool passed = true;
if (resSerial != res) {
passed = false;
std::cout << "Loop<" << typeid(T).name()
<< ">( test = WrappingDecAtomicTest"
<< " FAILED : " << resSerial << " != " << res << std::endl;
}
return passed;
}
//---------------------------------------------------
//--------------atomic_fetch_mul---------------------
//---------------------------------------------------
@ -1016,6 +1173,16 @@ bool AtomicOperationsTestIntegralType(int i0, int i1, int test) {
return 0;
}
template <class T, class DeviceType>
bool AtomicOperationsTestUnsignedIntegralType(int i0, int i1, int test) {
switch (test) {
case 1: return WrappingIncAtomicTest<T, DeviceType>((T)i0, (T)i1);
case 2: return WrappingDecAtomicTest<T, DeviceType>((T)i0, (T)i1);
}
return 0;
}
template <class T, class DeviceType>
bool AtomicOperationsTestNonIntegralType(int i0, int i1, int test) {
switch (test) {

View File

@ -0,0 +1,86 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
namespace Test {
// FIXME_SYCL This doesn't work yet for SYCL+CUDA
#if !defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ARCH_INTEL_GPU)
template <typename ExecutionSpace>
struct TestSharedAtomicsFunctor {
Kokkos::View<int, typename ExecutionSpace::memory_space> m_view;
TestSharedAtomicsFunctor(
Kokkos::View<int, typename ExecutionSpace::memory_space>& view)
: m_view(view) {}
KOKKOS_INLINE_FUNCTION void operator()(
const typename Kokkos::TeamPolicy<ExecutionSpace>::member_type t) const {
int* x = (int*)t.team_shmem().get_shmem(sizeof(int));
Kokkos::single(Kokkos::PerTeam(t), [&]() { *x = 0; });
t.team_barrier();
Kokkos::atomic_add(x, 1);
t.team_barrier();
Kokkos::single(Kokkos::PerTeam(t), [&]() { m_view() = *x; });
}
};
TEST(TEST_CATEGORY, atomic_shared) {
TEST_EXECSPACE exec;
Kokkos::View<int, typename TEST_EXECSPACE::memory_space> view("ref_value");
auto team_size =
Kokkos::TeamPolicy<TEST_EXECSPACE>(exec, 1, Kokkos::AUTO)
.team_size_recommended(TestSharedAtomicsFunctor<TEST_EXECSPACE>(view),
Kokkos::ParallelForTag{});
Kokkos::parallel_for(Kokkos::TeamPolicy<TEST_EXECSPACE>(exec, 1, team_size)
.set_scratch_size(0, Kokkos::PerTeam(8)),
TestSharedAtomicsFunctor<TEST_EXECSPACE>(view));
exec.fence("Fence after test kernel");
int i = 0;
Kokkos::deep_copy(i, view);
ASSERT_EQ(i, team_size);
}
#endif
} // namespace Test

View File

@ -73,6 +73,14 @@ TEST(TEST_CATEGORY, atomic_operations_unsigned) {
unsigned int, TEST_EXECSPACE>(start, end - i, 12)));
ASSERT_TRUE((TestAtomicOperations::AtomicOperationsTestIntegralType<
unsigned int, TEST_EXECSPACE>(start, end - i, 13)));
#ifdef KOKKOS_ENABLE_IMPL_DESUL_ATOMICS
ASSERT_TRUE(
(TestAtomicOperations::AtomicOperationsTestUnsignedIntegralType<
unsigned int, TEST_EXECSPACE>(start, end - i, 1))); // Wrapping Inc
ASSERT_TRUE(
(TestAtomicOperations::AtomicOperationsTestUnsignedIntegralType<
unsigned int, TEST_EXECSPACE>(start, end - i, 2))); // Wrapping Dec
#endif
}
}
} // namespace Test

View File

@ -73,6 +73,14 @@ TEST(TEST_CATEGORY, atomic_operations_unsignedlong) {
unsigned long int, TEST_EXECSPACE>(start, end - i, 12)));
ASSERT_TRUE((TestAtomicOperations::AtomicOperationsTestIntegralType<
unsigned long int, TEST_EXECSPACE>(start, end - i, 13)));
#ifdef KOKKOS_ENABLE_IMPL_DESUL_ATOMICS
ASSERT_TRUE((TestAtomicOperations::AtomicOperationsTestUnsignedIntegralType<
unsigned long int, TEST_EXECSPACE>(start, end - i,
1))); // Wrapping Inc
ASSERT_TRUE((TestAtomicOperations::AtomicOperationsTestUnsignedIntegralType<
unsigned long int, TEST_EXECSPACE>(start, end - i,
2))); // Wrapping Dec
#endif
}
}
} // namespace Test

View File

@ -194,19 +194,19 @@ class TestAtomicViewAPI {
dx = dView0("dx");
dy = dView0("dy");
ASSERT_EQ(dx.use_count(), size_t(1));
ASSERT_EQ(dy.use_count(), size_t(1));
ASSERT_EQ(dx.use_count(), 1);
ASSERT_EQ(dy.use_count(), 1);
ax = dx;
ay = dy;
ASSERT_EQ(dx.use_count(), size_t(2));
ASSERT_EQ(dy.use_count(), size_t(2));
ASSERT_EQ(dx.use_count(), 2);
ASSERT_EQ(dy.use_count(), 2);
ASSERT_EQ(dx.use_count(), ax.use_count());
az = ax;
ASSERT_EQ(dx.use_count(), size_t(3));
ASSERT_EQ(ax.use_count(), size_t(3));
ASSERT_EQ(az.use_count(), size_t(3));
ASSERT_EQ(dx.use_count(), 3);
ASSERT_EQ(ax.use_count(), 3);
ASSERT_EQ(az.use_count(), 3);
ASSERT_EQ(az.use_count(), ax.use_count());
}
@ -216,33 +216,33 @@ class TestAtomicViewAPI {
dx = dView4("dx", N0);
dy = dView4("dy", N0);
ASSERT_EQ(dx.use_count(), size_t(1));
ASSERT_EQ(dy.use_count(), size_t(1));
ASSERT_EQ(dx.use_count(), 1);
ASSERT_EQ(dy.use_count(), 1);
ax = dx;
ay = dy;
ASSERT_EQ(dx.use_count(), size_t(2));
ASSERT_EQ(dy.use_count(), size_t(2));
ASSERT_EQ(dx.use_count(), 2);
ASSERT_EQ(dy.use_count(), 2);
ASSERT_EQ(dx.use_count(), ax.use_count());
dView4_unmanaged unmanaged_dx = dx;
ASSERT_EQ(dx.use_count(), size_t(2));
ASSERT_EQ(dx.use_count(), 2);
az = ax;
ASSERT_EQ(dx.use_count(), size_t(3));
ASSERT_EQ(ax.use_count(), size_t(3));
ASSERT_EQ(az.use_count(), size_t(3));
ASSERT_EQ(dx.use_count(), 3);
ASSERT_EQ(ax.use_count(), 3);
ASSERT_EQ(az.use_count(), 3);
ASSERT_EQ(az.use_count(), ax.use_count());
aView4_unmanaged unmanaged_ax = ax;
ASSERT_EQ(ax.use_count(), size_t(3));
ASSERT_EQ(ax.use_count(), 3);
aView4_unmanaged unmanaged_ax_from_ptr_dx = aView4_unmanaged(
dx.data(), dx.extent(0), dx.extent(1), dx.extent(2), dx.extent(3));
ASSERT_EQ(ax.use_count(), size_t(3));
ASSERT_EQ(ax.use_count(), 3);
const_aView4 const_ax = ax;
ASSERT_EQ(ax.use_count(), size_t(4));
ASSERT_EQ(ax.use_count(), 4);
ASSERT_EQ(const_ax.use_count(), ax.use_count());
ASSERT_NE(ax.data(), nullptr);

View File

@ -24,12 +24,12 @@ int unsetenv(const char *name) { return _putenv_s(name, ""); }
// Needed because https://github.com/google/googletest/issues/952 has not been
// resolved
#define EXPECT_THROW_WITH_MESSAGE(stmt, etype, whatstring) \
EXPECT_THROW( \
try { stmt; } catch (const etype &ex) { \
EXPECT_EQ(whatstring, std::string(ex.what())); \
throw; \
}, \
#define EXPECT_THROW_WITH_MESSAGE(stmt, etype, whatstring) \
EXPECT_THROW( \
try { stmt; } catch (const etype &ex) { \
EXPECT_EQ(std::string(ex.what()).find(whatstring), 0u); \
throw; \
}, \
etype)
class ctest_environment : public ::testing::Test {
@ -80,54 +80,43 @@ TEST_F(ctest_environment, invalid_rank) {
EXPECT_THROW_WITH_MESSAGE(
Kokkos::Impl::get_ctest_gpu("10"), std::runtime_error,
"Error: local rank 10 is outside the bounds of resource groups provided "
"by"
" CTest. Raised by Kokkos::Impl::get_ctest_gpu().\nTraceback "
"functionality"
" not available\n");
"by CTest.");
}
TEST_F(ctest_environment, no_type_str) {
EXPECT_THROW_WITH_MESSAGE(
Kokkos::Impl::get_ctest_gpu("0"), std::runtime_error,
"Error: CTEST_RESOURCE_GROUP_0 is not specified. Raised by "
"Kokkos::Impl::get_ctest_gpu().\nTraceback functionality not "
"available\n");
"Kokkos::Impl::get_ctest_gpu().");
}
TEST_F(ctest_environment, missing_type) {
EXPECT_THROW_WITH_MESSAGE(
Kokkos::Impl::get_ctest_gpu("1"), std::runtime_error,
"Error: device type 'gpus' not included in CTEST_RESOURCE_GROUP_1. "
"Raised "
"by Kokkos::Impl::get_ctest_gpu().\nTraceback functionality not available"
"\n");
"Raised by Kokkos::Impl::get_ctest_gpu().");
EXPECT_THROW_WITH_MESSAGE(
Kokkos::Impl::get_ctest_gpu("2"), std::runtime_error,
"Error: device type 'gpus' not included in CTEST_RESOURCE_GROUP_2. "
"Raised "
"by Kokkos::Impl::get_ctest_gpu().\nTraceback functionality not available"
"\n");
"Raised by Kokkos::Impl::get_ctest_gpu().");
}
TEST_F(ctest_environment, no_id_str) {
EXPECT_THROW_WITH_MESSAGE(
Kokkos::Impl::get_ctest_gpu("3"), std::runtime_error,
"Error: CTEST_RESOURCE_GROUP_3_GPUS is not specified. Raised by "
"Kokkos::Impl::get_ctest_gpu().\nTraceback functionality not "
"available\n");
"Kokkos::Impl::get_ctest_gpu().");
}
TEST_F(ctest_environment, invalid_id_str) {
EXPECT_THROW_WITH_MESSAGE(
Kokkos::Impl::get_ctest_gpu("4"), std::runtime_error,
"Error: invalid value of CTEST_RESOURCE_GROUP_4_GPUS: 'id:2'. Raised by "
"Kokkos::Impl::get_ctest_gpu().\nTraceback functionality not "
"available\n");
"Kokkos::Impl::get_ctest_gpu().");
EXPECT_THROW_WITH_MESSAGE(
Kokkos::Impl::get_ctest_gpu("5"), std::runtime_error,
"Error: invalid value of CTEST_RESOURCE_GROUP_5_GPUS: 'slots:1,id:2'. "
"Raised by Kokkos::Impl::get_ctest_gpu().\nTraceback functionality not "
"available\n");
"Raised by Kokkos::Impl::get_ctest_gpu().");
}
TEST_F(ctest_environment, good) {

View File

@ -48,6 +48,11 @@
namespace Test {
#ifdef KOKKOS_COMPILER_NVHPC
// warning: 'long double' is treated as 'double' in device code
#pragma diag_suppress 20208
#endif
// Test construction and assignment
template <class ExecSpace>
@ -348,7 +353,9 @@ struct TestComplexSpecialFunctions {
r = std::acosh(a);
ASSERT_FLOAT_EQ(h_results(13).real(), r.real());
ASSERT_FLOAT_EQ(h_results(13).imag(), r.imag());
r = std::atanh(a);
// atanh
// Work around a bug in gcc 5.3.1 where the compiler cannot compute atanh
r = {0.163481616851666003, 1.27679502502111284};
ASSERT_FLOAT_EQ(h_results(14).real(), r.real());
ASSERT_FLOAT_EQ(h_results(14).imag(), r.imag());
r = std::asin(a);
@ -357,7 +364,9 @@ struct TestComplexSpecialFunctions {
r = std::acos(a);
ASSERT_FLOAT_EQ(h_results(16).real(), r.real());
ASSERT_FLOAT_EQ(h_results(16).imag(), r.imag());
r = std::atan(a);
// atan
// Work around a bug in gcc 5.3.1 where the compiler cannot compute atan
r = {1.380543138238714, 0.2925178131625636};
ASSERT_FLOAT_EQ(h_results(17).real(), r.real());
ASSERT_FLOAT_EQ(h_results(17).imag(), r.imag());
#endif
@ -459,6 +468,7 @@ TEST(TEST_CATEGORY, complex_issue_3865) {
TestBugPowAndLogComplex<TEST_EXECSPACE>();
}
#ifdef KOKKOS_ENABLE_OPENMPTARGET // FIXME_OPENMPTARGET
TEST(TEST_CATEGORY, complex_issue_3867) {
ASSERT_EQ(Kokkos::pow(Kokkos::complex<double>(2., 1.), 3.),
Kokkos::pow(Kokkos::complex<double>(2., 1.), 3));
@ -514,6 +524,7 @@ TEST(TEST_CATEGORY, complex_issue_3867) {
#undef CHECK_POW_COMPLEX_PROMOTION
}
#endif
TEST(TEST_CATEGORY, complex_operations_arithmetic_types_overloads) {
#define STATIC_ASSERT(cond) static_assert(cond, "")

View File

@ -1,4 +1,5 @@
#include <Kokkos_Core.hpp>
#include <cstddef>
namespace Test {
@ -62,7 +63,7 @@ struct TestDeepCopy {
reset_a_copy_and_b(a_char_copy, b_char);
{
int check = compare_equal(a_char_copy, a_char);
size_t check = compare_equal(a_char_copy, a_char);
ASSERT_EQ(check, a_char.extent(0));
}

View File

@ -86,11 +86,19 @@ char** init_kokkos_args(bool do_threads, bool do_numa, bool do_device,
int nthreads = 3;
#ifdef KOKKOS_ENABLE_OPENMP
if (omp_get_max_threads() < 3) nthreads = omp_get_max_threads();
if (omp_get_max_threads() < nthreads) {
nthreads = omp_get_max_threads();
}
#elif defined(KOKKOS_ENABLE_HPX)
const auto concurrency = std::thread::hardware_concurrency();
if (concurrency < nthreads) {
nthreads = concurrency;
}
#endif
if (Kokkos::hwloc::available()) {
if (Kokkos::hwloc::get_available_threads_per_core() < 3)
if (Kokkos::hwloc::get_available_threads_per_core() <
static_cast<unsigned>(nthreads))
nthreads = Kokkos::hwloc::get_available_threads_per_core() *
Kokkos::hwloc::get_available_numa_count();
}
@ -153,13 +161,19 @@ Kokkos::InitArguments init_initstruct(bool do_threads, bool do_numa,
int nthreads = 3;
#ifdef KOKKOS_ENABLE_OPENMP
if (omp_get_max_threads() < 3) {
if (omp_get_max_threads() < nthreads) {
nthreads = omp_get_max_threads();
}
#elif defined(KOKKOS_ENABLE_HPX)
const auto concurrency = std::thread::hardware_concurrency();
if (concurrency < nthreads) {
nthreads = concurrency;
}
#endif
if (Kokkos::hwloc::available()) {
if (Kokkos::hwloc::get_available_threads_per_core() < 3) {
if (Kokkos::hwloc::get_available_threads_per_core() <
static_cast<unsigned>(nthreads)) {
nthreads = Kokkos::hwloc::get_available_threads_per_core() *
Kokkos::hwloc::get_available_numa_count();
}

View File

@ -55,8 +55,6 @@ void test_half_conversion_type() {
T b = Kokkos::Experimental::cast_from_half<T>(a);
ASSERT_LT((double(b - base) / double(base)), epsilon);
// TODO: Remove ifndef once https://github.com/kokkos/kokkos/pull/3480 merges
#ifndef KOKKOS_ENABLE_SYCL
#ifdef KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA
Kokkos::View<T> b_v("b_v");
Kokkos::parallel_for(
@ -69,7 +67,28 @@ void test_half_conversion_type() {
Kokkos::deep_copy(b, b_v);
ASSERT_LT((double(b - base) / double(base)), epsilon);
#endif // KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA
#endif // KOKKOS_ENABLE_SYCL
}
template <class T>
void test_bhalf_conversion_type() {
double epsilon = KOKKOS_BHALF_T_IS_FLOAT ? 0.0000003 : 0.0003;
T base = static_cast<T>(3.3);
Kokkos::Experimental::bhalf_t a = Kokkos::Experimental::cast_to_bhalf(base);
T b = Kokkos::Experimental::cast_from_bhalf<T>(a);
ASSERT_LT((double(b - base) / double(base)), epsilon);
#ifdef KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA
Kokkos::View<T> b_v("b_v");
Kokkos::parallel_for(
"TestHalfConversion", 1, KOKKOS_LAMBDA(int) {
Kokkos::Experimental::bhalf_t d_a =
Kokkos::Experimental::cast_to_bhalf(base);
b_v() = Kokkos::Experimental::cast_from_bhalf<T>(d_a);
});
Kokkos::deep_copy(b, b_v);
ASSERT_LT((double(b - base) / double(base)), epsilon);
#endif // KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA
}
void test_half_conversion() {
@ -85,7 +104,22 @@ void test_half_conversion() {
test_half_conversion_type<unsigned long long>();
}
void test_bhalf_conversion() {
test_bhalf_conversion_type<float>();
test_bhalf_conversion_type<double>();
test_bhalf_conversion_type<short>();
test_bhalf_conversion_type<int>();
test_bhalf_conversion_type<long>();
test_bhalf_conversion_type<long long>();
test_bhalf_conversion_type<unsigned short>();
test_bhalf_conversion_type<unsigned int>();
test_bhalf_conversion_type<unsigned long>();
test_bhalf_conversion_type<unsigned long long>();
}
TEST(TEST_CATEGORY, half_conversion) { test_half_conversion(); }
TEST(TEST_CATEGORY, bhalf_conversion) { test_bhalf_conversion(); }
} // namespace Test
#endif

View File

@ -45,10 +45,9 @@
#ifndef TESTHALFOPERATOR_HPP_
#define TESTHALFOPERATOR_HPP_
// TODO: Remove ifndef once https://github.com/kokkos/kokkos/pull/3480 merges
#ifndef KOKKOS_ENABLE_SYCL
namespace Test {
#define FP16_EPSILON 0.0009765625F
#define FP16_EPSILON 0.0009765625F // 1/2^10
#define BF16_EPSILON 0.0078125F // 1/2^7
using namespace Kokkos::Experimental;
using ExecutionSpace = TEST_EXECSPACE;
using ScalarType = double;
@ -56,6 +55,10 @@ using ViewType = Kokkos::View<ScalarType*, ExecutionSpace>;
using ViewTypeHost = Kokkos::View<ScalarType*, Kokkos::HostSpace>;
KOKKOS_FUNCTION
const half_t& accept_ref(const half_t& a) { return a; }
#if !KOKKOS_BHALF_T_IS_FLOAT
KOKKOS_FUNCTION
const bhalf_t& accept_ref(const bhalf_t& a) { return a; }
#endif // !KOKKOS_BHALF_T_IS_FLOAT
enum OP_TESTS {
ASSIGN,
@ -269,18 +272,21 @@ enum OP_TESTS {
N_OP_TESTS
};
template <class view_type>
template <class view_type, class half_type>
struct Functor_TestHalfVolatileOperators {
volatile half_t h_lhs, h_rhs;
volatile half_type h_lhs, h_rhs;
view_type actual_lhs, expected_lhs;
double d_lhs, d_rhs;
Functor_TestHalfVolatileOperators(volatile half_t lhs = half_t(0),
volatile half_t rhs = half_t(0))
Functor_TestHalfVolatileOperators(volatile half_type lhs = half_type(0),
volatile half_type rhs = half_type(0))
: h_lhs(lhs), h_rhs(rhs) {
actual_lhs = view_type("actual_lhs", N_OP_TESTS);
expected_lhs = view_type("expected_lhs", N_OP_TESTS);
d_lhs = cast_from_half<double>(h_lhs);
d_rhs = cast_from_half<double>(h_rhs);
half_type nv_tmp;
nv_tmp = h_lhs;
d_lhs = static_cast<double>(nv_tmp);
nv_tmp = h_rhs;
d_rhs = static_cast<double>(nv_tmp);
if (std::is_same<view_type, ViewTypeHost>::value) {
auto run_on_host = *this;
run_on_host(0);
@ -292,7 +298,8 @@ struct Functor_TestHalfVolatileOperators {
KOKKOS_FUNCTION
void operator()(int) const {
volatile half_t tmp_lhs;
volatile half_type tmp_lhs;
half_type nv_tmp;
// Initialze output views to catch missing test invocations
for (int i = 0; i < N_OP_TESTS; ++i) {
@ -300,8 +307,8 @@ struct Functor_TestHalfVolatileOperators {
expected_lhs(i) = -1;
}
tmp_lhs = h_lhs;
actual_lhs(ASSIGN) = cast_from_half<double>(tmp_lhs);
nv_tmp = h_lhs;
actual_lhs(ASSIGN) = static_cast<double>(nv_tmp);
expected_lhs(ASSIGN) = d_lhs;
actual_lhs(LT) = h_lhs < h_rhs;
@ -324,42 +331,47 @@ struct Functor_TestHalfVolatileOperators {
tmp_lhs = h_lhs;
tmp_lhs += h_rhs;
actual_lhs(CADD_H_H) = cast_from_half<double>(tmp_lhs);
nv_tmp = tmp_lhs;
actual_lhs(CADD_H_H) = static_cast<double>(nv_tmp);
expected_lhs(CADD_H_H) = d_lhs;
expected_lhs(CADD_H_H) += d_rhs;
tmp_lhs = h_lhs;
tmp_lhs -= h_rhs;
actual_lhs(CSUB_H_H) = cast_from_half<double>(tmp_lhs);
nv_tmp = tmp_lhs;
actual_lhs(CSUB_H_H) = static_cast<double>(nv_tmp);
expected_lhs(CSUB_H_H) = d_lhs;
expected_lhs(CSUB_H_H) -= d_rhs;
tmp_lhs = h_lhs;
tmp_lhs *= h_rhs;
actual_lhs(CMUL_H_H) = cast_from_half<double>(tmp_lhs);
nv_tmp = tmp_lhs;
actual_lhs(CMUL_H_H) = static_cast<double>(nv_tmp);
expected_lhs(CMUL_H_H) = d_lhs;
expected_lhs(CMUL_H_H) *= d_rhs;
tmp_lhs = h_lhs;
tmp_lhs /= h_rhs;
actual_lhs(CDIV_H_H) = cast_from_half<double>(tmp_lhs);
nv_tmp = tmp_lhs;
actual_lhs(CDIV_H_H) = static_cast<double>(nv_tmp);
expected_lhs(CDIV_H_H) = d_lhs;
expected_lhs(CDIV_H_H) /= d_rhs;
}
};
template <class view_type>
template <class view_type, class half_type>
struct Functor_TestHalfOperators {
half_t h_lhs, h_rhs;
half_type h_lhs, h_rhs;
double d_lhs, d_rhs;
view_type actual_lhs, expected_lhs;
Functor_TestHalfOperators(half_t lhs = half_t(0), half_t rhs = half_t(0))
Functor_TestHalfOperators(half_type lhs = half_type(0),
half_type rhs = half_type(0))
: h_lhs(lhs), h_rhs(rhs) {
actual_lhs = view_type("actual_lhs", N_OP_TESTS);
expected_lhs = view_type("expected_lhs", N_OP_TESTS);
d_lhs = cast_from_half<double>(h_lhs);
d_rhs = cast_from_half<double>(h_rhs);
d_lhs = static_cast<double>(h_lhs);
d_rhs = static_cast<double>(h_rhs);
if (std::is_same<view_type, ViewTypeHost>::value) {
auto run_on_host = *this;
@ -377,13 +389,13 @@ struct Functor_TestHalfOperators {
auto sum = static_cast<LhsType>(h_lhs) + static_cast<RhsType>(h_rhs);
actual_lhs(op_test_idx) = static_cast<double>(sum);
if (std::is_same<RhsType, half_t>::value &&
std::is_same<LhsType, half_t>::value) {
if (std::is_same<RhsType, half_type>::value &&
std::is_same<LhsType, half_type>::value) {
expected_lhs(op_test_idx) = d_lhs + d_rhs;
} else {
if (std::is_same<LhsType, half_t>::value)
if (std::is_same<LhsType, half_type>::value)
expected_lhs(op_test_idx) = d_lhs + static_cast<RhsType>(d_rhs);
if (std::is_same<RhsType, half_t>::value)
if (std::is_same<RhsType, half_type>::value)
expected_lhs(op_test_idx) = static_cast<LhsType>(d_lhs) + d_rhs;
}
@ -397,13 +409,13 @@ struct Functor_TestHalfOperators {
auto result = static_cast<LhsType>(h_lhs) - static_cast<RhsType>(h_rhs);
actual_lhs(op_test_idx) = static_cast<double>(result);
if (std::is_same<RhsType, half_t>::value &&
std::is_same<LhsType, half_t>::value) {
if (std::is_same<RhsType, half_type>::value &&
std::is_same<LhsType, half_type>::value) {
expected_lhs(op_test_idx) = d_lhs - d_rhs;
} else {
if (std::is_same<LhsType, half_t>::value)
if (std::is_same<LhsType, half_type>::value)
expected_lhs(op_test_idx) = d_lhs - static_cast<RhsType>(d_rhs);
if (std::is_same<RhsType, half_t>::value)
if (std::is_same<RhsType, half_type>::value)
expected_lhs(op_test_idx) = static_cast<LhsType>(d_lhs) - d_rhs;
}
@ -417,13 +429,13 @@ struct Functor_TestHalfOperators {
auto result = static_cast<LhsType>(h_lhs) * static_cast<RhsType>(h_rhs);
actual_lhs(op_test_idx) = static_cast<double>(result);
if (std::is_same<RhsType, half_t>::value &&
std::is_same<LhsType, half_t>::value) {
if (std::is_same<RhsType, half_type>::value &&
std::is_same<LhsType, half_type>::value) {
expected_lhs(op_test_idx) = d_lhs * d_rhs;
} else {
if (std::is_same<LhsType, half_t>::value)
if (std::is_same<LhsType, half_type>::value)
expected_lhs(op_test_idx) = d_lhs * static_cast<RhsType>(d_rhs);
if (std::is_same<RhsType, half_t>::value)
if (std::is_same<RhsType, half_type>::value)
expected_lhs(op_test_idx) = static_cast<LhsType>(d_lhs) * d_rhs;
}
@ -437,13 +449,13 @@ struct Functor_TestHalfOperators {
auto result = static_cast<LhsType>(h_lhs) / static_cast<RhsType>(h_rhs);
actual_lhs(op_test_idx) = static_cast<double>(result);
if (std::is_same<RhsType, half_t>::value &&
std::is_same<LhsType, half_t>::value) {
if (std::is_same<RhsType, half_type>::value &&
std::is_same<LhsType, half_type>::value) {
expected_lhs(op_test_idx) = d_lhs / d_rhs;
} else {
if (std::is_same<LhsType, half_t>::value)
if (std::is_same<LhsType, half_type>::value)
expected_lhs(op_test_idx) = d_lhs / static_cast<RhsType>(d_rhs);
if (std::is_same<RhsType, half_t>::value)
if (std::is_same<RhsType, half_type>::value)
expected_lhs(op_test_idx) = static_cast<LhsType>(d_lhs) / d_rhs;
}
@ -454,10 +466,14 @@ struct Functor_TestHalfOperators {
KOKKOS_FUNCTION
void operator()(int) const {
half_t tmp_lhs, tmp2_lhs, *tmp_ptr;
half_type tmp_lhs, tmp2_lhs, *tmp_ptr;
double tmp_d_lhs;
float tmp_s_lhs;
using half_impl_type = Kokkos::Impl::half_impl_t::type;
#if !defined(KOKKOS_HALF_T_IS_FLOAT) && !KOKKOS_HALF_T_IS_FLOAT
using half_impl_type = typename half_type::impl_type;
#else
using half_impl_type = half_type;
#endif // !defined(KOKKOS_HALF_T_IS_FLOAT) && !KOKKOS_HALF_T_IS_FLOAT
half_impl_type half_tmp;
// Initialze output views to catch missing test invocations
@ -467,54 +483,55 @@ struct Functor_TestHalfOperators {
}
tmp_lhs = h_lhs;
actual_lhs(ASSIGN) = cast_from_half<double>(tmp_lhs);
actual_lhs(ASSIGN) = static_cast<double>(tmp_lhs);
expected_lhs(ASSIGN) = d_lhs;
tmp_lhs = 0;
tmp2_lhs = tmp_lhs = h_lhs;
actual_lhs(ASSIGN_CHAINED) = cast_from_half<double>(tmp2_lhs);
actual_lhs(ASSIGN_CHAINED) = static_cast<double>(tmp2_lhs);
expected_lhs(ASSIGN_CHAINED) = d_lhs;
actual_lhs(UNA) = cast_from_half<double>(+h_lhs);
actual_lhs(UNA) = static_cast<double>(+h_lhs);
expected_lhs(UNA) = +d_lhs;
actual_lhs(UNS) = cast_from_half<double>(-h_lhs);
actual_lhs(UNS) = static_cast<double>(-h_lhs);
expected_lhs(UNS) = -d_lhs;
tmp_lhs = h_lhs;
tmp_d_lhs = d_lhs;
actual_lhs(PREFIX_INC) = cast_from_half<double>(++tmp_lhs);
actual_lhs(PREFIX_INC) = static_cast<double>(++tmp_lhs);
expected_lhs(PREFIX_INC) = ++tmp_d_lhs;
actual_lhs(PREFIX_DEC) = cast_from_half<double>(--tmp_lhs);
actual_lhs(PREFIX_DEC) = static_cast<double>(--tmp_lhs);
expected_lhs(PREFIX_DEC) = --tmp_d_lhs;
// if (h_lhs != tmp_lhs) {
// printf("tmp_lhs = %f, h_lhs = %f\n", __half2float(tmp_lhs),
// __half2float(h_lhs)); Kokkos::abort("Error in half_t prefix operators");
// __half2float(h_lhs)); Kokkos::abort("Error in half_type prefix
// operators");
//}
actual_lhs(POSTFIX_INC) = cast_from_half<double>(tmp_lhs++);
actual_lhs(POSTFIX_INC) = static_cast<double>(tmp_lhs++);
expected_lhs(POSTFIX_INC) = tmp_d_lhs++;
actual_lhs(POSTFIX_DEC) = cast_from_half<double>(tmp_lhs--);
actual_lhs(POSTFIX_DEC) = static_cast<double>(tmp_lhs--);
expected_lhs(POSTFIX_DEC) = tmp_d_lhs--;
// if (h_lhs != tmp_lhs) {
// printf("tmp_lhs = %f, h_lhs = %f\n", __half2float(tmp_lhs),
// __half2float(h_lhs)); Kokkos::abort("Error in half_t postfix
// __half2float(h_lhs)); Kokkos::abort("Error in half_type postfix
// operators");
//}
tmp_lhs = h_lhs;
tmp_lhs += h_rhs;
actual_lhs(CADD_H_H) = cast_from_half<double>(tmp_lhs);
actual_lhs(CADD_H_H) = static_cast<double>(tmp_lhs);
expected_lhs(CADD_H_H) = d_lhs;
expected_lhs(CADD_H_H) += d_rhs;
tmp_lhs = h_lhs;
tmp_lhs += static_cast<float>(d_rhs);
actual_lhs(CADD_H_S) = cast_from_half<double>(tmp_lhs);
actual_lhs(CADD_H_S) = static_cast<double>(tmp_lhs);
expected_lhs(CADD_H_S) = d_lhs;
expected_lhs(CADD_H_S) += d_rhs;
@ -526,7 +543,7 @@ struct Functor_TestHalfOperators {
tmp_lhs = static_cast<double>(h_lhs);
tmp_lhs += static_cast<double>(d_rhs);
actual_lhs(CADD_H_D) = cast_from_half<double>(tmp_lhs);
actual_lhs(CADD_H_D) = static_cast<double>(tmp_lhs);
expected_lhs(CADD_H_D) = d_lhs;
expected_lhs(CADD_H_D) += d_rhs;
@ -538,13 +555,13 @@ struct Functor_TestHalfOperators {
tmp_lhs = h_lhs;
tmp_lhs -= h_rhs;
actual_lhs(CSUB_H_H) = cast_from_half<double>(tmp_lhs);
actual_lhs(CSUB_H_H) = static_cast<double>(tmp_lhs);
expected_lhs(CSUB_H_H) = d_lhs;
expected_lhs(CSUB_H_H) -= d_rhs;
tmp_lhs = h_lhs;
tmp_lhs -= static_cast<float>(d_rhs);
actual_lhs(CSUB_H_S) = cast_from_half<double>(tmp_lhs);
actual_lhs(CSUB_H_S) = static_cast<double>(tmp_lhs);
expected_lhs(CSUB_H_S) = d_lhs;
expected_lhs(CSUB_H_S) -= d_rhs;
@ -568,13 +585,13 @@ struct Functor_TestHalfOperators {
tmp_lhs = h_lhs;
tmp_lhs *= h_rhs;
actual_lhs(CMUL_H_H) = cast_from_half<double>(tmp_lhs);
actual_lhs(CMUL_H_H) = static_cast<double>(tmp_lhs);
expected_lhs(CMUL_H_H) = d_lhs;
expected_lhs(CMUL_H_H) *= d_rhs;
tmp_lhs = h_lhs;
tmp_lhs *= static_cast<float>(d_rhs);
actual_lhs(CMUL_H_S) = cast_from_half<double>(tmp_lhs);
actual_lhs(CMUL_H_S) = static_cast<double>(tmp_lhs);
expected_lhs(CMUL_H_S) = d_lhs;
expected_lhs(CMUL_H_S) *= d_rhs;
@ -598,13 +615,13 @@ struct Functor_TestHalfOperators {
tmp_lhs = h_lhs;
tmp_lhs /= h_rhs;
actual_lhs(CDIV_H_H) = cast_from_half<double>(tmp_lhs);
actual_lhs(CDIV_H_H) = static_cast<double>(tmp_lhs);
expected_lhs(CDIV_H_H) = d_lhs;
expected_lhs(CDIV_H_H) /= d_rhs;
tmp_lhs = h_lhs;
tmp_lhs /= static_cast<float>(d_rhs);
actual_lhs(CDIV_H_S) = cast_from_half<double>(tmp_lhs);
actual_lhs(CDIV_H_S) = static_cast<double>(tmp_lhs);
expected_lhs(CDIV_H_S) = d_lhs;
expected_lhs(CDIV_H_S) /= d_rhs;
@ -626,28 +643,30 @@ struct Functor_TestHalfOperators {
expected_lhs(CDIV_D_H) = d_lhs;
expected_lhs(CDIV_D_H) /= d_rhs;
test_add<half_t, half_t, half_t>(ADD_H_H, ADD_H_H_SZ);
test_add<float, half_t, float>(ADD_S_H, ADD_S_H_SZ);
test_add<double, half_t, double>(ADD_D_H, ADD_D_H_SZ);
test_add<short int, half_t, half_t>(ADD_SI_H, ADD_SI_H_SZ);
test_add<int, half_t, half_t>(ADD_I_H, ADD_I_H_SZ);
test_add<long int, half_t, half_t>(ADD_LI_H, ADD_LI_H_SZ);
test_add<long long int, half_t, half_t>(ADD_LLI_H, ADD_LLI_H_SZ);
test_add<half_t, float, float>(ADD_H_S, ADD_H_S_SZ);
test_add<half_t, double, double>(ADD_H_D, ADD_H_D_SZ);
test_add<half_t, short int, half_t>(ADD_H_SI, ADD_H_SI_SZ);
test_add<half_t, int, half_t>(ADD_H_I, ADD_H_I_SZ);
test_add<half_t, long int, half_t>(ADD_H_LI, ADD_H_LI_SZ);
test_add<half_t, long long int, half_t>(ADD_H_LLI, ADD_H_LLI_SZ);
test_add<half_type, half_type, half_type>(ADD_H_H, ADD_H_H_SZ);
test_add<float, half_type, float>(ADD_S_H, ADD_S_H_SZ);
test_add<double, half_type, double>(ADD_D_H, ADD_D_H_SZ);
test_add<short int, half_type, half_type>(ADD_SI_H, ADD_SI_H_SZ);
test_add<int, half_type, half_type>(ADD_I_H, ADD_I_H_SZ);
test_add<long int, half_type, half_type>(ADD_LI_H, ADD_LI_H_SZ);
test_add<long long int, half_type, half_type>(ADD_LLI_H, ADD_LLI_H_SZ);
test_add<half_type, float, float>(ADD_H_S, ADD_H_S_SZ);
test_add<half_type, double, double>(ADD_H_D, ADD_H_D_SZ);
test_add<half_type, short int, half_type>(ADD_H_SI, ADD_H_SI_SZ);
test_add<half_type, int, half_type>(ADD_H_I, ADD_H_I_SZ);
test_add<half_type, long int, half_type>(ADD_H_LI, ADD_H_LI_SZ);
test_add<half_type, long long int, half_type>(ADD_H_LLI, ADD_H_LLI_SZ);
// Check for potential overflow due to negative half_t -> unsigned integral
// cast
// Check for potential overflow due to negative half_type -> unsigned
// integral cast
if (h_lhs >= 0) {
test_add<unsigned short int, half_t, half_t>(ADD_USI_H, ADD_USI_H_SZ);
test_add<unsigned int, half_t, half_t>(ADD_UI_H, ADD_UI_H_SZ);
test_add<unsigned long int, half_t, half_t>(ADD_ULI_H, ADD_ULI_H_SZ);
test_add<unsigned long long int, half_t, half_t>(ADD_ULLI_H,
ADD_ULLI_H_SZ);
test_add<unsigned short int, half_type, half_type>(ADD_USI_H,
ADD_USI_H_SZ);
test_add<unsigned int, half_type, half_type>(ADD_UI_H, ADD_UI_H_SZ);
test_add<unsigned long int, half_type, half_type>(ADD_ULI_H,
ADD_ULI_H_SZ);
test_add<unsigned long long int, half_type, half_type>(ADD_ULLI_H,
ADD_ULLI_H_SZ);
} else {
actual_lhs(ADD_USI_H) = expected_lhs(ADD_USI_H);
actual_lhs(ADD_USI_H_SZ) = expected_lhs(ADD_USI_H_SZ);
@ -659,14 +678,16 @@ struct Functor_TestHalfOperators {
actual_lhs(ADD_ULLI_H_SZ) = expected_lhs(ADD_ULLI_H_SZ);
}
// Check for potential overflow due to negative half_t -> unsigned integral
// cast
// Check for potential overflow due to negative half_type -> unsigned
// integral cast
if (h_rhs >= 0) {
test_add<half_t, unsigned short int, half_t>(ADD_H_USI, ADD_H_USI_SZ);
test_add<half_t, unsigned int, half_t>(ADD_H_UI, ADD_H_UI_SZ);
test_add<half_t, unsigned long int, half_t>(ADD_H_ULI, ADD_H_ULI_SZ);
test_add<half_t, unsigned long long int, half_t>(ADD_H_ULLI,
ADD_H_ULLI_SZ);
test_add<half_type, unsigned short int, half_type>(ADD_H_USI,
ADD_H_USI_SZ);
test_add<half_type, unsigned int, half_type>(ADD_H_UI, ADD_H_UI_SZ);
test_add<half_type, unsigned long int, half_type>(ADD_H_ULI,
ADD_H_ULI_SZ);
test_add<half_type, unsigned long long int, half_type>(ADD_H_ULLI,
ADD_H_ULLI_SZ);
} else {
actual_lhs(ADD_H_USI) = expected_lhs(ADD_H_USI);
actual_lhs(ADD_H_USI_SZ) = expected_lhs(ADD_H_USI_SZ);
@ -678,28 +699,30 @@ struct Functor_TestHalfOperators {
actual_lhs(ADD_H_ULLI_SZ) = expected_lhs(ADD_H_ULLI_SZ);
}
test_sub<half_t, half_t, half_t>(SUB_H_H, SUB_H_H_SZ);
test_sub<float, half_t, float>(SUB_S_H, SUB_S_H_SZ);
test_sub<double, half_t, double>(SUB_D_H, SUB_D_H_SZ);
test_sub<short int, half_t, half_t>(SUB_SI_H, SUB_SI_H_SZ);
test_sub<int, half_t, half_t>(SUB_I_H, SUB_I_H_SZ);
test_sub<long int, half_t, half_t>(SUB_LI_H, SUB_LI_H_SZ);
test_sub<long long int, half_t, half_t>(SUB_LLI_H, SUB_LLI_H_SZ);
test_sub<half_t, float, float>(SUB_H_S, SUB_H_S_SZ);
test_sub<half_t, double, double>(SUB_H_D, SUB_H_D_SZ);
test_sub<half_t, short int, half_t>(SUB_H_SI, SUB_H_SI_SZ);
test_sub<half_t, int, half_t>(SUB_H_I, SUB_H_I_SZ);
test_sub<half_t, long int, half_t>(SUB_H_LI, SUB_H_LI_SZ);
test_sub<half_t, long long int, half_t>(SUB_H_LLI, SUB_H_LLI_SZ);
test_sub<half_type, half_type, half_type>(SUB_H_H, SUB_H_H_SZ);
test_sub<float, half_type, float>(SUB_S_H, SUB_S_H_SZ);
test_sub<double, half_type, double>(SUB_D_H, SUB_D_H_SZ);
test_sub<short int, half_type, half_type>(SUB_SI_H, SUB_SI_H_SZ);
test_sub<int, half_type, half_type>(SUB_I_H, SUB_I_H_SZ);
test_sub<long int, half_type, half_type>(SUB_LI_H, SUB_LI_H_SZ);
test_sub<long long int, half_type, half_type>(SUB_LLI_H, SUB_LLI_H_SZ);
test_sub<half_type, float, float>(SUB_H_S, SUB_H_S_SZ);
test_sub<half_type, double, double>(SUB_H_D, SUB_H_D_SZ);
test_sub<half_type, short int, half_type>(SUB_H_SI, SUB_H_SI_SZ);
test_sub<half_type, int, half_type>(SUB_H_I, SUB_H_I_SZ);
test_sub<half_type, long int, half_type>(SUB_H_LI, SUB_H_LI_SZ);
test_sub<half_type, long long int, half_type>(SUB_H_LLI, SUB_H_LLI_SZ);
// Check for potential overflow due to negative half_t -> unsigned integral
// cast
if (h_lhs >= half_t(0)) {
test_sub<unsigned short int, half_t, half_t>(SUB_USI_H, SUB_USI_H_SZ);
test_sub<unsigned int, half_t, half_t>(SUB_UI_H, SUB_UI_H_SZ);
test_sub<unsigned long int, half_t, half_t>(SUB_ULI_H, SUB_ULI_H_SZ);
test_sub<unsigned long long int, half_t, half_t>(SUB_ULLI_H,
SUB_ULLI_H_SZ);
// Check for potential overflow due to negative half_type -> unsigned
// integral cast
if (h_lhs >= half_type(0)) {
test_sub<unsigned short int, half_type, half_type>(SUB_USI_H,
SUB_USI_H_SZ);
test_sub<unsigned int, half_type, half_type>(SUB_UI_H, SUB_UI_H_SZ);
test_sub<unsigned long int, half_type, half_type>(SUB_ULI_H,
SUB_ULI_H_SZ);
test_sub<unsigned long long int, half_type, half_type>(SUB_ULLI_H,
SUB_ULLI_H_SZ);
} else {
actual_lhs(SUB_USI_H) = expected_lhs(SUB_USI_H);
actual_lhs(SUB_USI_H_SZ) = expected_lhs(SUB_USI_H_SZ);
@ -711,14 +734,16 @@ struct Functor_TestHalfOperators {
actual_lhs(SUB_ULLI_H_SZ) = expected_lhs(SUB_ULLI_H_SZ);
}
// Check for potential overflow due to negative half_t -> unsigned integral
// cast
if (h_rhs >= half_t(0)) {
test_sub<half_t, unsigned short int, half_t>(SUB_H_USI, SUB_H_USI_SZ);
test_sub<half_t, unsigned int, half_t>(SUB_H_UI, SUB_H_UI_SZ);
test_sub<half_t, unsigned long int, half_t>(SUB_H_ULI, SUB_H_ULI_SZ);
test_sub<half_t, unsigned long long int, half_t>(SUB_H_ULLI,
SUB_H_ULLI_SZ);
// Check for potential overflow due to negative half_type -> unsigned
// integral cast
if (h_rhs >= half_type(0)) {
test_sub<half_type, unsigned short int, half_type>(SUB_H_USI,
SUB_H_USI_SZ);
test_sub<half_type, unsigned int, half_type>(SUB_H_UI, SUB_H_UI_SZ);
test_sub<half_type, unsigned long int, half_type>(SUB_H_ULI,
SUB_H_ULI_SZ);
test_sub<half_type, unsigned long long int, half_type>(SUB_H_ULLI,
SUB_H_ULLI_SZ);
} else {
actual_lhs(SUB_H_USI) = expected_lhs(SUB_H_USI);
actual_lhs(SUB_H_USI_SZ) = expected_lhs(SUB_H_USI_SZ);
@ -730,28 +755,30 @@ struct Functor_TestHalfOperators {
actual_lhs(SUB_H_ULLI_SZ) = expected_lhs(SUB_H_ULLI_SZ);
}
test_mul<half_t, half_t, half_t>(MUL_H_H, MUL_H_H_SZ);
test_mul<float, half_t, float>(MUL_S_H, MUL_S_H_SZ);
test_mul<double, half_t, double>(MUL_D_H, MUL_D_H_SZ);
test_mul<short int, half_t, half_t>(MUL_SI_H, MUL_SI_H_SZ);
test_mul<int, half_t, half_t>(MUL_I_H, MUL_I_H_SZ);
test_mul<long int, half_t, half_t>(MUL_LI_H, MUL_LI_H_SZ);
test_mul<long long int, half_t, half_t>(MUL_LLI_H, MUL_LLI_H_SZ);
test_mul<half_t, float, float>(MUL_H_S, MUL_H_S_SZ);
test_mul<half_t, double, double>(MUL_H_D, MUL_H_D_SZ);
test_mul<half_t, short int, half_t>(MUL_H_SI, MUL_H_SI_SZ);
test_mul<half_t, int, half_t>(MUL_H_I, MUL_H_I_SZ);
test_mul<half_t, long int, half_t>(MUL_H_LI, MUL_H_LI_SZ);
test_mul<half_t, long long int, half_t>(MUL_H_LLI, MUL_H_LLI_SZ);
test_mul<half_type, half_type, half_type>(MUL_H_H, MUL_H_H_SZ);
test_mul<float, half_type, float>(MUL_S_H, MUL_S_H_SZ);
test_mul<double, half_type, double>(MUL_D_H, MUL_D_H_SZ);
test_mul<short int, half_type, half_type>(MUL_SI_H, MUL_SI_H_SZ);
test_mul<int, half_type, half_type>(MUL_I_H, MUL_I_H_SZ);
test_mul<long int, half_type, half_type>(MUL_LI_H, MUL_LI_H_SZ);
test_mul<long long int, half_type, half_type>(MUL_LLI_H, MUL_LLI_H_SZ);
test_mul<half_type, float, float>(MUL_H_S, MUL_H_S_SZ);
test_mul<half_type, double, double>(MUL_H_D, MUL_H_D_SZ);
test_mul<half_type, short int, half_type>(MUL_H_SI, MUL_H_SI_SZ);
test_mul<half_type, int, half_type>(MUL_H_I, MUL_H_I_SZ);
test_mul<half_type, long int, half_type>(MUL_H_LI, MUL_H_LI_SZ);
test_mul<half_type, long long int, half_type>(MUL_H_LLI, MUL_H_LLI_SZ);
// Check for potential overflow due to negative half_t -> unsigned integral
// cast
if (h_lhs >= half_t(0)) {
test_mul<unsigned short int, half_t, half_t>(MUL_USI_H, MUL_USI_H_SZ);
test_mul<unsigned int, half_t, half_t>(MUL_UI_H, MUL_UI_H_SZ);
test_mul<unsigned long int, half_t, half_t>(MUL_ULI_H, MUL_ULI_H_SZ);
test_mul<unsigned long long int, half_t, half_t>(MUL_ULLI_H,
MUL_ULLI_H_SZ);
// Check for potential overflow due to negative half_type -> unsigned
// integral cast
if (h_lhs >= half_type(0)) {
test_mul<unsigned short int, half_type, half_type>(MUL_USI_H,
MUL_USI_H_SZ);
test_mul<unsigned int, half_type, half_type>(MUL_UI_H, MUL_UI_H_SZ);
test_mul<unsigned long int, half_type, half_type>(MUL_ULI_H,
MUL_ULI_H_SZ);
test_mul<unsigned long long int, half_type, half_type>(MUL_ULLI_H,
MUL_ULLI_H_SZ);
} else {
actual_lhs(MUL_USI_H) = expected_lhs(MUL_USI_H);
actual_lhs(MUL_UI_H) = expected_lhs(MUL_UI_H);
@ -763,14 +790,16 @@ struct Functor_TestHalfOperators {
actual_lhs(MUL_ULLI_H_SZ) = expected_lhs(MUL_ULLI_H_SZ);
}
// Check for potential overflow due to negative half_t -> unsigned integral
// cast
if (h_rhs >= half_t(0)) {
test_mul<half_t, unsigned short int, half_t>(MUL_H_USI, MUL_H_USI_SZ);
test_mul<half_t, unsigned int, half_t>(MUL_H_UI, MUL_H_UI_SZ);
test_mul<half_t, unsigned long int, half_t>(MUL_H_ULI, MUL_H_ULI_SZ);
test_mul<half_t, unsigned long long int, half_t>(MUL_H_ULLI,
MUL_H_ULLI_SZ);
// Check for potential overflow due to negative half_type -> unsigned
// integral cast
if (h_rhs >= half_type(0)) {
test_mul<half_type, unsigned short int, half_type>(MUL_H_USI,
MUL_H_USI_SZ);
test_mul<half_type, unsigned int, half_type>(MUL_H_UI, MUL_H_UI_SZ);
test_mul<half_type, unsigned long int, half_type>(MUL_H_ULI,
MUL_H_ULI_SZ);
test_mul<half_type, unsigned long long int, half_type>(MUL_H_ULLI,
MUL_H_ULLI_SZ);
} else {
actual_lhs(MUL_H_USI) = expected_lhs(MUL_H_USI);
actual_lhs(MUL_H_UI) = expected_lhs(MUL_H_UI);
@ -782,22 +811,23 @@ struct Functor_TestHalfOperators {
actual_lhs(MUL_H_ULLI_SZ) = expected_lhs(MUL_H_ULLI_SZ);
}
test_div<half_t, half_t, half_t>(DIV_H_H, DIV_H_H_SZ);
test_div<float, half_t, float>(DIV_S_H, DIV_S_H_SZ);
test_div<double, half_t, double>(DIV_D_H, DIV_D_H_SZ);
test_div<short int, half_t, half_t>(DIV_SI_H, DIV_SI_H_SZ);
test_div<int, half_t, half_t>(DIV_I_H, DIV_I_H_SZ);
test_div<long int, half_t, half_t>(DIV_LI_H, DIV_LI_H_SZ);
test_div<long long int, half_t, half_t>(DIV_LLI_H, DIV_LLI_H_SZ);
test_div<half_t, float, float>(DIV_H_S, DIV_H_S_SZ);
test_div<half_t, double, double>(DIV_H_D, DIV_H_D_SZ);
test_div<half_type, half_type, half_type>(DIV_H_H, DIV_H_H_SZ);
test_div<float, half_type, float>(DIV_S_H, DIV_S_H_SZ);
test_div<double, half_type, double>(DIV_D_H, DIV_D_H_SZ);
test_div<short int, half_type, half_type>(DIV_SI_H, DIV_SI_H_SZ);
test_div<int, half_type, half_type>(DIV_I_H, DIV_I_H_SZ);
test_div<long int, half_type, half_type>(DIV_LI_H, DIV_LI_H_SZ);
test_div<long long int, half_type, half_type>(DIV_LLI_H, DIV_LLI_H_SZ);
test_div<half_type, float, float>(DIV_H_S, DIV_H_S_SZ);
test_div<half_type, double, double>(DIV_H_D, DIV_H_D_SZ);
// Check for division by zero due to truncation by half_t -> integral cast
if (h_rhs >= half_t(1) || h_rhs <= half_t(-1)) {
test_div<half_t, short int, half_t>(DIV_H_SI, DIV_H_SI_SZ);
test_div<half_t, int, half_t>(DIV_H_I, DIV_H_I_SZ);
test_div<half_t, long int, half_t>(DIV_H_LI, DIV_H_LI_SZ);
test_div<half_t, long long int, half_t>(DIV_H_LLI, DIV_H_LLI_SZ);
// Check for division by zero due to truncation by half_type -> integral
// cast
if (h_rhs >= half_type(1) || h_rhs <= half_type(-1)) {
test_div<half_type, short int, half_type>(DIV_H_SI, DIV_H_SI_SZ);
test_div<half_type, int, half_type>(DIV_H_I, DIV_H_I_SZ);
test_div<half_type, long int, half_type>(DIV_H_LI, DIV_H_LI_SZ);
test_div<half_type, long long int, half_type>(DIV_H_LLI, DIV_H_LLI_SZ);
} else {
actual_lhs(DIV_H_SI) = expected_lhs(DIV_H_SI);
actual_lhs(DIV_H_I) = expected_lhs(DIV_H_I);
@ -809,14 +839,16 @@ struct Functor_TestHalfOperators {
actual_lhs(DIV_H_LLI_SZ) = expected_lhs(DIV_H_LLI_SZ);
}
// Check for potential overflow due to negative half_t -> unsigned integral
// cast
if (h_lhs >= half_t(0)) {
test_div<unsigned short int, half_t, half_t>(DIV_USI_H, DIV_USI_H_SZ);
test_div<unsigned int, half_t, half_t>(DIV_UI_H, DIV_UI_H_SZ);
test_div<unsigned long int, half_t, half_t>(DIV_ULI_H, DIV_ULI_H_SZ);
test_div<unsigned long long int, half_t, half_t>(DIV_ULLI_H,
DIV_ULLI_H_SZ);
// Check for potential overflow due to negative half_type -> unsigned
// integral cast
if (h_lhs >= half_type(0)) {
test_div<unsigned short int, half_type, half_type>(DIV_USI_H,
DIV_USI_H_SZ);
test_div<unsigned int, half_type, half_type>(DIV_UI_H, DIV_UI_H_SZ);
test_div<unsigned long int, half_type, half_type>(DIV_ULI_H,
DIV_ULI_H_SZ);
test_div<unsigned long long int, half_type, half_type>(DIV_ULLI_H,
DIV_ULLI_H_SZ);
} else {
actual_lhs(DIV_USI_H) = expected_lhs(DIV_USI_H);
actual_lhs(DIV_UI_H) = expected_lhs(DIV_UI_H);
@ -828,13 +860,16 @@ struct Functor_TestHalfOperators {
actual_lhs(DIV_ULLI_H_SZ) = expected_lhs(DIV_ULLI_H_SZ);
}
// Check for division by zero due to truncation by half_t -> integral cast
if (h_rhs >= half_t(1)) {
test_div<half_t, unsigned short int, half_t>(DIV_H_USI, DIV_H_USI_SZ);
test_div<half_t, unsigned int, half_t>(DIV_H_UI, DIV_H_UI_SZ);
test_div<half_t, unsigned long int, half_t>(DIV_H_ULI, DIV_H_ULI_SZ);
test_div<half_t, unsigned long long int, half_t>(DIV_H_ULLI,
DIV_H_ULLI_SZ);
// Check for division by zero due to truncation by half_type -> integral
// cast
if (h_rhs >= half_type(1)) {
test_div<half_type, unsigned short int, half_type>(DIV_H_USI,
DIV_H_USI_SZ);
test_div<half_type, unsigned int, half_type>(DIV_H_UI, DIV_H_UI_SZ);
test_div<half_type, unsigned long int, half_type>(DIV_H_ULI,
DIV_H_ULI_SZ);
test_div<half_type, unsigned long long int, half_type>(DIV_H_ULLI,
DIV_H_ULLI_SZ);
} else {
actual_lhs(DIV_H_USI) = expected_lhs(DIV_H_USI);
actual_lhs(DIV_H_USI_SZ) = expected_lhs(DIV_H_USI_SZ);
@ -850,10 +885,10 @@ struct Functor_TestHalfOperators {
actual_lhs(NEG) = static_cast<double>(!h_lhs);
expected_lhs(NEG) = !d_lhs;
actual_lhs(AND) = static_cast<double>(half_t(0) && h_lhs);
actual_lhs(AND) = static_cast<double>(half_type(0) && h_lhs);
expected_lhs(AND) = double(0) && d_lhs;
actual_lhs(OR) = static_cast<double>(h_lhs || half_t(1));
actual_lhs(OR) = static_cast<double>(h_lhs || half_type(1));
expected_lhs(OR) = d_lhs || double(1);
actual_lhs(EQ) = h_lhs == h_rhs;
@ -877,21 +912,21 @@ struct Functor_TestHalfOperators {
// actual_lhs(TW) = h_lhs <=> h_rhs; // Need C++20?
// expected_lhs(TW) = d_lhs <=> d_rhs; // Need C++20?
actual_lhs(PASS_BY_REF) = cast_from_half<double>(accept_ref(h_lhs));
actual_lhs(PASS_BY_REF) = static_cast<double>(accept_ref(h_lhs));
expected_lhs(PASS_BY_REF) = d_lhs;
half_tmp = cast_from_half<float>(h_lhs);
half_tmp = static_cast<float>(h_lhs);
tmp_ptr = &(tmp_lhs = half_tmp);
if (tmp_ptr != &tmp_lhs)
Kokkos::abort("Error in half_t address-of operator");
actual_lhs(AO_IMPL_HALF) = cast_from_half<double>(*tmp_ptr);
Kokkos::abort("Error in half_type address-of operator");
actual_lhs(AO_IMPL_HALF) = static_cast<double>(*tmp_ptr);
expected_lhs(AO_IMPL_HALF) = d_lhs;
tmp2_lhs = h_lhs;
tmp_ptr = &(tmp_lhs = tmp2_lhs);
if (tmp_ptr != &tmp_lhs)
Kokkos::abort("Error in half_t address-of operator");
actual_lhs(AO_HALF_T) = cast_from_half<double>(tmp_ptr[0]);
Kokkos::abort("Error in half_type address-of operator");
actual_lhs(AO_HALF_T) = static_cast<double>(tmp_ptr[0]);
expected_lhs(AO_HALF_T) = d_lhs;
// TODO: Check upcasting and downcasting in large expressions involving
@ -899,10 +934,17 @@ struct Functor_TestHalfOperators {
}
};
void __test_half_operators(half_t h_lhs, half_t h_rhs) {
double epsilon = KOKKOS_HALF_T_IS_FLOAT ? FLT_EPSILON : FP16_EPSILON;
Functor_TestHalfOperators<ViewType> f_device(h_lhs, h_rhs); // Run on device
Functor_TestHalfOperators<ViewTypeHost> f_host(h_lhs, h_rhs); // Run on host
template <class half_type>
void __test_half_operators(half_type h_lhs, half_type h_rhs) {
double epsilon = FLT_EPSILON;
if (std::is_same<half_type, Kokkos::Experimental::half_t>::value)
epsilon = FP16_EPSILON;
if (std::is_same<half_type, Kokkos::Experimental::bhalf_t>::value)
epsilon = BF16_EPSILON;
Functor_TestHalfOperators<ViewType, half_type> f_device(h_lhs, h_rhs);
Functor_TestHalfOperators<ViewTypeHost, half_type> f_host(h_lhs, h_rhs);
typename ViewType::HostMirror f_device_actual_lhs =
Kokkos::create_mirror_view(f_device.actual_lhs);
typename ViewType::HostMirror f_device_expected_lhs =
@ -920,11 +962,12 @@ void __test_half_operators(half_t h_lhs, half_t h_rhs) {
}
// Test partial volatile support
volatile half_t _h_lhs = h_lhs;
volatile half_t _h_rhs = h_rhs;
Functor_TestHalfVolatileOperators<ViewType> f_volatile_device(_h_lhs, _h_rhs);
Functor_TestHalfVolatileOperators<ViewTypeHost> f_volatile_host(_h_lhs,
_h_rhs);
volatile half_type _h_lhs = h_lhs;
volatile half_type _h_rhs = h_rhs;
Functor_TestHalfVolatileOperators<ViewType, half_type> f_volatile_device(
_h_lhs, _h_rhs);
Functor_TestHalfVolatileOperators<ViewTypeHost, half_type> f_volatile_host(
_h_lhs, _h_rhs);
ExecutionSpace().fence();
Kokkos::deep_copy(f_device_actual_lhs, f_device.actual_lhs);
@ -944,12 +987,12 @@ void __test_half_operators(half_t h_lhs, half_t h_rhs) {
// is_trivially_copyable is false with the addition of explicit
// copy constructors that are required for supporting reductions
// ASSERT_TRUE(std::is_trivially_copyable<half_t>::value);
// ASSERT_TRUE(std::is_trivially_copyable<half_type>::value);
constexpr size_t n = 2;
constexpr size_t n_bytes = sizeof(half_t) * n;
const half_t h_arr0 = half_t(0x89ab), h_arr1 = half_t(0xcdef);
half_t h_arr[n];
constexpr size_t n_bytes = sizeof(half_type) * n;
const half_type h_arr0 = half_type(0x89ab), h_arr1 = half_type(0xcdef);
half_type h_arr[n];
char c_arr[n_bytes], *h_arr_ptr = nullptr;
size_t i;
@ -970,13 +1013,24 @@ void test_half_operators() {
for (int i = -3; i < 2; i++) {
// printf("%f OP %f\n", float(h_lhs + cast_to_half(i + 1)), float(h_rhs +
// cast_to_half(i)));
__test_half_operators(h_lhs + cast_to_half(i + 1), h_rhs + cast_to_half(i));
__test_half_operators<half_t>(h_lhs + cast_to_half(i + 1),
h_rhs + cast_to_half(i));
// TODO: __test_half_operators(h_lhs + cast_to_half(i + 1), half_t(0));
// TODO: __test_half_operators(half_t(0), h_rhs + cast_to_half(i));
}
}
void test_bhalf_operators() {
bhalf_t h_lhs = bhalf_t(0.23458), h_rhs = bhalf_t(0.67898);
for (int i = -2; i < 2; i++) {
// printf("%f OP %f\n", float(h_lhs + cast_to_bhalf(i + 1)), float(h_rhs +
// cast_to_bhalf(i)));
__test_half_operators<bhalf_t>(h_lhs + cast_to_bhalf(i + 1),
h_rhs + cast_to_bhalf(i));
}
}
TEST(TEST_CATEGORY, half_operators) { test_half_operators(); }
TEST(TEST_CATEGORY, bhalf_operators) { test_bhalf_operators(); }
} // namespace Test
#endif // KOKKOS_ENABLE_SYCL
#endif // TESTHALFOPERATOR_HPP_

View File

@ -124,6 +124,13 @@ struct TestMDRange_ReduceArray_2D {
parallel_for(range_init, functor); // Init the view to 3's
double sums[array_size];
#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_3
double *sums_ptr = sums;
parallel_reduce(range, functor, sums_ptr);
ASSERT_EQ(sums[0], 6 * N0 * N1);
ASSERT_EQ(sums[1], 3 * N0 * N1);
#endif
Kokkos::fence("Fence before accessing result on the host");
parallel_reduce(range, functor, sums);
// Check output

View File

@ -0,0 +1,111 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
//#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
namespace Test {
template <typename View>
struct SumView {
const View m_view;
KOKKOS_FUNCTION void operator()(const int i, const int j, int& update) const {
update += m_view(i, j);
}
SumView(View view) : m_view(view) {}
int run() {
int sum_view = 0;
Kokkos::parallel_reduce(
Kokkos::MDRangePolicy<typename View::execution_space, Kokkos::Rank<2>>(
{0, 0}, {m_view.extent(0), m_view.extent(1)}),
*this, sum_view);
return sum_view;
}
};
template <typename ExecutionSpace>
struct TestMDRangeLargeDeepCopy {
static void run() {
ExecutionSpace exec;
using MemorySpace = typename ExecutionSpace::memory_space;
// FIXME_SYCL
#ifdef KOKKOS_ENABLE_SYCL
const int s = 13;
#else
const int s = 45;
#endif
const int step_sizes[2] = {1, 10000};
Kokkos::View<int**, MemorySpace> view("v", s * step_sizes[0],
(s + 1) * step_sizes[1]);
Kokkos::deep_copy(exec, view, 1);
for (int step = 2; step < view.extent_int(0); ++step) {
auto subview =
Kokkos::subview(view, std::make_pair(0, (step + 1) * step_sizes[0]),
std::make_pair(0, (step + 2) * step_sizes[1]));
Kokkos::View<int**, MemorySpace> subview_copy(
"subview_copy", subview.extent(0), subview.extent(1));
Kokkos::deep_copy(TEST_EXECSPACE{}, subview_copy, subview);
exec.fence();
SumView<decltype(subview)> sum_subview(subview);
int total_subview = sum_subview.run();
SumView<decltype(subview_copy)> sum_subview_copy(subview_copy);
int total_subview_copy = sum_subview_copy.run();
ASSERT_EQ(total_subview, total_subview_copy);
}
}
};
// Check that deep_copy with a large range for a dimension different from the
// first one works successfully. There was a problem with this in the Cuda
// backend.
TEST(TEST_CATEGORY, mdrange_large_deep_copy) {
TestMDRangeLargeDeepCopy<TEST_EXECSPACE>::run();
}
} // namespace Test

View File

@ -0,0 +1,151 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
template <class T>
KOKKOS_FUNCTION T *take_address_of(T &arg) {
return &arg;
}
template <class T>
KOKKOS_FUNCTION void take_by_value(T) {}
#if defined(KOKKOS_ENABLE_CXX17)
#define DEFINE_MATH_CONSTANT_TRAIT(TRAIT) \
template <class T> \
struct TRAIT { \
static constexpr T value = Kokkos::Experimental::TRAIT##_v<T>; \
}
#else
#define DEFINE_MATH_CONSTANT_TRAIT(TRAIT) \
template <class> \
struct TRAIT; \
template <> \
struct TRAIT<float> { \
static constexpr float value = Kokkos::Experimental::TRAIT##_v<float>; \
}; \
template <> \
struct TRAIT<double> { \
static constexpr double value = Kokkos::Experimental::TRAIT##_v<double>; \
}; \
template <> \
struct TRAIT<long double> { \
static constexpr long double value = \
Kokkos::Experimental::TRAIT##_v<long double>; \
}; \
constexpr float TRAIT<float>::value; \
constexpr double TRAIT<double>::value; \
constexpr long double TRAIT<long double>::value
#endif
DEFINE_MATH_CONSTANT_TRAIT(e);
DEFINE_MATH_CONSTANT_TRAIT(log2e);
DEFINE_MATH_CONSTANT_TRAIT(log10e);
DEFINE_MATH_CONSTANT_TRAIT(pi);
DEFINE_MATH_CONSTANT_TRAIT(inv_pi);
DEFINE_MATH_CONSTANT_TRAIT(inv_sqrtpi);
DEFINE_MATH_CONSTANT_TRAIT(ln2);
DEFINE_MATH_CONSTANT_TRAIT(ln10);
DEFINE_MATH_CONSTANT_TRAIT(sqrt2);
DEFINE_MATH_CONSTANT_TRAIT(sqrt3);
DEFINE_MATH_CONSTANT_TRAIT(inv_sqrt3);
DEFINE_MATH_CONSTANT_TRAIT(egamma);
DEFINE_MATH_CONSTANT_TRAIT(phi);
template <class Space, class Trait>
struct TestMathematicalConstants {
using T = std::decay_t<decltype(Trait::value)>;
TestMathematicalConstants() { run(); }
void run() const {
int errors = 0;
Kokkos::parallel_reduce(Kokkos::RangePolicy<Space, Trait>(0, 1), *this,
errors);
ASSERT_EQ(errors, 0);
(void)take_address_of(Trait::value); // use on host
}
KOKKOS_FUNCTION void operator()(Trait, int, int &) const { use_on_device(); }
KOKKOS_FUNCTION void use_on_device() const {
#if defined(KOKKOS_COMPILER_NVCC) || defined(KOKKOS_ENABLE_OPENMPTARGET)
take_by_value(Trait::value);
#else
(void)take_address_of(Trait::value);
#endif
}
};
#if defined(KOKKOS_ENABLE_CUDA) || defined(KOKKOS_ENABLE_HIP) || \
defined(KOKKOS_ENABLE_SYCL) || defined(KOKKOS_ENABLE_OPENMPTARGET)
#define TEST_MATH_CONSTANT(TRAIT) \
TEST(TEST_CATEGORY, mathematical_constants_##TRAIT) { \
TestMathematicalConstants<TEST_EXECSPACE, TRAIT<float>>(); \
TestMathematicalConstants<TEST_EXECSPACE, TRAIT<double>>(); \
}
#else
#define TEST_MATH_CONSTANT(TRAIT) \
TEST(TEST_CATEGORY, mathematical_constants_##TRAIT) { \
TestMathematicalConstants<TEST_EXECSPACE, TRAIT<float>>(); \
TestMathematicalConstants<TEST_EXECSPACE, TRAIT<double>>(); \
TestMathematicalConstants<TEST_EXECSPACE, TRAIT<long double>>(); \
}
#endif
TEST_MATH_CONSTANT(e)
TEST_MATH_CONSTANT(log2e)
TEST_MATH_CONSTANT(log10e)
TEST_MATH_CONSTANT(pi)
TEST_MATH_CONSTANT(inv_pi)
TEST_MATH_CONSTANT(inv_sqrtpi)
TEST_MATH_CONSTANT(ln2)
TEST_MATH_CONSTANT(ln10)
TEST_MATH_CONSTANT(sqrt2)
TEST_MATH_CONSTANT(sqrt3)
TEST_MATH_CONSTANT(inv_sqrt3)
TEST_MATH_CONSTANT(egamma)
TEST_MATH_CONSTANT(phi)

View File

@ -59,6 +59,12 @@
#define MATHEMATICAL_FUNCTIONS_HAVE_LONG_DOUBLE_OVERLOADS
#endif
// WORKAROUND icpx changing default FP model when optimization level is >= 1
// using -fp-model=precise works too
#if defined(__INTEL_LLVM_COMPILER)
#define KOKKOS_IMPL_WORKAROUND_INTEL_LLVM_DEFAULT_FLOATING_POINT_MODEL
#endif
// clang-format off
template <class>
struct math_unary_function_return_type;
@ -342,7 +348,13 @@ DEFINE_UNARY_FUNCTION_EVAL(asinh, 4);
DEFINE_UNARY_FUNCTION_EVAL(acosh, 2);
DEFINE_UNARY_FUNCTION_EVAL(atanh, 2);
#if defined(__APPLE__)
// Apple's standard library implementation seems to have a poor implementation
DEFINE_UNARY_FUNCTION_EVAL(erf, 5);
#else
DEFINE_UNARY_FUNCTION_EVAL(erf, 2);
#endif
DEFINE_UNARY_FUNCTION_EVAL(erfc, 5);
// has a larger error due to some impls doing integer exact.
// We cast always to double leading to larger difference when comparing our
@ -415,8 +427,6 @@ struct TestMathUnaryFunction : FloatingPointComparison {
Arg val_[N];
Ret res_[N];
TestMathUnaryFunction(const Arg (&val)[N]) {
std::cout << math_function_name<Func>::name << "("
<< type_helper<Arg>::name() << ")\n";
std::copy(val, val + N, val_);
std::transform(val, val + N, res_,
[](auto x) { return Func::eval_std(x); });
@ -425,7 +435,9 @@ struct TestMathUnaryFunction : FloatingPointComparison {
void run() {
int errors = 0;
Kokkos::parallel_reduce(Kokkos::RangePolicy<Space>(0, N), *this, errors);
ASSERT_EQ(errors, 0);
ASSERT_EQ(errors, 0) << "Failed check no error for "
<< math_function_name<Func>::name << "("
<< type_helper<Arg>::name() << ")";
}
KOKKOS_FUNCTION void operator()(int i, int& e) const {
bool ar = compare(Func::eval(val_[i]), res_[i], Func::ulp_factor());
@ -456,15 +468,15 @@ struct TestMathBinaryFunction : FloatingPointComparison {
Ret res_;
TestMathBinaryFunction(Arg1 val1, Arg2 val2)
: val1_(val1), val2_(val2), res_(Func::eval_std(val1, val2)) {
std::cout << math_function_name<Func>::name << "("
<< type_helper<Arg1>::name() << ", " << type_helper<Arg2>::name()
<< ")\n";
run();
}
void run() {
int errors = 0;
Kokkos::parallel_reduce(Kokkos::RangePolicy<Space>(0, 1), *this, errors);
ASSERT_EQ(errors, 0);
ASSERT_EQ(errors, 0) << "Failed check no error for "
<< math_function_name<Func>::name << "("
<< type_helper<Arg1>::name() << ", "
<< type_helper<Arg2>::name() << ")";
}
KOKKOS_FUNCTION void operator()(int, int& e) const {
bool ar = compare(Func::eval(val1_, val2_), res_, Func::ulp_factor());
@ -917,9 +929,7 @@ struct TestAbsoluteValueFunction {
using Kokkos::Experimental::isinf;
using Kokkos::Experimental::isnan;
if (abs(-0.) != 0.
// WORKAROUND icpx changing default FP model when optimization level is >= 1
// using -fp-model=precise works too
#ifndef __INTEL_LLVM_COMPILER
#ifndef KOKKOS_IMPL_WORKAROUND_INTEL_LLVM_DEFAULT_FLOATING_POINT_MODEL
|| !isinf(abs(-INFINITY)) || !isnan(abs(-NAN))
#endif
) {
@ -942,3 +952,73 @@ struct TestAbsoluteValueFunction {
TEST(TEST_CATEGORY, mathematical_functions_absolute_value) {
TestAbsoluteValueFunction<TEST_EXECSPACE>();
}
template <class Space>
struct TestIsNaN {
TestIsNaN() { run(); }
void run() const {
int errors = 0;
Kokkos::parallel_reduce(Kokkos::RangePolicy<Space>(0, 1), *this, errors);
ASSERT_EQ(errors, 0);
}
KOKKOS_FUNCTION void operator()(int, int& e) const {
using Kokkos::Experimental::isnan;
using Kokkos::Experimental::quiet_NaN;
using Kokkos::Experimental::signaling_NaN;
if (isnan(1) || isnan(INT_MAX)) {
++e;
KOKKOS_IMPL_DO_NOT_USE_PRINTF("failed isnan(integral)\n");
}
if (isnan(2.f)
#ifndef KOKKOS_IMPL_WORKAROUND_INTEL_LLVM_DEFAULT_FLOATING_POINT_MODEL
|| !isnan(quiet_NaN<float>::value) ||
!isnan(signaling_NaN<float>::value)
#endif
) {
++e;
KOKKOS_IMPL_DO_NOT_USE_PRINTF("failed isnan(float)\n");
}
if (isnan(3.)
#ifndef KOKKOS_IMPL_WORKAROUND_INTEL_LLVM_DEFAULT_FLOATING_POINT_MODEL
|| !isnan(quiet_NaN<double>::value) ||
!isnan(signaling_NaN<double>::value)
#endif
) {
++e;
KOKKOS_IMPL_DO_NOT_USE_PRINTF("failed isnan(double)\n");
}
#ifdef MATHEMATICAL_FUNCTIONS_HAVE_LONG_DOUBLE_OVERLOADS
if (isnan(4.l)
#ifndef KOKKOS_IMPL_WORKAROUND_INTEL_LLVM_DEFAULT_FLOATING_POINT_MODEL
|| !isnan(quiet_NaN<long double>::value) ||
!isnan(signaling_NaN<long double>::value)
#endif
) {
++e;
KOKKOS_IMPL_DO_NOT_USE_PRINTF("failed isnan(long double)\n");
}
#endif
// special values
if (isnan(INFINITY)
#ifndef KOKKOS_IMPL_WORKAROUND_INTEL_LLVM_DEFAULT_FLOATING_POINT_MODEL
|| !isnan(NAN)
#endif
) {
++e;
KOKKOS_IMPL_DO_NOT_USE_PRINTF(
"failed isnan(floating_point) special values\n");
}
static_assert(std::is_same<decltype(isnan(1)), bool>::value, "");
static_assert(std::is_same<decltype(isnan(2.f)), bool>::value, "");
static_assert(std::is_same<decltype(isnan(3.)), bool>::value, "");
#ifdef MATHEMATICAL_FUNCTIONS_HAVE_LONG_DOUBLE_OVERLOADS
static_assert(std::is_same<decltype(isnan(4.l)), bool>::value, "");
#endif
}
};
TEST(TEST_CATEGORY, mathematical_functions_isnan) {
TestIsNaN<TEST_EXECSPACE>();
}

View File

@ -1857,10 +1857,14 @@ TEST(TEST_CATEGORY, mathspecialfunc_expint1) {
test.testit();
}
// FIXME_OPENMPTARGET: This unit test fails with a misaligned address error at
// runtime with LLVM/13.
#ifndef KOKKOS_ENABLE_OPENMPTARGET
TEST(TEST_CATEGORY, mathspecialfunc_errorfunc) {
TestComplexErrorFunction<TEST_EXECSPACE> test;
test.testit();
}
#endif
TEST(TEST_CATEGORY, mathspecialfunc_cbesselj0y0) {
TestComplexBesselJ0Y0Function<TEST_EXECSPACE> test;

View File

@ -0,0 +1,333 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
// FIXME C++17
#define STATIC_ASSERT(cond) static_assert(cond, "");
namespace Test {
template <class T>
struct Greater {
KOKKOS_FUNCTION constexpr bool operator()(T const& lhs, T const& rhs) {
return lhs > rhs;
}
};
struct PairIntCompareFirst {
int first;
int second;
private:
friend KOKKOS_FUNCTION constexpr bool operator<(
PairIntCompareFirst const& lhs, PairIntCompareFirst const& rhs) {
return lhs.first < rhs.first;
}
};
} // namespace Test
// ----------------------------------------------------------
// test max()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, max) {
namespace KE = Kokkos::Experimental;
int a = 1;
int b = 2;
EXPECT_TRUE(KE::max(a, b) == 2);
a = 3;
b = 1;
EXPECT_TRUE(KE::max(a, b) == 3);
STATIC_ASSERT(KE::max(1, 2) == 2);
STATIC_ASSERT(KE::max(1, 2, ::Test::Greater<int>{}) == 1);
EXPECT_TRUE(KE::max({3.f, -1.f, 0.f}) == 3.f);
STATIC_ASSERT(KE::max({3, -1, 0}) == 3);
STATIC_ASSERT(KE::max({3, -1, 0}, ::Test::Greater<int>{}) == -1);
STATIC_ASSERT(KE::max({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.second == 0); // leftmost element
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestMax {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
namespace KE = Kokkos::Experimental;
auto v1 = 10.;
if (KE::max(v1, m_view(ind)) == 10.) {
m_view(ind) = 6.;
}
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestMax(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, max_within_parfor) {
namespace KE = Kokkos::Experimental;
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestMax<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (int i = 0; i < 10; ++i) {
EXPECT_DOUBLE_EQ(a_h(0), 6.);
}
}
// ----------------------------------------------------------
// test min()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, min) {
namespace KE = Kokkos::Experimental;
int a = 1;
int b = 2;
EXPECT_TRUE(KE::min(a, b) == 1);
a = 3;
b = 2;
EXPECT_TRUE(KE::min(a, b) == 2);
STATIC_ASSERT(KE::min(3.f, 2.f) == 2.f);
STATIC_ASSERT(KE::min(3.f, 2.f, ::Test::Greater<int>{}) == 3.f);
EXPECT_TRUE(KE::min({3.f, -1.f, 0.f}) == -1.f);
STATIC_ASSERT(KE::min({3, -1, 0}) == -1);
STATIC_ASSERT(KE::min({3, -1, 0}, ::Test::Greater<int>{}) == 3);
STATIC_ASSERT(KE::min({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.second == 2); // leftmost element
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestMin {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
namespace KE = Kokkos::Experimental;
auto v1 = 10.;
if (KE::min(v1, m_view(ind)) == 0.) {
m_view(ind) = 8.;
}
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestMin(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, min_within_parfor) {
namespace KE = Kokkos::Experimental;
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestMin<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (int i = 0; i < 10; ++i) {
EXPECT_DOUBLE_EQ(a_h(0), 8.);
}
}
// ----------------------------------------------------------
// test minmax()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, minmax) {
namespace KE = Kokkos::Experimental;
int a = 1;
int b = 2;
const auto& r = KE::minmax(a, b);
EXPECT_TRUE(r.first == 1);
EXPECT_TRUE(r.second == 2);
a = 3;
b = 2;
const auto& r2 = KE::minmax(a, b);
EXPECT_TRUE(r2.first == 2);
EXPECT_TRUE(r2.second == 3);
STATIC_ASSERT((Kokkos::pair<float, float>(KE::minmax(3.f, 2.f)) ==
Kokkos::make_pair(2.f, 3.f)));
STATIC_ASSERT(
(Kokkos::pair<float, float>(KE::minmax(
3.f, 2.f, ::Test::Greater<int>{})) == Kokkos::make_pair(3.f, 2.f)));
EXPECT_TRUE(KE::minmax({3.f, -1.f, 0.f}) == Kokkos::make_pair(-1.f, 3.f));
STATIC_ASSERT(KE::minmax({3, -1, 0}) == Kokkos::make_pair(-1, 3));
STATIC_ASSERT(KE::minmax({3, -1, 0}, ::Test::Greater<int>{}) ==
Kokkos::make_pair(3, -1));
STATIC_ASSERT(KE::minmax({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.first.second == 2); // leftmost
STATIC_ASSERT(KE::minmax({
::Test::PairIntCompareFirst{255, 0},
::Test::PairIntCompareFirst{255, 1},
::Test::PairIntCompareFirst{0, 2},
::Test::PairIntCompareFirst{0, 3},
::Test::PairIntCompareFirst{255, 4},
::Test::PairIntCompareFirst{0, 5},
})
.second.second == 4); // rightmost
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestMinMax {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
namespace KE = Kokkos::Experimental;
auto v1 = 7.;
const auto& r = KE::minmax(v1, m_view(ind));
m_view(ind) = (double)(r.first - r.second);
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestMinMax(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, minmax_within_parfor) {
namespace KE = Kokkos::Experimental;
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestMinMax<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (int i = 0; i < 10; ++i) {
EXPECT_DOUBLE_EQ(a_h(0), -7.);
}
}
// ----------------------------------------------------------
// test clamp()
// ----------------------------------------------------------
TEST(TEST_CATEGORY, clamp) {
namespace KE = Kokkos::Experimental;
int a = 1;
int b = 2;
int c = 19;
const auto& r = KE::clamp(a, b, c);
EXPECT_TRUE(&r == &b);
EXPECT_TRUE(r == b);
a = 5;
b = -2;
c = 3;
const auto& r2 = KE::clamp(a, b, c);
EXPECT_TRUE(&r2 == &c);
EXPECT_TRUE(r2 == c);
a = 5;
b = -2;
c = 7;
const auto& r3 = KE::clamp(a, b, c);
EXPECT_TRUE(&r3 == &a);
EXPECT_TRUE(r3 == a);
}
template <class ViewType>
struct StdAlgoMinMaxOpsTestClamp {
ViewType m_view;
KOKKOS_INLINE_FUNCTION
void operator()(const int& ind) const {
namespace KE = Kokkos::Experimental;
m_view(ind) = 10.;
const auto b = -2.;
const auto c = 3.;
const auto& r = KE::clamp(m_view(ind), b, c);
m_view(ind) = (double)(r);
}
KOKKOS_INLINE_FUNCTION
StdAlgoMinMaxOpsTestClamp(ViewType aIn) : m_view(aIn) {}
};
TEST(TEST_CATEGORY, clamp_within_parfor) {
namespace KE = Kokkos::Experimental;
using view_t = Kokkos::View<double*>;
view_t a("a", 10);
StdAlgoMinMaxOpsTestClamp<view_t> fnc(a);
Kokkos::parallel_for(a.extent(0), fnc);
auto a_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), a);
for (std::size_t i = 0; i < a.extent(0); ++i) {
EXPECT_DOUBLE_EQ(a_h(0), 3.);
}
}

View File

@ -81,6 +81,8 @@ struct FiniteMin { template <class T> using trait = Kokkos::Experimental::finite
struct FiniteMax { template <class T> using trait = Kokkos::Experimental::finite_max<T>; };
struct RoundError { template <class T> using trait = Kokkos::Experimental::round_error<T>; };
struct NormMin { template <class T> using trait = Kokkos::Experimental::norm_min<T>; };
struct DenormMin { template <class T> using trait = Kokkos::Experimental::denorm_min<T>; };
struct ReciprocalOverflowThreshold { template <class T> using trait = Kokkos::Experimental::reciprocal_overflow_threshold<T>; };
struct Digits { template <class T> using trait = Kokkos::Experimental::digits<T>; };
struct Digits10 { template <class T> using trait = Kokkos::Experimental::digits10<T>; };
struct MaxDigits10 { template <class T> using trait = Kokkos::Experimental::max_digits10<T>; };
@ -89,6 +91,8 @@ struct MinExponent { template <class T> using trait = Kokkos::Experimental::min_
struct MaxExponent { template <class T> using trait = Kokkos::Experimental::max_exponent<T>; };
struct MinExponent10 { template <class T> using trait = Kokkos::Experimental::min_exponent10<T>; };
struct MaxExponent10 { template <class T> using trait = Kokkos::Experimental::max_exponent10<T>; };
struct QuietNaN { template <class T> using trait = Kokkos::Experimental::quiet_NaN<T>; };
struct SignalingNaN { template <class T> using trait = Kokkos::Experimental::signaling_NaN<T>; };
// clang-format on
template <class T>
@ -149,10 +153,23 @@ struct TestNumericTraits {
use_on_device();
}
KOKKOS_FUNCTION void operator()(ReciprocalOverflowThreshold, int,
int& e) const {
using Kokkos::Experimental::reciprocal_overflow_threshold;
auto const inv = 1 / reciprocal_overflow_threshold<T>::value;
if (inv + inv == inv && inv != 0) {
KOKKOS_IMPL_DO_NOT_USE_PRINTF(
"inverse of reciprocal overflow threshold is inf\n");
++e;
}
use_on_device();
}
// clang-format off
KOKKOS_FUNCTION void operator()(FiniteMax, int, int&) const { use_on_device(); }
KOKKOS_FUNCTION void operator()(RoundError, int, int&) const { use_on_device(); }
KOKKOS_FUNCTION void operator()(NormMin, int, int&) const { use_on_device(); }
KOKKOS_FUNCTION void operator()(DenormMin, int, int&) const { use_on_device(); }
KOKKOS_FUNCTION void operator()(Digits, int, int&) const { use_on_device(); }
KOKKOS_FUNCTION void operator()(Digits10, int, int&) const { use_on_device(); }
KOKKOS_FUNCTION void operator()(MaxDigits10, int, int&) const { use_on_device(); }
@ -162,6 +179,30 @@ struct TestNumericTraits {
KOKKOS_FUNCTION void operator()(MinExponent10, int, int&) const { use_on_device(); }
KOKKOS_FUNCTION void operator()(MaxExponent10, int, int&) const { use_on_device(); }
// clang-format on
KOKKOS_FUNCTION void operator()(QuietNaN, int, int& e) const {
#ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC
using Kokkos::Experimental::quiet_NaN;
constexpr auto nan = quiet_NaN<T>::value;
constexpr auto zero = T(0);
e += (int)!(nan != nan);
e += (int)!(nan != zero);
#else
(void)e;
#endif
use_on_device();
}
KOKKOS_FUNCTION void operator()(SignalingNaN, int, int& e) const {
#ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC
using Kokkos::Experimental::signaling_NaN;
constexpr auto nan = signaling_NaN<T>::value;
constexpr auto zero = T(0);
e += (int)!(nan != nan);
e += (int)!(nan != zero);
#else
(void)e;
#endif
use_on_device();
}
KOKKOS_FUNCTION void use_on_device() const {
#if defined(KOKKOS_COMPILER_NVCC) || defined(KOKKOS_ENABLE_OPENMPTARGET)
@ -196,6 +237,11 @@ struct TestNumericTraits<
};
#endif
#ifdef KOKKOS_COMPILER_NVHPC
// warning: 'long double' is treated as 'double' in device code
#pragma diag_suppress 20208
#endif
TEST(TEST_CATEGORY, numeric_traits_infinity) {
TestNumericTraits<TEST_EXECSPACE, float, Infinity>();
TestNumericTraits<TEST_EXECSPACE, double, Infinity>();
@ -224,6 +270,18 @@ TEST(TEST_CATEGORY, numeric_traits_norm_min) {
TestNumericTraits<TEST_EXECSPACE, long double, NormMin>();
}
TEST(TEST_CATEGORY, numeric_traits_denorm_min) {
TestNumericTraits<TEST_EXECSPACE, float, DenormMin>();
TestNumericTraits<TEST_EXECSPACE, double, DenormMin>();
TestNumericTraits<TEST_EXECSPACE, long double, DenormMin>();
}
TEST(TEST_CATEGORY, numeric_traits_reciprocal_overflow_threshold) {
TestNumericTraits<TEST_EXECSPACE, float, ReciprocalOverflowThreshold>();
TestNumericTraits<TEST_EXECSPACE, double, ReciprocalOverflowThreshold>();
TestNumericTraits<TEST_EXECSPACE, long double, ReciprocalOverflowThreshold>();
}
TEST(TEST_CATEGORY, numeric_traits_finite_min_max) {
TestNumericTraits<TEST_EXECSPACE, char, FiniteMin>();
TestNumericTraits<TEST_EXECSPACE, char, FiniteMax>();
@ -338,6 +396,15 @@ TEST(TEST_CATEGORY, numeric_traits_min_max_exponent10) {
TestNumericTraits<TEST_EXECSPACE, long double, MaxExponent10>();
}
TEST(TEST_CATEGORY, numeric_traits_quiet_and_signaling_nan) {
TestNumericTraits<TEST_EXECSPACE, float, QuietNaN>();
TestNumericTraits<TEST_EXECSPACE, float, SignalingNaN>();
TestNumericTraits<TEST_EXECSPACE, double, QuietNaN>();
TestNumericTraits<TEST_EXECSPACE, double, SignalingNaN>();
TestNumericTraits<TEST_EXECSPACE, long double, QuietNaN>();
TestNumericTraits<TEST_EXECSPACE, long double, SignalingNaN>();
}
namespace NumericTraitsSFINAE {
struct HasNoSpecialization {};
@ -355,6 +422,9 @@ CHECK_TRAIT_IS_SFINAE_FRIENDLY(finite_max)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(epsilon)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(round_error)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(norm_min)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(denorm_min)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(quiet_NaN)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(signaling_NaN)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(digits)
CHECK_TRAIT_IS_SFINAE_FRIENDLY(digits10)
@ -417,6 +487,11 @@ CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, epsilon);
CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, round_error);
CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, round_error);
CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, round_error);
CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, denorm_min);
CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, denorm_min);
CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, denorm_min);
// NOTE reciprocal_overflow_threshold purposefully omitted since it does not
// exist in std::numeric_limits
// clang-format off
static_assert(Kokkos::Experimental::norm_min<float >::value == std::numeric_limits< float>::min(), "");
static_assert(Kokkos::Experimental::norm_min<double >::value == std::numeric_limits< double>::min(), "");
@ -516,3 +591,108 @@ CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT(long double, max_exponent10);
#undef CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION
#undef CHECK_SAME_AS_NUMERIC_LIMITS_MEMBER_CONSTANT
#define CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(T, TRAIT) \
static_assert(Kokkos::Experimental::TRAIT<T>::value != \
Kokkos::Experimental::TRAIT<T>::value, \
""); \
static_assert( \
std::numeric_limits<T>::TRAIT() != std::numeric_limits<T>::TRAIT(), ""); \
static_assert(Kokkos::Experimental::TRAIT<T>::value != \
std::numeric_limits<T>::TRAIT(), \
"")
// Workaround compiler issue error: expression must have a constant value
// See kokkos/kokkos#4574
#ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC
CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, quiet_NaN);
CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, quiet_NaN);
CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, quiet_NaN);
CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(float, signaling_NaN);
CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(double, signaling_NaN);
CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION(long double, signaling_NaN);
#endif
#undef CHECK_NAN_SAME_AS_NUMERIC_LIMITS_MEMBER_FUNCTION
#define CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(T, TRAIT) \
static_assert(Kokkos::Experimental::TRAIT<T const>::value == \
Kokkos::Experimental::TRAIT<T>::value, \
""); \
static_assert(Kokkos::Experimental::TRAIT<T volatile>::value == \
Kokkos::Experimental::TRAIT<T>::value, \
""); \
static_assert(Kokkos::Experimental::TRAIT<T const volatile>::value == \
Kokkos::Experimental::TRAIT<T>::value, \
"")
#define CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(TRAIT) \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(float, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(double, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long double, TRAIT)
#define CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(TRAIT) \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(bool, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(char, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(signed char, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned char, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(short, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned short, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(int, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned int, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long int, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned long int, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long long int, TRAIT); \
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES(unsigned long long int, TRAIT)
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(infinity);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(finite_min);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(finite_min);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(finite_max);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(finite_max);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(epsilon);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(round_error);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(norm_min);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(
reciprocal_overflow_threshold);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(digits);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(digits);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(digits10);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(digits10);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(max_digits10);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(radix);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL(radix);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(min_exponent);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(min_exponent10);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(max_exponent);
CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(max_exponent10);
#undef CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_INTEGRAL
#undef CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT
#undef CHECK_INSTANTIATED_ON_CV_QUALIFIED_TYPES
#define CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(T, TRAIT) \
static_assert(Kokkos::Experimental::TRAIT<T>::value != \
Kokkos::Experimental::TRAIT<T>::value, \
""); \
static_assert(Kokkos::Experimental::TRAIT<T const>::value != \
Kokkos::Experimental::TRAIT<T>::value, \
""); \
static_assert(Kokkos::Experimental::TRAIT<T volatile>::value != \
Kokkos::Experimental::TRAIT<T>::value, \
""); \
static_assert(Kokkos::Experimental::TRAIT<T const volatile>::value != \
Kokkos::Experimental::TRAIT<T>::value, \
"")
#define CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(TRAIT) \
CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(float, TRAIT); \
CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(double, TRAIT); \
CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES(long double, TRAIT)
CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(quiet_NaN);
CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT(signaling_NaN);
#undef CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES_FLOATING_POINT
#undef CHECK_NAN_INSTANTIATED_ON_CV_QUALIFIED_TYPES

View File

@ -50,5 +50,8 @@
#include <TestCXX11.hpp>
#include <TestViewCtorPropEmbeddedDim.hpp>
// with VS 16.11.3 and CUDA 11.4.2 getting cudafe stackoverflow crash
#if !(defined(_WIN32) && defined(KOKKOS_ENABLE_CUDA))
#include <TestViewLayoutTiled.hpp>
#endif
#endif

View File

@ -288,37 +288,42 @@ class TestRangePolicyConstruction {
}
}
void test_runtime_parameters() {
using policy_t = Kokkos::RangePolicy<>;
using policy_t = Kokkos::RangePolicy<>;
using index_t = policy_t::index_type;
index_t work_begin = 5;
index_t work_end = 15;
index_t chunk_size = 10;
{
policy_t p(5, 15);
ASSERT_EQ(p.begin(), 5);
ASSERT_EQ(p.end(), 15);
policy_t p(work_begin, work_end);
ASSERT_EQ(p.begin(), work_begin);
ASSERT_EQ(p.end(), work_end);
}
{
policy_t p(Kokkos::DefaultExecutionSpace(), 5, 15);
ASSERT_EQ(p.begin(), 5);
ASSERT_EQ(p.end(), 15);
policy_t p(Kokkos::DefaultExecutionSpace(), work_begin, work_end);
ASSERT_EQ(p.begin(), work_begin);
ASSERT_EQ(p.end(), work_end);
}
{
policy_t p(5, 15, Kokkos::ChunkSize(10));
ASSERT_EQ(p.begin(), 5);
ASSERT_EQ(p.end(), 15);
ASSERT_EQ(p.chunk_size(), 10);
policy_t p(work_begin, work_end, Kokkos::ChunkSize(chunk_size));
ASSERT_EQ(p.begin(), work_begin);
ASSERT_EQ(p.end(), work_end);
ASSERT_EQ(p.chunk_size(), chunk_size);
}
{
policy_t p(Kokkos::DefaultExecutionSpace(), 5, 15, Kokkos::ChunkSize(10));
ASSERT_EQ(p.begin(), 5);
ASSERT_EQ(p.end(), 15);
ASSERT_EQ(p.chunk_size(), 10);
policy_t p(Kokkos::DefaultExecutionSpace(), work_begin, work_end,
Kokkos::ChunkSize(chunk_size));
ASSERT_EQ(p.begin(), work_begin);
ASSERT_EQ(p.end(), work_end);
ASSERT_EQ(p.chunk_size(), chunk_size);
}
{
policy_t p;
ASSERT_EQ(p.begin(), 0);
ASSERT_EQ(p.end(), 0);
p = policy_t(5, 15, Kokkos::ChunkSize(10));
ASSERT_EQ(p.begin(), 5);
ASSERT_EQ(p.end(), 15);
ASSERT_EQ(p.chunk_size(), 10);
ASSERT_EQ(p.begin(), index_t(0));
ASSERT_EQ(p.end(), index_t(0));
p = policy_t(work_begin, work_end, Kokkos::ChunkSize(chunk_size));
ASSERT_EQ(p.begin(), work_begin);
ASSERT_EQ(p.end(), work_end);
ASSERT_EQ(p.chunk_size(), chunk_size);
}
}
};
@ -580,88 +585,85 @@ class TestTeamPolicyConstruction {
policy_t p1(league_size, team_size);
ASSERT_EQ(p1.league_size(), league_size);
ASSERT_EQ(p1.team_size(), team_size);
// FIXME_SYCL implement chunk_size
#ifndef KOKKOS_ENABLE_SYCL
ASSERT_GT(p1.chunk_size(), 0);
#endif
ASSERT_EQ(p1.scratch_size(0), 0);
ASSERT_EQ(size_t(p1.scratch_size(0)), 0u);
policy_t p2 = p1.set_chunk_size(chunk_size);
ASSERT_EQ(p1.league_size(), league_size);
ASSERT_EQ(p1.team_size(), team_size);
ASSERT_EQ(p1.chunk_size(), chunk_size);
ASSERT_EQ(p1.scratch_size(0), 0);
ASSERT_EQ(size_t(p1.scratch_size(0)), 0u);
ASSERT_EQ(p2.league_size(), league_size);
ASSERT_EQ(p2.team_size(), team_size);
ASSERT_EQ(p2.chunk_size(), chunk_size);
ASSERT_EQ(p2.scratch_size(0), 0);
ASSERT_EQ(size_t(p2.scratch_size(0)), 0u);
policy_t p3 = p2.set_scratch_size(0, Kokkos::PerTeam(per_team_scratch));
ASSERT_EQ(p2.league_size(), league_size);
ASSERT_EQ(p2.team_size(), team_size);
ASSERT_EQ(p2.chunk_size(), chunk_size);
ASSERT_EQ(p2.scratch_size(0), per_team_scratch);
ASSERT_EQ(size_t(p2.scratch_size(0)), size_t(per_team_scratch));
ASSERT_EQ(p3.league_size(), league_size);
ASSERT_EQ(p3.team_size(), team_size);
ASSERT_EQ(p3.chunk_size(), chunk_size);
ASSERT_EQ(p3.scratch_size(0), per_team_scratch);
ASSERT_EQ(size_t(p3.scratch_size(0)), size_t(per_team_scratch));
policy_t p4 = p2.set_scratch_size(0, Kokkos::PerThread(per_thread_scratch));
ASSERT_EQ(p2.league_size(), league_size);
ASSERT_EQ(p2.team_size(), team_size);
ASSERT_EQ(p2.chunk_size(), chunk_size);
ASSERT_EQ(p2.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p2.scratch_size(0)), size_t(scratch_size));
ASSERT_EQ(p4.league_size(), league_size);
ASSERT_EQ(p4.team_size(), team_size);
ASSERT_EQ(p4.chunk_size(), chunk_size);
ASSERT_EQ(p4.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p4.scratch_size(0)), size_t(scratch_size));
policy_t p5 = p2.set_scratch_size(0, Kokkos::PerThread(per_thread_scratch),
Kokkos::PerTeam(per_team_scratch));
ASSERT_EQ(p2.league_size(), league_size);
ASSERT_EQ(p2.team_size(), team_size);
ASSERT_EQ(p2.chunk_size(), chunk_size);
ASSERT_EQ(p2.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p2.scratch_size(0)), size_t(scratch_size));
ASSERT_EQ(p5.league_size(), league_size);
ASSERT_EQ(p5.team_size(), team_size);
ASSERT_EQ(p5.chunk_size(), chunk_size);
ASSERT_EQ(p5.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p5.scratch_size(0)), size_t(scratch_size));
policy_t p6 = p2.set_scratch_size(0, Kokkos::PerTeam(per_team_scratch),
Kokkos::PerThread(per_thread_scratch));
ASSERT_EQ(p2.league_size(), league_size);
ASSERT_EQ(p2.team_size(), team_size);
ASSERT_EQ(p2.chunk_size(), chunk_size);
ASSERT_EQ(p2.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p2.scratch_size(0)), size_t(scratch_size));
ASSERT_EQ(p6.league_size(), league_size);
ASSERT_EQ(p6.team_size(), team_size);
ASSERT_EQ(p6.chunk_size(), chunk_size);
ASSERT_EQ(p6.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p6.scratch_size(0)), size_t(scratch_size));
policy_t p7 = p3.set_scratch_size(0, Kokkos::PerTeam(per_team_scratch),
Kokkos::PerThread(per_thread_scratch));
ASSERT_EQ(p3.league_size(), league_size);
ASSERT_EQ(p3.team_size(), team_size);
ASSERT_EQ(p3.chunk_size(), chunk_size);
ASSERT_EQ(p3.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p3.scratch_size(0)), size_t(scratch_size));
ASSERT_EQ(p7.league_size(), league_size);
ASSERT_EQ(p7.team_size(), team_size);
ASSERT_EQ(p7.chunk_size(), chunk_size);
ASSERT_EQ(p7.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p7.scratch_size(0)), size_t(scratch_size));
policy_t p8; // default constructed
ASSERT_EQ(p8.league_size(), 0);
ASSERT_EQ(p8.scratch_size(0), 0);
ASSERT_EQ(size_t(p8.scratch_size(0)), 0u);
p8 = p3; // call assignment operator
ASSERT_EQ(p3.league_size(), league_size);
ASSERT_EQ(p3.team_size(), team_size);
ASSERT_EQ(p3.chunk_size(), chunk_size);
ASSERT_EQ(p3.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p3.scratch_size(0)), size_t(scratch_size));
ASSERT_EQ(p8.league_size(), league_size);
ASSERT_EQ(p8.team_size(), team_size);
ASSERT_EQ(p8.chunk_size(), chunk_size);
ASSERT_EQ(p8.scratch_size(0), scratch_size);
ASSERT_EQ(size_t(p8.scratch_size(0)), size_t(scratch_size));
}
void test_run_time_parameters() {
@ -716,6 +718,7 @@ TEST(TEST_CATEGORY, policy_converting_constructor_from_other_policy) {
Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>>{});
}
#ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC
#ifndef KOKKOS_ENABLE_OPENMPTARGET // FIXME_OPENMPTARGET
TEST(TEST_CATEGORY_DEATH, policy_bounds_unsafe_narrowing_conversions) {
using Policy = Kokkos::MDRangePolicy<TEST_EXECSPACE, Kokkos::Rank<2>,
@ -729,6 +732,7 @@ TEST(TEST_CATEGORY_DEATH, policy_bounds_unsafe_narrowing_conversions) {
"unsafe narrowing conversion");
}
#endif
#endif
template <class Policy>
void test_prefer_desired_occupancy(Policy const& policy) {
@ -790,6 +794,8 @@ struct static_assert_dummy_policy_must_be_size_of_desired_occupancy<
sizeof(Kokkos::Experimental::DesiredOccupancy),
sizeof(Kokkos::Experimental::DesiredOccupancy)> {};
// EBO failure with VS 16.11.3 and CUDA 11.4.2
#if !(defined(_WIN32) && defined(KOKKOS_ENABLE_CUDA))
TEST(TEST_CATEGORY, desired_occupancy_empty_base_optimization) {
DummyPolicy<TEST_EXECSPACE> const policy{};
static_assert(sizeof(decltype(policy)) == 1, "");
@ -807,6 +813,7 @@ TEST(TEST_CATEGORY, desired_occupancy_empty_base_optimization) {
_assert2{};
(void)&_assert2; // avoid unused variable warning
}
#endif
template <typename Policy>
void test_desired_occupancy_converting_constructors(Policy const& policy) {

View File

@ -0,0 +1,164 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#ifndef TESTREALLOC_HPP_
#define TESTREALLOC_HPP_
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
namespace TestViewRealloc {
struct Default {};
struct WithoutInitializing {};
template <typename View, typename... Args>
inline void realloc_dispatch(Default, View& v, Args&&... args) {
Kokkos::realloc(v, std::forward<Args>(args)...);
}
template <typename View, typename... Args>
inline void realloc_dispatch(WithoutInitializing, View& v, Args&&... args) {
Kokkos::realloc(Kokkos::WithoutInitializing, v, std::forward<Args>(args)...);
}
template <class DeviceType, class Tag = Default>
void impl_testRealloc() {
const size_t sizes[8] = {2, 3, 4, 5, 6, 7, 8, 9};
// Check #904 fix (no reallocation if dimensions didn't change).
{
using view_type = Kokkos::View<int*, DeviceType>;
view_type view_1d("view_1d", sizes[0]);
const int* oldPointer = view_1d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_1d, sizes[0]);
const int* newPointer = view_1d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
{
using view_type = Kokkos::View<int**, DeviceType>;
view_type view_2d("view_2d", sizes[0], sizes[1]);
const int* oldPointer = view_2d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_2d, sizes[0], sizes[1]);
const int* newPointer = view_2d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
{
using view_type = Kokkos::View<int***, DeviceType>;
view_type view_3d("view_3d", sizes[0], sizes[1], sizes[2]);
const int* oldPointer = view_3d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_3d, sizes[0], sizes[1], sizes[2]);
const int* newPointer = view_3d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
{
using view_type = Kokkos::View<int****, DeviceType>;
view_type view_4d("view_4d", sizes[0], sizes[1], sizes[2], sizes[3]);
const int* oldPointer = view_4d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_4d, sizes[0], sizes[1], sizes[2], sizes[3]);
const int* newPointer = view_4d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
{
using view_type = Kokkos::View<int*****, DeviceType>;
view_type view_5d("view_5d", sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4]);
const int* oldPointer = view_5d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_5d, sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4]);
const int* newPointer = view_5d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
{
using view_type = Kokkos::View<int******, DeviceType>;
view_type view_6d("view_6d", sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4], sizes[5]);
const int* oldPointer = view_6d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_6d, sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4], sizes[5]);
const int* newPointer = view_6d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
{
using view_type = Kokkos::View<int*******, DeviceType>;
view_type view_7d("view_7d", sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4], sizes[5], sizes[6]);
const int* oldPointer = view_7d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_7d, sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4], sizes[5], sizes[6]);
const int* newPointer = view_7d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
{
using view_type = Kokkos::View<int********, DeviceType>;
view_type view_8d("view_8d", sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4], sizes[5], sizes[6], sizes[7]);
const int* oldPointer = view_8d.data();
EXPECT_TRUE(oldPointer != nullptr);
realloc_dispatch(Tag{}, view_8d, sizes[0], sizes[1], sizes[2], sizes[3],
sizes[4], sizes[5], sizes[6], sizes[7]);
const int* newPointer = view_8d.data();
EXPECT_TRUE(oldPointer == newPointer);
}
}
template <class DeviceType>
void testRealloc() {
{
impl_testRealloc<DeviceType>(); // with data initialization
}
{
impl_testRealloc<DeviceType,
WithoutInitializing>(); // without data initialization
}
}
} // namespace TestViewRealloc
#endif // TESTREALLOC_HPP_

View File

@ -520,6 +520,7 @@ class TestReduceDynamicView {
// Test result to host pointer:
std::string str("TestKernelReduce");
#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_3
if (count % 2 == 0) {
Kokkos::parallel_reduce(nw, functor_type(nw, count),
host_result.data());
@ -528,6 +529,20 @@ class TestReduceDynamicView {
host_result.data());
}
for (unsigned j = 0; j < count; ++j) {
const uint64_t correct = 0 == j % 3 ? nw : nsum;
ASSERT_EQ(host_result(j), (ScalarType)correct);
host_result(j) = 0;
}
#endif
if (count % 2 == 0) {
Kokkos::parallel_reduce(nw, functor_type(nw, count), host_result);
} else {
Kokkos::parallel_reduce(str, nw, functor_type(nw, count), host_result);
}
Kokkos::fence("Fence before accessing result on the host");
for (unsigned j = 0; j < count; ++j) {
const uint64_t correct = 0 == j % 3 ? nw : nsum;
ASSERT_EQ(host_result(j), (ScalarType)correct);
@ -539,10 +554,12 @@ class TestReduceDynamicView {
} // namespace
// FIXME_SYCL
// FIXME_OPENMPTARGET : The feature works with LLVM/13 on NVIDIA
// architectures. The jenkins currently tests with LLVM/12.
#if defined(KOKKOS_ENABLE_OPENMPTARGET) && defined(KOKKOS_COMPILER_CLANG) && \
(KOKKOS_COMPILER_CLANG >= 1300)
#if !defined(KOKKOS_ENABLE_SYCL) && \
(!defined(KOKKOS_ENABLE_OPENMPTARGET) || \
defined(KOKKOS_COMPILER_CLANG) && (KOKKOS_COMPILER_CLANG >= 1300))
TEST(TEST_CATEGORY, int64_t_reduce) {
TestReduce<int64_t, TEST_EXECSPACE>(0);
TestReduce<int64_t, TEST_EXECSPACE>(1000000);
@ -585,9 +602,9 @@ TEST(TEST_CATEGORY, int_combined_reduce) {
Kokkos::RangePolicy<TEST_EXECSPACE>(0, nw),
functor_type(nw), result1, result2, result3);
ASSERT_EQ(nw, result1);
ASSERT_EQ(nsum, result2);
ASSERT_EQ(nsum, result3);
ASSERT_EQ(nw, uint64_t(result1));
ASSERT_EQ(nsum, uint64_t(result2));
ASSERT_EQ(nsum, uint64_t(result3));
}
TEST(TEST_CATEGORY, mdrange_combined_reduce) {
@ -606,9 +623,9 @@ TEST(TEST_CATEGORY, mdrange_combined_reduce) {
{{nw, 1, 1}}),
functor_type(nw), result1, result2, result3);
ASSERT_EQ(nw, result1);
ASSERT_EQ(nsum, result2);
ASSERT_EQ(nsum, result3);
ASSERT_EQ(nw, uint64_t(result1));
ASSERT_EQ(nsum, uint64_t(result2));
ASSERT_EQ(nsum, uint64_t(result3));
}
TEST(TEST_CATEGORY, int_combined_reduce_mixed) {
@ -629,9 +646,9 @@ TEST(TEST_CATEGORY, int_combined_reduce_mixed) {
functor_type(nw), result1_v, result2,
Kokkos::Sum<int64_t, Kokkos::HostSpace>{result3_v});
ASSERT_EQ(nw, result1_v());
ASSERT_EQ(nsum, result2);
ASSERT_EQ(nsum, result3_v());
ASSERT_EQ(int64_t(nw), result1_v());
ASSERT_EQ(int64_t(nsum), result2);
ASSERT_EQ(int64_t(nsum), result3_v());
}
#endif
} // namespace Test

View File

@ -314,10 +314,7 @@ struct TestReducers {
Kokkos::parallel_reduce(Kokkos::RangePolicy<ExecSpace>(0, 0), f,
reducer_scalar);
// Zero length reduction not yet supported
#ifndef KOKKOS_ENABLE_OPENMPTARGET
ASSERT_EQ(sum_scalar, init);
#endif
Kokkos::parallel_reduce(Kokkos::RangePolicy<ExecSpace>(0, N), f,
reducer_scalar);
@ -340,10 +337,7 @@ struct TestReducers {
reducer_view);
Kokkos::fence();
Scalar sum_view_scalar = sum_view();
// Zero length reduction not yet supported
#ifndef KOKKOS_ENABLE_OPENMPTARGET
ASSERT_EQ(sum_view_scalar, init);
#endif
Kokkos::parallel_reduce(Kokkos::RangePolicy<ExecSpace>(0, N), f,
reducer_view);
@ -355,8 +349,6 @@ struct TestReducers {
ASSERT_EQ(sum_view_view, reference_sum);
}
// Reduction to device view not yet supported
#ifndef KOKKOS_ENABLE_OPENMPTARGET
{
Kokkos::View<Scalar, typename ExecSpace::memory_space> sum_view("View");
Kokkos::deep_copy(sum_view, Scalar(1));
@ -375,7 +367,6 @@ struct TestReducers {
Kokkos::deep_copy(sum_view_scalar, sum_view);
ASSERT_EQ(sum_view_scalar, reference_sum);
}
#endif
}
static void test_prod(int N) {
@ -400,10 +391,7 @@ struct TestReducers {
Kokkos::Prod<Scalar> reducer_scalar(prod_scalar);
Kokkos::parallel_reduce(Kokkos::RangePolicy<ExecSpace>(0, 0), f,
reducer_scalar);
// Zero length reduction not yet supported
#ifndef KOKKOS_ENABLE_OPENMPTARGET
ASSERT_EQ(prod_scalar, init);
#endif
Kokkos::parallel_reduce(Kokkos::RangePolicy<ExecSpace>(0, N), f,
reducer_scalar);
@ -426,10 +414,7 @@ struct TestReducers {
reducer_view);
Kokkos::fence();
Scalar prod_view_scalar = prod_view();
// Zero length reduction not yet supported
#ifndef KOKKOS_ENABLE_OPENMPTARGET
ASSERT_EQ(prod_view_scalar, init);
#endif
Kokkos::parallel_reduce(Kokkos::RangePolicy<ExecSpace>(0, N), f,
reducer_view);
@ -441,8 +426,6 @@ struct TestReducers {
ASSERT_EQ(prod_view_view, reference_prod);
}
// Reduction to device view not yet supported
#ifndef KOKKOS_ENABLE_OPENMPTARGET
{
Kokkos::View<Scalar, typename ExecSpace::memory_space> prod_view("View");
Kokkos::deep_copy(prod_view, Scalar(0));
@ -461,7 +444,6 @@ struct TestReducers {
Kokkos::deep_copy(prod_view_scalar, prod_view);
ASSERT_EQ(prod_view_scalar, reference_prod);
}
#endif
}
static void test_min(int N) {
@ -1016,10 +998,10 @@ struct TestReducers {
test_minloc(10003);
test_max(10007);
test_maxloc(10007);
// FIXME_OPENMPTARGET - The minmaxloc test fails in the Release and
// RelWithDebInfo builds for the OPENMPTARGET backend but passes in Debug
// mode.
#if !defined(KOKKOS_ENABLE_OPENMPTARGET)
#if defined(KOKKOS_ENABLE_OPENMPTARGET) && defined(KOKKOS_COMPILER_CLANG) && \
(KOKKOS_COMPILER_CLANG < 1300)
// FIXME_OPENMPTARGET - The minmaxloc test fails llvm <= 13 version.
#else
test_minmaxloc(10007);
#endif
}
@ -1034,10 +1016,10 @@ struct TestReducers {
test_minloc(10003);
test_max(10007);
test_maxloc(10007);
// FIXME_OPENMPTARGET - The minmaxloc test fails in the Release and
// RelWithDebInfo builds for the OPENMPTARGET backend but passes in Debug
// mode.
#if !defined(KOKKOS_ENABLE_OPENMPTARGET)
#if defined(KOKKOS_ENABLE_OPENMPTARGET) && defined(KOKKOS_COMPILER_CLANG) && \
(KOKKOS_COMPILER_CLANG < 1300)
// FIXME_OPENMPTARGET - The minmaxloc test fails llvm <= 13 version.
#else
test_minmaxloc(10007);
#endif
test_BAnd(35);
@ -1050,6 +1032,11 @@ struct TestReducers {
test_sum(10001);
test_prod(35);
}
static void execute_bool() {
test_LAnd(10001);
test_LOr(35);
}
};
} // namespace Test

View File

@ -79,6 +79,52 @@ TEST(TEST_CATEGORY, reducers_half_t) {
TestReducers<ThisTestType, TEST_EXECSPACE>::test_prod(25);
}
// TODO: File a bug report for this?
// This fails on the CUDA-11.0-NVCC-C++17-RDC CI check.
// TEST(TEST_CATEGORY, openmp_cuda11_reduction_bug_with_bhalf_t) {
// using ThisTestType = Kokkos::Experimental::bhalf_t;
// TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(50);
// TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(51);
// // For some reason commenting out reductions of 52,53,54,55 causes
// // the reduction of 56 to fail on OpenMP with Cuda/11.0
// //TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(52);
// //TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(53);
// //TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(54);
// //TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(55);
// TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(56);
//}
TEST(TEST_CATEGORY, reducers_bhalf_t) {
#if defined(KOKKOS_ENABLE_OPENMP)
if (!std::is_same<TEST_EXECSPACE, Kokkos::OpenMP>::value)
#else
if (true)
#endif // ENABLE_OPENMP
{
using ThisTestType = Kokkos::Experimental::bhalf_t;
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(2);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(50);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(51);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(52);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(53);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(54);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(55);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(56);
// TestReducers<ThisTestType, TEST_EXECSPACE>::test_sum(57);
// This could be 57 on device but there seems to be a loss of precision when
// running on OpenMP with Cuda/11.0
TestReducers<ThisTestType, TEST_EXECSPACE>::test_prod(5);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_prod(10);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_prod(15);
#if (CUDA_VERSION < 11000)
TestReducers<ThisTestType, TEST_EXECSPACE>::test_prod(20);
TestReducers<ThisTestType, TEST_EXECSPACE>::test_prod(21);
#endif
} else {
GTEST_SKIP();
}
}
TEST(TEST_CATEGORY, reducers_int8_t) {
using ThisTestType = int8_t;

View File

@ -0,0 +1,52 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <TestReducers.hpp>
namespace Test {
TEST(TEST_CATEGORY, reducers_bool) {
TestReducers<bool, TEST_EXECSPACE>::execute_bool();
}
} // namespace Test

View File

@ -54,6 +54,11 @@ void test_reduce_device_view(int64_t N, PolicyType policy,
Kokkos::deep_copy(reducer_result, result);
Kokkos::deep_copy(result, 0);
ASSERT_EQ(N, reducer_result);
// We need a warm-up to get reasonable results
Kokkos::parallel_reduce("Test::ReduceDeviceView::TestView", policy, functor,
result);
Kokkos::fence();
timer.reset();
// Test View

View File

@ -65,7 +65,6 @@ struct SharedAllocDestroy {
template <class MemorySpace, class ExecutionSpace>
void test_shared_alloc() {
#if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
using Header = const Kokkos::Impl::SharedAllocationHeader;
using Tracker = Kokkos::Impl::SharedAllocationTracker;
using RecordBase = Kokkos::Impl::SharedAllocationRecord<void, void>;
@ -91,16 +90,16 @@ void test_shared_alloc() {
{
// Since always executed on host space, leave [=]
Kokkos::parallel_for(range, [=](size_t i) {
Kokkos::parallel_for(range, [=](int i) {
char name[64];
sprintf(name, "test_%.2d", int(i));
sprintf(name, "test_%.2d", 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]);
for (int 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()));
@ -115,14 +114,18 @@ void test_shared_alloc() {
// RecordMemS::print_records( std::cout, s, true );
#endif
Kokkos::parallel_for(range, [=](size_t i) {
// This must be a plain for-loop since deallocation (which can be triggered
// by RecordBase::decrement) fences all execution space instances. If this
// is a parallel_for, the test can hang with the parallel_for blocking
// waiting for itself to complete.
for (size_t i = range.begin(); i < range.end(); ++i) {
while (nullptr !=
(r[i] = static_cast<RecordMemS*>(RecordBase::decrement(r[i])))) {
#ifdef KOKKOS_ENABLE_DEBUG
if (r[i]->use_count() == 1) RecordBase::is_sane(r[i]);
#endif
}
});
}
Kokkos::fence();
}
@ -146,7 +149,7 @@ void test_shared_alloc() {
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]->use_count(), int((i / 10) + 1));
ASSERT_EQ(r[i], RecordMemS::get_record(r[i]->data()));
});
@ -156,14 +159,18 @@ void test_shared_alloc() {
RecordBase::is_sane(r[0]);
#endif
Kokkos::parallel_for(range, [=](size_t i) {
// This must be a plain for-loop since deallocation (which can be triggered
// by RecordBase::decrement) fences all execution space instances. If this
// is a parallel_for, the test can hang with the parallel_for blocking
// waiting for itself to complete.
for (size_t i = range.begin(); i < range.end(); ++i) {
while (nullptr !=
(r[i] = static_cast<RecordMemS*>(RecordBase::decrement(r[i])))) {
#ifdef KOKKOS_ENABLE_DEBUG
if (r[i]->use_count() == 1) RecordBase::is_sane(r[i]);
#endif
}
});
}
Kokkos::fence();
@ -223,8 +230,6 @@ void test_shared_alloc() {
ASSERT_EQ(destroy_count, 1);
}
#endif /* #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) */
}
TEST(TEST_CATEGORY, impl_shared_alloc) {

View File

@ -465,8 +465,9 @@ class TestScanTeam {
functor_type functor;
policy_type team_exec(nteam, 1);
team_exec = policy_type(
nteam, team_exec.team_size_max(functor, Kokkos::ParallelReduceTag()));
const auto team_size =
team_exec.team_size_max(functor, Kokkos::ParallelReduceTag());
team_exec = policy_type(nteam, team_size);
for (unsigned i = 0; i < Repeat; ++i) {
int64_t accum = 0;
@ -807,6 +808,13 @@ struct TestScratchTeam {
Functor(), result_type(&error_count));
Kokkos::fence();
ASSERT_EQ(error_count, 0);
Kokkos::parallel_reduce(
team_exec.set_scratch_size(1, Kokkos::PerTeam(team_scratch_size),
Kokkos::PerThread(thread_scratch_size)),
Functor(), Kokkos::Sum<typename Functor::value_type>(error_count));
Kokkos::fence();
ASSERT_EQ(error_count, 0);
}
};
@ -1530,7 +1538,7 @@ struct TestScratchAlignment {
.set_scratch_size(0, Kokkos::PerTeam(shmem_size)),
KOKKOS_LAMBDA(
const typename Kokkos::TeamPolicy<ExecSpace>::member_type &team) {
if (allocate_small) ScratchViewInt p(team.team_scratch(0), 1);
if (allocate_small) ScratchViewInt(team.team_scratch(0), 1);
ScratchView a(team.team_scratch(0), 11);
if (ptrdiff_t(a.data()) % sizeof(TestScalar) != 0)
Kokkos::abort("Error: invalid scratch view alignment\n");

View File

@ -83,6 +83,37 @@ TEST(TEST_CATEGORY, team_reduce) {
}
#endif
template <typename ExecutionSpace>
struct TestTeamReduceLarge {
using team_policy_t = Kokkos::TeamPolicy<ExecutionSpace>;
using member_t = typename team_policy_t::member_type;
int m_range;
TestTeamReduceLarge(const int range) : m_range(range) {}
KOKKOS_INLINE_FUNCTION
void operator()(const member_t& t, int& update) const {
Kokkos::single(Kokkos::PerTeam(t), [&]() { update++; });
}
void run() {
int result = 0;
Kokkos::parallel_reduce(team_policy_t(m_range, Kokkos::AUTO), *this,
result);
EXPECT_EQ(m_range, result);
}
};
TEST(TEST_CATEGORY, team_reduce_large) {
std::vector<int> ranges{(2LU << 23) - 1, 2LU << 23, (2LU << 24),
(2LU << 24) + 1, 1LU << 29};
for (const auto range : ranges) {
TestTeamReduceLarge<TEST_EXECSPACE> test(range);
test.run();
}
}
TEST(TEST_CATEGORY, team_broadcast_long) {
TestTeamBroadcast<TEST_EXECSPACE, Kokkos::Schedule<Kokkos::Static>,
long>::test_teambroadcast(0, 1);

View File

@ -49,28 +49,6 @@
#include <sstream>
#include <type_traits>
#if defined(__clang__)
#define is_clang true
#else
#define is_clang false
#endif
#if !defined(KOKKOS_ENABLE_OPENMPTARGET)
// for avoid pre-processor block
namespace Kokkos {
namespace Experimental {
class OpenMPTarget;
}
} // namespace Kokkos
#endif
#if !defined(KOKKOS_ENABLE_CUDA)
// for avoid pre-processor block
namespace Kokkos {
class Cuda;
} // namespace Kokkos
#endif
namespace Test {
template <class ExecutionSpace, class DataType>
@ -105,9 +83,11 @@ struct TestTeamScan {
}
auto operator()(int32_t _M, int32_t _N) {
std::cout << "Launching " << Kokkos::Impl::demangle(typeid(*this).name())
<< " with "
<< "M=" << _M << " and N=" << _N << "..." << std::endl;
std::stringstream ss;
ss << Kokkos::Impl::demangle(typeid(*this).name());
ss << "(/*M=*/" << _M << ", /*N=*/" << _N << ")";
std::string const test_id = ss.str();
M = _M;
N = _N;
a_d = view_type("a_d", M, N);
@ -131,30 +111,32 @@ struct TestTeamScan {
Kokkos::deep_copy(a_o, a_r);
for (int32_t i = 0; i < M; ++i) {
value_type _scan_real = 0;
value_type _scan_calc = 0;
value_type _epsilon = std::numeric_limits<value_type>::epsilon();
value_type scan_ref = 0;
value_type scan_calc;
value_type abs_err = 0;
// each fp addition is subject to small loses in precision and these
// compound as loop so we set the base error to be the machine epsilon and
// then add in another epsilon each iteration. For example, with CUDA
// backend + 32-bit float + large N values (e.g. 1,000) + high
// thread-counts (e.g. 1024), this test will fail w/o epsilon
// accommodation
constexpr value_type epsilon = std::numeric_limits<value_type>::epsilon();
for (int32_t j = 0; j < N; ++j) {
_scan_real += a_i(i, j);
_scan_calc = a_o(i, j);
auto _get_mesg = [=]() {
std::stringstream ss, idx;
idx << "(" << i << ", " << j << ") = ";
ss << "a_d" << idx.str() << a_i(i, j);
ss << ", a_r" << idx.str() << a_o(i, j);
return ss.str();
};
scan_ref += a_i(i, j);
scan_calc = a_o(i, j);
if (std::is_integral<value_type>::value) {
ASSERT_EQ(_scan_real, _scan_calc) << _get_mesg();
ASSERT_EQ(scan_ref, scan_calc)
<< test_id
<< " calculated scan output value differs from reference at "
"indices i="
<< i << " and j=" << j;
} else {
_epsilon += std::numeric_limits<value_type>::epsilon();
ASSERT_NEAR(_scan_real, _scan_calc, _epsilon) << _get_mesg();
abs_err += epsilon;
ASSERT_NEAR(scan_ref, scan_calc, abs_err)
<< test_id
<< " calculated scan output value differs from reference at "
"indices i="
<< i << " and j=" << j;
}
}
}

View File

@ -182,27 +182,22 @@ TEST(TEST_CATEGORY, team_policy_max_recommended) {
}
template <typename TeamHandleType, typename ReducerValueType>
struct PrintFunctor1 {
KOKKOS_INLINE_FUNCTION void operator()(const TeamHandleType& team,
ReducerValueType&) const {
KOKKOS_IMPL_DO_NOT_USE_PRINTF("Test %i %i\n", int(team.league_rank()),
int(team.team_rank()));
struct MinMaxTeamLeagueRank {
KOKKOS_FUNCTION void operator()(const TeamHandleType& team,
ReducerValueType& update) const {
int const x = team.league_rank();
if (x < update.min_val) {
update.min_val = x;
}
if (x > update.max_val) {
update.max_val = x;
}
}
};
template <typename TeamHandleType, typename ReducerValueType>
struct PrintFunctor2 {
KOKKOS_INLINE_FUNCTION void operator()(const TeamHandleType& team,
ReducerValueType& teamVal) const {
KOKKOS_IMPL_DO_NOT_USE_PRINTF("Test %i %i\n", int(team.league_rank()),
int(team.team_rank()));
teamVal += 1;
}
};
TEST(TEST_CATEGORY, team_policy_max_scalar_without_plus_equal_k) {
TEST(TEST_CATEGORY, team_policy_minmax_scalar_without_plus_equal_k) {
using ExecSpace = TEST_EXECSPACE;
using ReducerType = Kokkos::MinMax<double, Kokkos::HostSpace>;
using ReducerType = Kokkos::MinMax<int, Kokkos::HostSpace>;
using ReducerValueType = typename ReducerType::value_type;
using DynamicScheduleType = Kokkos::Schedule<Kokkos::Dynamic>;
using TeamPolicyType = Kokkos::TeamPolicy<ExecSpace, DynamicScheduleType>;
@ -213,21 +208,11 @@ TEST(TEST_CATEGORY, team_policy_max_scalar_without_plus_equal_k) {
ReducerType reducer(val);
TeamPolicyType p(num_teams, Kokkos::AUTO);
PrintFunctor1<TeamHandleType, ReducerValueType> f1;
const int max_team_size =
p.team_size_max(f1, reducer, Kokkos::ParallelReduceTag());
const int recommended_team_size =
p.team_size_recommended(f1, reducer, Kokkos::ParallelReduceTag());
printf("Max TeamSize: %i Recommended TeamSize: %i\n", max_team_size,
recommended_team_size);
MinMaxTeamLeagueRank<TeamHandleType, ReducerValueType> f1;
Kokkos::parallel_reduce(p, f1, reducer);
double sum;
Kokkos::parallel_reduce(TeamPolicyType(num_teams, Kokkos::AUTO),
PrintFunctor2<TeamHandleType, double>{}, sum);
printf("Sum: %lf\n", sum);
ASSERT_EQ(val.min_val, 0);
ASSERT_EQ(val.max_val, num_teams - 1);
}
} // namespace Test

View File

@ -84,8 +84,8 @@ std::size_t do_comma_emulation_test(std::integer_sequence<std::size_t, Idxs...>,
}
TEST(utilities, comma_operator_emulation) {
ASSERT_EQ(
0, do_comma_emulation_test(std::make_index_sequence<5>{}, 0, 1, 2, 3, 4));
ASSERT_EQ(0u, do_comma_emulation_test(std::make_index_sequence<5>{}, 0, 1, 2,
3, 4));
}
} // namespace Test

View File

@ -892,8 +892,8 @@ struct TestViewMirror {
for (int i = 0; i < 10; i++) {
a_h(i) = (double)i;
}
auto a_d = Kokkos::create_mirror_view(DeviceType(), a_h,
Kokkos::WithoutInitializing);
auto a_d = Kokkos::create_mirror_view(Kokkos::WithoutInitializing,
DeviceType(), a_h);
int equal_ptr_h_d = (a_h.data() == a_d.data()) ? 1 : 0;
constexpr int is_same_memspace =
@ -1082,10 +1082,10 @@ class TestViewAPI {
dx = dView4("dx", N0);
dy = dView4("dy", N0);
ASSERT_EQ(dx.use_count(), size_t(1));
ASSERT_EQ(dx.use_count(), 1);
dView4_unmanaged unmanaged_dx = dx;
ASSERT_EQ(dx.use_count(), size_t(1));
ASSERT_EQ(dx.use_count(), 1);
dView4_unmanaged unmanaged_from_ptr_dx = dView4_unmanaged(
dx.data(), dx.extent(0), dx.extent(1), dx.extent(2), dx.extent(3));
@ -1097,24 +1097,24 @@ class TestViewAPI {
}
const_dView4 const_dx = dx;
ASSERT_EQ(dx.use_count(), size_t(2));
ASSERT_EQ(dx.use_count(), 2);
{
const_dView4 const_dx2;
const_dx2 = const_dx;
ASSERT_EQ(dx.use_count(), size_t(3));
ASSERT_EQ(dx.use_count(), 3);
const_dx2 = dy;
ASSERT_EQ(dx.use_count(), size_t(2));
ASSERT_EQ(dx.use_count(), 2);
const_dView4 const_dx3(dx);
ASSERT_EQ(dx.use_count(), size_t(3));
ASSERT_EQ(dx.use_count(), 3);
dView4_unmanaged dx4_unmanaged(dx);
ASSERT_EQ(dx.use_count(), size_t(3));
ASSERT_EQ(dx.use_count(), 3);
}
ASSERT_EQ(dx.use_count(), size_t(2));
ASSERT_EQ(dx.use_count(), 2);
ASSERT_NE(dx.data(), nullptr);
ASSERT_NE(const_dx.data(), nullptr);
@ -1478,6 +1478,13 @@ class TestViewAPI {
if (std::is_same<typename dView1::memory_space,
Kokkos::Experimental::OpenMPTargetSpace>::value)
return;
#endif
// FIXME_MSVC_WITH_CUDA
// This test doesn't behave as expected on Windows with CUDA
#if defined(_WIN32) && defined(KOKKOS_ENABLE_CUDA)
if (std::is_same<typename dView1::memory_space,
Kokkos::CudaUVMSpace>::value)
return;
#endif
auto alloc_size = std::numeric_limits<size_t>::max() - 42;
try {

View File

@ -617,6 +617,7 @@ TEST(TEST_CATEGORY, view_layoutstride_right_to_layoutright_assignment) {
}
}
#ifndef KOKKOS_COMPILER_NVHPC // FIXME_NVHPC
TEST(TEST_CATEGORY_DEATH, view_layoutstride_right_to_layoutleft_assignment) {
using exec_space = TEST_EXECSPACE;
@ -926,6 +927,7 @@ TEST(TEST_CATEGORY_DEATH, view_layoutstride_left_to_layoutright_assignment) {
"View assignment must have compatible layouts");
}
}
#endif
} // namespace Test

View File

@ -44,6 +44,7 @@
#include <gtest/gtest.h>
#include <cstddef>
#include <stdexcept>
#include <sstream>
#include <iostream>
@ -168,25 +169,25 @@ void test_view_mapping() {
dim_s0_s0_s0 d3(2, 3, 4, 5, 6, 7, 8, 9);
dim_s0_s0_s0_s0 d4(2, 3, 4, 5, 6, 7, 8, 9);
ASSERT_EQ(d1.N0, 2);
ASSERT_EQ(d2.N0, 2);
ASSERT_EQ(d3.N0, 2);
ASSERT_EQ(d4.N0, 2);
ASSERT_EQ(d1.N0, 2u);
ASSERT_EQ(d2.N0, 2u);
ASSERT_EQ(d3.N0, 2u);
ASSERT_EQ(d4.N0, 2u);
ASSERT_EQ(d1.N1, 1);
ASSERT_EQ(d2.N1, 3);
ASSERT_EQ(d3.N1, 3);
ASSERT_EQ(d4.N1, 3);
ASSERT_EQ(d1.N1, 1u);
ASSERT_EQ(d2.N1, 3u);
ASSERT_EQ(d3.N1, 3u);
ASSERT_EQ(d4.N1, 3u);
ASSERT_EQ(d1.N2, 1);
ASSERT_EQ(d2.N2, 1);
ASSERT_EQ(d3.N2, 4);
ASSERT_EQ(d4.N2, 4);
ASSERT_EQ(d1.N2, 1u);
ASSERT_EQ(d2.N2, 1u);
ASSERT_EQ(d3.N2, 4u);
ASSERT_EQ(d4.N2, 4u);
ASSERT_EQ(d1.N3, 1);
ASSERT_EQ(d2.N3, 1);
ASSERT_EQ(d3.N3, 1);
ASSERT_EQ(d4.N3, 5);
ASSERT_EQ(d1.N3, 1u);
ASSERT_EQ(d2.N3, 1u);
ASSERT_EQ(d3.N3, 1u);
ASSERT_EQ(d4.N3, 5u);
//----------------------------------------
@ -205,17 +206,17 @@ void test_view_mapping() {
stride_s0_s0_s0 stride3(off3);
ASSERT_EQ(off3.stride_0(), 1);
ASSERT_EQ(off3.stride_1(), 2);
ASSERT_EQ(off3.stride_2(), 6);
ASSERT_EQ(off3.span(), 24);
ASSERT_EQ(off3.stride_0(), 1u);
ASSERT_EQ(off3.stride_1(), 2u);
ASSERT_EQ(off3.stride_2(), 6u);
ASSERT_EQ(off3.span(), 24u);
ASSERT_EQ(off3.stride_0(), stride3.stride_0());
ASSERT_EQ(off3.stride_1(), stride3.stride_1());
ASSERT_EQ(off3.stride_2(), stride3.stride_2());
ASSERT_EQ(off3.span(), stride3.span());
int offset = 0;
unsigned offset = 0;
for (int k = 0; k < 4; ++k)
for (int j = 0; j < 3; ++j)
@ -236,32 +237,32 @@ void test_view_mapping() {
stride_s0_s0_s0 stride3(dyn_off3);
ASSERT_EQ(dyn_off3.m_dim.rank, 3);
ASSERT_EQ(dyn_off3.m_dim.N0, 2);
ASSERT_EQ(dyn_off3.m_dim.N1, 3);
ASSERT_EQ(dyn_off3.m_dim.N2, 4);
ASSERT_EQ(dyn_off3.m_dim.N3, 1);
ASSERT_EQ(dyn_off3.size(), 2 * 3 * 4);
ASSERT_EQ(dyn_off3.m_dim.rank, 3u);
ASSERT_EQ(dyn_off3.m_dim.N0, 2u);
ASSERT_EQ(dyn_off3.m_dim.N1, 3u);
ASSERT_EQ(dyn_off3.m_dim.N2, 4u);
ASSERT_EQ(dyn_off3.m_dim.N3, 1u);
ASSERT_EQ(dyn_off3.size(), (size_t)2 * 3 * 4);
const Kokkos::LayoutLeft layout = dyn_off3.layout();
ASSERT_EQ(layout.dimension[0], 2);
ASSERT_EQ(layout.dimension[1], 3);
ASSERT_EQ(layout.dimension[2], 4);
ASSERT_EQ(layout.dimension[3], 1);
ASSERT_EQ(layout.dimension[4], 1);
ASSERT_EQ(layout.dimension[5], 1);
ASSERT_EQ(layout.dimension[6], 1);
ASSERT_EQ(layout.dimension[7], 1);
ASSERT_EQ(layout.dimension[0], 2u);
ASSERT_EQ(layout.dimension[1], 3u);
ASSERT_EQ(layout.dimension[2], 4u);
ASSERT_EQ(layout.dimension[3], 1u);
ASSERT_EQ(layout.dimension[4], 1u);
ASSERT_EQ(layout.dimension[5], 1u);
ASSERT_EQ(layout.dimension[6], 1u);
ASSERT_EQ(layout.dimension[7], 1u);
ASSERT_EQ(stride3.m_dim.rank, 3);
ASSERT_EQ(stride3.m_dim.N0, 2);
ASSERT_EQ(stride3.m_dim.N1, 3);
ASSERT_EQ(stride3.m_dim.N2, 4);
ASSERT_EQ(stride3.m_dim.N3, 1);
ASSERT_EQ(stride3.size(), 2 * 3 * 4);
ASSERT_EQ(stride3.m_dim.rank, 3u);
ASSERT_EQ(stride3.m_dim.N0, 2u);
ASSERT_EQ(stride3.m_dim.N1, 3u);
ASSERT_EQ(stride3.m_dim.N2, 4u);
ASSERT_EQ(stride3.m_dim.N3, 1u);
ASSERT_EQ(stride3.size(), (size_t)2 * 3 * 4);
int offset = 0;
size_t offset = 0;
for (int k = 0; k < 4; ++k)
for (int j = 0; j < 3; ++j)
@ -277,8 +278,8 @@ void test_view_mapping() {
//----------------------------------------
// Large dimension is likely padded.
{
constexpr int N0 = 2000;
constexpr int N1 = 300;
constexpr size_t N0 = 2000;
constexpr size_t N1 = 300;
using left_s0_s0_s4 =
Kokkos::Impl::ViewOffset<dim_s0_s0_s4, Kokkos::LayoutLeft>;
@ -288,26 +289,26 @@ void test_view_mapping() {
stride_s0_s0_s0 stride3(dyn_off3);
ASSERT_EQ(dyn_off3.m_dim.rank, 3);
ASSERT_EQ(dyn_off3.m_dim.rank, 3u);
ASSERT_EQ(dyn_off3.m_dim.N0, N0);
ASSERT_EQ(dyn_off3.m_dim.N1, N1);
ASSERT_EQ(dyn_off3.m_dim.N2, 4);
ASSERT_EQ(dyn_off3.m_dim.N3, 1);
ASSERT_EQ(dyn_off3.m_dim.N2, 4u);
ASSERT_EQ(dyn_off3.m_dim.N3, 1u);
ASSERT_EQ(dyn_off3.size(), N0 * N1 * 4);
ASSERT_EQ(stride3.m_dim.rank, 3);
ASSERT_EQ(stride3.m_dim.rank, 3u);
ASSERT_EQ(stride3.m_dim.N0, N0);
ASSERT_EQ(stride3.m_dim.N1, N1);
ASSERT_EQ(stride3.m_dim.N2, 4);
ASSERT_EQ(stride3.m_dim.N3, 1);
ASSERT_EQ(stride3.m_dim.N2, 4u);
ASSERT_EQ(stride3.m_dim.N3, 1u);
ASSERT_EQ(stride3.size(), N0 * N1 * 4);
ASSERT_EQ(stride3.span(), dyn_off3.span());
int offset = 0;
size_t offset = 0;
for (int k = 0; k < 4; ++k)
for (int j = 0; j < N1; ++j)
for (int i = 0; i < N0; ++i) {
for (size_t k = 0; k < 4; ++k)
for (size_t j = 0; j < N1; ++j)
for (size_t i = 0; i < N0; ++i) {
ASSERT_LE(offset, dyn_off3(i, j, k));
ASSERT_EQ(stride3(i, j, k), dyn_off3(i, j, k));
offset = dyn_off3(i, j, k) + 1;
@ -328,9 +329,9 @@ void test_view_mapping() {
stride_s0_s0_s0 stride3(off3);
ASSERT_EQ(off3.stride_0(), 12);
ASSERT_EQ(off3.stride_1(), 4);
ASSERT_EQ(off3.stride_2(), 1);
ASSERT_EQ(off3.stride_0(), 12u);
ASSERT_EQ(off3.stride_1(), 4u);
ASSERT_EQ(off3.stride_2(), 1u);
ASSERT_EQ(off3.dimension_0(), stride3.dimension_0());
ASSERT_EQ(off3.dimension_1(), stride3.dimension_1());
@ -340,7 +341,7 @@ void test_view_mapping() {
ASSERT_EQ(off3.stride_2(), stride3.stride_2());
ASSERT_EQ(off3.span(), stride3.span());
int offset = 0;
size_t offset = 0;
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 3; ++j)
@ -363,12 +364,12 @@ void test_view_mapping() {
stride_s0_s0_s0 stride3(dyn_off3);
ASSERT_EQ(dyn_off3.m_dim.rank, 3);
ASSERT_EQ(dyn_off3.m_dim.N0, 2);
ASSERT_EQ(dyn_off3.m_dim.N1, 3);
ASSERT_EQ(dyn_off3.m_dim.N2, 4);
ASSERT_EQ(dyn_off3.m_dim.N3, 1);
ASSERT_EQ(dyn_off3.size(), 2 * 3 * 4);
ASSERT_EQ(dyn_off3.m_dim.rank, 3u);
ASSERT_EQ(dyn_off3.m_dim.N0, 2u);
ASSERT_EQ(dyn_off3.m_dim.N1, 3u);
ASSERT_EQ(dyn_off3.m_dim.N2, 4u);
ASSERT_EQ(dyn_off3.m_dim.N3, 1u);
ASSERT_EQ(dyn_off3.size(), (size_t)2 * 3 * 4);
ASSERT_EQ(dyn_off3.dimension_0(), stride3.dimension_0());
ASSERT_EQ(dyn_off3.dimension_1(), stride3.dimension_1());
@ -378,7 +379,7 @@ void test_view_mapping() {
ASSERT_EQ(dyn_off3.stride_2(), stride3.stride_2());
ASSERT_EQ(dyn_off3.span(), stride3.span());
int offset = 0;
size_t offset = 0;
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 3; ++j)
@ -393,8 +394,8 @@ void test_view_mapping() {
//----------------------------------------
// Large dimension is likely padded.
{
constexpr int N0 = 2000;
constexpr int N1 = 300;
constexpr size_t N0 = 2000;
constexpr size_t N1 = 300;
using right_s0_s0_s4 =
Kokkos::Impl::ViewOffset<dim_s0_s0_s4, Kokkos::LayoutRight>;
@ -404,11 +405,11 @@ void test_view_mapping() {
stride_s0_s0_s0 stride3(dyn_off3);
ASSERT_EQ(dyn_off3.m_dim.rank, 3);
ASSERT_EQ(dyn_off3.m_dim.rank, 3u);
ASSERT_EQ(dyn_off3.m_dim.N0, N0);
ASSERT_EQ(dyn_off3.m_dim.N1, N1);
ASSERT_EQ(dyn_off3.m_dim.N2, 4);
ASSERT_EQ(dyn_off3.m_dim.N3, 1);
ASSERT_EQ(dyn_off3.m_dim.N2, 4u);
ASSERT_EQ(dyn_off3.m_dim.N3, 1u);
ASSERT_EQ(dyn_off3.size(), N0 * N1 * 4);
ASSERT_EQ(dyn_off3.dimension_0(), stride3.dimension_0());
@ -419,11 +420,11 @@ void test_view_mapping() {
ASSERT_EQ(dyn_off3.stride_2(), stride3.stride_2());
ASSERT_EQ(dyn_off3.span(), stride3.span());
int offset = 0;
size_t offset = 0;
for (int i = 0; i < N0; ++i)
for (int j = 0; j < N1; ++j)
for (int k = 0; k < 4; ++k) {
for (size_t i = 0; i < N0; ++i)
for (size_t j = 0; j < N1; ++j)
for (size_t k = 0; k < 4; ++k) {
ASSERT_LE(offset, dyn_off3(i, j, k));
ASSERT_EQ(dyn_off3(i, j, k), stride3(i, j, k));
offset = dyn_off3(i, j, k) + 1;
@ -438,10 +439,10 @@ void test_view_mapping() {
// Mapping rank 4 to rank 3
using SubviewExtents = Kokkos::Impl::SubviewExtents<4, 3>;
constexpr int N0 = 1000;
constexpr int N1 = 2000;
constexpr int N2 = 3000;
constexpr int N3 = 4000;
constexpr size_t N0 = 1000;
constexpr size_t N1 = 2000;
constexpr size_t N2 = 3000;
constexpr size_t N3 = 4000;
Kokkos::Impl::ViewDimension<N0, N1, N2, N3> dim;
@ -450,26 +451,26 @@ void test_view_mapping() {
Kokkos::pair<int, int>(N3 / 4, 20 + N3 / 4));
ASSERT_EQ(tmp.domain_offset(0), N0 / 2);
ASSERT_EQ(tmp.domain_offset(1), 0);
ASSERT_EQ(tmp.domain_offset(1), 0u);
ASSERT_EQ(tmp.domain_offset(2), N2 / 4);
ASSERT_EQ(tmp.domain_offset(3), N3 / 4);
ASSERT_EQ(tmp.range_index(0), 1);
ASSERT_EQ(tmp.range_index(1), 2);
ASSERT_EQ(tmp.range_index(2), 3);
ASSERT_EQ(tmp.range_index(0), 1u);
ASSERT_EQ(tmp.range_index(1), 2u);
ASSERT_EQ(tmp.range_index(2), 3u);
ASSERT_EQ(tmp.range_extent(0), N1);
ASSERT_EQ(tmp.range_extent(1), 10);
ASSERT_EQ(tmp.range_extent(2), 20);
ASSERT_EQ(tmp.range_extent(1), 10u);
ASSERT_EQ(tmp.range_extent(2), 20u);
}
{
constexpr int N0 = 2000;
constexpr int N1 = 300;
constexpr size_t N0 = 2000;
constexpr size_t N1 = 300;
constexpr int sub_N0 = 1000;
constexpr int sub_N1 = 200;
constexpr int sub_N2 = 4;
constexpr size_t sub_N0 = 1000;
constexpr size_t sub_N1 = 200;
constexpr size_t sub_N2 = 4;
using left_s0_s0_s4 =
Kokkos::Impl::ViewOffset<dim_s0_s0_s4, Kokkos::LayoutLeft>;
@ -493,20 +494,20 @@ void test_view_mapping() {
ASSERT_EQ(dyn_off3.stride_2(), stride3.stride_2());
ASSERT_GE(dyn_off3.span(), stride3.span());
for (int k = 0; k < sub_N2; ++k)
for (int j = 0; j < sub_N1; ++j)
for (int i = 0; i < sub_N0; ++i) {
for (size_t k = 0; k < sub_N2; ++k)
for (size_t j = 0; j < sub_N1; ++j)
for (size_t i = 0; i < sub_N0; ++i) {
ASSERT_EQ(stride3(i, j, k), dyn_off3(i, j, k));
}
}
{
constexpr int N0 = 2000;
constexpr int N1 = 300;
constexpr size_t N0 = 2000;
constexpr size_t N1 = 300;
constexpr int sub_N0 = 1000;
constexpr int sub_N1 = 200;
constexpr int sub_N2 = 4;
constexpr size_t sub_N0 = 1000;
constexpr size_t sub_N1 = 200;
constexpr size_t sub_N2 = 4;
using right_s0_s0_s4 =
Kokkos::Impl::ViewOffset<dim_s0_s0_s4, Kokkos::LayoutRight>;
@ -530,9 +531,9 @@ void test_view_mapping() {
ASSERT_EQ(dyn_off3.stride_2(), stride3.stride_2());
ASSERT_GE(dyn_off3.span(), stride3.span());
for (int i = 0; i < sub_N0; ++i)
for (int j = 0; j < sub_N1; ++j)
for (int k = 0; k < sub_N2; ++k) {
for (size_t i = 0; i < sub_N0; ++i)
for (size_t j = 0; j < sub_N1; ++j)
for (size_t k = 0; k < sub_N2; ++k) {
ASSERT_EQ(stride3(i, j, k), dyn_off3(i, j, k));
}
}
@ -720,8 +721,8 @@ void test_view_mapping() {
// Generate static_assert error:
// T tmp( cr1 );
ASSERT_EQ(vr1.span(), N);
ASSERT_EQ(cr1.span(), N);
ASSERT_EQ(vr1.span(), size_t(N));
ASSERT_EQ(cr1.span(), size_t(N));
ASSERT_EQ(vr1.data(), &data[0]);
ASSERT_EQ(cr1.data(), &data[0]);
@ -766,7 +767,7 @@ void test_view_mapping() {
ASSERT_EQ(C::Rank, 1);
ASSERT_EQ(vr1.extent(0), N);
ASSERT_EQ(vr1.extent(0), size_t(N));
if (Kokkos::SpaceAccessibility<Kokkos::HostSpace,
typename Space::memory_space>::accessible) {
@ -813,7 +814,7 @@ void test_view_mapping() {
ASSERT_TRUE((std::is_same<typename T::reference_type, int&>::value));
ASSERT_EQ(T::Rank, 1);
ASSERT_EQ(vr1.extent(0), N);
ASSERT_EQ(vr1.extent(0), size_t(N));
if (Kokkos::SpaceAccessibility<Kokkos::HostSpace,
typename Space::memory_space>::accessible) {
@ -841,8 +842,8 @@ void test_view_mapping() {
T vr1("vr1", N);
C cr1(vr1);
ASSERT_EQ(vr1.extent(0), 0);
ASSERT_EQ(cr1.extent(0), 0);
ASSERT_EQ(vr1.extent(0), 0u);
ASSERT_EQ(cr1.extent(0), 0u);
}
// Testing using space instance for allocation.
@ -890,15 +891,15 @@ void test_view_mapping() {
const offset_t offset(std::integral_constant<unsigned, 0>(), stride);
ASSERT_EQ(offset.dimension_0(), 3);
ASSERT_EQ(offset.dimension_1(), 4);
ASSERT_EQ(offset.dimension_2(), 5);
ASSERT_EQ(offset.dimension_0(), 3u);
ASSERT_EQ(offset.dimension_1(), 4u);
ASSERT_EQ(offset.dimension_2(), 5u);
ASSERT_EQ(offset.stride_0(), 4);
ASSERT_EQ(offset.stride_1(), 1);
ASSERT_EQ(offset.stride_2(), 12);
ASSERT_EQ(offset.stride_0(), 4u);
ASSERT_EQ(offset.stride_1(), 1u);
ASSERT_EQ(offset.stride_2(), 12u);
ASSERT_EQ(offset.span(), 60);
ASSERT_EQ(offset.span(), 60u);
ASSERT_TRUE(offset.span_is_contiguous());
Kokkos::Impl::ViewMapping<traits_t, void> v(
@ -910,24 +911,24 @@ void test_view_mapping() {
using M = typename V::HostMirror;
using layout_type = typename Kokkos::View<int**, Space>::array_layout;
constexpr int N0 = 10;
constexpr int N1 = 11;
constexpr size_t N0 = 10;
constexpr size_t N1 = 11;
V a("a", N0, N1);
M b = Kokkos::create_mirror(a);
M c = Kokkos::create_mirror_view(a);
M d;
for (int i0 = 0; i0 < N0; ++i0)
for (int i1 = 0; i1 < N1; ++i1) {
for (size_t i0 = 0; i0 < N0; ++i0)
for (size_t i1 = 0; i1 < N1; ++i1) {
b(i0, i1) = 1 + i0 + i1 * N0;
}
Kokkos::deep_copy(a, b);
Kokkos::deep_copy(c, a);
for (int i0 = 0; i0 < N0; ++i0)
for (int i1 = 0; i1 < N1; ++i1) {
for (size_t i0 = 0; i0 < N0; ++i0)
for (size_t i1 = 0; i1 < N1; ++i1) {
ASSERT_EQ(b(i0, i1), c(i0, i1));
}
@ -943,12 +944,12 @@ void test_view_mapping() {
Kokkos::realloc(c, 5, 6);
Kokkos::realloc(d, 5, 6);
ASSERT_EQ(b.extent(0), 5);
ASSERT_EQ(b.extent(1), 6);
ASSERT_EQ(c.extent(0), 5);
ASSERT_EQ(c.extent(1), 6);
ASSERT_EQ(d.extent(0), 5);
ASSERT_EQ(d.extent(1), 6);
ASSERT_EQ(b.extent(0), 5u);
ASSERT_EQ(b.extent(1), 6u);
ASSERT_EQ(c.extent(0), 5u);
ASSERT_EQ(c.extent(1), 6u);
ASSERT_EQ(d.extent(0), 5u);
ASSERT_EQ(d.extent(1), 6u);
layout_type layout(7, 8);
Kokkos::resize(b, layout);
@ -971,12 +972,12 @@ void test_view_mapping() {
Kokkos::realloc(c, layout);
Kokkos::realloc(d, layout);
ASSERT_EQ(b.extent(0), 7);
ASSERT_EQ(b.extent(1), 8);
ASSERT_EQ(c.extent(0), 7);
ASSERT_EQ(c.extent(1), 8);
ASSERT_EQ(d.extent(0), 7);
ASSERT_EQ(d.extent(1), 8);
ASSERT_EQ(b.extent(0), 7u);
ASSERT_EQ(b.extent(1), 8u);
ASSERT_EQ(c.extent(0), 7u);
ASSERT_EQ(c.extent(1), 8u);
ASSERT_EQ(d.extent(0), 7u);
ASSERT_EQ(d.extent(1), 8u);
}
{
@ -985,8 +986,8 @@ void test_view_mapping() {
using layout_type =
typename Kokkos::View<int**, Kokkos::LayoutStride, Space>::array_layout;
constexpr int N0 = 10;
constexpr int N1 = 11;
constexpr size_t N0 = 10;
constexpr size_t N1 = 11;
const int dimensions[] = {N0, N1};
const int order[] = {1, 0};
@ -996,16 +997,16 @@ void test_view_mapping() {
M c = Kokkos::create_mirror_view(a);
M d;
for (int i0 = 0; i0 < N0; ++i0)
for (int i1 = 0; i1 < N1; ++i1) {
for (size_t i0 = 0; i0 < N0; ++i0)
for (size_t i1 = 0; i1 < N1; ++i1) {
b(i0, i1) = 1 + i0 + i1 * N0;
}
Kokkos::deep_copy(a, b);
Kokkos::deep_copy(c, a);
for (int i0 = 0; i0 < N0; ++i0)
for (int i1 = 0; i1 < N1; ++i1) {
for (size_t i0 = 0; i0 < N0; ++i0)
for (size_t i1 = 0; i1 < N1; ++i1) {
ASSERT_EQ(b(i0, i1), c(i0, i1));
}
@ -1024,12 +1025,12 @@ void test_view_mapping() {
Kokkos::realloc(c, layout);
Kokkos::realloc(d, layout);
ASSERT_EQ(b.extent(0), 7);
ASSERT_EQ(b.extent(1), 8);
ASSERT_EQ(c.extent(0), 7);
ASSERT_EQ(c.extent(1), 8);
ASSERT_EQ(d.extent(0), 7);
ASSERT_EQ(d.extent(1), 8);
ASSERT_EQ(b.extent(0), 7u);
ASSERT_EQ(b.extent(1), 8u);
ASSERT_EQ(c.extent(0), 7u);
ASSERT_EQ(c.extent(1), 8u);
ASSERT_EQ(d.extent(0), 7u);
ASSERT_EQ(d.extent(1), 8u);
}
{
@ -1203,22 +1204,30 @@ struct TestViewMapOperator {
}
void run() {
ASSERT_EQ(v.extent(0),
(0 < ViewType::rank ? TestViewMapOperator<ViewType>::N0 : 1));
ASSERT_EQ(v.extent(1),
(1 < ViewType::rank ? TestViewMapOperator<ViewType>::N1 : 1));
ASSERT_EQ(v.extent(2),
(2 < ViewType::rank ? TestViewMapOperator<ViewType>::N2 : 1));
ASSERT_EQ(v.extent(3),
(3 < ViewType::rank ? TestViewMapOperator<ViewType>::N3 : 1));
ASSERT_EQ(v.extent(4),
(4 < ViewType::rank ? TestViewMapOperator<ViewType>::N4 : 1));
ASSERT_EQ(v.extent(5),
(5 < ViewType::rank ? TestViewMapOperator<ViewType>::N5 : 1));
ASSERT_EQ(v.extent(6),
(6 < ViewType::rank ? TestViewMapOperator<ViewType>::N6 : 1));
ASSERT_EQ(v.extent(7),
(7 < ViewType::rank ? TestViewMapOperator<ViewType>::N7 : 1));
ASSERT_EQ(
v.extent(0),
(size_t)(0 < ViewType::rank ? TestViewMapOperator<ViewType>::N0 : 1));
ASSERT_EQ(
v.extent(1),
(size_t)(1 < ViewType::rank ? TestViewMapOperator<ViewType>::N1 : 1));
ASSERT_EQ(
v.extent(2),
(size_t)(2 < ViewType::rank ? TestViewMapOperator<ViewType>::N2 : 1));
ASSERT_EQ(
v.extent(3),
(size_t)(3 < ViewType::rank ? TestViewMapOperator<ViewType>::N3 : 1));
ASSERT_EQ(
v.extent(4),
(size_t)(4 < ViewType::rank ? TestViewMapOperator<ViewType>::N4 : 1));
ASSERT_EQ(
v.extent(5),
(size_t)(5 < ViewType::rank ? TestViewMapOperator<ViewType>::N5 : 1));
ASSERT_EQ(
v.extent(6),
(size_t)(6 < ViewType::rank ? TestViewMapOperator<ViewType>::N6 : 1));
ASSERT_EQ(
v.extent(7),
(size_t)(7 < ViewType::rank ? TestViewMapOperator<ViewType>::N7 : 1));
ASSERT_LE(v.extent(0) * v.extent(1) * v.extent(2) * v.extent(3) *
v.extent(4) * v.extent(5) * v.extent(6) * v.extent(7),
@ -1321,8 +1330,8 @@ TEST(TEST_CATEGORY, view_mapping_operator) {
TEST(TEST_CATEGORY, static_extent) {
using T = Kokkos::View<double * [2][3]>;
ASSERT_EQ(T::static_extent(1), 2);
ASSERT_EQ(T::static_extent(2), 3);
ASSERT_EQ(T::static_extent(1), 2u);
ASSERT_EQ(T::static_extent(2), 3u);
}
} // namespace Test

View File

@ -141,25 +141,17 @@ struct MappingClassValueType {
KOKKOS_INLINE_FUNCTION
MappingClassValueType() {
#if 0
#if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA)
printf( "TestViewMappingClassValue construct on Cuda\n" );
#elif defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
printf( "TestViewMappingClassValue construct on Host\n" );
#else
printf( "TestViewMappingClassValue construct unknown\n" );
#endif
KOKKOS_IF_ON_DEVICE(
(printf("TestViewMappingClassValue construct on Device\n");))
KOKKOS_IF_ON_HOST((printf("TestViewMappingClassValue construct on Host\n");))
#endif
}
KOKKOS_INLINE_FUNCTION
~MappingClassValueType() {
#if 0
#if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_CUDA)
printf( "TestViewMappingClassValue destruct on Cuda\n" );
#elif defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
printf( "TestViewMappingClassValue destruct on Host\n" );
#else
printf( "TestViewMappingClassValue destruct unknown\n" );
#endif
KOKKOS_IF_ON_DEVICE(
(printf("TestViewMappingClassValue destruct on Device\n");))
KOKKOS_IF_ON_HOST((printf("TestViewMappingClassValue destruct on Host\n");))
#endif
}
};

View File

@ -164,23 +164,23 @@ struct TestViewMappingSubview {
TestViewMappingSubview<ExecSpace> self;
ASSERT_EQ(Aa.extent(0), AN);
ASSERT_EQ(Ab.extent(0), AN - 2);
ASSERT_EQ(Ac.extent(0), AN - 2);
ASSERT_EQ(Ab.extent(0), (size_t)AN - 2);
ASSERT_EQ(Ac.extent(0), (size_t)AN - 2);
ASSERT_EQ(Ba.extent(0), BN0);
ASSERT_EQ(Ba.extent(1), BN1);
ASSERT_EQ(Ba.extent(2), BN2);
ASSERT_EQ(Bb.extent(0), BN0 - 2);
ASSERT_EQ(Bb.extent(1), BN1 - 2);
ASSERT_EQ(Bb.extent(2), BN2 - 2);
ASSERT_EQ(Bb.extent(0), (size_t)BN0 - 2);
ASSERT_EQ(Bb.extent(1), (size_t)BN1 - 2);
ASSERT_EQ(Bb.extent(2), (size_t)BN2 - 2);
ASSERT_EQ(Ca.extent(0), CN0);
ASSERT_EQ(Ca.extent(1), CN1);
ASSERT_EQ(Ca.extent(2), CN2);
ASSERT_EQ(Ca.extent(3), 13);
ASSERT_EQ(Ca.extent(4), 14);
ASSERT_EQ(Cb.extent(0), CN0 - 2);
ASSERT_EQ(Cb.extent(1), CN1 - 2);
ASSERT_EQ(Cb.extent(2), CN2 - 2);
ASSERT_EQ(Ca.extent(3), (size_t)13);
ASSERT_EQ(Ca.extent(4), (size_t)14);
ASSERT_EQ(Cb.extent(0), (size_t)CN0 - 2);
ASSERT_EQ(Cb.extent(1), (size_t)CN1 - 2);
ASSERT_EQ(Cb.extent(2), (size_t)CN2 - 2);
ASSERT_EQ(Da.extent(0), DN0);
ASSERT_EQ(Da.extent(1), DN1);
@ -188,9 +188,9 @@ struct TestViewMappingSubview {
ASSERT_EQ(Da.extent(3), DN3);
ASSERT_EQ(Da.extent(4), DN4);
ASSERT_EQ(Db.extent(0), DN1 - 2);
ASSERT_EQ(Db.extent(1), DN2 - 2);
ASSERT_EQ(Db.extent(2), DN3 - 2);
ASSERT_EQ(Db.extent(0), (size_t)DN1 - 2);
ASSERT_EQ(Db.extent(1), (size_t)DN2 - 2);
ASSERT_EQ(Db.extent(2), (size_t)DN3 - 2);
ASSERT_EQ(Da.stride_1(), Db.stride_0());
ASSERT_EQ(Da.stride_2(), Db.stride_1());

View File

@ -46,6 +46,7 @@
#include <gtest/gtest.h>
#include "TestResize.hpp"
#include "TestRealloc.hpp"
namespace Test {
@ -54,5 +55,10 @@ TEST(TEST_CATEGORY, view_resize) {
TestViewResize::testResize<ExecSpace>();
}
TEST(TEST_CATEGORY, view_realloc) {
using ExecSpace = TEST_EXECSPACE;
TestViewRealloc::testRealloc<ExecSpace>();
}
} // namespace Test
#endif // TESTVIEWRESIZE_HPP_

View File

@ -336,7 +336,7 @@ void test_left_0(bool constr) {
make_subview(constr, x0, x_static_8, 0, 0, 0, 0, 0, 0, 0, 0);
ASSERT_TRUE(x0.span_is_contiguous());
ASSERT_EQ(x0.span(), 1);
ASSERT_EQ(x0.span(), 1u);
ASSERT_EQ(&x0(), &x_static_8(0, 0, 0, 0, 0, 0, 0, 0));
Kokkos::View<int*, Kokkos::LayoutLeft, Space> x1;
@ -344,7 +344,7 @@ void test_left_0(bool constr) {
0, 1, 2, 3);
ASSERT_TRUE(x1.span_is_contiguous());
ASSERT_EQ(x1.span(), 2);
ASSERT_EQ(x1.span(), 2u);
ASSERT_EQ(&x1(0), &x_static_8(0, 1, 2, 3, 0, 1, 2, 3));
ASSERT_EQ(&x1(1), &x_static_8(1, 1, 2, 3, 0, 1, 2, 3));
@ -353,7 +353,7 @@ void test_left_0(bool constr) {
3, 0, 1, 2, 3);
ASSERT_TRUE(x_deg1.span_is_contiguous());
ASSERT_EQ(x_deg1.span(), 0);
ASSERT_EQ(x_deg1.span(), 0u);
ASSERT_EQ(x_deg1.data(), &x_static_8(0, 1, 2, 3, 0, 1, 2, 3));
Kokkos::View<int*, Kokkos::LayoutLeft, Space> x_deg2;
@ -361,7 +361,7 @@ void test_left_0(bool constr) {
4, 1, 2, 3, 4);
ASSERT_TRUE(x_deg2.span_is_contiguous());
ASSERT_EQ(x_deg2.span(), 0);
ASSERT_EQ(x_deg2.span(), 0u);
ASSERT_EQ(x_deg2.data(), x_static_8.data() + x_static_8.span());
Kokkos::View<int**, Kokkos::LayoutLeft, Space> x2;
@ -444,14 +444,14 @@ void test_left_1(bool use_constr) {
0, 1, 2, 3);
ASSERT_TRUE(x1_deg1.span_is_contiguous());
ASSERT_EQ(0, x1_deg1.span());
ASSERT_EQ(0u, x1_deg1.span());
ASSERT_EQ(x1_deg1.data(), &x8(0, 1, 2, 3, 0, 1, 2, 3));
Kokkos::View<int*, Kokkos::LayoutLeft, Space> x1_deg2;
make_subview(use_constr, x1_deg2, x8, Kokkos::pair<int, int>(2, 2), 2, 3, 4,
1, 2, 3, 4);
ASSERT_EQ(0, x1_deg2.span());
ASSERT_EQ(0u, x1_deg2.span());
ASSERT_TRUE(x1_deg2.span_is_contiguous());
ASSERT_EQ(x1_deg2.data(), x8.data() + x8.span());
@ -468,7 +468,7 @@ void test_left_1(bool use_constr) {
Kokkos::View<int**, Kokkos::LayoutLeft, Space> x2_deg2;
make_subview(use_constr, x2_deg2, x8, Kokkos::pair<int, int>(2, 2), 2, 3, 4,
1, 2, Kokkos::pair<int, int>(2, 3), 4);
ASSERT_EQ(0, x2_deg2.span());
ASSERT_EQ(0u, x2_deg2.span());
// Kokkos::View< int**, Kokkos::LayoutLeft, Space > error_2 =
Kokkos::View<int**, Kokkos::LayoutStride, Space> sx2;
@ -484,7 +484,7 @@ void test_left_1(bool use_constr) {
Kokkos::View<int**, Kokkos::LayoutStride, Space> sx2_deg;
make_subview(use_constr, sx2, x8, 1, Kokkos::pair<int, int>(0, 0), 2, 3,
Kokkos::pair<int, int>(0, 2), 1, 2, 3);
ASSERT_EQ(0, sx2_deg.span());
ASSERT_EQ(0u, sx2_deg.span());
Kokkos::View<int****, Kokkos::LayoutStride, Space> sx4;
make_subview(use_constr, sx4, x8, 0,
@ -625,14 +625,14 @@ void test_left_3() {
Kokkos::View<int**, Kokkos::LayoutLeft, Space> x2_n1 =
Kokkos::subview(xm, std::pair<int, int>(1, 1), Kokkos::ALL);
ASSERT_EQ(x2_n1.extent(0), 0);
ASSERT_EQ(x2_n1.extent(0), 0u);
ASSERT_EQ(x2_n1.extent(1), xm.extent(1));
Kokkos::View<int**, Kokkos::LayoutLeft, Space> x2_n2 =
Kokkos::subview(xm, Kokkos::ALL, std::pair<int, int>(1, 1));
ASSERT_EQ(x2_n2.extent(0), xm.extent(0));
ASSERT_EQ(x2_n2.extent(1), 0);
ASSERT_EQ(x2_n2.extent(1), 0u);
}
}
@ -656,7 +656,7 @@ void test_right_0(bool use_constr) {
make_subview(use_constr, x1, x_static_8, 0, 1, 2, 3, 0, 1, 2,
Kokkos::pair<int, int>(1, 3));
ASSERT_EQ(x1.extent(0), 2);
ASSERT_EQ(x1.extent(0), 2u);
ASSERT_EQ(&x1(0), &x_static_8(0, 1, 2, 3, 0, 1, 2, 1));
ASSERT_EQ(&x1(1), &x_static_8(0, 1, 2, 3, 0, 1, 2, 2));
@ -665,8 +665,8 @@ void test_right_0(bool use_constr) {
Kokkos::pair<int, int>(1, 3), 0, 1, 2,
Kokkos::pair<int, int>(1, 3));
ASSERT_EQ(x2.extent(0), 2);
ASSERT_EQ(x2.extent(1), 2);
ASSERT_EQ(x2.extent(0), 2u);
ASSERT_EQ(x2.extent(1), 2u);
ASSERT_EQ(&x2(0, 0), &x_static_8(0, 1, 2, 1, 0, 1, 2, 1));
ASSERT_EQ(&x2(1, 0), &x_static_8(0, 1, 2, 2, 0, 1, 2, 1));
ASSERT_EQ(&x2(0, 1), &x_static_8(0, 1, 2, 1, 0, 1, 2, 2));
@ -677,8 +677,8 @@ void test_right_0(bool use_constr) {
make_subview(use_constr, sx2, x_static_8, 1, Kokkos::pair<int, int>(0, 2),
2, 3, Kokkos::pair<int, int>(0, 2), 1, 2, 3);
ASSERT_EQ(sx2.extent(0), 2);
ASSERT_EQ(sx2.extent(1), 2);
ASSERT_EQ(sx2.extent(0), 2u);
ASSERT_EQ(sx2.extent(1), 2u);
ASSERT_EQ(&sx2(0, 0), &x_static_8(1, 0, 2, 3, 0, 1, 2, 3));
ASSERT_EQ(&sx2(1, 0), &x_static_8(1, 1, 2, 3, 0, 1, 2, 3));
ASSERT_EQ(&sx2(0, 1), &x_static_8(1, 0, 2, 3, 1, 1, 2, 3));
@ -695,10 +695,10 @@ void test_right_0(bool use_constr) {
2, Kokkos::pair<int, int>(2, 4) /* of [5] */
);
ASSERT_EQ(sx4.extent(0), 2);
ASSERT_EQ(sx4.extent(1), 2);
ASSERT_EQ(sx4.extent(2), 2);
ASSERT_EQ(sx4.extent(3), 2);
ASSERT_EQ(sx4.extent(0), 2u);
ASSERT_EQ(sx4.extent(1), 2u);
ASSERT_EQ(sx4.extent(2), 2u);
ASSERT_EQ(sx4.extent(3), 2u);
for (int i0 = 0; i0 < (int)sx4.extent(0); ++i0)
for (int i1 = 0; i1 < (int)sx4.extent(1); ++i1)
for (int i2 = 0; i2 < (int)sx4.extent(2); ++i2)
@ -739,7 +739,7 @@ void test_right_1(bool use_constr) {
Kokkos::View<int*, Kokkos::LayoutRight, Space> x1_deg1;
make_subview(use_constr, x1_deg1, x8, 0, 1, 2, 3, 0, 1, 2,
Kokkos::pair<int, int>(3, 3));
ASSERT_EQ(0, x1_deg1.span());
ASSERT_EQ(0u, x1_deg1.span());
Kokkos::View<int**, Kokkos::LayoutRight, Space> x2;
make_subview(use_constr, x2, x8, 0, 1, 2, Kokkos::pair<int, int>(1, 3), 0,
@ -753,7 +753,7 @@ void test_right_1(bool use_constr) {
Kokkos::View<int**, Kokkos::LayoutRight, Space> x2_deg2;
make_subview(use_constr, x2_deg2, x8, 0, 1, 2, Kokkos::pair<int, int>(1, 3),
0, 1, 2, Kokkos::pair<int, int>(3, 3));
ASSERT_EQ(0, x2_deg2.span());
ASSERT_EQ(0u, x2_deg2.span());
// Kokkos::View< int**, Kokkos::LayoutRight, Space > error_2 =
Kokkos::View<int**, Kokkos::LayoutStride, Space> sx2;
@ -768,7 +768,7 @@ void test_right_1(bool use_constr) {
Kokkos::View<int**, Kokkos::LayoutStride, Space> sx2_deg;
make_subview(use_constr, sx2_deg, x8, 1, Kokkos::pair<int, int>(0, 2), 2, 3,
1, 1, 2, Kokkos::pair<int, int>(3, 3));
ASSERT_EQ(0, sx2_deg.span());
ASSERT_EQ(0u, sx2_deg.span());
Kokkos::View<int****, Kokkos::LayoutStride, Space> sx4;
make_subview(use_constr, sx4, x8, 0,
@ -842,14 +842,14 @@ void test_right_3() {
Kokkos::View<int**, Kokkos::LayoutRight, Space> x2_n1 =
Kokkos::subview(xm, std::pair<int, int>(1, 1), Kokkos::ALL);
ASSERT_EQ(x2_n1.extent(0), 0);
ASSERT_EQ(x2_n1.extent(0), 0u);
ASSERT_EQ(x2_n1.extent(1), xm.extent(1));
Kokkos::View<int**, Kokkos::LayoutRight, Space> x2_n2 =
Kokkos::subview(xm, Kokkos::ALL, std::pair<int, int>(1, 1));
ASSERT_EQ(x2_n2.extent(0), xm.extent(0));
ASSERT_EQ(x2_n2.extent(1), 0);
ASSERT_EQ(x2_n2.extent(1), 0u);
}
}

View File

@ -0,0 +1,98 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Core.hpp>
#include "tools/include/ToolTestingUtilities.hpp"
TEST(TEST_CATEGORY, resize_realloc_no_init) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableKernels());
Kokkos::View<int*** * [1][2][3][4], TEST_EXECSPACE> bla("bla", 5, 6, 7, 8);
auto success = validate_absence(
[&]() {
Kokkos::resize(Kokkos::WithoutInitializing, bla, 5, 6, 7, 9);
Kokkos::realloc(Kokkos::WithoutInitializing, bla, 8, 8, 8, 8);
},
[&](BeginParallelForEvent event) {
if (event.descriptor().find("initialization") != std::string::npos)
return MatchDiagnostic{true, {"Found begin event"}};
return MatchDiagnostic{false};
},
[&](EndParallelForEvent event) {
if (event.descriptor().find("initialization") != std::string::npos)
return MatchDiagnostic{true, {"Found end event"}};
return MatchDiagnostic{false};
});
ASSERT_TRUE(success);
listen_tool_events(Config::DisableAll());
}
TEST(TEST_CATEGORY, resize_realloc_no_alloc) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableKernels(),
Config::EnableAllocs());
Kokkos::View<int*** * [1][2][3][4], TEST_EXECSPACE> bla("bla", 8, 7, 6, 5);
auto success = validate_absence(
[&]() {
Kokkos::resize(bla, 8, 7, 6, 5);
Kokkos::realloc(Kokkos::WithoutInitializing, bla, 8, 7, 6, 5);
},
[&](BeginParallelForEvent) {
return MatchDiagnostic{true, {"Found begin event"}};
},
[&](EndParallelForEvent) {
return MatchDiagnostic{true, {"Found end event"}};
},
[&](AllocateDataEvent) {
return MatchDiagnostic{true, {"Found alloc event"}};
},
[&](DeallocateDataEvent) {
return MatchDiagnostic{true, {"Found dealloc event"}};
});
ASSERT_TRUE(success);
listen_tool_events(Config::DisableAll());
}

View File

@ -0,0 +1,195 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <TestCuda_Category.hpp>
#include <Kokkos_Core.hpp>
namespace Test {
using ValueType = double;
using MemSpace = Kokkos::CudaSpace;
using Matrix2D = Kokkos::View<ValueType**, MemSpace>;
using Matrix3D = Kokkos::View<ValueType***, MemSpace>;
using Vector = Kokkos::View<ValueType*, MemSpace>;
namespace Impl {
struct ArrayReduceFunctor {
using value_type = ValueType[];
int value_count;
Matrix2D m;
ArrayReduceFunctor(const Matrix2D& m_) : value_count(m_.extent(1)), m(m_) {}
KOKKOS_INLINE_FUNCTION void operator()(const int i, value_type sum) const {
const int numVecs = value_count;
for (int j = 0; j < numVecs; ++j) {
sum[j] += m(i, j);
}
}
KOKKOS_INLINE_FUNCTION void init(value_type update) const {
const int numVecs = value_count;
for (int j = 0; j < numVecs; ++j) {
update[j] = 0.0;
}
}
KOKKOS_INLINE_FUNCTION void join(volatile value_type update,
const volatile value_type source) const {
const int numVecs = value_count;
for (int j = 0; j < numVecs; ++j) {
update[j] += source[j];
}
}
KOKKOS_INLINE_FUNCTION void join(value_type update,
const value_type source) const {
const int numVecs = value_count;
for (int j = 0; j < numVecs; ++j) {
update[j] += source[j];
}
}
KOKKOS_INLINE_FUNCTION void final(value_type) const {}
};
struct MDArrayReduceFunctor {
using value_type = ValueType[];
int value_count;
Matrix3D m;
MDArrayReduceFunctor(const Matrix3D& m_) : value_count(m_.extent(2)), m(m_) {}
KOKKOS_INLINE_FUNCTION void operator()(const int i, const int j,
value_type sum) const {
const int numVecs = value_count;
for (int k = 0; k < numVecs; ++k) {
sum[k] += m(i, j, k);
}
}
KOKKOS_INLINE_FUNCTION void init(value_type update) const {
const int numVecs = value_count;
for (int j = 0; j < numVecs; ++j) {
update[j] = 0.0;
}
}
KOKKOS_INLINE_FUNCTION void final(value_type) const {}
};
struct ReduceViewSizeLimitTester {
const ValueType initValue = 3;
const size_t nGlobalEntries = 100;
const int testViewSize = 200;
const size_t expectedInitShmemLimit = 373584;
const unsigned initBlockSize = Kokkos::Impl::CudaTraits::WarpSize * 8;
void run_test_range() {
Matrix2D matrix;
Vector sum;
for (int i = 0; i < testViewSize; ++i) {
size_t sumInitShmemSize = (initBlockSize + 2) * sizeof(ValueType) * i;
Kokkos::resize(Kokkos::WithoutInitializing, sum, i);
Kokkos::resize(Kokkos::WithoutInitializing, matrix, nGlobalEntries, i);
Kokkos::deep_copy(matrix, initValue);
auto policy = Kokkos::RangePolicy<TEST_EXECSPACE>(0, nGlobalEntries);
auto functor = ArrayReduceFunctor(matrix);
if (sumInitShmemSize < expectedInitShmemLimit) {
EXPECT_NO_THROW(Kokkos::parallel_reduce(policy, functor, sum));
} else {
EXPECT_THROW(Kokkos::parallel_reduce(policy, functor, sum),
std::runtime_error);
}
}
}
void run_test_md_range_2D() {
Matrix3D matrix;
Vector sum;
for (int i = 0; i < testViewSize; ++i) {
size_t sumInitShmemSize = (initBlockSize + 2) * sizeof(ValueType) * i;
Kokkos::resize(Kokkos::WithoutInitializing, sum, i);
Kokkos::resize(Kokkos::WithoutInitializing, matrix, nGlobalEntries,
nGlobalEntries, i);
Kokkos::deep_copy(matrix, initValue);
auto policy = Kokkos::MDRangePolicy<Kokkos::Rank<2>>(
{0, 0}, {nGlobalEntries, nGlobalEntries});
auto functor = MDArrayReduceFunctor(matrix);
if (sumInitShmemSize < expectedInitShmemLimit) {
EXPECT_NO_THROW(Kokkos::parallel_reduce(policy, functor, sum));
} else {
EXPECT_THROW(Kokkos::parallel_reduce(policy, functor, sum),
std::runtime_error);
}
}
}
};
} // namespace Impl
TEST(cuda, reduceRangePolicyViewSizeLimit) {
Impl::ReduceViewSizeLimitTester reduceViewSizeLimitTester;
reduceViewSizeLimitTester.run_test_range();
}
TEST(cuda, reduceMDRangePolicyViewSizeLimit) {
Impl::ReduceViewSizeLimitTester reduceViewSizeLimitTester;
reduceViewSizeLimitTester.run_test_md_range_2D();
}
} // namespace Test

View File

@ -0,0 +1,152 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#include <TestDefaultDeviceType_Category.hpp>
template <size_t... Ds>
using _sizes = std::integer_sequence<size_t, Ds...>;
template <class>
struct TestViewAPI;
template <class DataType, class Layout, size_t... DynamicSizes,
size_t... AllSizes>
struct TestViewAPI<
std::tuple<DataType, Layout, std::integer_sequence<size_t, DynamicSizes...>,
std::integer_sequence<size_t, AllSizes...>>>
: public ::testing::Test {
using data_type = DataType;
using layout_type = Layout;
using space_type = Kokkos::DefaultExecutionSpace;
using traits_type =
Kokkos::MemoryTraits<0>; // maybe we want to add that later to the matrix
using view_type =
Kokkos::View<data_type, layout_type, space_type, traits_type>;
using alloc_layout_type = typename std::conditional<
std::is_same<layout_type, Kokkos::LayoutStride>::value,
Kokkos::LayoutLeft, layout_type>::type;
using d_alloc_type = Kokkos::View<data_type, alloc_layout_type, space_type>;
using h_alloc_type = typename Kokkos::View<data_type, alloc_layout_type,
space_type>::HostMirror;
// add a +1 to avoid zero length static array
size_t dyn_sizes[sizeof...(DynamicSizes) + 1] = {DynamicSizes..., 1};
size_t all_sizes[sizeof...(AllSizes) + 1] = {AllSizes..., 1};
constexpr static size_t expected_rank = sizeof...(AllSizes);
inline view_type create_view() const {
return d_alloc_type("TestViewAPI", DynamicSizes...);
}
};
using Kokkos::LayoutLeft;
using Kokkos::LayoutRight;
using Kokkos::LayoutStride;
using compatible_extents_test_types = ::testing::Types<
// LayoutLeft
std::tuple<int, LayoutLeft, _sizes<>, _sizes<>>,
std::tuple<int[5], LayoutLeft, _sizes<>, _sizes<5>>,
std::tuple<int*, LayoutLeft, _sizes<5>, _sizes<5>>,
std::tuple<int[5][10], LayoutLeft, _sizes<>, _sizes<5, 10>>,
std::tuple<int * [10], LayoutLeft, _sizes<5>, _sizes<5, 10>>,
std::tuple<int**, LayoutLeft, _sizes<5, 10>, _sizes<5, 10>>,
std::tuple<int[5][10][15], LayoutLeft, _sizes<>, _sizes<5, 10, 15>>,
std::tuple<int * [10][15], LayoutLeft, _sizes<5>, _sizes<5, 10, 15>>,
std::tuple<int* * [15], LayoutLeft, _sizes<5, 10>, _sizes<5, 10, 15>>,
std::tuple<int***, LayoutLeft, _sizes<5, 10, 15>, _sizes<5, 10, 15>>,
// LayoutRight
std::tuple<int, LayoutRight, _sizes<>, _sizes<>>,
std::tuple<int[5], LayoutRight, _sizes<>, _sizes<5>>,
std::tuple<int*, LayoutRight, _sizes<5>, _sizes<5>>,
std::tuple<int[5][10], LayoutRight, _sizes<>, _sizes<5, 10>>,
std::tuple<int * [10], LayoutRight, _sizes<5>, _sizes<5, 10>>,
std::tuple<int**, LayoutRight, _sizes<5, 10>, _sizes<5, 10>>,
std::tuple<int[5][10][15], LayoutRight, _sizes<>, _sizes<5, 10, 15>>,
std::tuple<int * [10][15], LayoutRight, _sizes<5>, _sizes<5, 10, 15>>,
std::tuple<int* * [15], LayoutRight, _sizes<5, 10>, _sizes<5, 10, 15>>,
std::tuple<int***, LayoutRight, _sizes<5, 10, 15>, _sizes<5, 10, 15>>,
// LayoutStride
std::tuple<int, LayoutStride, _sizes<>, _sizes<>>,
std::tuple<int[5], LayoutStride, _sizes<>, _sizes<5>>,
std::tuple<int*, LayoutStride, _sizes<5>, _sizes<5>>,
std::tuple<int[5][10], LayoutStride, _sizes<>, _sizes<5, 10>>,
std::tuple<int * [10], LayoutStride, _sizes<5>, _sizes<5, 10>>,
std::tuple<int**, LayoutStride, _sizes<5, 10>, _sizes<5, 10>>,
std::tuple<int[5][10][15], LayoutStride, _sizes<>, _sizes<5, 10, 15>>,
std::tuple<int * [10][15], LayoutStride, _sizes<5>, _sizes<5, 10, 15>>,
std::tuple<int* * [15], LayoutStride, _sizes<5, 10>, _sizes<5, 10, 15>>,
std::tuple<int***, LayoutStride, _sizes<5, 10, 15>, _sizes<5, 10, 15>>,
// Degenerated Sizes
std::tuple<int*, LayoutLeft, _sizes<0>, _sizes<0>>,
std::tuple<int * [10], LayoutLeft, _sizes<0>, _sizes<0, 10>>,
std::tuple<int* * [15], LayoutLeft, _sizes<0, 0>, _sizes<0, 0, 15>>,
std::tuple<int*, LayoutRight, _sizes<0>, _sizes<0>>,
std::tuple<int * [10], LayoutRight, _sizes<0>, _sizes<0, 10>>,
std::tuple<int* * [15], LayoutRight, _sizes<0, 0>, _sizes<0, 0, 15>>,
std::tuple<int*, LayoutStride, _sizes<0>, _sizes<0>>,
std::tuple<int * [10], LayoutStride, _sizes<0>, _sizes<0, 10>>,
std::tuple<int* * [15], LayoutStride, _sizes<0, 0>, _sizes<0, 0, 15>>>;
TYPED_TEST_SUITE(TestViewAPI, compatible_extents_test_types, );
TYPED_TEST(TestViewAPI, sizes) {
using view_t = typename TestFixture::view_type;
auto a = this->create_view();
static_assert(view_t::rank == TestFixture::expected_rank,
"TestViewAPI: Error: rank mismatch");
size_t expected_span = 1;
for (int r = 0; r < view_t::rank; r++) expected_span *= this->all_sizes[r];
EXPECT_EQ(expected_span, a.span());
for (int r = 0; r < view_t::rank; r++) {
EXPECT_EQ(this->all_sizes[r], a.extent(r));
EXPECT_EQ(this->all_sizes[r], size_t(a.extent_int(r)));
}
}

View File

@ -13,6 +13,7 @@ file(GLOB KOKKOS_ALGORITHMS_HEADERS RELATIVE ${BASE_DIR}/algorithms/src
foreach (_header ${KOKKOS_CORE_HEADERS} ${KOKKOS_CONTAINERS_HEADERS} ${KOKKOS_ALGORITHMS_HEADERS})
string(REGEX REPLACE "[\./]" "_" header_test_name ${_header})
set(header_test_name Kokkos_HeaderSelfContained_${header_test_name})
set_source_files_properties(tstHeader.cpp PROPERTIES LANGUAGE ${KOKKOS_COMPILE_LANGUAGE})
add_executable(${header_test_name} tstHeader.cpp)
target_link_libraries(${header_test_name} PRIVATE Kokkos::kokkos)
target_compile_definitions(${header_test_name} PRIVATE KOKKOS_HEADER_TEST_NAME=${_header})

View File

@ -46,7 +46,7 @@
#include <TestHPX_Category.hpp>
#include <hpx/config.hpp>
#include <hpx/include/lcos.hpp>
#include <hpx/local/future.hpp>
#ifdef KOKKOS_ENABLE_HPX_ASYNC_DISPATCH
#ifndef HPX_COMPUTE_DEVICE_CODE
@ -153,7 +153,7 @@ TEST(hpx, independent_instances) {
// future<void>>> (return type of when_all) into a future<void> which is
// ready whenever the un-collapsed future would've been ready. HPX does not
// currently have the functionality to collapse this automatically.
Kokkos::Experimental::HPX hpx4(hpx::util::get<0>(hpx::split_future(
Kokkos::Experimental::HPX hpx4(hpx::get<0>(hpx::split_future(
hpx::when_all(hpx2.impl_get_future(), hpx3.impl_get_future()))));
Kokkos::parallel_for(
"Test::hpx::independent_instances::pointwise_sum",

View File

@ -45,7 +45,7 @@
#include <Kokkos_Core.hpp>
#include <TestHPX_Category.hpp>
#include <hpx/include/lcos.hpp>
#include <hpx/local/future.hpp>
#ifdef KOKKOS_ENABLE_HPX_ASYNC_DISPATCH

View File

@ -45,6 +45,8 @@
#include <Kokkos_Core.hpp>
#include <TestHPX_Category.hpp>
#include <hpx/local/future.hpp>
#ifdef KOKKOS_ENABLE_HPX_ASYNC_DISPATCH
namespace Test {
@ -54,35 +56,49 @@ TEST(hpx, instance_ids) {
Kokkos::initialize(arguments);
{
Kokkos::Experimental::HPX hpx_global1;
Kokkos::Experimental::HPX hpx_global2 = hpx_global1;
Kokkos::Experimental::HPX hpx_global3{hpx_global1};
Kokkos::Experimental::HPX hpx_global4(
Kokkos::Experimental::HPX::instance_mode::global);
Kokkos::Experimental::HPX hpx_default1;
Kokkos::Experimental::HPX hpx_default2 = hpx_default1;
Kokkos::Experimental::HPX hpx_default3{hpx_default1};
Kokkos::Experimental::HPX hpx_default4(
Kokkos::Experimental::HPX::instance_mode::default_);
Kokkos::Experimental::HPX hpx_default5;
hpx_default5 = hpx_default1;
ASSERT_EQ(0, hpx_global1.impl_instance_id());
ASSERT_EQ(0, hpx_global2.impl_instance_id());
ASSERT_EQ(0, hpx_global3.impl_instance_id());
ASSERT_EQ(0, hpx_global4.impl_instance_id());
ASSERT_EQ(Kokkos::Experimental::HPX::impl_default_instance_id(),
hpx_default1.impl_instance_id());
ASSERT_EQ(Kokkos::Experimental::HPX::impl_default_instance_id(),
hpx_default2.impl_instance_id());
ASSERT_EQ(Kokkos::Experimental::HPX::impl_default_instance_id(),
hpx_default3.impl_instance_id());
ASSERT_EQ(Kokkos::Experimental::HPX::impl_default_instance_id(),
hpx_default4.impl_instance_id());
ASSERT_EQ(Kokkos::Experimental::HPX::impl_default_instance_id(),
hpx_default5.impl_instance_id());
Kokkos::Experimental::HPX hpx_independent1(
Kokkos::Experimental::HPX::instance_mode::independent);
Kokkos::Experimental::HPX hpx_independent2 = hpx_independent1;
Kokkos::Experimental::HPX hpx_independent3{hpx_independent1};
Kokkos::Experimental::HPX hpx_independent4;
hpx_independent4 = hpx_independent1;
ASSERT_NE(hpx_global1.impl_instance_id(),
ASSERT_NE(hpx_default1.impl_instance_id(),
hpx_independent1.impl_instance_id());
ASSERT_EQ(hpx_independent1.impl_instance_id(),
hpx_independent2.impl_instance_id());
ASSERT_EQ(hpx_independent1.impl_instance_id(),
hpx_independent3.impl_instance_id());
ASSERT_EQ(hpx_independent1.impl_instance_id(),
hpx_independent4.impl_instance_id());
hpx::shared_future<void> f = hpx::make_ready_future<void>();
Kokkos::Experimental::HPX hpx_independent_future1(f);
Kokkos::Experimental::HPX hpx_independent_future2 = hpx_independent_future1;
Kokkos::Experimental::HPX hpx_independent_future3{hpx_independent_future1};
Kokkos::Experimental::HPX hpx_independent_future4;
hpx_independent_future4 = hpx_independent_future1;
ASSERT_NE(hpx_global1.impl_instance_id(),
ASSERT_NE(hpx_default1.impl_instance_id(),
hpx_independent1.impl_instance_id());
ASSERT_NE(hpx_independent1.impl_instance_id(),
hpx_independent_future1.impl_instance_id());
@ -90,6 +106,8 @@ TEST(hpx, instance_ids) {
hpx_independent_future2.impl_instance_id());
ASSERT_EQ(hpx_independent_future1.impl_instance_id(),
hpx_independent_future3.impl_instance_id());
ASSERT_EQ(hpx_independent_future1.impl_instance_id(),
hpx_independent_future4.impl_instance_id());
}
Kokkos::finalize();

View File

@ -104,7 +104,7 @@ TEST(TEST_CATEGORY, IncrTest_01_execspace_typedef) {
}
TEST(TEST_CATEGORY, IncrTest_01_execspace) {
ASSERT_TRUE(Kokkos::is_execution_space<TEST_EXECSPACE>::value);
ASSERT_FALSE(!Kokkos::is_execution_space<TEST_EXECSPACE>::value);
ASSERT_FALSE(Kokkos::is_execution_space<
TestIncrExecSpaceTypedef<TEST_EXECSPACE>>::value);
TestIncrExecSpace<TEST_EXECSPACE> test;

View File

@ -110,6 +110,7 @@ struct TestParallel_For {
// Copy the data back to Host memory space
Kokkos::Impl::DeepCopy<h_memspace_type, d_memspace_type>(
hostData, deviceData, num_elements * sizeof(value_type));
Kokkos::fence("Fence after copying data to host memory space");
// Check if all data has been update correctly
correctness_check(hostData);

View File

@ -170,6 +170,7 @@ struct TestMDRangePolicy {
// Copy the data back to Host memory space
Kokkos::Impl::DeepCopy<h_memspace_type, d_memspace_type>(
hostData, deviceData, num_elements * sizeof(value_type));
Kokkos::fence("Fence after copying data to host");
// Check if all data has been update correctly
compare_equal_2D();
@ -201,6 +202,7 @@ struct TestMDRangePolicy {
// Copy the data back to Host memory space
Kokkos::Impl::DeepCopy<h_memspace_type, d_memspace_type>(
hostData, deviceData, num_elements * sizeof(value_type));
Kokkos::fence("Fence after copying data to host");
// Check if all data has been update correctly
compare_equal_3D();
@ -232,6 +234,7 @@ struct TestMDRangePolicy {
// Copy the data back to Host memory space
Kokkos::Impl::DeepCopy<h_memspace_type, d_memspace_type>(
hostData, deviceData, num_elements * sizeof(value_type));
Kokkos::fence("Fence after copying data to host");
// Check if all data has been update correctly
compare_equal_4D();

View File

@ -50,6 +50,7 @@
namespace Test {
#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_3
TEST(openmp, partition_master) {
using Mutex = Kokkos::Experimental::MasterLock<Kokkos::OpenMP>;
@ -128,5 +129,6 @@ TEST(openmp, partition_master) {
Kokkos::OpenMP::partition_master(master, 8, 8);
ASSERT_EQ(errors, 0);
}
#endif
} // namespace Test

View File

@ -49,7 +49,10 @@ namespace Test {
// Test Interoperability with SYCL Streams
TEST(sycl, raw_sycl_queues) {
sycl::default_selector device_selector;
sycl::queue queue(device_selector);
// FIXME_SYCL using an in-order queue here should not be necessary since we
// are using submit_barrier for managing kernel dependencies but this seems to
// be required as a hot fix for now.
sycl::queue queue(device_selector, sycl::property::queue::in_order());
Kokkos::InitArguments arguments{-1, -1, -1, false};
Kokkos::initialize(arguments);
int* p = sycl::malloc_device<int>(100, queue);

View File

@ -42,6 +42,7 @@
//@HEADER
*/
#include <Kokkos_Core.hpp>
#include <impl/Kokkos_Tools_Generic.hpp>
using ExecSpace = Kokkos::DefaultHostExecutionSpace;
using TeamMember = Kokkos::TeamPolicy<ExecSpace>::member_type;
struct TestTeamFunctor {
@ -57,11 +58,11 @@ int main(int argc, char* argv[]) {
Kokkos::MDRangePolicy<Kokkos::Rank<2>> mdp({0, 0}, {1, 1});
Kokkos::Tools::Experimental::TeamSizeTuner team_tune_this(
"team_tuner", teamp, TestTeamFunctor{}, Kokkos::ParallelForTag{},
Kokkos::Tools::Impl::Impl::SimpleTeamSizeCalculator{});
Kokkos::Tools::Experimental::Impl::Impl::SimpleTeamSizeCalculator{});
Kokkos::Tools::Experimental::MDRangeTuner<2> md_tune_this(
"md_tuner", mdp, TestMDFunctor{}, Kokkos::ParallelForTag{},
Kokkos::Tools::Impl::Impl::SimpleTeamSizeCalculator{});
Kokkos::Tools::Experimental::Impl::Impl::SimpleTeamSizeCalculator{});
std::vector<int> options{1, 2, 3, 4, 5};

View File

@ -1,2 +1,2 @@
#include <impl/Kokkos_Profiling_C_Interface.h>
int main(){}
int main() {}

View File

@ -46,4 +46,3 @@
#include "Kokkos_Core.hpp"
#include <tools/TestEventCorrectness.hpp>
#include "../UnitTestMainInit.cpp"

View File

@ -48,6 +48,8 @@
#include <impl/Kokkos_Stacktrace.hpp>
#include <vector>
#include <algorithm>
#include "Kokkos_Core_fwd.hpp"
#include "include/ToolTestingUtilities.hpp"
namespace Kokkos {
class Serial;
class OpenMP;
@ -118,9 +120,19 @@ struct increment {
constexpr static const int size = 0;
};
int num_instances = 1;
using index_type = Kokkos::RangePolicy<>::index_type;
struct TestFunctor {
KOKKOS_FUNCTION void operator()(const int) const {}
KOKKOS_FUNCTION void operator()(const index_type) const {}
};
struct TestReduceFunctor {
using value_type = int;
KOKKOS_FUNCTION void operator()(const index_type, value_type&) const {}
};
struct TestScanFunctor {
using value_type = int;
KOKKOS_FUNCTION void operator()(const index_type, value_type&, bool) const {}
};
template <typename Lambda>
void test_wrapper(const Lambda& lambda) {
if (!std::is_same<Kokkos::DefaultExecutionSpace, Kokkos::Serial>::value) {
@ -131,7 +143,7 @@ void test_wrapper(const Lambda& lambda) {
* Test that fencing an instance with a name yields a fence
* event of that name, and the correct device ID
*/
TEST(defaultdevicetype, test_named_instance_fence) {
TEST(kokkosp, test_named_instance_fence) {
test_wrapper([&]() {
auto root = Kokkos::Tools::Experimental::device_id_root<
Kokkos::DefaultExecutionSpace>();
@ -150,7 +162,7 @@ TEST(defaultdevicetype, test_named_instance_fence) {
* Test that fencing an instance without a name yields a fence
* event of a correct name, and the correct device ID
*/
TEST(defaultdevicetype, test_unnamed_instance_fence) {
TEST(kokkosp, test_unnamed_instance_fence) {
test_wrapper([&]() {
auto root = Kokkos::Tools::Experimental::device_id_root<
Kokkos::DefaultExecutionSpace>();
@ -170,7 +182,7 @@ TEST(defaultdevicetype, test_unnamed_instance_fence) {
* Test that invoking a global fence with a name yields a fence
* event of a correct name, and fences the root of the default device
*/
TEST(defaultdevicetype, test_named_global_fence) {
TEST(kokkosp, test_named_global_fence) {
test_wrapper([&]() {
auto root = Kokkos::Tools::Experimental::device_id_root<
Kokkos::DefaultExecutionSpace>();
@ -187,7 +199,7 @@ TEST(defaultdevicetype, test_named_global_fence) {
* Test that invoking a global fence with no name yields a fence
* event of a correct name, and fences the root of the default device
*/
TEST(defaultdevicetype, test_unnamed_global_fence) {
TEST(kokkosp, test_unnamed_global_fence) {
test_wrapper([&]() {
auto root = Kokkos::Tools::Experimental::device_id_root<
Kokkos::DefaultExecutionSpace>();
@ -204,7 +216,7 @@ TEST(defaultdevicetype, test_unnamed_global_fence) {
* Test that creating two default instances and fencing both yields
* fence on the same device ID, as these should yield the same instance
*/
TEST(defaultdevicetype, test_multiple_default_instances) {
TEST(kokkosp, test_multiple_default_instances) {
test_wrapper([&]() {
std::vector<FencePayload> expected{};
expect_fence_events(expected, [=]() {
@ -217,10 +229,29 @@ TEST(defaultdevicetype, test_multiple_default_instances) {
});
}
/**
* Test that device_id() and identifier_from_devid(id) are reciprocal
* operations
*/
TEST(kokkosp, test_id_gen) {
using namespace Kokkos::Tools::Experimental;
using Kokkos::Tools::Experimental::DeviceTypeTraits;
test_wrapper([&]() {
Kokkos::DefaultExecutionSpace ex;
auto id = device_id(ex);
auto id_ref = identifier_from_devid(id);
auto success = (id_ref.instance_id == ex.impl_instance_id()) &&
(id_ref.device_id ==
static_cast<uint32_t>(
DeviceTypeTraits<Kokkos::DefaultExecutionSpace>::id));
ASSERT_TRUE(success);
});
}
/**
* Test that fencing and kernels yield events on the correct device ID's
*/
TEST(defaultdevicetype, test_kernel_sequence) {
TEST(kokkosp, test_kernel_sequence) {
test_wrapper([&]() {
auto root = Kokkos::Tools::Experimental::device_id_root<
Kokkos::DefaultExecutionSpace>();
@ -248,7 +279,7 @@ TEST(defaultdevicetype, test_kernel_sequence) {
* CUDA ONLY: test that creating instances from streams leads to events
* on different device ID's
*/
TEST(defaultdevicetype, test_streams) {
TEST(kokkosp, test_streams) {
test_wrapper([&]() {
// auto root = Kokkos::Tools::Experimental::device_id_root<
// Kokkos::DefaultExecutionSpace>();
@ -268,17 +299,366 @@ TEST(defaultdevicetype, test_streams) {
found_payloads.erase(
std::remove_if(found_payloads.begin(), found_payloads.end(),
[&](const auto& entry) {
return (
entry.name.find("Fence on space initialization") !=
std::string::npos);
return (entry.name.find("Unnamed Instance Fence") ==
std::string::npos);
}),
found_payloads.end());
ASSERT_TRUE(found_payloads[0].dev_id != found_payloads[1].dev_id);
ASSERT_TRUE(found_payloads[2].dev_id != found_payloads[1].dev_id);
ASSERT_TRUE(found_payloads[2].dev_id != found_payloads[0].dev_id);
ASSERT_NE(found_payloads[0].dev_id, found_payloads[1].dev_id);
ASSERT_NE(found_payloads[2].dev_id, found_payloads[1].dev_id);
ASSERT_NE(found_payloads[2].dev_id, found_payloads[0].dev_id);
});
}
#endif
/** FIXME: OpenMPTarget currently has unexpected fences */
#ifndef KOKKOS_ENABLE_OPENMPTARGET
TEST(kokkosp, async_deep_copy) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableFences());
Kokkos::View<float*> left("left", 5), right("right", 5);
auto success = validate_absence(
[&]() {
Kokkos::deep_copy(Kokkos::DefaultExecutionSpace(), left, right);
},
[&](BeginFenceEvent begin) {
if (begin.deviceID !=
Kokkos::DefaultExecutionSpace().impl_instance_id()) {
std::stringstream error_message;
error_message
<< "Fence encountered outside of the default instance, default: "
<< Kokkos::DefaultExecutionSpace().impl_instance_id()
<< ", encountered " << begin.deviceID << " , fence name "
<< begin.name;
return MatchDiagnostic{true, {error_message.str()}};
}
return MatchDiagnostic{false};
});
ASSERT_TRUE(success);
}
#endif
TEST(kokkosp, parallel_for) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableKernels());
auto success = validate_event_set(
[=]() {
TestFunctor tf;
Kokkos::parallel_for("dogs", Kokkos::RangePolicy<>(0, 1), tf);
},
[=](BeginParallelForEvent begin_event, EndParallelForEvent end_event) {
if (begin_event.name != "dogs") {
return MatchDiagnostic{false, {"No match on BeginParallelFor name"}};
}
if (end_event.kID != ((begin_event.kID))) {
return MatchDiagnostic{false, {"No match on kID's"}};
}
return MatchDiagnostic{true};
});
ASSERT_TRUE(success);
}
TEST(kokkosp, parallel_reduce) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableKernels());
auto success = validate_event_set(
[=]() {
TestReduceFunctor tf;
int result;
Kokkos::parallel_reduce("dogs", Kokkos::RangePolicy<>(0, 1), tf,
Kokkos::Sum<int>(result));
},
[=](BeginParallelReduceEvent begin_event,
EndParallelReduceEvent end_event) {
if (begin_event.name != "dogs") {
return MatchDiagnostic{false,
{"No match on BeginParallelReduce name"}};
}
if (end_event.kID != ((begin_event.kID))) {
return MatchDiagnostic{false, {"No match on kID's"}};
}
return MatchDiagnostic{true};
});
ASSERT_TRUE(success);
}
TEST(kokkosp, parallel_scan) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableKernels());
auto success = validate_event_set(
[=]() {
TestScanFunctor tf;
Kokkos::parallel_scan("dogs", Kokkos::RangePolicy<>(0, 1), tf);
},
[=](BeginParallelScanEvent begin_event, EndParallelScanEvent end_event) {
if (begin_event.name != "dogs") {
return MatchDiagnostic{false, {"No match on BeginParallelScan name"}};
}
if (end_event.kID != ((begin_event.kID))) {
return MatchDiagnostic{false, {"No match on kID's"}};
}
return MatchDiagnostic{true};
});
// Currently, this test is known to fail with OpenMPTarget
#ifndef KOKKOS_ENABLE_OPENMPTARGET
ASSERT_TRUE(success);
#else
(void)success;
#endif
}
TEST(kokkosp, regions) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableRegions());
auto success = validate_event_set(
[=]() {
Kokkos::Tools::pushRegion("dogs");
Kokkos::Tools::popRegion();
},
[=](PushRegionEvent push_event, PopRegionEvent) {
if (push_event.name != "dogs") {
return MatchDiagnostic{false, {"No match on PushRegion name"}};
}
return MatchDiagnostic{true};
});
ASSERT_TRUE(success);
}
TEST(kokkosp, fences) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableFences());
auto success = validate_event_set(
[=]() { Kokkos::DefaultExecutionSpace().fence("dogs"); },
[=](BeginFenceEvent begin_event, EndFenceEvent end_event) {
if (begin_event.name != "dogs") {
return MatchDiagnostic{false, {"No match on BeginFence name"}};
}
if (end_event.kID != ((begin_event.kID))) {
return MatchDiagnostic{false, {"No match on kID's"}};
}
return MatchDiagnostic{true};
});
ASSERT_TRUE(success);
}
TEST(kokkosp, raw_allocation) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableAllocs());
auto success = validate_event_set(
[=]() {
void* foo =
Kokkos::kokkos_malloc<Kokkos::DefaultExecutionSpace::memory_space>(
"dogs", 1000);
Kokkos::kokkos_free(foo);
},
[=](AllocateDataEvent alloc, DeallocateDataEvent free) {
if (alloc.name != "dogs") {
return MatchDiagnostic{false, {"No match on alloc name"}};
}
if (alloc.size != 1000) {
return MatchDiagnostic{false, {"No match on alloc size"}};
}
if (alloc.ptr != free.ptr) {
return MatchDiagnostic{false, {"No match on pointers"}};
}
if (free.name != "dogs") {
return MatchDiagnostic{false, {"No match on free name"}};
}
if (free.size != 1000) {
return MatchDiagnostic{false, {"No match on free size"}};
}
return MatchDiagnostic{true};
});
// Currently, this test is known to fail with OpenMPTarget
#ifndef KOKKOS_ENABLE_OPENMPTARGET
ASSERT_TRUE(success);
#else
(void)success;
#endif
}
TEST(kokkosp, view) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableAllocs());
auto success = validate_event_set(
[=]() { Kokkos::View<float*> dogs("dogs", 1000); },
[=](AllocateDataEvent alloc, DeallocateDataEvent free) {
if (alloc.name != "dogs") {
return MatchDiagnostic{false, {"No match on alloc name"}};
}
if (alloc.size != 1000 * sizeof(float)) {
return MatchDiagnostic{false, {"No match on alloc size"}};
}
if (alloc.ptr != free.ptr) {
return MatchDiagnostic{false, {"No match on pointers"}};
}
if (free.name != "dogs") {
return MatchDiagnostic{false, {"No match on free name"}};
}
if (free.size != 1000 * sizeof(float)) {
return MatchDiagnostic{false, {"No match on free size"}};
}
return MatchDiagnostic{true};
});
// Currently, this test is known to fail with OpenMPTarget
#ifndef KOKKOS_ENABLE_OPENMPTARGET
ASSERT_TRUE(success);
#else
(void)success;
#endif
}
TEST(kokkosp, sections) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableSections());
auto success = validate_event_set(
[=]() {
uint32_t section_id;
Kokkos::Tools::createProfileSection("dogs", &section_id);
Kokkos::Tools::startSection(section_id);
Kokkos::Tools::stopSection(section_id);
Kokkos::Tools::destroyProfileSection(section_id);
},
[=](CreateProfileSectionEvent create, StartProfileSectionEvent start,
StopProfileSectionEvent stop, DestroyProfileSectionEvent destroy) {
if (create.name != "dogs") {
return MatchDiagnostic{false, {"No match on section name"}};
}
if ((create.id != start.id) || (stop.id != start.id) ||
(stop.id != destroy.id)) {
return MatchDiagnostic{false, {"No match on section IDs"}};
}
return MatchDiagnostic{true};
});
ASSERT_TRUE(success);
}
TEST(kokkosp, metadata) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableMetadata());
auto success = validate_event_set(
[=]() {
/** Attempts to decrease the value of dog_goodness will be rejected on
* review */
Kokkos::Tools::declareMetadata("dog_goodness", "infinity");
},
[=](DeclareMetadataEvent meta) {
if (meta.key != "dog_goodness") {
return MatchDiagnostic{false, {"No match on metadata key"}};
}
if (meta.value != "infinity") {
return MatchDiagnostic{false, {"No match on metadata value"}};
}
return MatchDiagnostic{true};
});
ASSERT_TRUE(success);
}
TEST(kokkosp, profile_events) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableProfileEvents());
auto success = validate_event_set(
[=]() { Kokkos::Tools::markEvent("dog_goodness>=infinity"); },
[=](ProfileEvent event) {
if (event.name != "dog_goodness>=infinity") {
return MatchDiagnostic{false, {"No match on profiled event name"}};
}
return MatchDiagnostic{true};
});
ASSERT_TRUE(success);
}
#if defined(KOKKOS_ENABLE_TUNING)
TEST(kokkosp, tuning_sequence) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableTuning());
size_t input_id, output_id;
Kokkos::Tools::Experimental::VariableInfo input_info;
input_info.type = Kokkos::Tools::Experimental::ValueType::kokkos_value_int64;
input_info.category = Kokkos::Tools::Experimental::StatisticalCategory::
kokkos_value_categorical;
input_info.valueQuantity =
Kokkos::Tools::Experimental::CandidateValueType::kokkos_value_unbounded;
Kokkos::Tools::Experimental::VariableInfo output_info = input_info;
output_info.valueQuantity =
Kokkos::Tools::Experimental::CandidateValueType::kokkos_value_set;
std::vector<int64_t> values{1, 2, 3, 4, 5};
output_info.candidates = Kokkos::Tools::Experimental::make_candidate_set(
values.size(), values.data());
auto success = validate_event_set(
[&]() {
input_id = Kokkos::Tools::Experimental::declare_input_type("input.dogs",
input_info);
output_id = Kokkos::Tools::Experimental::declare_output_type(
"output.dogs", output_info);
auto next_context = Kokkos::Tools::Experimental::get_new_context_id();
Kokkos::Tools::Experimental::begin_context(next_context);
Kokkos::Tools::Experimental::VariableValue feature_value =
Kokkos::Tools::Experimental::make_variable_value(input_id,
int64_t(0));
Kokkos::Tools::Experimental::VariableValue tuning_value =
Kokkos::Tools::Experimental::make_variable_value(output_id,
int64_t(1));
Kokkos::Tools::Experimental::set_input_values(next_context, 1,
&feature_value);
Kokkos::Tools::Experimental::request_output_values(next_context, 1,
&tuning_value);
Kokkos::Tools::Experimental::end_context(next_context);
},
[&](DeclareInputTypeEvent input, DeclareOutputTypeEvent output) {
if (input.variable_id != input_id) {
return MatchDiagnostic{false, {"No match on input id"}};
}
if (output.variable_id != output_id) {
return MatchDiagnostic{false, {"No match on output id"}};
}
if (output.info.candidates.set.size != 5) {
return MatchDiagnostic{
false, {"Candidates not properly passed through tuning system"}};
}
return MatchDiagnostic{true};
},
[=](BeginContextEvent) { return MatchDiagnostic{true}; },
[&](RequestOutputValuesEvent value_request) {
if (value_request.inputs[0].metadata->type != input_info.type) {
return MatchDiagnostic{false, {"No match on input in request"}};
}
if (value_request.outputs[0].metadata->type != output_info.type) {
return MatchDiagnostic{false, {"No match on output in request"}};
}
return MatchDiagnostic{true};
},
[=](EndContextEvent) { return MatchDiagnostic{true}; });
ASSERT_TRUE(success);
}
#endif
TEST(kokkosp, no_init_kernel) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableKernels());
auto success = validate_absence(
[=]() {
Kokkos::View<float*> not_inited(
Kokkos::ViewAllocateWithoutInitializing("no_inits_here_dog"), 100);
},
[=](BeginParallelForEvent) {
return MatchDiagnostic{true, {"Found begin event"}};
},
[=](EndParallelForEvent) {
return MatchDiagnostic{true, {"Found end event"}};
});
ASSERT_TRUE(success);
}
TEST(kokkosp, get_events) {
using namespace Kokkos::Test::Tools;
auto event_vector = get_event_set([=]() {
Kokkos::Tools::pushRegion("dogs");
Kokkos::Tools::popRegion();
});
for (const auto& ptr : event_vector) {
auto ptr_as_begin = std::dynamic_pointer_cast<BeginParallelForEvent>(ptr);
ASSERT_TRUE(ptr_as_begin == nullptr);
}
}
} // namespace Test

View File

@ -0,0 +1,58 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <impl/Kokkos_Tools.hpp>
int main(int argc, char* argv[]) {
Kokkos::Tools::initialize(argc, argv);
Kokkos::Tools::pushRegion(
"The unanimous Declaration of the thirteen united States of America, "
"When in the Course of human events, it becomes necessary for one people "
"to dissolve the political bands which have connected them with another, "
"and to assume among the powers of the earth, the separate and equal "
"station to which the Laws of Nature and of Nature's God entitle them, a "
"decent respect to the opinions of mankind requires that they should "
"declare the causes which impel them to the separation.");
Kokkos::Tools::popRegion();
Kokkos::Tools::finalize();
}

View File

@ -173,6 +173,7 @@ void test_allowed_access() {
"access_allowed",
Kokkos::RangePolicy<typename Space::execution_space>(0, data_size),
functor);
Kokkos::fence();
}
using semantically_independent_logical_space =

View File

@ -0,0 +1,143 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <Kokkos_Profiling_ProfileSection.hpp>
#include <gtest/gtest.h>
namespace {
struct Section {
std::string name;
int start_call_cnt;
int stop_call_cnt;
int is_destroyed;
friend std::ostream& operator<<(std::ostream& os, Section const& s) {
os << "( " << s.name << ", " << s.start_call_cnt << ", " << s.stop_call_cnt
<< ", " << s.is_destroyed << " )";
return os;
}
friend bool operator==(Section const& l, Section const& r) {
return (l.name == r.name) && (l.start_call_cnt == r.start_call_cnt) &&
(l.stop_call_cnt == r.stop_call_cnt) &&
(l.is_destroyed == r.is_destroyed);
}
};
std::vector<Section> kokkosp_test_section_vector;
void kokkosp_test_create_section(char const* label, std::uint32_t* id) {
*id = kokkosp_test_section_vector.size();
kokkosp_test_section_vector.emplace_back(Section{label, 0, 0, 0});
}
void kokkosp_test_start_section(std::uint32_t id) {
++kokkosp_test_section_vector[id].start_call_cnt;
}
void kokkosp_test_stop_section(std::uint32_t id) {
++kokkosp_test_section_vector[id].stop_call_cnt;
}
void kokkosp_test_destroy_section(std::uint32_t id) {
++kokkosp_test_section_vector[id].is_destroyed;
}
} // namespace
TEST(defaultdevicetype, profiling_section) {
Kokkos::Profiling::Experimental::set_create_profile_section_callback(
kokkosp_test_create_section);
Kokkos::Profiling::Experimental::set_destroy_profile_section_callback(
kokkosp_test_destroy_section);
Kokkos::Profiling::Experimental::set_start_profile_section_callback(
kokkosp_test_start_section);
Kokkos::Profiling::Experimental::set_stop_profile_section_callback(
kokkosp_test_stop_section);
ASSERT_TRUE(kokkosp_test_section_vector.empty());
{
Kokkos::Profiling::ProfilingSection profile_1("one");
ASSERT_EQ(kokkosp_test_section_vector.size(), 1u);
ASSERT_EQ(kokkosp_test_section_vector[0], (Section{"one", 0, 0, 0}));
// NOTE: ProfilingSection is a wrapper that manages the lifetime of the
// underlying section but does not care whether the start and stop call
// sequence makes any sense.
profile_1.stop();
profile_1.stop();
profile_1.start();
profile_1.start();
profile_1.start();
ASSERT_EQ(kokkosp_test_section_vector[0], (Section{"one", 3, 2, 0}));
{
Kokkos::Profiling::ProfilingSection profile_2("two");
profile_2.start();
}
ASSERT_EQ(kokkosp_test_section_vector.size(), 2u);
ASSERT_EQ(kokkosp_test_section_vector[1], (Section{"two", 1, 0, 1}));
profile_1.start();
profile_1.start();
}
ASSERT_EQ(kokkosp_test_section_vector.size(), 2u);
ASSERT_EQ(kokkosp_test_section_vector[0], (Section{"one", 5, 2, 1}));
ASSERT_EQ(kokkosp_test_section_vector[1], (Section{"two", 1, 0, 1}));
// Cleanup
kokkosp_test_section_vector.clear();
Kokkos::Tools::Experimental::set_create_profile_section_callback(nullptr);
Kokkos::Tools::Experimental::set_destroy_profile_section_callback(nullptr);
Kokkos::Tools::Experimental::set_start_profile_section_callback(nullptr);
Kokkos::Tools::Experimental::set_stop_profile_section_callback(nullptr);
}
using Kokkos::Profiling::ProfilingSection;
static_assert(!std::is_default_constructible<ProfilingSection>::value, "");
static_assert(!std::is_copy_constructible<ProfilingSection>::value, "");
static_assert(!std::is_move_constructible<ProfilingSection>::value, "");
static_assert(!std::is_copy_assignable<ProfilingSection>::value, "");
static_assert(!std::is_move_assignable<ProfilingSection>::value, "");

View File

@ -0,0 +1,77 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// 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 NTESS "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 NTESS 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 Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#include "include/ToolTestingUtilities.hpp"
TEST(kokkosp, create_mirror_no_init) {
using namespace Kokkos::Test::Tools;
listen_tool_events(Config::DisableAll(), Config::EnableKernels());
Kokkos::View<int*, Kokkos::DefaultExecutionSpace> device_view("device view",
10);
Kokkos::View<int*, Kokkos::HostSpace> host_view("host view", 10);
auto success = validate_absence(
[&]() {
auto mirror_device =
Kokkos::create_mirror(Kokkos::WithoutInitializing, device_view);
auto mirror_host =
Kokkos::create_mirror(Kokkos::WithoutInitializing,
Kokkos::DefaultExecutionSpace{}, host_view);
auto mirror_device_view = Kokkos::create_mirror_view(
Kokkos::WithoutInitializing, device_view);
auto mirror_host_view = Kokkos::create_mirror_view(
Kokkos::WithoutInitializing, Kokkos::DefaultExecutionSpace{},
host_view);
},
[&](BeginParallelForEvent) {
return MatchDiagnostic{true, {"Found begin event"}};
},
[&](EndParallelForEvent) {
return MatchDiagnostic{true, {"Found end event"}};
});
ASSERT_TRUE(success);
}

File diff suppressed because it is too large Load Diff