Update Kokkos library in LAMMPS to v3.0

This commit is contained in:
Stan Moore
2020-03-25 14:08:39 -06:00
parent 0252d8c210
commit 60864e38d1
2169 changed files with 121406 additions and 126492 deletions

View File

@ -1,12 +1,12 @@
TRIBITS_SUBPACKAGE(Algorithms)
IF(KOKKOS_HAS_TRILINOS)
ADD_SUBDIRECTORY(src)
ENDIF()
TRIBITS_ADD_TEST_DIRECTORIES(unit_tests)
#TRIBITS_ADD_TEST_DIRECTORIES(performance_tests)
TRIBITS_SUBPACKAGE_POSTPROCESS()
KOKKOS_SUBPACKAGE(Algorithms)
ADD_SUBDIRECTORY(src)
KOKKOS_ADD_TEST_DIRECTORIES(unit_tests)
KOKKOS_SUBPACKAGE_POSTPROCESS()

View File

@ -1,8 +1,9 @@
TRIBITS_CONFIGURE_FILE(${PACKAGE_NAME}_config.h)
KOKKOS_CONFIGURE_FILE(${PACKAGE_NAME}_config.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
#I have to leave these here for tribits
KOKKOS_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
KOKKOS_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
#-----------------------------------------------------------------------------
@ -12,10 +13,18 @@ LIST(APPEND HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}_config.h)
#-----------------------------------------------------------------------------
TRIBITS_ADD_LIBRARY(
kokkosalgorithms
HEADERS ${HEADERS}
SOURCES ${SOURCES}
DEPLIBS
)
# We have to pass the sources in here for Tribits
# These will get ignored for standalone CMake and a true interface library made
KOKKOS_ADD_INTERFACE_LIBRARY(
kokkosalgorithms
HEADERS ${HEADERS}
SOURCES ${SOURCES}
)
KOKKOS_LIB_INCLUDE_DIRECTORIES(kokkosalgorithms
${KOKKOS_TOP_BUILD_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,14 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
//
// 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:
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -36,12 +37,11 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Christian R. Trott (crtrott@sandia.gov)
//
//
// ************************************************************************
//@HEADER
*/
#ifndef KOKKOS_SORT_HPP_
#define KOKKOS_SORT_HPP_
@ -51,125 +51,107 @@
namespace Kokkos {
namespace Impl {
namespace Impl {
template< class DstViewType , class SrcViewType
, int Rank = DstViewType::Rank >
struct CopyOp;
template <class DstViewType, class SrcViewType, int Rank = DstViewType::Rank>
struct CopyOp;
template< class DstViewType , class SrcViewType >
struct CopyOp<DstViewType,SrcViewType,1> {
KOKKOS_INLINE_FUNCTION
static void copy(DstViewType const& dst, size_t i_dst,
SrcViewType const& src, size_t i_src ) {
dst(i_dst) = src(i_src);
}
};
template< class DstViewType , class SrcViewType >
struct CopyOp<DstViewType,SrcViewType,2> {
KOKKOS_INLINE_FUNCTION
static void copy(DstViewType const& dst, size_t i_dst,
SrcViewType const& src, size_t i_src ) {
for(int j = 0;j< (int) dst.extent(1); j++)
dst(i_dst,j) = src(i_src,j);
}
};
template< class DstViewType , class SrcViewType >
struct CopyOp<DstViewType,SrcViewType,3> {
KOKKOS_INLINE_FUNCTION
static void copy(DstViewType const& dst, size_t i_dst,
SrcViewType const& src, size_t i_src ) {
for(int j = 0; j<dst.extent(1); j++)
for(int k = 0; k<dst.extent(2); k++)
dst(i_dst,j,k) = src(i_src,j,k);
}
};
template <class DstViewType, class SrcViewType>
struct CopyOp<DstViewType, SrcViewType, 1> {
KOKKOS_INLINE_FUNCTION
static void copy(DstViewType const& dst, size_t i_dst, SrcViewType const& src,
size_t i_src) {
dst(i_dst) = src(i_src);
}
};
template <class DstViewType, class SrcViewType>
struct CopyOp<DstViewType, SrcViewType, 2> {
KOKKOS_INLINE_FUNCTION
static void copy(DstViewType const& dst, size_t i_dst, SrcViewType const& src,
size_t i_src) {
for (int j = 0; j < (int)dst.extent(1); j++) dst(i_dst, j) = src(i_src, j);
}
};
template <class DstViewType, class SrcViewType>
struct CopyOp<DstViewType, SrcViewType, 3> {
KOKKOS_INLINE_FUNCTION
static void copy(DstViewType const& dst, size_t i_dst, SrcViewType const& src,
size_t i_src) {
for (int j = 0; j < dst.extent(1); j++)
for (int k = 0; k < dst.extent(2); k++)
dst(i_dst, j, k) = src(i_src, j, k);
}
};
} // namespace Impl
//----------------------------------------------------------------------------
template< class KeyViewType
, class BinSortOp
, class Space = typename KeyViewType::device_type
, class SizeType = typename KeyViewType::memory_space::size_type
>
template <class KeyViewType, class BinSortOp,
class Space = typename KeyViewType::device_type,
class SizeType = typename KeyViewType::memory_space::size_type>
class BinSort {
public:
template< class DstViewType , class SrcViewType >
public:
template <class DstViewType, class SrcViewType>
struct copy_functor {
typedef typename SrcViewType::const_type src_view_type;
typedef typename SrcViewType::const_type src_view_type ;
typedef Impl::CopyOp<DstViewType, src_view_type> copy_op;
typedef Impl::CopyOp< DstViewType , src_view_type > copy_op ;
DstViewType dst_values;
src_view_type src_values;
int dst_offset;
DstViewType dst_values ;
src_view_type src_values ;
int dst_offset ;
copy_functor( DstViewType const & dst_values_
, int const & dst_offset_
, SrcViewType const & src_values_
)
: dst_values( dst_values_ )
, src_values( src_values_ )
, dst_offset( dst_offset_ )
{}
copy_functor(DstViewType const& dst_values_, int const& dst_offset_,
SrcViewType const& src_values_)
: dst_values(dst_values_),
src_values(src_values_),
dst_offset(dst_offset_) {}
KOKKOS_INLINE_FUNCTION
void operator() (const int& i) const {
copy_op::copy(dst_values,i+dst_offset,src_values,i);
void operator()(const int& i) const {
copy_op::copy(dst_values, i + dst_offset, src_values, i);
}
};
template< class DstViewType
, class PermuteViewType
, class SrcViewType
>
template <class DstViewType, class PermuteViewType, class SrcViewType>
struct copy_permute_functor {
// If a Kokkos::View then can generate constant random access
// otherwise can only use the constant type.
typedef typename std::conditional
< Kokkos::is_view< SrcViewType >::value
, Kokkos::View< typename SrcViewType::const_data_type
, typename SrcViewType::array_layout
, typename SrcViewType::device_type
, Kokkos::MemoryTraits<Kokkos::RandomAccess>
>
, typename SrcViewType::const_type
>::type src_view_type ;
typedef typename std::conditional<
Kokkos::is_view<SrcViewType>::value,
Kokkos::View<typename SrcViewType::const_data_type,
typename SrcViewType::array_layout,
typename SrcViewType::device_type,
Kokkos::MemoryTraits<Kokkos::RandomAccess> >,
typename SrcViewType::const_type>::type src_view_type;
typedef typename PermuteViewType::const_type perm_view_type ;
typedef typename PermuteViewType::const_type perm_view_type;
typedef Impl::CopyOp< DstViewType , src_view_type > copy_op ;
typedef Impl::CopyOp<DstViewType, src_view_type> copy_op;
DstViewType dst_values ;
perm_view_type sort_order ;
src_view_type src_values ;
int src_offset ;
DstViewType dst_values;
perm_view_type sort_order;
src_view_type src_values;
int src_offset;
copy_permute_functor( DstViewType const & dst_values_
, PermuteViewType const & sort_order_
, SrcViewType const & src_values_
, int const & src_offset_
)
: dst_values( dst_values_ )
, sort_order( sort_order_ )
, src_values( src_values_ )
, src_offset( src_offset_ )
{}
copy_permute_functor(DstViewType const& dst_values_,
PermuteViewType const& sort_order_,
SrcViewType const& src_values_, int const& src_offset_)
: dst_values(dst_values_),
sort_order(sort_order_),
src_values(src_values_),
src_offset(src_offset_) {}
KOKKOS_INLINE_FUNCTION
void operator() (const int& i) const {
copy_op::copy(dst_values,i,src_values,src_offset+sort_order(i));
void operator()(const int& i) const {
copy_op::copy(dst_values, i, src_values, src_offset + sort_order(i));
}
};
typedef typename Space::execution_space execution_space;
typedef typename Space::execution_space execution_space;
typedef BinSortOp bin_op_type;
struct bin_count_tag {};
@ -177,221 +159,236 @@ public:
struct bin_binning_tag {};
struct bin_sort_bins_tag {};
public:
public:
typedef SizeType size_type;
typedef size_type value_type;
typedef Kokkos::View<size_type*, Space> offset_type;
typedef Kokkos::View<const int*, Space> bin_count_type;
typedef typename KeyViewType::const_type const_key_view_type ;
typedef typename KeyViewType::const_type const_key_view_type;
// If a Kokkos::View then can generate constant random access
// otherwise can only use the constant type.
typedef typename std::conditional
< Kokkos::is_view< KeyViewType >::value
, Kokkos::View< typename KeyViewType::const_data_type,
typename KeyViewType::array_layout,
typename KeyViewType::device_type,
Kokkos::MemoryTraits<Kokkos::RandomAccess> >
, const_key_view_type
>::type const_rnd_key_view_type;
typedef typename std::conditional<
Kokkos::is_view<KeyViewType>::value,
Kokkos::View<typename KeyViewType::const_data_type,
typename KeyViewType::array_layout,
typename KeyViewType::device_type,
Kokkos::MemoryTraits<Kokkos::RandomAccess> >,
const_key_view_type>::type const_rnd_key_view_type;
typedef typename KeyViewType::non_const_value_type non_const_key_scalar;
typedef typename KeyViewType::const_value_type const_key_scalar;
typedef typename KeyViewType::const_value_type const_key_scalar;
typedef Kokkos::View<int*, Space, Kokkos::MemoryTraits<Kokkos::Atomic> > bin_count_atomic_type ;
private:
typedef Kokkos::View<int*, Space, Kokkos::MemoryTraits<Kokkos::Atomic> >
bin_count_atomic_type;
private:
const_key_view_type keys;
const_rnd_key_view_type keys_rnd;
public:
public:
BinSortOp bin_op;
offset_type bin_offsets;
bin_count_atomic_type bin_count_atomic;
bin_count_type bin_count_const;
offset_type sort_order;
BinSortOp bin_op ;
offset_type bin_offsets ;
bin_count_atomic_type bin_count_atomic ;
bin_count_type bin_count_const ;
offset_type sort_order ;
int range_begin ;
int range_end ;
bool sort_within_bins ;
public:
int range_begin;
int range_end;
bool sort_within_bins;
public:
BinSort() {}
//----------------------------------------
// Constructor: takes the keys, the binning_operator and optionally whether to sort within bins (default false)
BinSort( const_key_view_type keys_
, int range_begin_
, int range_end_
, BinSortOp bin_op_
, bool sort_within_bins_ = false
)
: keys(keys_)
, keys_rnd(keys_)
, bin_op(bin_op_)
, bin_offsets()
, bin_count_atomic()
, bin_count_const()
, sort_order()
, range_begin( range_begin_ )
, range_end( range_end_ )
, sort_within_bins( sort_within_bins_ )
{
bin_count_atomic = Kokkos::View<int*, Space >("Kokkos::SortImpl::BinSortFunctor::bin_count",bin_op.max_bins());
bin_count_const = bin_count_atomic;
bin_offsets = offset_type(ViewAllocateWithoutInitializing("Kokkos::SortImpl::BinSortFunctor::bin_offsets"),bin_op.max_bins());
sort_order = offset_type(ViewAllocateWithoutInitializing("Kokkos::SortImpl::BinSortFunctor::sort_order"),range_end-range_begin);
// Constructor: takes the keys, the binning_operator and optionally whether to
// sort within bins (default false)
BinSort(const_key_view_type keys_, int range_begin_, int range_end_,
BinSortOp bin_op_, bool sort_within_bins_ = false)
: keys(keys_),
keys_rnd(keys_),
bin_op(bin_op_),
bin_offsets(),
bin_count_atomic(),
bin_count_const(),
sort_order(),
range_begin(range_begin_),
range_end(range_end_),
sort_within_bins(sort_within_bins_) {
bin_count_atomic = Kokkos::View<int*, Space>(
"Kokkos::SortImpl::BinSortFunctor::bin_count", bin_op.max_bins());
bin_count_const = bin_count_atomic;
bin_offsets =
offset_type(ViewAllocateWithoutInitializing(
"Kokkos::SortImpl::BinSortFunctor::bin_offsets"),
bin_op.max_bins());
sort_order =
offset_type(ViewAllocateWithoutInitializing(
"Kokkos::SortImpl::BinSortFunctor::sort_order"),
range_end - range_begin);
}
BinSort( const_key_view_type keys_
, BinSortOp bin_op_
, bool sort_within_bins_ = false
)
: BinSort( keys_ , 0 , keys_.extent(0), bin_op_ , sort_within_bins_ ) {}
BinSort(const_key_view_type keys_, BinSortOp bin_op_,
bool sort_within_bins_ = false)
: BinSort(keys_, 0, keys_.extent(0), bin_op_, sort_within_bins_) {}
//----------------------------------------
// Create the permutation vector, the bin_offset array and the bin_count array. Can be called again if keys changed
// Create the permutation vector, the bin_offset array and the bin_count
// array. Can be called again if keys changed
void create_permute_vector() {
const size_t len = range_end - range_begin ;
Kokkos::parallel_for ("Kokkos::Sort::BinCount",Kokkos::RangePolicy<execution_space,bin_count_tag> (0,len),*this);
Kokkos::parallel_scan("Kokkos::Sort::BinOffset",Kokkos::RangePolicy<execution_space,bin_offset_tag> (0,bin_op.max_bins()) ,*this);
const size_t len = range_end - range_begin;
Kokkos::parallel_for(
"Kokkos::Sort::BinCount",
Kokkos::RangePolicy<execution_space, bin_count_tag>(0, len), *this);
Kokkos::parallel_scan("Kokkos::Sort::BinOffset",
Kokkos::RangePolicy<execution_space, bin_offset_tag>(
0, bin_op.max_bins()),
*this);
Kokkos::deep_copy(bin_count_atomic,0);
Kokkos::parallel_for ("Kokkos::Sort::BinBinning",Kokkos::RangePolicy<execution_space,bin_binning_tag> (0,len),*this);
Kokkos::deep_copy(bin_count_atomic, 0);
Kokkos::parallel_for(
"Kokkos::Sort::BinBinning",
Kokkos::RangePolicy<execution_space, bin_binning_tag>(0, len), *this);
if(sort_within_bins)
Kokkos::parallel_for ("Kokkos::Sort::BinSort",Kokkos::RangePolicy<execution_space,bin_sort_bins_tag>(0,bin_op.max_bins()) ,*this);
if (sort_within_bins)
Kokkos::parallel_for(
"Kokkos::Sort::BinSort",
Kokkos::RangePolicy<execution_space, bin_sort_bins_tag>(
0, bin_op.max_bins()),
*this);
}
// Sort a subset of a view with respect to the first dimension using the permutation array
template<class ValuesViewType>
void sort( ValuesViewType const & values
, int values_range_begin
, int values_range_end) const
{
typedef
Kokkos::View< typename ValuesViewType::data_type,
typename ValuesViewType::array_layout,
typename ValuesViewType::device_type >
scratch_view_type ;
// Sort a subset of a view with respect to the first dimension using the
// permutation array
template <class ValuesViewType>
void sort(ValuesViewType const& values, int values_range_begin,
int values_range_end) const {
typedef Kokkos::View<typename ValuesViewType::data_type,
typename ValuesViewType::array_layout,
typename ValuesViewType::device_type>
scratch_view_type;
const size_t len = range_end - range_begin ;
const size_t values_len = values_range_end - values_range_begin ;
const size_t len = range_end - range_begin;
const size_t values_len = values_range_end - values_range_begin;
if (len != values_len) {
Kokkos::abort("BinSort::sort: values range length != permutation vector length");
Kokkos::abort(
"BinSort::sort: values range length != permutation vector length");
}
#ifdef KOKKOS_ENABLE_DEPRECATED_CODE
scratch_view_type
sorted_values(ViewAllocateWithoutInitializing("Kokkos::SortImpl::BinSortFunctor::sorted_values"),
len,
values.extent(1),
values.extent(2),
values.extent(3),
values.extent(4),
values.extent(5),
values.extent(6),
values.extent(7));
scratch_view_type sorted_values(
ViewAllocateWithoutInitializing(
"Kokkos::SortImpl::BinSortFunctor::sorted_values"),
len, values.extent(1), values.extent(2), values.extent(3),
values.extent(4), values.extent(5), values.extent(6), values.extent(7));
#else
scratch_view_type
sorted_values(ViewAllocateWithoutInitializing("Kokkos::SortImpl::BinSortFunctor::sorted_values"),
values.rank_dynamic > 0 ? len : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 1 ? values.extent(1) : KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
values.rank_dynamic > 2 ? values.extent(2) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 3 ? values.extent(3) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 4 ? values.extent(4) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 5 ? values.extent(5) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 6 ? values.extent(6) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 7 ? values.extent(7) : KOKKOS_IMPL_CTOR_DEFAULT_ARG);
scratch_view_type sorted_values(
ViewAllocateWithoutInitializing(
"Kokkos::SortImpl::BinSortFunctor::sorted_values"),
values.rank_dynamic > 0 ? len : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 1 ? values.extent(1)
: KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 2 ? values.extent(2)
: KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 3 ? values.extent(3)
: KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 4 ? values.extent(4)
: KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 5 ? values.extent(5)
: KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 6 ? values.extent(6)
: KOKKOS_IMPL_CTOR_DEFAULT_ARG,
values.rank_dynamic > 7 ? values.extent(7)
: KOKKOS_IMPL_CTOR_DEFAULT_ARG);
#endif
{
copy_permute_functor< scratch_view_type /* DstViewType */
, offset_type /* PermuteViewType */
, ValuesViewType /* SrcViewType */
>
functor( sorted_values , sort_order , values, values_range_begin - range_begin );
copy_permute_functor<scratch_view_type /* DstViewType */
,
offset_type /* PermuteViewType */
,
ValuesViewType /* SrcViewType */
>
functor(sorted_values, sort_order, values,
values_range_begin - range_begin);
parallel_for("Kokkos::Sort::CopyPermute", Kokkos::RangePolicy<execution_space>(0,len),functor);
parallel_for("Kokkos::Sort::CopyPermute",
Kokkos::RangePolicy<execution_space>(0, len), functor);
}
{
copy_functor< ValuesViewType , scratch_view_type >
functor( values , range_begin , sorted_values );
copy_functor<ValuesViewType, scratch_view_type> functor(
values, range_begin, sorted_values);
parallel_for("Kokkos::Sort::Copy", Kokkos::RangePolicy<execution_space>(0,len),functor);
parallel_for("Kokkos::Sort::Copy",
Kokkos::RangePolicy<execution_space>(0, len), functor);
}
Kokkos::fence();
}
template<class ValuesViewType>
void sort( ValuesViewType const & values ) const
{
this->sort( values, 0, /*values.extent(0)*/ range_end - range_begin );
template <class ValuesViewType>
void sort(ValuesViewType const& values) const {
this->sort(values, 0, /*values.extent(0)*/ range_end - range_begin);
}
// Get the permutation vector
KOKKOS_INLINE_FUNCTION
offset_type get_permute_vector() const { return sort_order;}
offset_type get_permute_vector() const { return sort_order; }
// Get the start offsets for each bin
KOKKOS_INLINE_FUNCTION
offset_type get_bin_offsets() const { return bin_offsets;}
offset_type get_bin_offsets() const { return bin_offsets; }
// Get the count for each bin
KOKKOS_INLINE_FUNCTION
bin_count_type get_bin_count() const {return bin_count_const;}
public:
bin_count_type get_bin_count() const { return bin_count_const; }
public:
KOKKOS_INLINE_FUNCTION
void operator() (const bin_count_tag& tag, const int& i) const {
const int j = range_begin + i ;
void operator()(const bin_count_tag& tag, const int& i) const {
const int j = range_begin + i;
bin_count_atomic(bin_op.bin(keys, j))++;
}
KOKKOS_INLINE_FUNCTION
void operator() (const bin_offset_tag& tag, const int& i, value_type& offset, const bool& final) const {
if(final) {
void operator()(const bin_offset_tag& tag, const int& i, value_type& offset,
const bool& final) const {
if (final) {
bin_offsets(i) = offset;
}
offset+=bin_count_const(i);
offset += bin_count_const(i);
}
KOKKOS_INLINE_FUNCTION
void operator() (const bin_binning_tag& tag, const int& i) const {
const int j = range_begin + i ;
const int bin = bin_op.bin(keys,j);
void operator()(const bin_binning_tag& tag, const int& i) const {
const int j = range_begin + i;
const int bin = bin_op.bin(keys, j);
const int count = bin_count_atomic(bin)++;
sort_order(bin_offsets(bin) + count) = j ;
sort_order(bin_offsets(bin) + count) = j;
}
KOKKOS_INLINE_FUNCTION
void operator() (const bin_sort_bins_tag& tag, const int&i ) const {
void operator()(const bin_sort_bins_tag& tag, const int& i) const {
auto bin_size = bin_count_const(i);
if (bin_size <= 1) return;
int upper_bound = bin_offsets(i)+bin_size;
bool sorted = false;
while(!sorted) {
sorted = true;
int upper_bound = bin_offsets(i) + bin_size;
bool sorted = false;
while (!sorted) {
sorted = true;
int old_idx = sort_order(bin_offsets(i));
int new_idx;
for(int k=bin_offsets(i)+1; k<upper_bound; k++) {
for (int k = bin_offsets(i) + 1; k < upper_bound; k++) {
new_idx = sort_order(k);
if(!bin_op(keys_rnd,old_idx,new_idx)) {
sort_order(k-1) = new_idx;
sort_order(k) = old_idx;
sorted = false;
if (!bin_op(keys_rnd, old_idx, new_idx)) {
sort_order(k - 1) = new_idx;
sort_order(k) = old_idx;
sorted = false;
} else {
old_idx = new_idx;
}
@ -403,44 +400,46 @@ public:
//----------------------------------------------------------------------------
template<class KeyViewType>
template <class KeyViewType>
struct BinOp1D {
int max_bins_;
double mul_;
typename KeyViewType::const_value_type range_;
typename KeyViewType::const_value_type min_;
BinOp1D():max_bins_(0),mul_(0.0),
range_(typename KeyViewType::const_value_type()),
min_(typename KeyViewType::const_value_type()) {}
BinOp1D()
: max_bins_(0),
mul_(0.0),
range_(typename KeyViewType::const_value_type()),
min_(typename KeyViewType::const_value_type()) {}
//Construct BinOp with number of bins, minimum value and maxuimum value
// Construct BinOp with number of bins, minimum value and maxuimum value
BinOp1D(int max_bins__, typename KeyViewType::const_value_type min,
typename KeyViewType::const_value_type max )
:max_bins_(max_bins__+1),mul_(1.0*max_bins__/(max-min)),range_(max-min),min_(min) {}
typename KeyViewType::const_value_type max)
: max_bins_(max_bins__ + 1),
mul_(1.0 * max_bins__ / (max - min)),
range_(max - min),
min_(min) {}
//Determine bin index from key value
template<class ViewType>
KOKKOS_INLINE_FUNCTION
int bin(ViewType& keys, const int& i) const {
return int(mul_*(keys(i)-min_));
// Determine bin index from key value
template <class ViewType>
KOKKOS_INLINE_FUNCTION int bin(ViewType& keys, const int& i) const {
return int(mul_ * (keys(i) - min_));
}
//Return maximum bin index + 1
// Return maximum bin index + 1
KOKKOS_INLINE_FUNCTION
int max_bins() const {
return max_bins_;
}
int max_bins() const { return max_bins_; }
//Compare to keys within a bin if true new_val will be put before old_val
template<class ViewType, typename iType1, typename iType2>
KOKKOS_INLINE_FUNCTION
bool operator()(ViewType& keys, iType1& i1, iType2& i2) const {
return keys(i1)<keys(i2);
// Compare to keys within a bin if true new_val will be put before old_val
template <class ViewType, typename iType1, typename iType2>
KOKKOS_INLINE_FUNCTION bool operator()(ViewType& keys, iType1& i1,
iType2& i2) const {
return keys(i1) < keys(i2);
}
};
template<class KeyViewType>
template <class KeyViewType>
struct BinOp3D {
int max_bins_[3];
double mul_[3];
@ -450,43 +449,42 @@ struct BinOp3D {
BinOp3D() {}
BinOp3D(int max_bins__[], typename KeyViewType::const_value_type min[],
typename KeyViewType::const_value_type max[] )
{
typename KeyViewType::const_value_type max[]) {
max_bins_[0] = max_bins__[0];
max_bins_[1] = max_bins__[1];
max_bins_[2] = max_bins__[2];
mul_[0] = 1.0*max_bins__[0]/(max[0]-min[0]);
mul_[1] = 1.0*max_bins__[1]/(max[1]-min[1]);
mul_[2] = 1.0*max_bins__[2]/(max[2]-min[2]);
range_[0] = max[0]-min[0];
range_[1] = max[1]-min[1];
range_[2] = max[2]-min[2];
min_[0] = min[0];
min_[1] = min[1];
min_[2] = min[2];
mul_[0] = 1.0 * max_bins__[0] / (max[0] - min[0]);
mul_[1] = 1.0 * max_bins__[1] / (max[1] - min[1]);
mul_[2] = 1.0 * max_bins__[2] / (max[2] - min[2]);
range_[0] = max[0] - min[0];
range_[1] = max[1] - min[1];
range_[2] = max[2] - min[2];
min_[0] = min[0];
min_[1] = min[1];
min_[2] = min[2];
}
template<class ViewType>
KOKKOS_INLINE_FUNCTION
int bin(ViewType& keys, const int& i) const {
return int( (((int(mul_[0]*(keys(i,0)-min_[0]))*max_bins_[1]) +
int(mul_[1]*(keys(i,1)-min_[1])))*max_bins_[2]) +
int(mul_[2]*(keys(i,2)-min_[2])));
template <class ViewType>
KOKKOS_INLINE_FUNCTION int bin(ViewType& keys, const int& i) const {
return int((((int(mul_[0] * (keys(i, 0) - min_[0])) * max_bins_[1]) +
int(mul_[1] * (keys(i, 1) - min_[1]))) *
max_bins_[2]) +
int(mul_[2] * (keys(i, 2) - min_[2])));
}
KOKKOS_INLINE_FUNCTION
int max_bins() const {
return max_bins_[0]*max_bins_[1]*max_bins_[2];
}
int max_bins() const { return max_bins_[0] * max_bins_[1] * max_bins_[2]; }
template<class ViewType, typename iType1, typename iType2>
KOKKOS_INLINE_FUNCTION
bool operator()(ViewType& keys, iType1& i1 , iType2& i2) const {
if (keys(i1,0)>keys(i2,0)) return true;
else if (keys(i1,0)==keys(i2,0)) {
if (keys(i1,1)>keys(i2,1)) return true;
else if (keys(i1,1)==keys(i2,1)) {
if (keys(i1,2)>keys(i2,2)) return true;
template <class ViewType, typename iType1, typename iType2>
KOKKOS_INLINE_FUNCTION bool operator()(ViewType& keys, iType1& i1,
iType2& i2) const {
if (keys(i1, 0) > keys(i2, 0))
return true;
else if (keys(i1, 0) == keys(i2, 0)) {
if (keys(i1, 1) > keys(i2, 1))
return true;
else if (keys(i1, 1) == keys(i2, 1)) {
if (keys(i1, 2) > keys(i2, 2)) return true;
}
}
return false;
@ -495,85 +493,80 @@ struct BinOp3D {
namespace Impl {
template<class ViewType>
template <class ViewType>
bool try_std_sort(ViewType view) {
bool possible = true;
size_t stride[8] = { view.stride_0()
, view.stride_1()
, view.stride_2()
, view.stride_3()
, view.stride_4()
, view.stride_5()
, view.stride_6()
, view.stride_7()
};
possible = possible && std::is_same<typename ViewType::memory_space, HostSpace>::value;
possible = possible && (ViewType::Rank == 1);
possible = possible && (stride[0] == 1);
if(possible) {
std::sort(view.data(),view.data()+view.extent(0));
bool possible = true;
size_t stride[8] = {view.stride_0(), view.stride_1(), view.stride_2(),
view.stride_3(), view.stride_4(), view.stride_5(),
view.stride_6(), view.stride_7()};
possible = possible &&
std::is_same<typename ViewType::memory_space, HostSpace>::value;
possible = possible && (ViewType::Rank == 1);
possible = possible && (stride[0] == 1);
if (possible) {
std::sort(view.data(), view.data() + view.extent(0));
}
return possible;
}
template<class ViewType>
template <class ViewType>
struct min_max_functor {
typedef Kokkos::MinMaxScalar<typename ViewType::non_const_value_type> minmax_scalar;
typedef Kokkos::MinMaxScalar<typename ViewType::non_const_value_type>
minmax_scalar;
ViewType view;
min_max_functor(const ViewType& view_):view(view_) {}
min_max_functor(const ViewType& view_) : view(view_) {}
KOKKOS_INLINE_FUNCTION
void operator() (const size_t& i, minmax_scalar& minmax) const {
if(view(i) < minmax.min_val) minmax.min_val = view(i);
if(view(i) > minmax.max_val) minmax.max_val = view(i);
void operator()(const size_t& i, minmax_scalar& minmax) const {
if (view(i) < minmax.min_val) minmax.min_val = view(i);
if (view(i) > minmax.max_val) minmax.max_val = view(i);
}
};
}
} // namespace Impl
template<class ViewType>
void sort( ViewType const & view , bool const always_use_kokkos_sort = false)
{
if(!always_use_kokkos_sort) {
if(Impl::try_std_sort(view)) return;
template <class ViewType>
void sort(ViewType const& view, bool const always_use_kokkos_sort = false) {
if (!always_use_kokkos_sort) {
if (Impl::try_std_sort(view)) return;
}
typedef BinOp1D<ViewType> CompType;
Kokkos::MinMaxScalar<typename ViewType::non_const_value_type> result;
Kokkos::MinMax<typename ViewType::non_const_value_type> reducer(result);
parallel_reduce("Kokkos::Sort::FindExtent",Kokkos::RangePolicy<typename ViewType::execution_space>(0,view.extent(0)),
Impl::min_max_functor<ViewType>(view),reducer);
if(result.min_val == result.max_val) return;
BinSort<ViewType, CompType> bin_sort(view,CompType(view.extent(0)/2,result.min_val,result.max_val),true);
parallel_reduce("Kokkos::Sort::FindExtent",
Kokkos::RangePolicy<typename ViewType::execution_space>(
0, view.extent(0)),
Impl::min_max_functor<ViewType>(view), reducer);
if (result.min_val == result.max_val) return;
BinSort<ViewType, CompType> bin_sort(
view, CompType(view.extent(0) / 2, result.min_val, result.max_val), true);
bin_sort.create_permute_vector();
bin_sort.sort(view);
}
template<class ViewType>
void sort( ViewType view
, size_t const begin
, size_t const end
)
{
typedef Kokkos::RangePolicy<typename ViewType::execution_space> range_policy ;
template <class ViewType>
void sort(ViewType view, size_t const begin, size_t const end) {
typedef Kokkos::RangePolicy<typename ViewType::execution_space> range_policy;
typedef BinOp1D<ViewType> CompType;
Kokkos::MinMaxScalar<typename ViewType::non_const_value_type> result;
Kokkos::MinMax<typename ViewType::non_const_value_type> reducer(result);
parallel_reduce("Kokkos::Sort::FindExtent", range_policy( begin , end )
, Impl::min_max_functor<ViewType>(view),reducer );
parallel_reduce("Kokkos::Sort::FindExtent", range_policy(begin, end),
Impl::min_max_functor<ViewType>(view), reducer);
if(result.min_val == result.max_val) return;
if (result.min_val == result.max_val) return;
BinSort<ViewType, CompType>
bin_sort(view,begin,end,CompType((end-begin)/2,result.min_val,result.max_val),true);
BinSort<ViewType, CompType> bin_sort(
view, begin, end,
CompType((end - begin) / 2, result.min_val, result.max_val), true);
bin_sort.create_permute_vector();
bin_sort.sort(view,begin,end);
bin_sort.sort(view, begin, end);
}
}
} // namespace Kokkos
#endif

View File

@ -1,18 +1,12 @@
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../src )
#Leave these here for now - I don't need transitive deps anyway
KOKKOS_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
KOKKOS_INCLUDE_DIRECTORIES(REQUIRED_DURING_INSTALLATION_TESTING ${CMAKE_CURRENT_SOURCE_DIR})
KOKKOS_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../src )
IF(NOT KOKKOS_HAS_TRILINOS)
IF(KOKKOS_SEPARATE_LIBS)
set(TEST_LINK_TARGETS kokkoscore)
ELSE()
set(TEST_LINK_TARGETS kokkos)
ENDIF()
ENDIF()
SET(GTEST_SOURCE_DIR ${${PARENT_PACKAGE_NAME}_SOURCE_DIR}/tpls/gtest)
INCLUDE_DIRECTORIES(${GTEST_SOURCE_DIR})
KOKKOS_INCLUDE_DIRECTORIES(${GTEST_SOURCE_DIR})
# mfh 03 Nov 2017: The gtest library used here must have a different
# name than that of the gtest library built in KokkosCore. We can't
@ -20,23 +14,20 @@ INCLUDE_DIRECTORIES(${GTEST_SOURCE_DIR})
# possible to build only (e.g.,) KokkosAlgorithms tests, without
# building KokkosCore tests.
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_HAS_PTHREAD=0")
TRIBITS_ADD_LIBRARY(
KOKKOS_ADD_TEST_LIBRARY(
kokkosalgorithms_gtest
HEADERS ${GTEST_SOURCE_DIR}/gtest/gtest.h
SOURCES ${GTEST_SOURCE_DIR}/gtest/gtest-all.cc
TESTONLY
)
)
KOKKOS_TARGET_COMPILE_DEFINITIONS(kokkosalgorithms_gtest PUBLIC "-DGTEST_HAS_PTHREAD=0")
SET(SOURCES
UnitTestMain.cpp
TestCuda.cpp
)
SET(LIBRARIES kokkoscore)
IF(Kokkos_ENABLE_OpenMP)
IF(Kokkos_ENABLE_OPENMP)
LIST( APPEND SOURCES
TestOpenMP.cpp
)
@ -48,23 +39,19 @@ IF(Kokkos_ENABLE_HPX)
)
ENDIF()
IF(Kokkos_ENABLE_Serial)
IF(Kokkos_ENABLE_SERIAL)
LIST( APPEND SOURCES
TestSerial.cpp
)
ENDIF()
IF(Kokkos_ENABLE_Pthread)
IF(Kokkos_ENABLE_PTHREAD)
LIST( APPEND SOURCES
TestThreads.cpp
)
ENDIF()
TRIBITS_ADD_EXECUTABLE_AND_TEST(
KOKKOS_ADD_EXECUTABLE_AND_TEST(
UnitTest
SOURCES ${SOURCES}
COMM serial mpi
NUM_MPI_PROCS 1
FAIL_REGULAR_EXPRESSION " FAILED "
TESTONLYLIBS kokkosalgorithms_gtest ${TEST_LINK_TARGETS}
)
)

View File

@ -2,10 +2,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -57,51 +58,31 @@
namespace Test {
class cuda : public ::testing::Test {
protected:
static void SetUpTestCase()
{
}
static void TearDownTestCase()
{
}
};
void cuda_test_random_xorshift64( int num_draws )
{
void cuda_test_random_xorshift64(int num_draws) {
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::Cuda> >(num_draws);
}
void cuda_test_random_xorshift1024( int num_draws )
{
void cuda_test_random_xorshift1024(int num_draws) {
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Cuda> >(num_draws);
}
#define CUDA_RANDOM_XORSHIFT64(num_draws) \
TEST(cuda, Random_XorShift64) { cuda_test_random_xorshift64(num_draws); }
#define CUDA_RANDOM_XORSHIFT64( num_draws ) \
TEST_F( cuda, Random_XorShift64 ) { \
cuda_test_random_xorshift64(num_draws); \
}
#define CUDA_RANDOM_XORSHIFT1024(num_draws) \
TEST(cuda, Random_XorShift1024) { cuda_test_random_xorshift1024(num_draws); }
#define CUDA_RANDOM_XORSHIFT1024( num_draws ) \
TEST_F( cuda, Random_XorShift1024 ) { \
cuda_test_random_xorshift1024(num_draws); \
}
#define CUDA_SORT_UNSIGNED(size) \
TEST(cuda, SortUnsigned) { Impl::test_sort<Kokkos::Cuda, unsigned>(size); }
#define CUDA_SORT_UNSIGNED( size ) \
TEST_F( cuda, SortUnsigned ) { \
Impl::test_sort< Kokkos::Cuda, unsigned >(size); \
}
CUDA_RANDOM_XORSHIFT64( 132141141 )
CUDA_RANDOM_XORSHIFT1024( 52428813 )
CUDA_RANDOM_XORSHIFT64(132141141)
CUDA_RANDOM_XORSHIFT1024(52428813)
CUDA_SORT_UNSIGNED(171)
#undef CUDA_RANDOM_XORSHIFT64
#undef CUDA_RANDOM_XORSHIFT1024
#undef CUDA_SORT_UNSIGNED
}
} // namespace Test
#else
void KOKKOS_ALGORITHMS_UNITTESTS_TESTCUDA_PREVENT_LINK_ERROR() {}
#endif /* #ifdef KOKKOS_ENABLE_CUDA */
#endif /* #ifdef KOKKOS_ENABLE_CUDA */

View File

@ -2,10 +2,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -41,7 +42,6 @@
//@HEADER
*/
#include <Kokkos_Macros.hpp>
#ifdef KOKKOS_ENABLE_HPX
@ -55,42 +55,33 @@
namespace Test {
class hpx : public ::testing::Test {
protected:
static void SetUpTestCase()
{
std::cout << std::setprecision(5) << std::scientific;
#define HPX_RANDOM_XORSHIFT64(num_draws) \
TEST(hpx, Random_XorShift64) { \
Impl::test_random< \
Kokkos::Random_XorShift64_Pool<Kokkos::Experimental::HPX> >( \
num_draws); \
}
static void TearDownTestCase()
{
}
};
#define HPX_RANDOM_XORSHIFT64( num_draws ) \
TEST_F( hpx, Random_XorShift64 ) { \
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::Experimental::HPX> >(num_draws); \
#define HPX_RANDOM_XORSHIFT1024(num_draws) \
TEST(hpx, Random_XorShift1024) { \
Impl::test_random< \
Kokkos::Random_XorShift1024_Pool<Kokkos::Experimental::HPX> >( \
num_draws); \
}
#define HPX_RANDOM_XORSHIFT1024( num_draws ) \
TEST_F( hpx, Random_XorShift1024 ) { \
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Experimental::HPX> >(num_draws); \
#define HPX_SORT_UNSIGNED(size) \
TEST(hpx, SortUnsigned) { \
Impl::test_sort<Kokkos::Experimental::HPX, unsigned>(size); \
}
#define HPX_SORT_UNSIGNED( size ) \
TEST_F( hpx, SortUnsigned ) { \
Impl::test_sort< Kokkos::Experimental::HPX, unsigned >(size); \
}
HPX_RANDOM_XORSHIFT64( 10240000 )
HPX_RANDOM_XORSHIFT1024( 10130144 )
HPX_RANDOM_XORSHIFT64(10240000)
HPX_RANDOM_XORSHIFT1024(10130144)
HPX_SORT_UNSIGNED(171)
#undef HPX_RANDOM_XORSHIFT64
#undef HPX_RANDOM_XORSHIFT1024
#undef HPX_SORT_UNSIGNED
} // namespace test
} // namespace Test
#else
void KOKKOS_ALGORITHMS_UNITTESTS_TESTHPX_PREVENT_LINK_ERROR() {}
#endif

View File

@ -2,10 +2,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -41,7 +42,6 @@
//@HEADER
*/
#include <Kokkos_Macros.hpp>
#ifdef KOKKOS_ENABLE_OPENMP
@ -55,42 +55,31 @@
namespace Test {
class openmp : public ::testing::Test {
protected:
static void SetUpTestCase()
{
std::cout << std::setprecision(5) << std::scientific;
#define OPENMP_RANDOM_XORSHIFT64(num_draws) \
TEST(openmp, Random_XorShift64) { \
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP> >( \
num_draws); \
}
static void TearDownTestCase()
{
}
};
#define OPENMP_RANDOM_XORSHIFT64( num_draws ) \
TEST_F( openmp, Random_XorShift64 ) { \
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::OpenMP> >(num_draws); \
#define OPENMP_RANDOM_XORSHIFT1024(num_draws) \
TEST(openmp, Random_XorShift1024) { \
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::OpenMP> >( \
num_draws); \
}
#define OPENMP_RANDOM_XORSHIFT1024( num_draws ) \
TEST_F( openmp, Random_XorShift1024 ) { \
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::OpenMP> >(num_draws); \
#define OPENMP_SORT_UNSIGNED(size) \
TEST(openmp, SortUnsigned) { \
Impl::test_sort<Kokkos::OpenMP, unsigned>(size); \
}
#define OPENMP_SORT_UNSIGNED( size ) \
TEST_F( openmp, SortUnsigned ) { \
Impl::test_sort< Kokkos::OpenMP, unsigned >(size); \
}
OPENMP_RANDOM_XORSHIFT64( 10240000 )
OPENMP_RANDOM_XORSHIFT1024( 10130144 )
OPENMP_RANDOM_XORSHIFT64(10240000)
OPENMP_RANDOM_XORSHIFT1024(10130144)
OPENMP_SORT_UNSIGNED(171)
#undef OPENMP_RANDOM_XORSHIFT64
#undef OPENMP_RANDOM_XORSHIFT1024
#undef OPENMP_SORT_UNSIGNED
} // namespace test
} // namespace Test
#else
void KOKKOS_ALGORITHMS_UNITTESTS_TESTOPENMP_PREVENT_LINK_ERROR() {}
#endif

View File

@ -2,10 +2,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -57,52 +58,35 @@
namespace Test {
class rocm : public ::testing::Test {
protected:
static void SetUpTestCase()
{
std::cout << std::setprecision(5) << std::scientific;
}
static void TearDownTestCase()
{
}
};
void rocm_test_random_xorshift64( int num_draws )
{
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::Experimental::ROCm> >(num_draws);
void rocm_test_random_xorshift64(int num_draws) {
Impl::test_random<
Kokkos::Random_XorShift64_Pool<Kokkos::Experimental::ROCm> >(num_draws);
}
void rocm_test_random_xorshift1024( int num_draws )
{
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Experimental::ROCm> >(num_draws);
void rocm_test_random_xorshift1024(int num_draws) {
Impl::test_random<
Kokkos::Random_XorShift1024_Pool<Kokkos::Experimental::ROCm> >(num_draws);
}
#define ROCM_RANDOM_XORSHIFT64(num_draws) \
TEST(rocm, Random_XorShift64) { rocm_test_random_xorshift64(num_draws); }
#define ROCM_RANDOM_XORSHIFT64( num_draws ) \
TEST_F( rocm, Random_XorShift64 ) { \
rocm_test_random_xorshift64(num_draws); \
#define ROCM_RANDOM_XORSHIFT1024(num_draws) \
TEST(rocm, Random_XorShift1024) { rocm_test_random_xorshift1024(num_draws); }
#define ROCM_SORT_UNSIGNED(size) \
TEST(rocm, SortUnsigned) { \
Impl::test_sort<Kokkos::Experimental::ROCm, unsigned>(size); \
}
#define ROCM_RANDOM_XORSHIFT1024( num_draws ) \
TEST_F( rocm, Random_XorShift1024 ) { \
rocm_test_random_xorshift1024(num_draws); \
}
#define ROCM_SORT_UNSIGNED( size ) \
TEST_F( rocm, SortUnsigned ) { \
Impl::test_sort< Kokkos::Experimental::ROCm, unsigned >(size); \
}
ROCM_RANDOM_XORSHIFT64( 132141141 )
ROCM_RANDOM_XORSHIFT1024( 52428813 )
ROCM_RANDOM_XORSHIFT64(132141141)
ROCM_RANDOM_XORSHIFT1024(52428813)
ROCM_SORT_UNSIGNED(171)
#undef ROCM_RANDOM_XORSHIFT64
#undef ROCM_RANDOM_XORSHIFT1024
#undef ROCM_SORT_UNSIGNED
}
} // namespace Test
#else
void KOKKOS_ALGORITHMS_UNITTESTS_TESTROCM_PREVENT_LINK_ERROR() {}
#endif /* #ifdef KOKKOS_ENABLE_ROCM */
#endif /* #ifdef KOKKOS_ENABLE_ROCM */

View File

@ -1,10 +1,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -22,10 +23,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -54,18 +55,19 @@
namespace Test {
namespace Impl{
namespace Impl {
// This test runs the random number generators and uses some statistic tests to
// check the 'goodness' of the random numbers:
// (i) mean: the mean is expected to be 0.5*RAND_MAX
// (ii) variance: the variance is 1/3*mean*mean
// (iii) covariance: the covariance is 0
// (iv) 1-tupledistr: the mean, variance and covariance of a 1D Histrogram of random numbers
// (v) 3-tupledistr: the mean, variance and covariance of a 3D Histrogram of random numbers
// (iv) 1-tupledistr: the mean, variance and covariance of a 1D Histrogram
// of random numbers (v) 3-tupledistr: the mean, variance and covariance of
// a 3D Histrogram of random numbers
#define HIST_DIM3D 24
#define HIST_DIM1D (HIST_DIM3D*HIST_DIM3D*HIST_DIM3D)
#define HIST_DIM1D (HIST_DIM3D * HIST_DIM3D * HIST_DIM3D)
struct RandomProperties {
uint64_t count;
@ -77,37 +79,37 @@ struct RandomProperties {
KOKKOS_INLINE_FUNCTION
RandomProperties() {
count = 0;
mean = 0.0;
variance = 0.0;
count = 0;
mean = 0.0;
variance = 0.0;
covariance = 0.0;
min = 1e64;
max = -1e64;
min = 1e64;
max = -1e64;
}
KOKKOS_INLINE_FUNCTION
RandomProperties& operator+=(const RandomProperties& add) {
count += add.count;
mean += add.mean;
variance += add.variance;
count += add.count;
mean += add.mean;
variance += add.variance;
covariance += add.covariance;
min = add.min<min?add.min:min;
max = add.max>max?add.max:max;
min = add.min < min ? add.min : min;
max = add.max > max ? add.max : max;
return *this;
}
KOKKOS_INLINE_FUNCTION
void operator+=(const volatile RandomProperties& add) volatile {
count += add.count;
mean += add.mean;
variance += add.variance;
count += add.count;
mean += add.mean;
variance += add.variance;
covariance += add.covariance;
min = add.min<min?add.min:min;
max = add.max>max?add.max:max;
min = add.min < min ? add.min : min;
max = add.max > max ? add.max : max;
}
};
template<class GeneratorPool, class Scalar>
template <class GeneratorPool, class Scalar>
struct test_random_functor {
typedef typename GeneratorPool::generator_type rnd_type;
@ -123,38 +125,40 @@ struct test_random_functor {
// implementations might violate this upper bound, due to rounding
// error. Just in case, we leave an extra space at the end of each
// dimension, in the View types below.
typedef Kokkos::View<int[HIST_DIM1D+1],typename GeneratorPool::device_type> type_1d;
typedef Kokkos::View<int[HIST_DIM1D + 1], typename GeneratorPool::device_type>
type_1d;
type_1d density_1d;
typedef Kokkos::View<int[HIST_DIM3D+1][HIST_DIM3D+1][HIST_DIM3D+1],typename GeneratorPool::device_type> type_3d;
typedef Kokkos::View<int[HIST_DIM3D + 1][HIST_DIM3D + 1][HIST_DIM3D + 1],
typename GeneratorPool::device_type>
type_3d;
type_3d density_3d;
test_random_functor (GeneratorPool rand_pool_, type_1d d1d, type_3d d3d) :
rand_pool (rand_pool_),
mean (0.5*Kokkos::rand<rnd_type,Scalar>::max ()),
density_1d (d1d),
density_3d (d3d)
{}
test_random_functor(GeneratorPool rand_pool_, type_1d d1d, type_3d d3d)
: rand_pool(rand_pool_),
mean(0.5 * Kokkos::rand<rnd_type, Scalar>::max()),
density_1d(d1d),
density_3d(d3d) {}
KOKKOS_INLINE_FUNCTION
void operator() (int i, RandomProperties& prop) const {
void operator()(int i, RandomProperties& prop) const {
using Kokkos::atomic_fetch_add;
rnd_type rand_gen = rand_pool.get_state();
for (int k = 0; k < 1024; ++k) {
const Scalar tmp = Kokkos::rand<rnd_type,Scalar>::draw(rand_gen);
const Scalar tmp = Kokkos::rand<rnd_type, Scalar>::draw(rand_gen);
prop.count++;
prop.mean += tmp;
prop.variance += (tmp-mean)*(tmp-mean);
const Scalar tmp2 = Kokkos::rand<rnd_type,Scalar>::draw(rand_gen);
prop.variance += (tmp - mean) * (tmp - mean);
const Scalar tmp2 = Kokkos::rand<rnd_type, Scalar>::draw(rand_gen);
prop.count++;
prop.mean += tmp2;
prop.variance += (tmp2-mean)*(tmp2-mean);
prop.covariance += (tmp-mean)*(tmp2-mean);
const Scalar tmp3 = Kokkos::rand<rnd_type,Scalar>::draw(rand_gen);
prop.variance += (tmp2 - mean) * (tmp2 - mean);
prop.covariance += (tmp - mean) * (tmp2 - mean);
const Scalar tmp3 = Kokkos::rand<rnd_type, Scalar>::draw(rand_gen);
prop.count++;
prop.mean += tmp3;
prop.variance += (tmp3-mean)*(tmp3-mean);
prop.covariance += (tmp2-mean)*(tmp3-mean);
prop.variance += (tmp3 - mean) * (tmp3 - mean);
prop.covariance += (tmp2 - mean) * (tmp3 - mean);
// NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to
// define an exclusive upper bound on the range of random
@ -169,26 +173,32 @@ struct test_random_functor {
// returns values of max(), the histograms will still catch this
// indirectly, since none of the other values will be filled in.
const Scalar theMax = Kokkos::rand<rnd_type, Scalar>::max ();
const Scalar theMax = Kokkos::rand<rnd_type, Scalar>::max();
const uint64_t ind1_1d = static_cast<uint64_t> (1.0 * HIST_DIM1D * tmp / theMax);
const uint64_t ind2_1d = static_cast<uint64_t> (1.0 * HIST_DIM1D * tmp2 / theMax);
const uint64_t ind3_1d = static_cast<uint64_t> (1.0 * HIST_DIM1D * tmp3 / theMax);
const uint64_t ind1_1d =
static_cast<uint64_t>(1.0 * HIST_DIM1D * tmp / theMax);
const uint64_t ind2_1d =
static_cast<uint64_t>(1.0 * HIST_DIM1D * tmp2 / theMax);
const uint64_t ind3_1d =
static_cast<uint64_t>(1.0 * HIST_DIM1D * tmp3 / theMax);
const uint64_t ind1_3d = static_cast<uint64_t> (1.0 * HIST_DIM3D * tmp / theMax);
const uint64_t ind2_3d = static_cast<uint64_t> (1.0 * HIST_DIM3D * tmp2 / theMax);
const uint64_t ind3_3d = static_cast<uint64_t> (1.0 * HIST_DIM3D * tmp3 / theMax);
const uint64_t ind1_3d =
static_cast<uint64_t>(1.0 * HIST_DIM3D * tmp / theMax);
const uint64_t ind2_3d =
static_cast<uint64_t>(1.0 * HIST_DIM3D * tmp2 / theMax);
const uint64_t ind3_3d =
static_cast<uint64_t>(1.0 * HIST_DIM3D * tmp3 / theMax);
atomic_fetch_add (&density_1d(ind1_1d), 1);
atomic_fetch_add (&density_1d(ind2_1d), 1);
atomic_fetch_add (&density_1d(ind3_1d), 1);
atomic_fetch_add (&density_3d(ind1_3d, ind2_3d, ind3_3d), 1);
atomic_fetch_add(&density_1d(ind1_1d), 1);
atomic_fetch_add(&density_1d(ind2_1d), 1);
atomic_fetch_add(&density_1d(ind3_1d), 1);
atomic_fetch_add(&density_3d(ind1_3d, ind2_3d, ind3_3d), 1);
}
rand_pool.free_state(rand_gen);
}
};
template<class DeviceType>
template <class DeviceType>
struct test_histogram1d_functor {
typedef RandomProperties value_type;
typedef typename DeviceType::execution_space execution_space;
@ -200,34 +210,29 @@ struct test_histogram1d_functor {
// implementations might violate this upper bound, due to rounding
// error. Just in case, we leave an extra space at the end of each
// dimension, in the View type below.
typedef Kokkos::View<int[HIST_DIM1D+1], memory_space> type_1d;
typedef Kokkos::View<int[HIST_DIM1D + 1], memory_space> type_1d;
type_1d density_1d;
double mean;
test_histogram1d_functor (type_1d d1d, int num_draws) :
density_1d (d1d),
mean (1.0*num_draws/HIST_DIM1D*3)
{
}
test_histogram1d_functor(type_1d d1d, int num_draws)
: density_1d(d1d), mean(1.0 * num_draws / HIST_DIM1D * 3) {}
KOKKOS_INLINE_FUNCTION void
operator() (const typename memory_space::size_type i,
RandomProperties& prop) const
{
KOKKOS_INLINE_FUNCTION void operator()(
const typename memory_space::size_type i, RandomProperties& prop) const {
typedef typename memory_space::size_type size_type;
const double count = density_1d(i);
prop.mean += count;
prop.variance += 1.0 * (count - mean) * (count - mean);
//prop.covariance += 1.0*count*count;
// prop.covariance += 1.0*count*count;
prop.min = count < prop.min ? count : prop.min;
prop.max = count > prop.max ? count : prop.max;
if (i < static_cast<size_type> (HIST_DIM1D-1)) {
prop.covariance += (count - mean) * (density_1d(i+1) - mean);
if (i < static_cast<size_type>(HIST_DIM1D - 1)) {
prop.covariance += (count - mean) * (density_1d(i + 1) - mean);
}
}
};
template<class DeviceType>
template <class DeviceType>
struct test_histogram3d_functor {
typedef RandomProperties value_type;
typedef typename DeviceType::execution_space execution_space;
@ -239,29 +244,28 @@ struct test_histogram3d_functor {
// implementations might violate this upper bound, due to rounding
// error. Just in case, we leave an extra space at the end of each
// dimension, in the View type below.
typedef Kokkos::View<int[HIST_DIM3D+1][HIST_DIM3D+1][HIST_DIM3D+1], memory_space> type_3d;
typedef Kokkos::View<int[HIST_DIM3D + 1][HIST_DIM3D + 1][HIST_DIM3D + 1],
memory_space>
type_3d;
type_3d density_3d;
double mean;
test_histogram3d_functor (type_3d d3d, int num_draws) :
density_3d (d3d),
mean (1.0*num_draws/HIST_DIM1D)
{}
test_histogram3d_functor(type_3d d3d, int num_draws)
: density_3d(d3d), mean(1.0 * num_draws / HIST_DIM1D) {}
KOKKOS_INLINE_FUNCTION void
operator() (const typename memory_space::size_type i,
RandomProperties& prop) const
{
KOKKOS_INLINE_FUNCTION void operator()(
const typename memory_space::size_type i, RandomProperties& prop) const {
typedef typename memory_space::size_type size_type;
const double count = density_3d(i/(HIST_DIM3D*HIST_DIM3D),
(i % (HIST_DIM3D*HIST_DIM3D))/HIST_DIM3D,
i % HIST_DIM3D);
const double count = density_3d(
i / (HIST_DIM3D * HIST_DIM3D),
(i % (HIST_DIM3D * HIST_DIM3D)) / HIST_DIM3D, i % HIST_DIM3D);
prop.mean += count;
prop.variance += (count - mean) * (count - mean);
if (i < static_cast<size_type> (HIST_DIM1D-1)) {
const double count_next = density_3d((i+1)/(HIST_DIM3D*HIST_DIM3D),
((i+1)%(HIST_DIM3D*HIST_DIM3D))/HIST_DIM3D,
(i+1)%HIST_DIM3D);
if (i < static_cast<size_type>(HIST_DIM1D - 1)) {
const double count_next =
density_3d((i + 1) / (HIST_DIM3D * HIST_DIM3D),
((i + 1) % (HIST_DIM3D * HIST_DIM3D)) / HIST_DIM3D,
(i + 1) % HIST_DIM3D);
prop.covariance += (count - mean) * (count_next - mean);
}
}
@ -270,212 +274,223 @@ struct test_histogram3d_functor {
//
// Templated test that uses the above functors.
//
template <class RandomGenerator,class Scalar>
template <class RandomGenerator, class Scalar>
struct test_random_scalar {
typedef typename RandomGenerator::generator_type rnd_type;
int pass_mean,pass_var,pass_covar;
int pass_hist1d_mean,pass_hist1d_var,pass_hist1d_covar;
int pass_hist3d_mean,pass_hist3d_var,pass_hist3d_covar;
int pass_mean, pass_var, pass_covar;
int pass_hist1d_mean, pass_hist1d_var, pass_hist1d_covar;
int pass_hist3d_mean, pass_hist3d_var, pass_hist3d_covar;
test_random_scalar (typename test_random_functor<RandomGenerator,int>::type_1d& density_1d,
typename test_random_functor<RandomGenerator,int>::type_3d& density_3d,
RandomGenerator& pool,
unsigned int num_draws)
{
test_random_scalar(
typename test_random_functor<RandomGenerator, int>::type_1d& density_1d,
typename test_random_functor<RandomGenerator, int>::type_3d& density_3d,
RandomGenerator& pool, unsigned int num_draws) {
using Kokkos::parallel_reduce;
using std::cout;
using std::endl;
using Kokkos::parallel_reduce;
{
cout << " -- Testing randomness properties" << endl;
RandomProperties result;
typedef test_random_functor<RandomGenerator, Scalar> functor_type;
parallel_reduce (num_draws/1024, functor_type (pool, density_1d, density_3d), result);
parallel_reduce(num_draws / 1024,
functor_type(pool, density_1d, density_3d), result);
//printf("Result: %lf %lf %lf\n",result.mean/num_draws/3,result.variance/num_draws/3,result.covariance/num_draws/2);
double tolerance = 1.6*std::sqrt(1.0/num_draws);
double mean_expect = 0.5*Kokkos::rand<rnd_type,Scalar>::max();
double variance_expect = 1.0/3.0*mean_expect*mean_expect;
double mean_eps = mean_expect/(result.mean/num_draws/3)-1.0;
double variance_eps = variance_expect/(result.variance/num_draws/3)-1.0;
double covariance_eps = result.covariance/num_draws/2/variance_expect;
pass_mean = ((-tolerance < mean_eps) &&
( tolerance > mean_eps)) ? 1:0;
pass_var = ((-1.5*tolerance < variance_eps) &&
( 1.5*tolerance > variance_eps)) ? 1:0;
pass_covar = ((-2.0*tolerance < covariance_eps) &&
( 2.0*tolerance > covariance_eps)) ? 1:0;
cout << "Pass: " << pass_mean
<< " " << pass_var
<< " " << mean_eps
<< " " << variance_eps
<< " " << covariance_eps
<< " || " << tolerance << endl;
// printf("Result: %lf %lf
// %lf\n",result.mean/num_draws/3,result.variance/num_draws/3,result.covariance/num_draws/2);
double tolerance = 1.6 * std::sqrt(1.0 / num_draws);
double mean_expect = 0.5 * Kokkos::rand<rnd_type, Scalar>::max();
double variance_expect = 1.0 / 3.0 * mean_expect * mean_expect;
double mean_eps = mean_expect / (result.mean / num_draws / 3) - 1.0;
double variance_eps =
variance_expect / (result.variance / num_draws / 3) - 1.0;
double covariance_eps =
result.covariance / num_draws / 2 / variance_expect;
pass_mean = ((-tolerance < mean_eps) && (tolerance > mean_eps)) ? 1 : 0;
pass_var = ((-1.5 * tolerance < variance_eps) &&
(1.5 * tolerance > variance_eps))
? 1
: 0;
pass_covar = ((-2.0 * tolerance < covariance_eps) &&
(2.0 * tolerance > covariance_eps))
? 1
: 0;
cout << "Pass: " << pass_mean << " " << pass_var << " " << mean_eps << " "
<< variance_eps << " " << covariance_eps << " || " << tolerance
<< endl;
}
{
cout << " -- Testing 1-D histogram" << endl;
RandomProperties result;
typedef test_histogram1d_functor<typename RandomGenerator::device_type> functor_type;
parallel_reduce (HIST_DIM1D, functor_type (density_1d, num_draws), result);
typedef test_histogram1d_functor<typename RandomGenerator::device_type>
functor_type;
parallel_reduce(HIST_DIM1D, functor_type(density_1d, num_draws), result);
double tolerance = 6*std::sqrt(1.0/HIST_DIM1D);
double mean_expect = 1.0*num_draws*3/HIST_DIM1D;
double variance_expect = 1.0*num_draws*3/HIST_DIM1D*(1.0-1.0/HIST_DIM1D);
double covariance_expect = -1.0*num_draws*3/HIST_DIM1D/HIST_DIM1D;
double mean_eps = mean_expect/(result.mean/HIST_DIM1D)-1.0;
double variance_eps = variance_expect/(result.variance/HIST_DIM1D)-1.0;
double covariance_eps = (result.covariance/HIST_DIM1D - covariance_expect)/mean_expect;
pass_hist1d_mean = ((-0.0001 < mean_eps) &&
( 0.0001 > mean_eps)) ? 1:0;
pass_hist1d_var = ((-0.07 < variance_eps) &&
( 0.07 > variance_eps)) ? 1:0;
pass_hist1d_covar = ((-0.06 < covariance_eps) &&
( 0.06 > covariance_eps)) ? 1:0;
double tolerance = 6 * std::sqrt(1.0 / HIST_DIM1D);
double mean_expect = 1.0 * num_draws * 3 / HIST_DIM1D;
double variance_expect =
1.0 * num_draws * 3 / HIST_DIM1D * (1.0 - 1.0 / HIST_DIM1D);
double covariance_expect = -1.0 * num_draws * 3 / HIST_DIM1D / HIST_DIM1D;
double mean_eps = mean_expect / (result.mean / HIST_DIM1D) - 1.0;
double variance_eps =
variance_expect / (result.variance / HIST_DIM1D) - 1.0;
double covariance_eps =
(result.covariance / HIST_DIM1D - covariance_expect) / mean_expect;
pass_hist1d_mean = ((-0.0001 < mean_eps) && (0.0001 > mean_eps)) ? 1 : 0;
pass_hist1d_var =
((-0.07 < variance_eps) && (0.07 > variance_eps)) ? 1 : 0;
pass_hist1d_covar =
((-0.06 < covariance_eps) && (0.06 > covariance_eps)) ? 1 : 0;
cout << "Density 1D: " << mean_eps
<< " " << variance_eps
<< " " << (result.covariance/HIST_DIM1D/HIST_DIM1D)
<< " || " << tolerance
<< " " << result.min
<< " " << result.max
<< " || " << result.variance/HIST_DIM1D
<< " " << 1.0*num_draws*3/HIST_DIM1D*(1.0-1.0/HIST_DIM1D)
<< " || " << result.covariance/HIST_DIM1D
<< " " << -1.0*num_draws*3/HIST_DIM1D/HIST_DIM1D
<< endl;
cout << "Density 1D: " << mean_eps << " " << variance_eps << " "
<< (result.covariance / HIST_DIM1D / HIST_DIM1D) << " || "
<< tolerance << " " << result.min << " " << result.max << " || "
<< result.variance / HIST_DIM1D << " "
<< 1.0 * num_draws * 3 / HIST_DIM1D * (1.0 - 1.0 / HIST_DIM1D)
<< " || " << result.covariance / HIST_DIM1D << " "
<< -1.0 * num_draws * 3 / HIST_DIM1D / HIST_DIM1D << endl;
}
{
cout << " -- Testing 3-D histogram" << endl;
RandomProperties result;
typedef test_histogram3d_functor<typename RandomGenerator::device_type> functor_type;
parallel_reduce (HIST_DIM1D, functor_type (density_3d, num_draws), result);
typedef test_histogram3d_functor<typename RandomGenerator::device_type>
functor_type;
parallel_reduce(HIST_DIM1D, functor_type(density_3d, num_draws), result);
double tolerance = 6*std::sqrt(1.0/HIST_DIM1D);
double mean_expect = 1.0*num_draws/HIST_DIM1D;
double variance_expect = 1.0*num_draws/HIST_DIM1D*(1.0-1.0/HIST_DIM1D);
double covariance_expect = -1.0*num_draws/HIST_DIM1D/HIST_DIM1D;
double mean_eps = mean_expect/(result.mean/HIST_DIM1D)-1.0;
double variance_eps = variance_expect/(result.variance/HIST_DIM1D)-1.0;
double covariance_eps = (result.covariance/HIST_DIM1D - covariance_expect)/mean_expect;
pass_hist3d_mean = ((-tolerance < mean_eps) &&
( tolerance > mean_eps)) ? 1:0;
pass_hist3d_var = ((-1.2*tolerance < variance_eps) &&
( 1.2*tolerance > variance_eps)) ? 1:0;
pass_hist3d_covar = ((-tolerance < covariance_eps) &&
( tolerance > covariance_eps)) ? 1:0;
double tolerance = 6 * std::sqrt(1.0 / HIST_DIM1D);
double mean_expect = 1.0 * num_draws / HIST_DIM1D;
double variance_expect =
1.0 * num_draws / HIST_DIM1D * (1.0 - 1.0 / HIST_DIM1D);
double covariance_expect = -1.0 * num_draws / HIST_DIM1D / HIST_DIM1D;
double mean_eps = mean_expect / (result.mean / HIST_DIM1D) - 1.0;
double variance_eps =
variance_expect / (result.variance / HIST_DIM1D) - 1.0;
double covariance_eps =
(result.covariance / HIST_DIM1D - covariance_expect) / mean_expect;
pass_hist3d_mean =
((-tolerance < mean_eps) && (tolerance > mean_eps)) ? 1 : 0;
pass_hist3d_var = ((-1.2 * tolerance < variance_eps) &&
(1.2 * tolerance > variance_eps))
? 1
: 0;
pass_hist3d_covar =
((-tolerance < covariance_eps) && (tolerance > covariance_eps)) ? 1
: 0;
cout << "Density 3D: " << mean_eps
<< " " << variance_eps
<< " " << result.covariance/HIST_DIM1D/HIST_DIM1D
<< " || " << tolerance
<< " " << result.min
<< " " << result.max << endl;
cout << "Density 3D: " << mean_eps << " " << variance_eps << " "
<< result.covariance / HIST_DIM1D / HIST_DIM1D << " || " << tolerance
<< " " << result.min << " " << result.max << endl;
}
}
};
template <class RandomGenerator>
void test_random(unsigned int num_draws)
{
void test_random(unsigned int num_draws) {
using std::cout;
using std::endl;
typename test_random_functor<RandomGenerator,int>::type_1d density_1d("D1d");
typename test_random_functor<RandomGenerator,int>::type_3d density_3d("D3d");
typename test_random_functor<RandomGenerator, int>::type_1d density_1d("D1d");
typename test_random_functor<RandomGenerator, int>::type_3d density_3d("D3d");
uint64_t ticks = std::chrono::high_resolution_clock::now().time_since_epoch().count();
uint64_t ticks =
std::chrono::high_resolution_clock::now().time_since_epoch().count();
cout << "Test Seed:" << ticks << endl;
RandomGenerator pool(ticks);
cout << "Test Scalar=int" << endl;
test_random_scalar<RandomGenerator,int> test_int(density_1d,density_3d,pool,num_draws);
ASSERT_EQ( test_int.pass_mean,1);
ASSERT_EQ( test_int.pass_var,1);
ASSERT_EQ( test_int.pass_covar,1);
ASSERT_EQ( test_int.pass_hist1d_mean,1);
ASSERT_EQ( test_int.pass_hist1d_var,1);
ASSERT_EQ( test_int.pass_hist1d_covar,1);
ASSERT_EQ( test_int.pass_hist3d_mean,1);
ASSERT_EQ( test_int.pass_hist3d_var,1);
ASSERT_EQ( test_int.pass_hist3d_covar,1);
deep_copy(density_1d,0);
deep_copy(density_3d,0);
test_random_scalar<RandomGenerator, int> test_int(density_1d, density_3d,
pool, num_draws);
ASSERT_EQ(test_int.pass_mean, 1);
ASSERT_EQ(test_int.pass_var, 1);
ASSERT_EQ(test_int.pass_covar, 1);
ASSERT_EQ(test_int.pass_hist1d_mean, 1);
ASSERT_EQ(test_int.pass_hist1d_var, 1);
ASSERT_EQ(test_int.pass_hist1d_covar, 1);
ASSERT_EQ(test_int.pass_hist3d_mean, 1);
ASSERT_EQ(test_int.pass_hist3d_var, 1);
ASSERT_EQ(test_int.pass_hist3d_covar, 1);
deep_copy(density_1d, 0);
deep_copy(density_3d, 0);
cout << "Test Scalar=unsigned int" << endl;
test_random_scalar<RandomGenerator,unsigned int> test_uint(density_1d,density_3d,pool,num_draws);
ASSERT_EQ( test_uint.pass_mean,1);
ASSERT_EQ( test_uint.pass_var,1);
ASSERT_EQ( test_uint.pass_covar,1);
ASSERT_EQ( test_uint.pass_hist1d_mean,1);
ASSERT_EQ( test_uint.pass_hist1d_var,1);
ASSERT_EQ( test_uint.pass_hist1d_covar,1);
ASSERT_EQ( test_uint.pass_hist3d_mean,1);
ASSERT_EQ( test_uint.pass_hist3d_var,1);
ASSERT_EQ( test_uint.pass_hist3d_covar,1);
deep_copy(density_1d,0);
deep_copy(density_3d,0);
test_random_scalar<RandomGenerator, unsigned int> test_uint(
density_1d, density_3d, pool, num_draws);
ASSERT_EQ(test_uint.pass_mean, 1);
ASSERT_EQ(test_uint.pass_var, 1);
ASSERT_EQ(test_uint.pass_covar, 1);
ASSERT_EQ(test_uint.pass_hist1d_mean, 1);
ASSERT_EQ(test_uint.pass_hist1d_var, 1);
ASSERT_EQ(test_uint.pass_hist1d_covar, 1);
ASSERT_EQ(test_uint.pass_hist3d_mean, 1);
ASSERT_EQ(test_uint.pass_hist3d_var, 1);
ASSERT_EQ(test_uint.pass_hist3d_covar, 1);
deep_copy(density_1d, 0);
deep_copy(density_3d, 0);
cout << "Test Scalar=int64_t" << endl;
test_random_scalar<RandomGenerator,int64_t> test_int64(density_1d,density_3d,pool,num_draws);
ASSERT_EQ( test_int64.pass_mean,1);
ASSERT_EQ( test_int64.pass_var,1);
ASSERT_EQ( test_int64.pass_covar,1);
ASSERT_EQ( test_int64.pass_hist1d_mean,1);
ASSERT_EQ( test_int64.pass_hist1d_var,1);
ASSERT_EQ( test_int64.pass_hist1d_covar,1);
ASSERT_EQ( test_int64.pass_hist3d_mean,1);
ASSERT_EQ( test_int64.pass_hist3d_var,1);
ASSERT_EQ( test_int64.pass_hist3d_covar,1);
deep_copy(density_1d,0);
deep_copy(density_3d,0);
test_random_scalar<RandomGenerator, int64_t> test_int64(
density_1d, density_3d, pool, num_draws);
ASSERT_EQ(test_int64.pass_mean, 1);
ASSERT_EQ(test_int64.pass_var, 1);
ASSERT_EQ(test_int64.pass_covar, 1);
ASSERT_EQ(test_int64.pass_hist1d_mean, 1);
ASSERT_EQ(test_int64.pass_hist1d_var, 1);
ASSERT_EQ(test_int64.pass_hist1d_covar, 1);
ASSERT_EQ(test_int64.pass_hist3d_mean, 1);
ASSERT_EQ(test_int64.pass_hist3d_var, 1);
ASSERT_EQ(test_int64.pass_hist3d_covar, 1);
deep_copy(density_1d, 0);
deep_copy(density_3d, 0);
cout << "Test Scalar=uint64_t" << endl;
test_random_scalar<RandomGenerator,uint64_t> test_uint64(density_1d,density_3d,pool,num_draws);
ASSERT_EQ( test_uint64.pass_mean,1);
ASSERT_EQ( test_uint64.pass_var,1);
ASSERT_EQ( test_uint64.pass_covar,1);
ASSERT_EQ( test_uint64.pass_hist1d_mean,1);
ASSERT_EQ( test_uint64.pass_hist1d_var,1);
ASSERT_EQ( test_uint64.pass_hist1d_covar,1);
ASSERT_EQ( test_uint64.pass_hist3d_mean,1);
ASSERT_EQ( test_uint64.pass_hist3d_var,1);
ASSERT_EQ( test_uint64.pass_hist3d_covar,1);
deep_copy(density_1d,0);
deep_copy(density_3d,0);
test_random_scalar<RandomGenerator, uint64_t> test_uint64(
density_1d, density_3d, pool, num_draws);
ASSERT_EQ(test_uint64.pass_mean, 1);
ASSERT_EQ(test_uint64.pass_var, 1);
ASSERT_EQ(test_uint64.pass_covar, 1);
ASSERT_EQ(test_uint64.pass_hist1d_mean, 1);
ASSERT_EQ(test_uint64.pass_hist1d_var, 1);
ASSERT_EQ(test_uint64.pass_hist1d_covar, 1);
ASSERT_EQ(test_uint64.pass_hist3d_mean, 1);
ASSERT_EQ(test_uint64.pass_hist3d_var, 1);
ASSERT_EQ(test_uint64.pass_hist3d_covar, 1);
deep_copy(density_1d, 0);
deep_copy(density_3d, 0);
cout << "Test Scalar=float" << endl;
test_random_scalar<RandomGenerator,float> test_float(density_1d,density_3d,pool,num_draws);
ASSERT_EQ( test_float.pass_mean,1);
ASSERT_EQ( test_float.pass_var,1);
ASSERT_EQ( test_float.pass_covar,1);
ASSERT_EQ( test_float.pass_hist1d_mean,1);
ASSERT_EQ( test_float.pass_hist1d_var,1);
ASSERT_EQ( test_float.pass_hist1d_covar,1);
ASSERT_EQ( test_float.pass_hist3d_mean,1);
ASSERT_EQ( test_float.pass_hist3d_var,1);
ASSERT_EQ( test_float.pass_hist3d_covar,1);
deep_copy(density_1d,0);
deep_copy(density_3d,0);
test_random_scalar<RandomGenerator, float> test_float(density_1d, density_3d,
pool, num_draws);
ASSERT_EQ(test_float.pass_mean, 1);
ASSERT_EQ(test_float.pass_var, 1);
ASSERT_EQ(test_float.pass_covar, 1);
ASSERT_EQ(test_float.pass_hist1d_mean, 1);
ASSERT_EQ(test_float.pass_hist1d_var, 1);
ASSERT_EQ(test_float.pass_hist1d_covar, 1);
ASSERT_EQ(test_float.pass_hist3d_mean, 1);
ASSERT_EQ(test_float.pass_hist3d_var, 1);
ASSERT_EQ(test_float.pass_hist3d_covar, 1);
deep_copy(density_1d, 0);
deep_copy(density_3d, 0);
cout << "Test Scalar=double" << endl;
test_random_scalar<RandomGenerator,double> test_double(density_1d,density_3d,pool,num_draws);
ASSERT_EQ( test_double.pass_mean,1);
ASSERT_EQ( test_double.pass_var,1);
ASSERT_EQ( test_double.pass_covar,1);
ASSERT_EQ( test_double.pass_hist1d_mean,1);
ASSERT_EQ( test_double.pass_hist1d_var,1);
ASSERT_EQ( test_double.pass_hist1d_covar,1);
ASSERT_EQ( test_double.pass_hist3d_mean,1);
ASSERT_EQ( test_double.pass_hist3d_var,1);
ASSERT_EQ( test_double.pass_hist3d_covar,1);
}
test_random_scalar<RandomGenerator, double> test_double(
density_1d, density_3d, pool, num_draws);
ASSERT_EQ(test_double.pass_mean, 1);
ASSERT_EQ(test_double.pass_var, 1);
ASSERT_EQ(test_double.pass_covar, 1);
ASSERT_EQ(test_double.pass_hist1d_mean, 1);
ASSERT_EQ(test_double.pass_hist1d_var, 1);
ASSERT_EQ(test_double.pass_hist1d_covar, 1);
ASSERT_EQ(test_double.pass_hist3d_mean, 1);
ASSERT_EQ(test_double.pass_hist3d_var, 1);
ASSERT_EQ(test_double.pass_hist3d_covar, 1);
}
} // namespace Impl
} // namespace Test
} // namespace Test
#endif //KOKKOS_TEST_UNORDERED_MAP_HPP
#endif // KOKKOS_TEST_UNORDERED_MAP_HPP

View File

@ -2,10 +2,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -52,49 +53,36 @@
#include <TestSort.hpp>
#include <iomanip>
//----------------------------------------------------------------------------
namespace Test {
class serial : public ::testing::Test {
protected:
static void SetUpTestCase()
{
#define SERIAL_RANDOM_XORSHIFT64(num_draws) \
TEST(serial, Random_XorShift64) { \
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::Serial> >( \
num_draws); \
}
static void TearDownTestCase ()
{
}
};
#define SERIAL_RANDOM_XORSHIFT64( num_draws ) \
TEST_F( serial, Random_XorShift64 ) { \
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::Serial> >(num_draws); \
#define SERIAL_RANDOM_XORSHIFT1024(num_draws) \
TEST(serial, Random_XorShift1024) { \
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Serial> >( \
num_draws); \
}
#define SERIAL_RANDOM_XORSHIFT1024( num_draws ) \
TEST_F( serial, Random_XorShift1024 ) { \
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Serial> >(num_draws); \
#define SERIAL_SORT_UNSIGNED(size) \
TEST(serial, SortUnsigned) { \
Impl::test_sort<Kokkos::Serial, unsigned>(size); \
}
#define SERIAL_SORT_UNSIGNED( size ) \
TEST_F( serial, SortUnsigned ) { \
Impl::test_sort< Kokkos::Serial, unsigned >(size); \
}
SERIAL_RANDOM_XORSHIFT64( 10240000 )
SERIAL_RANDOM_XORSHIFT1024( 10130144 )
SERIAL_RANDOM_XORSHIFT64(10240000)
SERIAL_RANDOM_XORSHIFT1024(10130144)
SERIAL_SORT_UNSIGNED(171)
#undef SERIAL_RANDOM_XORSHIFT64
#undef SERIAL_RANDOM_XORSHIFT1024
#undef SERIAL_SORT_UNSIGNED
} // namespace Test
} // namespace Test
#else
void KOKKOS_ALGORITHMS_UNITTESTS_TESTSERIAL_PREVENT_LINK_ERROR() {}
#endif // KOKKOS_ENABLE_SERIAL
#endif // KOKKOS_ENABLE_SERIAL

View File

@ -1,10 +1,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -22,10 +23,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -43,235 +44,248 @@
#define KOKKOS_ALGORITHMS_UNITTESTS_TESTSORT_HPP
#include <gtest/gtest.h>
#include<Kokkos_Core.hpp>
#include<Kokkos_DynamicView.hpp>
#include<Kokkos_Random.hpp>
#include<Kokkos_Sort.hpp>
#include <Kokkos_Core.hpp>
#include <Kokkos_DynamicView.hpp>
#include <Kokkos_Random.hpp>
#include <Kokkos_Sort.hpp>
namespace Test {
namespace Impl{
namespace Impl {
template<class ExecutionSpace, class Scalar>
template <class ExecutionSpace, class Scalar>
struct is_sorted_struct {
typedef unsigned int value_type;
typedef ExecutionSpace execution_space;
Kokkos::View<Scalar*,ExecutionSpace> keys;
Kokkos::View<Scalar*, ExecutionSpace> keys;
is_sorted_struct(Kokkos::View<Scalar*,ExecutionSpace> keys_):keys(keys_) {}
is_sorted_struct(Kokkos::View<Scalar*, ExecutionSpace> keys_) : keys(keys_) {}
KOKKOS_INLINE_FUNCTION
void operator() (int i, unsigned int& count) const {
if(keys(i)>keys(i+1)) count++;
void operator()(int i, unsigned int& count) const {
if (keys(i) > keys(i + 1)) count++;
}
};
template<class ExecutionSpace, class Scalar>
template <class ExecutionSpace, class Scalar>
struct sum {
typedef double value_type;
typedef ExecutionSpace execution_space;
Kokkos::View<Scalar*,ExecutionSpace> keys;
Kokkos::View<Scalar*, ExecutionSpace> keys;
sum(Kokkos::View<Scalar*,ExecutionSpace> keys_):keys(keys_) {}
sum(Kokkos::View<Scalar*, ExecutionSpace> keys_) : keys(keys_) {}
KOKKOS_INLINE_FUNCTION
void operator() (int i, double& count) const {
count+=keys(i);
}
void operator()(int i, double& count) const { count += keys(i); }
};
template<class ExecutionSpace, class Scalar>
template <class ExecutionSpace, class Scalar>
struct bin3d_is_sorted_struct {
typedef unsigned int value_type;
typedef ExecutionSpace execution_space;
Kokkos::View<Scalar*[3],ExecutionSpace> keys;
Kokkos::View<Scalar * [3], ExecutionSpace> keys;
int max_bins;
Scalar min;
Scalar max;
bin3d_is_sorted_struct(Kokkos::View<Scalar*[3],ExecutionSpace> keys_,int max_bins_,Scalar min_,Scalar max_):
keys(keys_),max_bins(max_bins_),min(min_),max(max_) {
}
bin3d_is_sorted_struct(Kokkos::View<Scalar * [3], ExecutionSpace> keys_,
int max_bins_, Scalar min_, Scalar max_)
: keys(keys_), max_bins(max_bins_), min(min_), max(max_) {}
KOKKOS_INLINE_FUNCTION
void operator() (int i, unsigned int& count) const {
int ix1 = int ((keys(i,0)-min)/max * max_bins);
int iy1 = int ((keys(i,1)-min)/max * max_bins);
int iz1 = int ((keys(i,2)-min)/max * max_bins);
int ix2 = int ((keys(i+1,0)-min)/max * max_bins);
int iy2 = int ((keys(i+1,1)-min)/max * max_bins);
int iz2 = int ((keys(i+1,2)-min)/max * max_bins);
void operator()(int i, unsigned int& count) const {
int ix1 = int((keys(i, 0) - min) / max * max_bins);
int iy1 = int((keys(i, 1) - min) / max * max_bins);
int iz1 = int((keys(i, 2) - min) / max * max_bins);
int ix2 = int((keys(i + 1, 0) - min) / max * max_bins);
int iy2 = int((keys(i + 1, 1) - min) / max * max_bins);
int iz2 = int((keys(i + 1, 2) - min) / max * max_bins);
if (ix1>ix2) count++;
else if(ix1==ix2) {
if (iy1>iy2) count++;
else if ((iy1==iy2) && (iz1>iz2)) count++;
if (ix1 > ix2)
count++;
else if (ix1 == ix2) {
if (iy1 > iy2)
count++;
else if ((iy1 == iy2) && (iz1 > iz2))
count++;
}
}
};
template<class ExecutionSpace, class Scalar>
template <class ExecutionSpace, class Scalar>
struct sum3D {
typedef double value_type;
typedef ExecutionSpace execution_space;
Kokkos::View<Scalar*[3],ExecutionSpace> keys;
Kokkos::View<Scalar * [3], ExecutionSpace> keys;
sum3D(Kokkos::View<Scalar*[3],ExecutionSpace> keys_):keys(keys_) {}
sum3D(Kokkos::View<Scalar * [3], ExecutionSpace> keys_) : keys(keys_) {}
KOKKOS_INLINE_FUNCTION
void operator() (int i, double& count) const {
count+=keys(i,0);
count+=keys(i,1);
count+=keys(i,2);
void operator()(int i, double& count) const {
count += keys(i, 0);
count += keys(i, 1);
count += keys(i, 2);
}
};
template<class ExecutionSpace, typename KeyType>
void test_1D_sort(unsigned int n,bool force_kokkos) {
typedef Kokkos::View<KeyType*,ExecutionSpace> KeyViewType;
KeyViewType keys("Keys",n);
template <class ExecutionSpace, typename KeyType>
void test_1D_sort(unsigned int n, bool force_kokkos) {
typedef Kokkos::View<KeyType*, ExecutionSpace> KeyViewType;
KeyViewType keys("Keys", n);
// Test sorting array with all numbers equal
Kokkos::deep_copy(keys,KeyType(1));
Kokkos::sort(keys,force_kokkos);
Kokkos::deep_copy(keys, KeyType(1));
Kokkos::sort(keys, force_kokkos);
Kokkos::Random_XorShift64_Pool<ExecutionSpace> g(1931);
Kokkos::fill_random(keys,g,Kokkos::Random_XorShift64_Pool<ExecutionSpace>::generator_type::MAX_URAND);
Kokkos::fill_random(keys, g,
Kokkos::Random_XorShift64_Pool<
ExecutionSpace>::generator_type::MAX_URAND);
double sum_before = 0.0;
double sum_after = 0.0;
double sum_before = 0.0;
double sum_after = 0.0;
unsigned int sort_fails = 0;
Kokkos::parallel_reduce(n,sum<ExecutionSpace, KeyType>(keys),sum_before);
Kokkos::parallel_reduce(n, sum<ExecutionSpace, KeyType>(keys), sum_before);
Kokkos::sort(keys,force_kokkos);
Kokkos::sort(keys, force_kokkos);
Kokkos::parallel_reduce(n,sum<ExecutionSpace, KeyType>(keys),sum_after);
Kokkos::parallel_reduce(n-1,is_sorted_struct<ExecutionSpace, KeyType>(keys),sort_fails);
Kokkos::parallel_reduce(n, sum<ExecutionSpace, KeyType>(keys), sum_after);
Kokkos::parallel_reduce(
n - 1, is_sorted_struct<ExecutionSpace, KeyType>(keys), sort_fails);
double ratio = sum_before/sum_after;
double ratio = sum_before / sum_after;
double epsilon = 1e-10;
unsigned int equal_sum = (ratio > (1.0-epsilon)) && (ratio < (1.0+epsilon)) ? 1 : 0;
unsigned int equal_sum =
(ratio > (1.0 - epsilon)) && (ratio < (1.0 + epsilon)) ? 1 : 0;
ASSERT_EQ(sort_fails,0);
ASSERT_EQ(equal_sum,1);
ASSERT_EQ(sort_fails, 0);
ASSERT_EQ(equal_sum, 1);
}
template<class ExecutionSpace, typename KeyType>
template <class ExecutionSpace, typename KeyType>
void test_3D_sort(unsigned int n) {
typedef Kokkos::View<KeyType*[3],ExecutionSpace > KeyViewType;
typedef Kokkos::View<KeyType * [3], ExecutionSpace> KeyViewType;
KeyViewType keys("Keys",n*n*n);
KeyViewType keys("Keys", n * n * n);
Kokkos::Random_XorShift64_Pool<ExecutionSpace> g(1931);
Kokkos::fill_random(keys,g,100.0);
Kokkos::fill_random(keys, g, 100.0);
double sum_before = 0.0;
double sum_after = 0.0;
double sum_before = 0.0;
double sum_after = 0.0;
unsigned int sort_fails = 0;
Kokkos::parallel_reduce(keys.extent(0),sum3D<ExecutionSpace, KeyType>(keys),sum_before);
Kokkos::parallel_reduce(keys.extent(0), sum3D<ExecutionSpace, KeyType>(keys),
sum_before);
int bin_1d = 1;
while( bin_1d*bin_1d*bin_1d*4< (int) keys.extent(0) ) bin_1d*=2;
int bin_max[3] = {bin_1d,bin_1d,bin_1d};
typename KeyViewType::value_type min[3] = {0,0,0};
typename KeyViewType::value_type max[3] = {100,100,100};
while (bin_1d * bin_1d * bin_1d * 4 < (int)keys.extent(0)) bin_1d *= 2;
int bin_max[3] = {bin_1d, bin_1d, bin_1d};
typename KeyViewType::value_type min[3] = {0, 0, 0};
typename KeyViewType::value_type max[3] = {100, 100, 100};
typedef Kokkos::BinOp3D< KeyViewType > BinOp;
BinOp bin_op(bin_max,min,max);
Kokkos::BinSort< KeyViewType , BinOp >
Sorter(keys,bin_op,false);
typedef Kokkos::BinOp3D<KeyViewType> BinOp;
BinOp bin_op(bin_max, min, max);
Kokkos::BinSort<KeyViewType, BinOp> Sorter(keys, bin_op, false);
Sorter.create_permute_vector();
Sorter.template sort< KeyViewType >(keys);
Sorter.template sort<KeyViewType>(keys);
Kokkos::parallel_reduce(keys.extent(0),sum3D<ExecutionSpace, KeyType>(keys),sum_after);
Kokkos::parallel_reduce(keys.extent(0)-1,bin3d_is_sorted_struct<ExecutionSpace, KeyType>(keys,bin_1d,min[0],max[0]),sort_fails);
Kokkos::parallel_reduce(keys.extent(0), sum3D<ExecutionSpace, KeyType>(keys),
sum_after);
Kokkos::parallel_reduce(keys.extent(0) - 1,
bin3d_is_sorted_struct<ExecutionSpace, KeyType>(
keys, bin_1d, min[0], max[0]),
sort_fails);
double ratio = sum_before/sum_after;
double ratio = sum_before / sum_after;
double epsilon = 1e-10;
unsigned int equal_sum = (ratio > (1.0-epsilon)) && (ratio < (1.0+epsilon)) ? 1 : 0;
unsigned int equal_sum =
(ratio > (1.0 - epsilon)) && (ratio < (1.0 + epsilon)) ? 1 : 0;
if ( sort_fails )
printf("3D Sort Sum: %f %f Fails: %u\n",sum_before,sum_after,sort_fails);
if (sort_fails)
printf("3D Sort Sum: %f %f Fails: %u\n", sum_before, sum_after, sort_fails);
ASSERT_EQ(sort_fails,0);
ASSERT_EQ(equal_sum,1);
ASSERT_EQ(sort_fails, 0);
ASSERT_EQ(equal_sum, 1);
}
//----------------------------------------------------------------------------
template<class ExecutionSpace, typename KeyType>
void test_dynamic_view_sort(unsigned int n )
{
typedef Kokkos::Experimental::DynamicView<KeyType*,ExecutionSpace> KeyDynamicViewType;
typedef Kokkos::View<KeyType*,ExecutionSpace> KeyViewType;
template <class ExecutionSpace, typename KeyType>
void test_dynamic_view_sort(unsigned int n) {
typedef Kokkos::Experimental::DynamicView<KeyType*, ExecutionSpace>
KeyDynamicViewType;
typedef Kokkos::View<KeyType*, ExecutionSpace> KeyViewType;
const size_t upper_bound = 2 * n ;
const size_t upper_bound = 2 * n;
const size_t min_chunk_size = 1024;
KeyDynamicViewType keys("Keys", min_chunk_size, upper_bound);
keys.resize_serial(n);
KeyViewType keys_view("KeysTmp", n );
KeyViewType keys_view("KeysTmp", n);
// Test sorting array with all numbers equal
Kokkos::deep_copy(keys_view,KeyType(1));
Kokkos::deep_copy(keys,keys_view);
Kokkos::sort(keys, 0 /* begin */ , n /* end */ );
Kokkos::deep_copy(keys_view, KeyType(1));
Kokkos::deep_copy(keys, keys_view);
Kokkos::sort(keys, 0 /* begin */, n /* end */);
Kokkos::Random_XorShift64_Pool<ExecutionSpace> g(1931);
Kokkos::fill_random(keys_view,g,Kokkos::Random_XorShift64_Pool<ExecutionSpace>::generator_type::MAX_URAND);
Kokkos::fill_random(keys_view, g,
Kokkos::Random_XorShift64_Pool<
ExecutionSpace>::generator_type::MAX_URAND);
ExecutionSpace().fence();
Kokkos::deep_copy(keys,keys_view);
//ExecutionSpace().fence();
Kokkos::deep_copy(keys, keys_view);
// ExecutionSpace().fence();
double sum_before = 0.0;
double sum_after = 0.0;
double sum_before = 0.0;
double sum_after = 0.0;
unsigned int sort_fails = 0;
Kokkos::parallel_reduce(n,sum<ExecutionSpace, KeyType>(keys_view),sum_before);
Kokkos::parallel_reduce(n, sum<ExecutionSpace, KeyType>(keys_view),
sum_before);
Kokkos::sort(keys, 0 /* begin */ , n /* end */ );
Kokkos::sort(keys, 0 /* begin */, n /* end */);
ExecutionSpace().fence(); // Need this fence to prevent BusError with Cuda
Kokkos::deep_copy( keys_view , keys );
//ExecutionSpace().fence();
ExecutionSpace().fence(); // Need this fence to prevent BusError with Cuda
Kokkos::deep_copy(keys_view, keys);
// ExecutionSpace().fence();
Kokkos::parallel_reduce(n,sum<ExecutionSpace, KeyType>(keys_view),sum_after);
Kokkos::parallel_reduce(n-1,is_sorted_struct<ExecutionSpace, KeyType>(keys_view),sort_fails);
Kokkos::parallel_reduce(n, sum<ExecutionSpace, KeyType>(keys_view),
sum_after);
Kokkos::parallel_reduce(
n - 1, is_sorted_struct<ExecutionSpace, KeyType>(keys_view), sort_fails);
double ratio = sum_before/sum_after;
double ratio = sum_before / sum_after;
double epsilon = 1e-10;
unsigned int equal_sum = (ratio > (1.0-epsilon)) && (ratio < (1.0+epsilon)) ? 1 : 0;
unsigned int equal_sum =
(ratio > (1.0 - epsilon)) && (ratio < (1.0 + epsilon)) ? 1 : 0;
if ( sort_fails != 0 || equal_sum != 1 ) {
std::cout << " N = " << n
<< " ; sum_before = " << sum_before
<< " ; sum_after = " << sum_after
<< " ; ratio = " << ratio
<< std::endl ;
if (sort_fails != 0 || equal_sum != 1) {
std::cout << " N = " << n << " ; sum_before = " << sum_before
<< " ; sum_after = " << sum_after << " ; ratio = " << ratio
<< std::endl;
}
ASSERT_EQ(sort_fails,0);
ASSERT_EQ(equal_sum,1);
ASSERT_EQ(sort_fails, 0);
ASSERT_EQ(equal_sum, 1);
}
//----------------------------------------------------------------------------
template<class ExecutionSpace>
void test_issue_1160()
{
template <class ExecutionSpace>
void test_issue_1160() {
Kokkos::View<int*, ExecutionSpace> element_("element", 10);
Kokkos::View<double*, ExecutionSpace> x_("x", 10);
Kokkos::View<double*, ExecutionSpace> v_("y", 10);
auto h_element = Kokkos::create_mirror_view(element_);
auto h_x = Kokkos::create_mirror_view(x_);
auto h_v = Kokkos::create_mirror_view(v_);
auto h_x = Kokkos::create_mirror_view(x_);
auto h_v = Kokkos::create_mirror_view(v_);
h_element(0) = 9;
h_element(1) = 8;
@ -292,20 +306,21 @@ void test_issue_1160()
Kokkos::deep_copy(v_, h_v);
typedef decltype(element_) KeyViewType;
typedef Kokkos::BinOp1D< KeyViewType > BinOp;
typedef Kokkos::BinOp1D<KeyViewType> BinOp;
int begin = 3;
int end = 8;
auto max = h_element(begin);
auto min = h_element(end - 1);
int end = 8;
auto max = h_element(begin);
auto min = h_element(end - 1);
BinOp binner(end - begin, min, max);
Kokkos::BinSort<KeyViewType , BinOp > Sorter(element_,begin,end,binner,false);
Kokkos::BinSort<KeyViewType, BinOp> Sorter(element_, begin, end, binner,
false);
Sorter.create_permute_vector();
Sorter.sort(element_,begin,end);
Sorter.sort(element_, begin, end);
Sorter.sort(x_,begin,end);
Sorter.sort(v_,begin,end);
Sorter.sort(x_, begin, end);
Sorter.sort(v_, begin, end);
Kokkos::deep_copy(h_element, element_);
Kokkos::deep_copy(h_x, x_);
@ -330,18 +345,17 @@ void test_issue_1160()
//----------------------------------------------------------------------------
template<class ExecutionSpace, typename KeyType>
void test_sort(unsigned int N)
{
test_1D_sort<ExecutionSpace,KeyType>(N*N*N, true);
test_1D_sort<ExecutionSpace,KeyType>(N*N*N, false);
template <class ExecutionSpace, typename KeyType>
void test_sort(unsigned int N) {
test_1D_sort<ExecutionSpace, KeyType>(N * N * N, true);
test_1D_sort<ExecutionSpace, KeyType>(N * N * N, false);
#if !defined(KOKKOS_ENABLE_ROCM)
test_3D_sort<ExecutionSpace,KeyType>(N);
test_dynamic_view_sort<ExecutionSpace,KeyType>(N*N);
test_3D_sort<ExecutionSpace, KeyType>(N);
test_dynamic_view_sort<ExecutionSpace, KeyType>(N * N);
#endif
test_issue_1160<ExecutionSpace>();
}
}
}
} // namespace Impl
} // namespace Test
#endif /* KOKKOS_ALGORITHMS_UNITTESTS_TESTSORT_HPP */

View File

@ -2,10 +2,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -52,51 +53,36 @@
#include <TestSort.hpp>
#include <iomanip>
//----------------------------------------------------------------------------
namespace Test {
class threads : public ::testing::Test {
protected:
static void SetUpTestCase()
{
std::cout << std::setprecision(5) << std::scientific;
#define THREADS_RANDOM_XORSHIFT64(num_draws) \
TEST(threads, Random_XorShift64) { \
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::Threads> >( \
num_draws); \
}
static void TearDownTestCase()
{
}
};
#define THREADS_RANDOM_XORSHIFT64( num_draws ) \
TEST_F( threads, Random_XorShift64 ) { \
Impl::test_random<Kokkos::Random_XorShift64_Pool<Kokkos::Threads> >(num_draws); \
#define THREADS_RANDOM_XORSHIFT1024(num_draws) \
TEST(threads, Random_XorShift1024) { \
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Threads> >( \
num_draws); \
}
#define THREADS_RANDOM_XORSHIFT1024( num_draws ) \
TEST_F( threads, Random_XorShift1024 ) { \
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Threads> >(num_draws); \
#define THREADS_SORT_UNSIGNED(size) \
TEST(threads, SortUnsigned) { \
Impl::test_sort<Kokkos::Threads, double>(size); \
}
#define THREADS_SORT_UNSIGNED( size ) \
TEST_F( threads, SortUnsigned ) { \
Impl::test_sort< Kokkos::Threads, double >(size); \
}
THREADS_RANDOM_XORSHIFT64( 10240000 )
THREADS_RANDOM_XORSHIFT1024( 10130144 )
THREADS_RANDOM_XORSHIFT64(10240000)
THREADS_RANDOM_XORSHIFT1024(10130144)
THREADS_SORT_UNSIGNED(171)
#undef THREADS_RANDOM_XORSHIFT64
#undef THREADS_RANDOM_XORSHIFT1024
#undef THREADS_SORT_UNSIGNED
} // namespace Test
} // namespace Test
#else
void KOKKOS_ALGORITHMS_UNITTESTS_TESTTHREADS_PREVENT_LINK_ERROR() {}
#endif

View File

@ -2,10 +2,11 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 2.0
// Copyright (2014) Sandia Corporation
// Kokkos v. 3.0
// Copyright (2020) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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
@ -23,10 +24,10 @@
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// 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 SANDIA CORPORATION OR THE
// 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
@ -45,10 +46,9 @@
#include <Kokkos_Core.hpp>
int main(int argc, char *argv[]) {
Kokkos::initialize(argc,argv);
::testing::InitGoogleTest(&argc,argv);
Kokkos::initialize(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
Kokkos::finalize();
return result;
}