Updating Kokkos lib
git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@15556 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
10
lib/kokkos/algorithms/CMakeLists.txt
Normal file
10
lib/kokkos/algorithms/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
TRIBITS_SUBPACKAGE(Algorithms)
|
||||
|
||||
ADD_SUBDIRECTORY(src)
|
||||
|
||||
TRIBITS_ADD_TEST_DIRECTORIES(unit_tests)
|
||||
#TRIBITS_ADD_TEST_DIRECTORIES(performance_tests)
|
||||
|
||||
TRIBITS_SUBPACKAGE_POSTPROCESS()
|
||||
5
lib/kokkos/algorithms/cmake/Dependencies.cmake
Normal file
5
lib/kokkos/algorithms/cmake/Dependencies.cmake
Normal file
@ -0,0 +1,5 @@
|
||||
TRIBITS_PACKAGE_DEFINE_DEPENDENCIES(
|
||||
LIB_REQUIRED_PACKAGES KokkosCore
|
||||
LIB_OPTIONAL_TPLS Pthread CUDA HWLOC
|
||||
TEST_OPTIONAL_TPLS CUSPARSE
|
||||
)
|
||||
4
lib/kokkos/algorithms/cmake/KokkosAlgorithms_config.h.in
Normal file
4
lib/kokkos/algorithms/cmake/KokkosAlgorithms_config.h.in
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef KOKKOS_ALGORITHMS_CONFIG_H
|
||||
#define KOKKOS_ALGORITHMS_CONFIG_H
|
||||
|
||||
#endif
|
||||
21
lib/kokkos/algorithms/src/CMakeLists.txt
Normal file
21
lib/kokkos/algorithms/src/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
TRIBITS_CONFIGURE_FILE(${PACKAGE_NAME}_config.h)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
FILE(GLOB HEADERS *.hpp)
|
||||
FILE(GLOB SOURCES *.cpp)
|
||||
LIST(APPEND HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}_config.h)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
TRIBITS_ADD_LIBRARY(
|
||||
kokkosalgorithms
|
||||
HEADERS ${HEADERS}
|
||||
SOURCES ${SOURCES}
|
||||
DEPLIBS
|
||||
)
|
||||
|
||||
1751
lib/kokkos/algorithms/src/Kokkos_Random.hpp
Normal file
1751
lib/kokkos/algorithms/src/Kokkos_Random.hpp
Normal file
File diff suppressed because it is too large
Load Diff
496
lib/kokkos/algorithms/src/Kokkos_Sort.hpp
Normal file
496
lib/kokkos/algorithms/src/Kokkos_Sort.hpp
Normal file
@ -0,0 +1,496 @@
|
||||
/*
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
|
||||
#ifndef KOKKOS_SORT_HPP_
|
||||
#define KOKKOS_SORT_HPP_
|
||||
|
||||
#include <Kokkos_Core.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Kokkos {
|
||||
|
||||
namespace SortImpl {
|
||||
|
||||
template<class ValuesViewType, int Rank=ValuesViewType::Rank>
|
||||
struct CopyOp;
|
||||
|
||||
template<class ValuesViewType>
|
||||
struct CopyOp<ValuesViewType,1> {
|
||||
template<class DstType, class SrcType>
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
static void copy(DstType& dst, size_t i_dst,
|
||||
SrcType& src, size_t i_src ) {
|
||||
dst(i_dst) = src(i_src);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ValuesViewType>
|
||||
struct CopyOp<ValuesViewType,2> {
|
||||
template<class DstType, class SrcType>
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
static void copy(DstType& dst, size_t i_dst,
|
||||
SrcType& src, size_t i_src ) {
|
||||
for(int j = 0;j< (int) dst.dimension_1(); j++)
|
||||
dst(i_dst,j) = src(i_src,j);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ValuesViewType>
|
||||
struct CopyOp<ValuesViewType,3> {
|
||||
template<class DstType, class SrcType>
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
static void copy(DstType& dst, size_t i_dst,
|
||||
SrcType& src, size_t i_src ) {
|
||||
for(int j = 0; j<dst.dimension_1(); j++)
|
||||
for(int k = 0; k<dst.dimension_2(); k++)
|
||||
dst(i_dst,j,k) = src(i_src,j,k);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<class KeyViewType, class BinSortOp, class ExecutionSpace = typename KeyViewType::execution_space,
|
||||
class SizeType = typename KeyViewType::memory_space::size_type>
|
||||
class BinSort {
|
||||
|
||||
|
||||
public:
|
||||
template<class ValuesViewType, class PermuteViewType, class CopyOp>
|
||||
struct bin_sort_sort_functor {
|
||||
typedef ExecutionSpace execution_space;
|
||||
typedef typename ValuesViewType::non_const_type values_view_type;
|
||||
typedef typename ValuesViewType::const_type const_values_view_type;
|
||||
Kokkos::View<typename values_view_type::const_data_type,typename values_view_type::array_layout,
|
||||
typename values_view_type::memory_space,Kokkos::MemoryTraits<Kokkos::RandomAccess> > values;
|
||||
values_view_type sorted_values;
|
||||
typename PermuteViewType::const_type sort_order;
|
||||
bin_sort_sort_functor(const_values_view_type values_, values_view_type sorted_values_, PermuteViewType sort_order_):
|
||||
values(values_),sorted_values(sorted_values_),sort_order(sort_order_) {}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator() (const int& i) const {
|
||||
//printf("Sort: %i %i\n",i,sort_order(i));
|
||||
CopyOp::copy(sorted_values,i,values,sort_order(i));
|
||||
}
|
||||
};
|
||||
|
||||
typedef ExecutionSpace execution_space;
|
||||
typedef BinSortOp bin_op_type;
|
||||
|
||||
struct bin_count_tag {};
|
||||
struct bin_offset_tag {};
|
||||
struct bin_binning_tag {};
|
||||
struct bin_sort_bins_tag {};
|
||||
|
||||
public:
|
||||
typedef SizeType size_type;
|
||||
typedef size_type value_type;
|
||||
|
||||
typedef Kokkos::View<size_type*, execution_space> offset_type;
|
||||
typedef Kokkos::View<const int*, execution_space> bin_count_type;
|
||||
|
||||
|
||||
typedef Kokkos::View<typename KeyViewType::const_data_type,
|
||||
typename KeyViewType::array_layout,
|
||||
typename KeyViewType::memory_space> const_key_view_type;
|
||||
typedef Kokkos::View<typename KeyViewType::const_data_type,
|
||||
typename KeyViewType::array_layout,
|
||||
typename KeyViewType::memory_space,
|
||||
Kokkos::MemoryTraits<Kokkos::RandomAccess> > 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;
|
||||
|
||||
private:
|
||||
const_key_view_type keys;
|
||||
const_rnd_key_view_type keys_rnd;
|
||||
|
||||
public:
|
||||
BinSortOp bin_op;
|
||||
|
||||
offset_type bin_offsets;
|
||||
|
||||
Kokkos::View<int*, ExecutionSpace, Kokkos::MemoryTraits<Kokkos::Atomic> > bin_count_atomic;
|
||||
bin_count_type bin_count_const;
|
||||
|
||||
offset_type sort_order;
|
||||
|
||||
bool sort_within_bins;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor: takes the keys, the binning_operator and optionally whether to sort within bins (default false)
|
||||
BinSort(const_key_view_type keys_, BinSortOp bin_op_,
|
||||
bool sort_within_bins_ = false)
|
||||
:keys(keys_),keys_rnd(keys_), bin_op(bin_op_) {
|
||||
|
||||
bin_count_atomic = Kokkos::View<int*, ExecutionSpace >("Kokkos::SortImpl::BinSortFunctor::bin_count",bin_op.max_bins());
|
||||
bin_count_const = bin_count_atomic;
|
||||
bin_offsets = offset_type("Kokkos::SortImpl::BinSortFunctor::bin_offsets",bin_op.max_bins());
|
||||
sort_order = offset_type("PermutationVector",keys.dimension_0());
|
||||
sort_within_bins = sort_within_bins_;
|
||||
}
|
||||
|
||||
// Create the permutation vector, the bin_offset array and the bin_count array. Can be called again if keys changed
|
||||
void create_permute_vector() {
|
||||
Kokkos::parallel_for (Kokkos::RangePolicy<ExecutionSpace,bin_count_tag> (0,keys.dimension_0()),*this);
|
||||
Kokkos::parallel_scan(Kokkos::RangePolicy<ExecutionSpace,bin_offset_tag> (0,bin_op.max_bins()) ,*this);
|
||||
|
||||
Kokkos::deep_copy(bin_count_atomic,0);
|
||||
Kokkos::parallel_for (Kokkos::RangePolicy<ExecutionSpace,bin_binning_tag> (0,keys.dimension_0()),*this);
|
||||
|
||||
if(sort_within_bins)
|
||||
Kokkos::parallel_for (Kokkos::RangePolicy<ExecutionSpace,bin_sort_bins_tag>(0,bin_op.max_bins()) ,*this);
|
||||
}
|
||||
|
||||
// Sort a view with respect ot the first dimension using the permutation array
|
||||
template<class ValuesViewType>
|
||||
void sort(ValuesViewType values) {
|
||||
ValuesViewType sorted_values = ValuesViewType("Copy",
|
||||
values.dimension_0(),
|
||||
values.dimension_1(),
|
||||
values.dimension_2(),
|
||||
values.dimension_3(),
|
||||
values.dimension_4(),
|
||||
values.dimension_5(),
|
||||
values.dimension_6(),
|
||||
values.dimension_7());
|
||||
|
||||
parallel_for(values.dimension_0(),
|
||||
bin_sort_sort_functor<ValuesViewType, offset_type,
|
||||
SortImpl::CopyOp<ValuesViewType> >(values,sorted_values,sort_order));
|
||||
|
||||
deep_copy(values,sorted_values);
|
||||
}
|
||||
|
||||
// Get the permutation vector
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
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;}
|
||||
|
||||
// Get the count for each bin
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
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 {
|
||||
bin_count_atomic(bin_op.bin(keys,i))++;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
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);
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator() (const bin_binning_tag& tag, const int& i) const {
|
||||
const int bin = bin_op.bin(keys,i);
|
||||
const int count = bin_count_atomic(bin)++;
|
||||
|
||||
sort_order(bin_offsets(bin) + count) = i;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator() (const bin_sort_bins_tag& tag, const int&i ) const {
|
||||
bool sorted = false;
|
||||
int upper_bound = bin_offsets(i)+bin_count_const(i);
|
||||
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++) {
|
||||
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;
|
||||
} else {
|
||||
old_idx = new_idx;
|
||||
}
|
||||
}
|
||||
upper_bound--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace SortImpl {
|
||||
|
||||
template<class KeyViewType>
|
||||
struct DefaultBinOp1D {
|
||||
const int max_bins_;
|
||||
const double mul_;
|
||||
typename KeyViewType::const_value_type range_;
|
||||
typename KeyViewType::const_value_type min_;
|
||||
|
||||
//Construct BinOp with number of bins, minimum value and maxuimum value
|
||||
DefaultBinOp1D(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) {}
|
||||
|
||||
//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
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
template<class KeyViewType>
|
||||
struct DefaultBinOp3D {
|
||||
int max_bins_[3];
|
||||
double mul_[3];
|
||||
typename KeyViewType::non_const_value_type range_[3];
|
||||
typename KeyViewType::non_const_value_type min_[3];
|
||||
|
||||
DefaultBinOp3D(int max_bins__[], typename KeyViewType::const_value_type min[],
|
||||
typename KeyViewType::const_value_type max[] )
|
||||
{
|
||||
max_bins_[0] = max_bins__[0]+1;
|
||||
max_bins_[1] = max_bins__[1]+1;
|
||||
max_bins_[2] = max_bins__[2]+1;
|
||||
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])));
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
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,2)) {
|
||||
if (keys(i1,2)>keys(i2,2)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
struct min_max {
|
||||
Scalar min;
|
||||
Scalar max;
|
||||
bool init;
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
min_max() {
|
||||
min = 0;
|
||||
max = 0;
|
||||
init = 0;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
min_max (const min_max& val) {
|
||||
min = val.min;
|
||||
max = val.max;
|
||||
init = val.init;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
min_max operator = (const min_max& val) {
|
||||
min = val.min;
|
||||
max = val.max;
|
||||
init = val.init;
|
||||
return *this;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator+= (const Scalar& val) {
|
||||
if(init) {
|
||||
min = min<val?min:val;
|
||||
max = max>val?max:val;
|
||||
} else {
|
||||
min = val;
|
||||
max = val;
|
||||
init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator+= (const min_max& val) {
|
||||
if(init && val.init) {
|
||||
min = min<val.min?min:val.min;
|
||||
max = max>val.max?max:val.max;
|
||||
} else {
|
||||
if(val.init) {
|
||||
min = val.min;
|
||||
max = val.max;
|
||||
init = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator+= (volatile const Scalar& val) volatile {
|
||||
if(init) {
|
||||
min = min<val?min:val;
|
||||
max = max>val?max:val;
|
||||
} else {
|
||||
min = val;
|
||||
max = val;
|
||||
init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator+= (volatile const min_max& val) volatile {
|
||||
if(init && val.init) {
|
||||
min = min<val.min?min:val.min;
|
||||
max = max>val.max?max:val.max;
|
||||
} else {
|
||||
if(val.init) {
|
||||
min = val.min;
|
||||
max = val.max;
|
||||
init = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class ViewType>
|
||||
struct min_max_functor {
|
||||
typedef typename ViewType::execution_space execution_space;
|
||||
ViewType view;
|
||||
typedef min_max<typename ViewType::non_const_value_type> value_type;
|
||||
min_max_functor (const ViewType view_):view(view_) {
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator()(const size_t& i, value_type& val) const {
|
||||
val += view(i);
|
||||
}
|
||||
};
|
||||
|
||||
template<class ViewType>
|
||||
bool try_std_sort(ViewType view) {
|
||||
bool possible = true;
|
||||
#if ! KOKKOS_USING_EXP_VIEW
|
||||
size_t stride[8];
|
||||
view.stride(stride);
|
||||
#else
|
||||
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()
|
||||
};
|
||||
#endif
|
||||
possible = possible && Impl::is_same<typename ViewType::memory_space, HostSpace>::value;
|
||||
possible = possible && (ViewType::Rank == 1);
|
||||
possible = possible && (stride[0] == 1);
|
||||
if(possible) {
|
||||
std::sort(view.ptr_on_device(),view.ptr_on_device()+view.dimension_0());
|
||||
}
|
||||
return possible;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<class ViewType>
|
||||
void sort(ViewType view, bool always_use_kokkos_sort = false) {
|
||||
if(!always_use_kokkos_sort) {
|
||||
if(SortImpl::try_std_sort(view)) return;
|
||||
}
|
||||
|
||||
typedef SortImpl::DefaultBinOp1D<ViewType> CompType;
|
||||
SortImpl::min_max<typename ViewType::non_const_value_type> val;
|
||||
parallel_reduce(view.dimension_0(),SortImpl::min_max_functor<ViewType>(view),val);
|
||||
BinSort<ViewType, CompType> bin_sort(view,CompType(view.dimension_0()/2,val.min,val.max),true);
|
||||
bin_sort.create_permute_vector();
|
||||
bin_sort.sort(view);
|
||||
}
|
||||
|
||||
/*template<class ViewType, class Comparator>
|
||||
void sort(ViewType view, Comparator comp, bool always_use_kokkos_sort = false) {
|
||||
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
38
lib/kokkos/algorithms/unit_tests/CMakeLists.txt
Normal file
38
lib/kokkos/algorithms/unit_tests/CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../src )
|
||||
|
||||
SET(SOURCES
|
||||
UnitTestMain.cpp
|
||||
TestCuda.cpp
|
||||
)
|
||||
|
||||
SET(LIBRARIES kokkoscore)
|
||||
|
||||
IF(Kokkos_ENABLE_OpenMP)
|
||||
LIST( APPEND SOURCES
|
||||
TestOpenMP.cpp
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(Kokkos_ENABLE_Serial)
|
||||
LIST( APPEND SOURCES
|
||||
TestSerial.cpp
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(Kokkos_ENABLE_Pthread)
|
||||
LIST( APPEND SOURCES
|
||||
TestThreads.cpp
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
TRIBITS_ADD_EXECUTABLE_AND_TEST(
|
||||
UnitTest
|
||||
SOURCES ${SOURCES}
|
||||
COMM serial mpi
|
||||
NUM_MPI_PROCS 1
|
||||
FAIL_REGULAR_EXPRESSION " FAILED "
|
||||
TESTONLYLIBS kokkos_gtest
|
||||
)
|
||||
92
lib/kokkos/algorithms/unit_tests/Makefile
Normal file
92
lib/kokkos/algorithms/unit_tests/Makefile
Normal file
@ -0,0 +1,92 @@
|
||||
KOKKOS_PATH = ../..
|
||||
|
||||
GTEST_PATH = ../../TPL/gtest
|
||||
|
||||
vpath %.cpp ${KOKKOS_PATH}/algorithms/unit_tests
|
||||
|
||||
default: build_all
|
||||
echo "End Build"
|
||||
|
||||
|
||||
include $(KOKKOS_PATH)/Makefile.kokkos
|
||||
|
||||
ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1)
|
||||
CXX = $(NVCC_WRAPPER)
|
||||
CXXFLAGS ?= -O3
|
||||
LINK = $(CXX)
|
||||
LDFLAGS ?= -lpthread
|
||||
else
|
||||
CXX ?= g++
|
||||
CXXFLAGS ?= -O3
|
||||
LINK ?= $(CXX)
|
||||
LDFLAGS ?= -lpthread
|
||||
endif
|
||||
|
||||
KOKKOS_CXXFLAGS += -I$(GTEST_PATH) -I${KOKKOS_PATH}/algorithms/unit_tests
|
||||
|
||||
TEST_TARGETS =
|
||||
TARGETS =
|
||||
|
||||
ifeq ($(KOKKOS_INTERNAL_USE_CUDA), 1)
|
||||
OBJ_CUDA = TestCuda.o UnitTestMain.o gtest-all.o
|
||||
TARGETS += KokkosAlgorithms_UnitTest_Cuda
|
||||
TEST_TARGETS += test-cuda
|
||||
endif
|
||||
|
||||
ifeq ($(KOKKOS_INTERNAL_USE_PTHREADS), 1)
|
||||
OBJ_THREADS = TestThreads.o UnitTestMain.o gtest-all.o
|
||||
TARGETS += KokkosAlgorithms_UnitTest_Threads
|
||||
TEST_TARGETS += test-threads
|
||||
endif
|
||||
|
||||
ifeq ($(KOKKOS_INTERNAL_USE_OPENMP), 1)
|
||||
OBJ_OPENMP = TestOpenMP.o UnitTestMain.o gtest-all.o
|
||||
TARGETS += KokkosAlgorithms_UnitTest_OpenMP
|
||||
TEST_TARGETS += test-openmp
|
||||
endif
|
||||
|
||||
ifeq ($(KOKKOS_INTERNAL_USE_SERIAL), 1)
|
||||
OBJ_SERIAL = TestSerial.o UnitTestMain.o gtest-all.o
|
||||
TARGETS += KokkosAlgorithms_UnitTest_Serial
|
||||
TEST_TARGETS += test-serial
|
||||
endif
|
||||
|
||||
KokkosAlgorithms_UnitTest_Cuda: $(OBJ_CUDA) $(KOKKOS_LINK_DEPENDS)
|
||||
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_CUDA) $(KOKKOS_LIBS) $(LIB) -o KokkosAlgorithms_UnitTest_Cuda
|
||||
|
||||
KokkosAlgorithms_UnitTest_Threads: $(OBJ_THREADS) $(KOKKOS_LINK_DEPENDS)
|
||||
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_THREADS) $(KOKKOS_LIBS) $(LIB) -o KokkosAlgorithms_UnitTest_Threads
|
||||
|
||||
KokkosAlgorithms_UnitTest_OpenMP: $(OBJ_OPENMP) $(KOKKOS_LINK_DEPENDS)
|
||||
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_OPENMP) $(KOKKOS_LIBS) $(LIB) -o KokkosAlgorithms_UnitTest_OpenMP
|
||||
|
||||
KokkosAlgorithms_UnitTest_Serial: $(OBJ_SERIAL) $(KOKKOS_LINK_DEPENDS)
|
||||
$(LINK) $(KOKKOS_LDFLAGS) $(LDFLAGS) $(EXTRA_PATH) $(OBJ_SERIAL) $(KOKKOS_LIBS) $(LIB) -o KokkosAlgorithms_UnitTest_Serial
|
||||
|
||||
test-cuda: KokkosAlgorithms_UnitTest_Cuda
|
||||
./KokkosAlgorithms_UnitTest_Cuda
|
||||
|
||||
test-threads: KokkosAlgorithms_UnitTest_Threads
|
||||
./KokkosAlgorithms_UnitTest_Threads
|
||||
|
||||
test-openmp: KokkosAlgorithms_UnitTest_OpenMP
|
||||
./KokkosAlgorithms_UnitTest_OpenMP
|
||||
|
||||
test-serial: KokkosAlgorithms_UnitTest_Serial
|
||||
./KokkosAlgorithms_UnitTest_Serial
|
||||
|
||||
build_all: $(TARGETS)
|
||||
|
||||
test: $(TEST_TARGETS)
|
||||
|
||||
clean: kokkos-clean
|
||||
rm -f *.o $(TARGETS)
|
||||
|
||||
# Compilation rules
|
||||
|
||||
%.o:%.cpp $(KOKKOS_CPP_DEPENDS)
|
||||
$(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) $(EXTRA_INC) -c $<
|
||||
|
||||
gtest-all.o:$(GTEST_PATH)/gtest/gtest-all.cc
|
||||
$(CXX) $(KOKKOS_CPPFLAGS) $(KOKKOS_CXXFLAGS) $(CXXFLAGS) $(EXTRA_INC) -c $(GTEST_PATH)/gtest/gtest-all.cc
|
||||
|
||||
110
lib/kokkos/algorithms/unit_tests/TestCuda.cpp
Normal file
110
lib/kokkos/algorithms/unit_tests/TestCuda.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <Kokkos_Core.hpp>
|
||||
|
||||
#ifdef KOKKOS_HAVE_CUDA
|
||||
|
||||
#include <TestRandom.hpp>
|
||||
#include <TestSort.hpp>
|
||||
|
||||
namespace Test {
|
||||
|
||||
class cuda : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
std::cout << std::setprecision(5) << std::scientific;
|
||||
Kokkos::HostSpace::execution_space::initialize();
|
||||
Kokkos::Cuda::initialize( Kokkos::Cuda::SelectDevice(0) );
|
||||
}
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
Kokkos::Cuda::finalize();
|
||||
Kokkos::HostSpace::execution_space::finalize();
|
||||
}
|
||||
};
|
||||
|
||||
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 )
|
||||
{
|
||||
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Cuda> >(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_F( cuda, Random_XorShift1024 ) { \
|
||||
cuda_test_random_xorshift1024(num_draws); \
|
||||
}
|
||||
|
||||
#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_SORT_UNSIGNED(171)
|
||||
|
||||
#undef CUDA_RANDOM_XORSHIFT64
|
||||
#undef CUDA_RANDOM_XORSHIFT1024
|
||||
#undef CUDA_SORT_UNSIGNED
|
||||
}
|
||||
|
||||
#endif /* #ifdef KOKKOS_HAVE_CUDA */
|
||||
|
||||
102
lib/kokkos/algorithms/unit_tests/TestOpenMP.cpp
Normal file
102
lib/kokkos/algorithms/unit_tests/TestOpenMP.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <Kokkos_Core.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#include <TestRandom.hpp>
|
||||
#include <TestSort.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
namespace Test {
|
||||
|
||||
#ifdef KOKKOS_HAVE_OPENMP
|
||||
class openmp : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
std::cout << std::setprecision(5) << std::scientific;
|
||||
|
||||
unsigned threads_count = omp_get_max_threads();
|
||||
|
||||
if ( Kokkos::hwloc::available() ) {
|
||||
threads_count = Kokkos::hwloc::get_available_numa_count() *
|
||||
Kokkos::hwloc::get_available_cores_per_numa();
|
||||
}
|
||||
|
||||
Kokkos::OpenMP::initialize( threads_count );
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
Kokkos::OpenMP::finalize();
|
||||
}
|
||||
};
|
||||
|
||||
#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_F( openmp, Random_XorShift1024 ) { \
|
||||
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::OpenMP> >(num_draws); \
|
||||
}
|
||||
|
||||
#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_SORT_UNSIGNED(171)
|
||||
|
||||
#undef OPENMP_RANDOM_XORSHIFT64
|
||||
#undef OPENMP_RANDOM_XORSHIFT1024
|
||||
#undef OPENMP_SORT_UNSIGNED
|
||||
#endif
|
||||
} // namespace test
|
||||
|
||||
481
lib/kokkos/algorithms/unit_tests/TestRandom.hpp
Normal file
481
lib/kokkos/algorithms/unit_tests/TestRandom.hpp
Normal file
@ -0,0 +1,481 @@
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
|
||||
#ifndef KOKKOS_TEST_DUALVIEW_HPP
|
||||
#define KOKKOS_TEST_DUALVIEW_HPP
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <impl/Kokkos_Timer.hpp>
|
||||
#include <Kokkos_Core.hpp>
|
||||
#include <Kokkos_Random.hpp>
|
||||
#include <cmath>
|
||||
#include <chrono>
|
||||
|
||||
namespace Test {
|
||||
|
||||
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
|
||||
|
||||
#define HIST_DIM3D 24
|
||||
#define HIST_DIM1D (HIST_DIM3D*HIST_DIM3D*HIST_DIM3D)
|
||||
|
||||
struct RandomProperties {
|
||||
uint64_t count;
|
||||
double mean;
|
||||
double variance;
|
||||
double covariance;
|
||||
double min;
|
||||
double max;
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
RandomProperties() {
|
||||
count = 0;
|
||||
mean = 0.0;
|
||||
variance = 0.0;
|
||||
covariance = 0.0;
|
||||
min = 1e64;
|
||||
max = -1e64;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
RandomProperties& operator+=(const RandomProperties& add) {
|
||||
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;
|
||||
return *this;
|
||||
}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator+=(const volatile RandomProperties& add) volatile {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
template<class GeneratorPool, class Scalar>
|
||||
struct test_random_functor {
|
||||
typedef typename GeneratorPool::generator_type rnd_type;
|
||||
|
||||
typedef RandomProperties value_type;
|
||||
typedef typename GeneratorPool::device_type device_type;
|
||||
|
||||
GeneratorPool rand_pool;
|
||||
const double mean;
|
||||
|
||||
// NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to define
|
||||
// an exclusive upper bound on the range of random numbers that
|
||||
// draw() can generate. However, for the float specialization, some
|
||||
// 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;
|
||||
type_1d density_1d;
|
||||
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)
|
||||
{}
|
||||
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
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);
|
||||
prop.count++;
|
||||
prop.mean += tmp;
|
||||
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.count++;
|
||||
prop.mean += tmp3;
|
||||
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
|
||||
// numbers that draw() can generate. However, for the float
|
||||
// specialization, some implementations might violate this upper
|
||||
// bound, due to rounding error. Just in case, we have left an
|
||||
// extra space at the end of each dimension of density_1d and
|
||||
// density_3d.
|
||||
//
|
||||
// Please note that those extra entries might not get counted in
|
||||
// the histograms. However, if Kokkos::rand is broken and only
|
||||
// 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 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);
|
||||
|
||||
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>
|
||||
struct test_histogram1d_functor {
|
||||
typedef RandomProperties value_type;
|
||||
typedef typename DeviceType::execution_space execution_space;
|
||||
typedef typename DeviceType::memory_space memory_space;
|
||||
|
||||
// NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to define
|
||||
// an exclusive upper bound on the range of random numbers that
|
||||
// draw() can generate. However, for the float specialization, some
|
||||
// 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;
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
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.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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class DeviceType>
|
||||
struct test_histogram3d_functor {
|
||||
typedef RandomProperties value_type;
|
||||
typedef typename DeviceType::execution_space execution_space;
|
||||
typedef typename DeviceType::memory_space memory_space;
|
||||
|
||||
// NOTE (mfh 03 Nov 2014): Kokkos::rand::max() is supposed to define
|
||||
// an exclusive upper bound on the range of random numbers that
|
||||
// draw() can generate. However, for the float specialization, some
|
||||
// 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;
|
||||
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)
|
||||
{}
|
||||
|
||||
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);
|
||||
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);
|
||||
prop.covariance += (count - mean) * (count_next - mean);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Templated test that uses the above functors.
|
||||
//
|
||||
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;
|
||||
|
||||
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 std::cerr;
|
||||
using std::endl;
|
||||
using Kokkos::parallel_reduce;
|
||||
|
||||
{
|
||||
cerr << " -- 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);
|
||||
|
||||
//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*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;
|
||||
cerr << "Pass: " << pass_mean
|
||||
<< " " << pass_var
|
||||
<< " " << mean_eps
|
||||
<< " " << variance_eps
|
||||
<< " " << covariance_eps
|
||||
<< " || " << tolerance << endl;
|
||||
}
|
||||
{
|
||||
cerr << " -- 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);
|
||||
|
||||
double tolerance = 6*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;
|
||||
|
||||
cerr << "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;
|
||||
}
|
||||
{
|
||||
cerr << " -- 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);
|
||||
|
||||
double tolerance = 6*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;
|
||||
|
||||
cerr << "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)
|
||||
{
|
||||
using std::cerr;
|
||||
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");
|
||||
|
||||
|
||||
uint64_t ticks = std::chrono::high_resolution_clock::now().time_since_epoch().count();
|
||||
cerr << "Test Seed:" << ticks << endl;
|
||||
|
||||
RandomGenerator pool(ticks);
|
||||
|
||||
cerr << "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);
|
||||
|
||||
cerr << "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);
|
||||
|
||||
cerr << "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);
|
||||
|
||||
cerr << "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);
|
||||
|
||||
cerr << "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);
|
||||
|
||||
cerr << "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);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Test
|
||||
|
||||
#endif //KOKKOS_TEST_UNORDERED_MAP_HPP
|
||||
99
lib/kokkos/algorithms/unit_tests/TestSerial.cpp
Normal file
99
lib/kokkos/algorithms/unit_tests/TestSerial.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <Kokkos_Core.hpp>
|
||||
|
||||
#include <TestRandom.hpp>
|
||||
#include <TestSort.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Test {
|
||||
|
||||
#ifdef KOKKOS_HAVE_SERIAL
|
||||
class serial : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
std::cout << std::setprecision (5) << std::scientific;
|
||||
Kokkos::Serial::initialize ();
|
||||
}
|
||||
|
||||
static void TearDownTestCase ()
|
||||
{
|
||||
Kokkos::Serial::finalize ();
|
||||
}
|
||||
};
|
||||
|
||||
#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_F( serial, Random_XorShift1024 ) { \
|
||||
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Serial> >(num_draws); \
|
||||
}
|
||||
|
||||
#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_SORT_UNSIGNED(171)
|
||||
|
||||
#undef SERIAL_RANDOM_XORSHIFT64
|
||||
#undef SERIAL_RANDOM_XORSHIFT1024
|
||||
#undef SERIAL_SORT_UNSIGNED
|
||||
|
||||
#endif // KOKKOS_HAVE_SERIAL
|
||||
} // namespace Test
|
||||
|
||||
|
||||
206
lib/kokkos/algorithms/unit_tests/TestSort.hpp
Normal file
206
lib/kokkos/algorithms/unit_tests/TestSort.hpp
Normal file
@ -0,0 +1,206 @@
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
|
||||
#ifndef TESTSORT_HPP_
|
||||
#define TESTSORT_HPP_
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include<Kokkos_Core.hpp>
|
||||
#include<Kokkos_Random.hpp>
|
||||
#include<Kokkos_Sort.hpp>
|
||||
|
||||
namespace Test {
|
||||
|
||||
namespace Impl{
|
||||
|
||||
template<class ExecutionSpace, class Scalar>
|
||||
struct is_sorted_struct {
|
||||
typedef unsigned int value_type;
|
||||
typedef ExecutionSpace execution_space;
|
||||
|
||||
Kokkos::View<Scalar*,ExecutionSpace> 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++;
|
||||
}
|
||||
};
|
||||
|
||||
template<class ExecutionSpace, class Scalar>
|
||||
struct sum {
|
||||
typedef double value_type;
|
||||
typedef ExecutionSpace execution_space;
|
||||
|
||||
Kokkos::View<Scalar*,ExecutionSpace> keys;
|
||||
|
||||
sum(Kokkos::View<Scalar*,ExecutionSpace> keys_):keys(keys_) {}
|
||||
KOKKOS_INLINE_FUNCTION
|
||||
void operator() (int i, double& count) const {
|
||||
count+=keys(i);
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
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_) {
|
||||
}
|
||||
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);
|
||||
|
||||
if (ix1>ix2) count++;
|
||||
else if(ix1==ix2) {
|
||||
if (iy1>iy2) count++;
|
||||
else if ((iy1==iy2) && (iz1>iz2)) count++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class ExecutionSpace, class Scalar>
|
||||
struct sum3D {
|
||||
typedef double value_type;
|
||||
typedef ExecutionSpace execution_space;
|
||||
|
||||
Kokkos::View<Scalar*[3],ExecutionSpace> 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);
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
Kokkos::Random_XorShift64_Pool<ExecutionSpace> g(1931);
|
||||
Kokkos::fill_random(keys,g,Kokkos::Random_XorShift64_Pool<ExecutionSpace>::generator_type::MAX_URAND);
|
||||
|
||||
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::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);
|
||||
|
||||
double ratio = sum_before/sum_after;
|
||||
double epsilon = 1e-10;
|
||||
unsigned int equal_sum = (ratio > (1.0-epsilon)) && (ratio < (1.0+epsilon)) ? 1 : 0;
|
||||
|
||||
ASSERT_EQ(sort_fails,0);
|
||||
ASSERT_EQ(equal_sum,1);
|
||||
}
|
||||
|
||||
template<class ExecutionSpace, typename KeyType>
|
||||
void test_3D_sort(unsigned int n) {
|
||||
typedef Kokkos::View<KeyType*[3],ExecutionSpace > KeyViewType;
|
||||
|
||||
KeyViewType keys("Keys",n*n*n);
|
||||
|
||||
Kokkos::Random_XorShift64_Pool<ExecutionSpace> g(1931);
|
||||
Kokkos::fill_random(keys,g,100.0);
|
||||
|
||||
double sum_before = 0.0;
|
||||
double sum_after = 0.0;
|
||||
unsigned int sort_fails = 0;
|
||||
|
||||
Kokkos::parallel_reduce(keys.dimension_0(),sum3D<ExecutionSpace, KeyType>(keys),sum_before);
|
||||
|
||||
int bin_1d = 1;
|
||||
while( bin_1d*bin_1d*bin_1d*4< (int) keys.dimension_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::SortImpl::DefaultBinOp3D< 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);
|
||||
|
||||
Kokkos::parallel_reduce(keys.dimension_0(),sum3D<ExecutionSpace, KeyType>(keys),sum_after);
|
||||
Kokkos::parallel_reduce(keys.dimension_0()-1,bin3d_is_sorted_struct<ExecutionSpace, KeyType>(keys,bin_1d,min[0],max[0]),sort_fails);
|
||||
|
||||
double ratio = sum_before/sum_after;
|
||||
double epsilon = 1e-10;
|
||||
unsigned int equal_sum = (ratio > (1.0-epsilon)) && (ratio < (1.0+epsilon)) ? 1 : 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
test_3D_sort<ExecutionSpace,KeyType>(N);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* TESTSORT_HPP_ */
|
||||
113
lib/kokkos/algorithms/unit_tests/TestThreads.cpp
Normal file
113
lib/kokkos/algorithms/unit_tests/TestThreads.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <Kokkos_Core.hpp>
|
||||
|
||||
#include <TestRandom.hpp>
|
||||
#include <TestSort.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace Test {
|
||||
|
||||
#ifdef KOKKOS_HAVE_PTHREAD
|
||||
class threads : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
std::cout << std::setprecision(5) << std::scientific;
|
||||
|
||||
unsigned num_threads = 4;
|
||||
|
||||
if (Kokkos::hwloc::available()) {
|
||||
num_threads = Kokkos::hwloc::get_available_numa_count()
|
||||
* Kokkos::hwloc::get_available_cores_per_numa()
|
||||
// * Kokkos::hwloc::get_available_threads_per_core()
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
std::cout << "Threads: " << num_threads << std::endl;
|
||||
|
||||
Kokkos::Threads::initialize( num_threads );
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
Kokkos::Threads::finalize();
|
||||
}
|
||||
};
|
||||
|
||||
#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_F( threads, Random_XorShift1024 ) { \
|
||||
Impl::test_random<Kokkos::Random_XorShift1024_Pool<Kokkos::Threads> >(num_draws); \
|
||||
}
|
||||
|
||||
#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_SORT_UNSIGNED(171)
|
||||
|
||||
#undef THREADS_RANDOM_XORSHIFT64
|
||||
#undef THREADS_RANDOM_XORSHIFT1024
|
||||
#undef THREADS_SORT_UNSIGNED
|
||||
|
||||
#endif
|
||||
} // namespace Test
|
||||
|
||||
|
||||
50
lib/kokkos/algorithms/unit_tests/UnitTestMain.cpp
Normal file
50
lib/kokkos/algorithms/unit_tests/UnitTestMain.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
//@HEADER
|
||||
// ************************************************************************
|
||||
//
|
||||
// Kokkos v. 2.0
|
||||
// Copyright (2014) Sandia Corporation
|
||||
//
|
||||
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the Corporation nor the names of the
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
||||
//
|
||||
// ************************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
::testing::InitGoogleTest(&argc,argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user