Commit f8a481f8 authored by zhouxiang's avatar zhouxiang
Browse files

添加dtk中的cub头文件

parent 7b7c64c5
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ROCPRIM_ITERATOR_DISCARD_ITERATOR_HPP_
#define ROCPRIM_ITERATOR_DISCARD_ITERATOR_HPP_
#include <iterator>
#include <cstddef>
#include <type_traits>
#include "../config.hpp"
/// \addtogroup iteratormodule
/// @{
BEGIN_ROCPRIM_NAMESPACE
/// \class discard_iterator
/// \brief A random-access iterator which discards values assigned to it upon dereference.
///
/// \par Overview
/// * discard_iterator does not have any underlying array (memory) and does not save values
/// written to it upon dereference.
/// * discard_iterator can be used to safely ignore certain output of algorithms, which
/// saves memory capacity and/or bandwidth.
class discard_iterator
{
public:
struct discard_value
{
ROCPRIM_HOST_DEVICE inline
discard_value() = default;
template<class T>
ROCPRIM_HOST_DEVICE inline
discard_value(T) {};
ROCPRIM_HOST_DEVICE inline
~discard_value() = default;
template<class T>
ROCPRIM_HOST_DEVICE inline
discard_value& operator=(const T&)
{
return *this;
}
};
/// The type of the value that can be obtained by dereferencing the iterator.
using value_type = discard_value;
/// \brief A reference type of the type iterated over (\p value_type).
using reference = discard_value;
/// \brief A pointer type of the type iterated over (\p value_type).
using pointer = discard_value*;
/// A type used for identify distance between iterators.
using difference_type = std::ptrdiff_t;
/// The category of the iterator.
using iterator_category = std::random_access_iterator_tag;
/// \brief Creates a new discard_iterator.
///
/// \param index - optional index of discard iterator (default = 0).
ROCPRIM_HOST_DEVICE inline
discard_iterator(size_t index = 0)
: index_(index)
{
}
ROCPRIM_HOST_DEVICE inline
~discard_iterator() = default;
//! \skip_doxy_start
ROCPRIM_HOST_DEVICE inline
discard_iterator& operator++()
{
index_++;
return *this;
}
ROCPRIM_HOST_DEVICE inline
discard_iterator operator++(int)
{
discard_iterator old = *this;
index_++;
return old;
}
ROCPRIM_HOST_DEVICE inline
discard_iterator& operator--()
{
index_--;
return *this;
}
ROCPRIM_HOST_DEVICE inline
discard_iterator operator--(int)
{
discard_iterator old = *this;
index_--;
return old;
}
ROCPRIM_HOST_DEVICE inline
discard_value operator*() const
{
return discard_value();
}
ROCPRIM_HOST_DEVICE inline
discard_value operator[](difference_type distance) const
{
discard_iterator i = (*this) + distance;
return *i;
}
ROCPRIM_HOST_DEVICE inline
discard_iterator operator+(difference_type distance) const
{
auto i = static_cast<size_t>(static_cast<difference_type>(index_) + distance);
return discard_iterator(i);
}
ROCPRIM_HOST_DEVICE inline
discard_iterator& operator+=(difference_type distance)
{
index_ = static_cast<size_t>(static_cast<difference_type>(index_) + distance);
return *this;
}
ROCPRIM_HOST_DEVICE inline
discard_iterator operator-(difference_type distance) const
{
auto i = static_cast<size_t>(static_cast<difference_type>(index_) - distance);
return discard_iterator(i);
}
ROCPRIM_HOST_DEVICE inline
discard_iterator& operator-=(difference_type distance)
{
index_ = static_cast<size_t>(static_cast<difference_type>(index_) - distance);
return *this;
}
ROCPRIM_HOST_DEVICE inline
difference_type operator-(discard_iterator other) const
{
return index_ - other.index_;
}
ROCPRIM_HOST_DEVICE inline
bool operator==(discard_iterator other) const
{
return index_ == other.index_;
}
ROCPRIM_HOST_DEVICE inline
bool operator!=(discard_iterator other) const
{
return index_ != other.index_;
}
ROCPRIM_HOST_DEVICE inline
bool operator<(discard_iterator other) const
{
return index_ < other.index_;
}
ROCPRIM_HOST_DEVICE inline
bool operator<=(discard_iterator other) const
{
return index_ <= other.index_;
}
ROCPRIM_HOST_DEVICE inline
bool operator>(discard_iterator other) const
{
return index_ > other.index_;
}
ROCPRIM_HOST_DEVICE inline
bool operator>=(discard_iterator other) const
{
return index_ >= other.index_;
}
friend std::ostream& operator<<(std::ostream& os, const discard_iterator& /* iter */)
{
return os;
}
//! \skip_doxy_end
private:
mutable size_t index_;
};
ROCPRIM_HOST_DEVICE inline
discard_iterator
operator+(typename discard_iterator::difference_type distance,
const discard_iterator& iterator)
{
return iterator + distance;
}
/// make_discard_iterator creates a discard_iterator using optional
/// index parameter \p index.
///
/// \param index - optional index of discard iterator (default = 0).
/// \return A new discard_iterator object.
ROCPRIM_HOST_DEVICE inline
discard_iterator
make_discard_iterator(size_t index = 0)
{
return discard_iterator(index);
}
/// @}
// end of group iteratormodule
END_ROCPRIM_NAMESPACE
#endif // ROCPRIM_ITERATOR_DISCARD_ITERATOR_HPP_
// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ROCPRIM_ITERATOR_REVERSE_ITERATOR_HPP_
#define ROCPRIM_ITERATOR_REVERSE_ITERATOR_HPP_
#include <cstddef>
#include <iterator>
#include <type_traits>
#include "../config.hpp"
/// \addtogroup iteratormodule
/// @{
BEGIN_ROCPRIM_NAMESPACE
/// \class reverse_iterator
/// \brief A reverse iterator is an iterator adaptor that reverses the direction of a wrapped iterator.
///
/// \par Overview
/// * reverse_iterator can be used with random access iterators to reverse the direction of the iteration.
/// * The increment operators on the reverse iterator are mapped to decrements on the wrapped iterator,
/// * And the decrement operators on the reverse iterators are mapped to increments on the wrapped iterator.
/// * Use it to iterate over the elements of a container in reverse.
///
/// \tparam SourceIterator - type of the wrapped iterator.
template<class SourceIterator>
class reverse_iterator
{
public:
static_assert(
std::is_base_of<std::random_access_iterator_tag,
typename std::iterator_traits<SourceIterator>::iterator_category>::value,
"SourceIterator must be a random access iterator");
/// The type of the value that can be obtained by dereferencing the iterator.
using value_type = typename std::iterator_traits<SourceIterator>::value_type;
/// \brief A reference type of the type iterated over (\p value_type).
using reference = typename std::iterator_traits<SourceIterator>::reference;
/// \brief A pointer type of the type iterated over (\p value_type).
using pointer = typename std::iterator_traits<SourceIterator>::pointer;
/// A type used for identify distance between iterators.
using difference_type = typename std::iterator_traits<SourceIterator>::difference_type;
/// The category of the iterator.
using iterator_category = std::random_access_iterator_tag;
ROCPRIM_HOST_DEVICE
reverse_iterator(SourceIterator source_iterator) : source_iterator_(source_iterator) {}
//! \skip_doxy_start
ROCPRIM_HOST_DEVICE
reverse_iterator& operator++()
{
--source_iterator_;
return *this;
}
ROCPRIM_HOST_DEVICE
reverse_iterator operator++(int)
{
reverse_iterator old = *this;
--source_iterator_;
return old;
}
ROCPRIM_HOST_DEVICE
reverse_iterator& operator--()
{
++source_iterator_;
return *this;
}
ROCPRIM_HOST_DEVICE
reverse_iterator operator--(int)
{
reverse_iterator old = *this;
++source_iterator_;
return old;
}
ROCPRIM_HOST_DEVICE
reference operator*()
{
return *(source_iterator_ - static_cast<difference_type>(1));
}
ROCPRIM_HOST_DEVICE
reference operator[](difference_type distance)
{
reverse_iterator i = (*this) + distance;
return *i;
}
ROCPRIM_HOST_DEVICE
reverse_iterator operator+(difference_type distance) const
{
return reverse_iterator(source_iterator_ - distance);
}
ROCPRIM_HOST_DEVICE
reverse_iterator& operator+=(difference_type distance)
{
source_iterator_ -= distance;
return *this;
}
ROCPRIM_HOST_DEVICE
reverse_iterator operator-(difference_type distance) const
{
return reverse_iterator(source_iterator_ + distance);
}
ROCPRIM_HOST_DEVICE
reverse_iterator& operator-=(difference_type distance)
{
source_iterator_ += distance;
return *this;
}
ROCPRIM_HOST_DEVICE
difference_type operator-(reverse_iterator other) const
{
return other.source_iterator_ - source_iterator_;
}
ROCPRIM_HOST_DEVICE
bool operator==(reverse_iterator other) const
{
return source_iterator_ == other.source_iterator_;
}
ROCPRIM_HOST_DEVICE
bool operator!=(reverse_iterator other) const
{
return source_iterator_ != other.source_iterator_;
}
ROCPRIM_HOST_DEVICE
bool operator<(reverse_iterator other) const
{
return other.source_iterator_ < source_iterator_;
}
ROCPRIM_HOST_DEVICE
bool operator<=(reverse_iterator other) const
{
return other.source_iterator_ <= source_iterator_;
}
ROCPRIM_HOST_DEVICE
bool operator>(reverse_iterator other) const
{
return other.source_iterator_ > source_iterator_;
}
ROCPRIM_HOST_DEVICE
bool operator>=(reverse_iterator other) const
{
return other.source_iterator_ >= source_iterator_;
}
//! \skip_doxy_end
private:
SourceIterator source_iterator_;
};
template<class SourceIterator>
ROCPRIM_HOST_DEVICE reverse_iterator<SourceIterator>
operator+(typename reverse_iterator<SourceIterator>::difference_type distance,
const reverse_iterator<SourceIterator>& iterator)
{
return iterator + distance;
}
/// make_reverse_iterator creates a \p reverse_iterator wrapping \p source_iterator.
///
/// \tparam SourceIterator - type of \p source_iterator.
///
/// \param source_iterator - the iterator to wrap in the created \p reverse_iterator.
/// \return A \p reverse_iterator that wraps \p source_iterator.
template<class SourceIterator>
ROCPRIM_HOST_DEVICE reverse_iterator<SourceIterator>
make_reverse_iterator(SourceIterator source_iterator)
{
return reverse_iterator<SourceIterator>(source_iterator);
}
/// @}
// end of group iteratormodule
END_ROCPRIM_NAMESPACE
#endif // ROCPRIM_ITERATOR_REVERSE_ITERATOR_HPP_
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ROCPRIM_ITERATOR_TEXTURE_CACHE_ITERATOR_HPP_
#define ROCPRIM_ITERATOR_TEXTURE_CACHE_ITERATOR_HPP_
#include <iterator>
#include <cstddef>
#include <type_traits>
#include <string.h>
#include "../config.hpp"
#include "../detail/various.hpp"
/// \addtogroup iteratormodule
/// @{
BEGIN_ROCPRIM_NAMESPACE
namespace detail
{
// Takes a scalar type T and matches to a texture type based on NumElements.
template <class T, unsigned int NumElements>
struct make_texture_type
{
using type = void;
};
template <>
struct make_texture_type<char, 1>
{
using type = char;
};
template <>
struct make_texture_type<int, 1>
{
using type = int;
};
template <>
struct make_texture_type<short, 1>
{
using type = short;
};
#define DEFINE_MAKE_TEXTURE_TYPE(base, suffix) \
\
template<> \
struct make_texture_type<base, suffix> \
{ \
using type = ::base##suffix; \
};
DEFINE_MAKE_TEXTURE_TYPE(char, 2);
DEFINE_MAKE_TEXTURE_TYPE(char, 4);
DEFINE_MAKE_TEXTURE_TYPE(int, 2);
DEFINE_MAKE_TEXTURE_TYPE(int, 4);
DEFINE_MAKE_TEXTURE_TYPE(short, 2);
DEFINE_MAKE_TEXTURE_TYPE(short, 4);
// Selects an appropriate vector_type based on the input T and size N.
// The byte size is calculated and used to select an appropriate vector_type.
template<class T>
struct match_texture_type
{
static constexpr unsigned int size = sizeof(T);
using texture_base_type =
typename std::conditional<
sizeof(T) >= 4,
int,
typename std::conditional<
sizeof(T) >= 2,
short,
char
>::type
>::type;
using texture_4 = typename make_texture_type<texture_base_type, 4>::type;
using texture_2 = typename make_texture_type<texture_base_type, 2>::type;
using texture_1 = typename make_texture_type<texture_base_type, 1>::type;
using type =
typename std::conditional<
size % sizeof(texture_4) == 0,
texture_4,
typename std::conditional<
size % sizeof(texture_2) == 0,
texture_2,
texture_1
>::type
>::type;
};
}
/// \class texture_cache_iterator
/// \brief A random-access input (read-only) iterator adaptor for dereferencing array values
/// through texture cache.
///
/// \par Overview
/// * A texture_cache_iterator wraps a device pointer of type T, where values are obtained
/// by dereferencing through texture cache.
/// * Can be exchanged and manipulated within and between host and device functions.
/// * Can only be constructed within host functions, and can only be dereferenced within
/// device functions.
/// * Accepts any data type from memory, and loads through texture cache.
///
/// \tparam T - type of value that can be obtained by dereferencing the iterator.
/// \tparam Difference - a type used for identify distance between iterators.
template<
class T,
class Difference = std::ptrdiff_t
>
class texture_cache_iterator
{
public:
/// The type of the value that can be obtained by dereferencing the iterator.
using value_type = typename std::remove_const<T>::type;
/// \brief A reference type of the type iterated over (\p value_type).
using reference = const value_type&;
/// \brief A pointer type of the type iterated over (\p value_type).
using pointer = const value_type*;
/// A type used for identify distance between iterators.
using difference_type = Difference;
/// The category of the iterator.
using iterator_category = std::random_access_iterator_tag;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
using self_type = texture_cache_iterator;
#endif
ROCPRIM_HOST_DEVICE inline
~texture_cache_iterator() = default;
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator()
: ptr(NULL), texture_offset(0), texture_object(0)
{
}
template<class Qualified>
inline
cudaError_t bind_texture(Qualified* ptr,
size_t bytes = size_t(-1),
size_t texture_offset = 0)
{
this->ptr = const_cast<typename std::remove_cv<Qualified>::type*>(ptr);
this->texture_offset = texture_offset;
cudaChannelFormatDesc channel_desc = cudaCreateChannelDesc<texture_type>();
cudaResourceDesc resourse_desc;
cudaTextureDesc texture_desc;
memset(&resourse_desc, 0, sizeof(cudaResourceDesc));
memset(&texture_desc, 0, sizeof(cudaTextureDesc));
resourse_desc.resType = cudaResourceTypeLinear;
resourse_desc.res.linear.devPtr = this->ptr;
resourse_desc.res.linear.desc = channel_desc;
resourse_desc.res.linear.sizeInBytes = bytes;
texture_desc.readMode = cudaReadModeElementType;
return cudaCreateTextureObject(&texture_object, &resourse_desc, &texture_desc, NULL);
}
inline
cudaError_t unbind_texture()
{
return cudaDestroyTextureObject(texture_object);
}
//! \skip_doxy_start
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator& operator++()
{
ptr++;
texture_offset++;
return *this;
}
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator operator++(int)
{
texture_cache_iterator old_tc = *this;
ptr++;
texture_offset++;
return old_tc;
}
ROCPRIM_HOST_DEVICE inline
value_type operator*() const
{
#ifndef __CUDA_ARCH__
return ptr[texture_offset];
#else
texture_type words[multiple];
ROCPRIM_UNROLL
for(unsigned int i = 0; i < multiple; i++)
{
tex1Dfetch(
&words[i],
texture_object,
(texture_offset * multiple) + i
);
}
return *reinterpret_cast<value_type*>(words);
#endif
}
ROCPRIM_HOST_DEVICE inline
pointer operator->() const
{
return &(*(*this));
}
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator operator+(difference_type distance) const
{
self_type retval;
retval.ptr = ptr + distance;
retval.texture_object = texture_object;
retval.texture_offset = texture_offset + distance;
return retval;
}
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator& operator+=(difference_type distance)
{
ptr += distance;
texture_offset += distance;
return *this;
}
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator operator-(difference_type distance) const
{
self_type retval;
retval.ptr = ptr - distance;
retval.texture_object = texture_object;
retval.texture_offset = texture_offset - distance;
return retval;
}
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator& operator-=(difference_type distance)
{
ptr -= distance;
texture_offset -= distance;
return *this;
}
ROCPRIM_HOST_DEVICE inline
difference_type operator-(texture_cache_iterator other) const
{
return ptr - other.ptr;
}
ROCPRIM_HOST_DEVICE inline
value_type operator[](difference_type distance) const
{
texture_cache_iterator i = (*this) + distance;
return *i;
}
ROCPRIM_HOST_DEVICE inline
bool operator==(texture_cache_iterator other) const
{
return (ptr == other.ptr) && (texture_offset == other.texture_offset);
}
ROCPRIM_HOST_DEVICE inline
bool operator!=(texture_cache_iterator other) const
{
return (ptr != other.ptr) || (texture_offset != other.texture_offset);
}
ROCPRIM_HOST_DEVICE inline
bool operator<(texture_cache_iterator other) const
{
return (ptr - other.ptr) > 0;
}
ROCPRIM_HOST_DEVICE inline
bool operator<=(texture_cache_iterator other) const
{
return (ptr - other.ptr) >= 0;
}
ROCPRIM_HOST_DEVICE inline
bool operator>(texture_cache_iterator other) const
{
return (ptr - other.ptr) < 0;
}
ROCPRIM_HOST_DEVICE inline
bool operator>=(texture_cache_iterator other) const
{
return (ptr - other.ptr) <= 0;
}
friend std::ostream& operator<<(std::ostream& os, const texture_cache_iterator& /* iter */)
{
return os;
}
//! \skip_doxy_end
private:
using texture_type = typename ::rocprim::detail::match_texture_type<T>::type;
static constexpr unsigned int multiple = sizeof(T) / sizeof(texture_type);
value_type* ptr;
difference_type texture_offset;
cudaTextureObject_t texture_object;
};
template<
class T,
class Difference
>
ROCPRIM_HOST_DEVICE inline
texture_cache_iterator<T, Difference>
operator+(typename texture_cache_iterator<T, Difference>::difference_type distance,
const texture_cache_iterator<T, Difference>& iterator)
{
return iterator + distance;
}
/// @}
// end of group iteratormodule
END_ROCPRIM_NAMESPACE
#endif // ROCPRIM_ITERATOR_TEXTURE_CACHE_ITERATOR_HPP_
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ROCPRIM_ITERATOR_TRANSFORM_ITERATOR_HPP_
#define ROCPRIM_ITERATOR_TRANSFORM_ITERATOR_HPP_
#include <iterator>
#include <cstddef>
#include <type_traits>
#include "../config.hpp"
#include "../detail/match_result_type.hpp"
/// \addtogroup iteratormodule
/// @{
BEGIN_ROCPRIM_NAMESPACE
/// \class transform_iterator
/// \brief A random-access input (read-only) iterator adaptor for transforming dereferenced values.
///
/// \par Overview
/// * A transform_iterator uses functor of type UnaryFunction to transform value obtained
/// by dereferencing underlying iterator.
/// * Using it for simulating a range filled with results of applying functor of type
/// \p UnaryFunction to another range saves memory capacity and/or bandwidth.
///
/// \tparam InputIterator - type of the underlying random-access input iterator. Must be
/// a random-access iterator.
/// \tparam UnaryFunction - type of the transform functor.
/// \tparam ValueType - type of value that can be obtained by dereferencing the iterator.
/// By default it is the return type of \p UnaryFunction.
template<
class InputIterator,
class UnaryFunction,
class ValueType =
typename ::rocprim::detail::invoke_result<
UnaryFunction, typename std::iterator_traits<InputIterator>::value_type
>::type
>
class transform_iterator
{
public:
/// The type of the value that can be obtained by dereferencing the iterator.
using value_type = ValueType;
/// \brief A reference type of the type iterated over (\p value_type).
/// It's `const` since transform_iterator is a read-only iterator.
using reference = const value_type&;
/// \brief A pointer type of the type iterated over (\p value_type).
/// It's `const` since transform_iterator is a read-only iterator.
using pointer = const value_type*;
/// A type used for identify distance between iterators.
using difference_type = typename std::iterator_traits<InputIterator>::difference_type;
/// The category of the iterator.
using iterator_category = std::random_access_iterator_tag;
/// The type of unary function used to transform input range.
using unary_function = UnaryFunction;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
using self_type = transform_iterator;
#endif
ROCPRIM_HOST_DEVICE inline
~transform_iterator() = default;
/// \brief Creates a new transform_iterator.
///
/// \param iterator input iterator to iterate over and transform.
/// \param transform unary function used to transform values obtained
/// from range pointed by \p iterator.
ROCPRIM_HOST_DEVICE inline
transform_iterator(InputIterator iterator, UnaryFunction transform)
: iterator_(iterator), transform_(transform)
{
}
//! \skip_doxy_start
ROCPRIM_HOST_DEVICE inline
transform_iterator& operator++()
{
iterator_++;
return *this;
}
ROCPRIM_HOST_DEVICE inline
transform_iterator operator++(int)
{
transform_iterator old = *this;
iterator_++;
return old;
}
ROCPRIM_HOST_DEVICE inline
transform_iterator& operator--()
{
iterator_--;
return *this;
}
ROCPRIM_HOST_DEVICE inline
transform_iterator operator--(int)
{
transform_iterator old = *this;
iterator_--;
return old;
}
ROCPRIM_HOST_DEVICE inline
value_type operator*() const
{
return transform_(*iterator_);
}
ROCPRIM_HOST_DEVICE inline
pointer operator->() const
{
return &(*(*this));
}
ROCPRIM_HOST_DEVICE inline
value_type operator[](difference_type distance) const
{
transform_iterator i = (*this) + distance;
return *i;
}
ROCPRIM_HOST_DEVICE inline
transform_iterator operator+(difference_type distance) const
{
return transform_iterator(iterator_ + distance, transform_);
}
ROCPRIM_HOST_DEVICE inline
transform_iterator& operator+=(difference_type distance)
{
iterator_ += distance;
return *this;
}
ROCPRIM_HOST_DEVICE inline
transform_iterator operator-(difference_type distance) const
{
return transform_iterator(iterator_ - distance, transform_);
}
ROCPRIM_HOST_DEVICE inline
transform_iterator& operator-=(difference_type distance)
{
iterator_ -= distance;
return *this;
}
ROCPRIM_HOST_DEVICE inline
difference_type operator-(transform_iterator other) const
{
return iterator_ - other.iterator_;
}
ROCPRIM_HOST_DEVICE inline
bool operator==(transform_iterator other) const
{
return iterator_ == other.iterator_;
}
ROCPRIM_HOST_DEVICE inline
bool operator!=(transform_iterator other) const
{
return iterator_ != other.iterator_;
}
ROCPRIM_HOST_DEVICE inline
bool operator<(transform_iterator other) const
{
return iterator_ < other.iterator_;
}
ROCPRIM_HOST_DEVICE inline
bool operator<=(transform_iterator other) const
{
return iterator_ <= other.iterator_;
}
ROCPRIM_HOST_DEVICE inline
bool operator>(transform_iterator other) const
{
return iterator_ > other.iterator_;
}
ROCPRIM_HOST_DEVICE inline
bool operator>=(transform_iterator other) const
{
return iterator_ >= other.iterator_;
}
friend std::ostream& operator<<(std::ostream& os, const transform_iterator& /* iter */)
{
return os;
}
//! \skip_doxy_end
private:
InputIterator iterator_;
UnaryFunction transform_;
};
template<
class InputIterator,
class UnaryFunction,
class ValueType
>
ROCPRIM_HOST_DEVICE inline
transform_iterator<InputIterator, UnaryFunction, ValueType>
operator+(typename transform_iterator<InputIterator, UnaryFunction, ValueType>::difference_type distance,
const transform_iterator<InputIterator, UnaryFunction, ValueType>& iterator)
{
return iterator + distance;
}
/// make_transform_iterator creates a transform_iterator using \p iterator as
/// the underlying iterator and \p transform as the unary function.
///
/// \tparam InputIterator - type of the underlying random-access input iterator.
/// \tparam UnaryFunction - type of the transform functor.
///
/// \param iterator - input iterator.
/// \param transform - transform functor to use in created transform_iterator.
/// \return A new transform_iterator object which transforms the range pointed
/// by \p iterator using \p transform functor.
template<
class InputIterator,
class UnaryFunction
>
ROCPRIM_HOST_DEVICE inline
transform_iterator<InputIterator, UnaryFunction>
make_transform_iterator(InputIterator iterator, UnaryFunction transform)
{
return transform_iterator<InputIterator, UnaryFunction>(iterator, transform);
}
/// @}
// end of group iteratormodule
END_ROCPRIM_NAMESPACE
#endif // ROCPRIM_ITERATOR_TRANSFORM_ITERATOR_HPP_
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ROCPRIM_ITERATOR_ZIP_ITERATOR_HPP_
#define ROCPRIM_ITERATOR_ZIP_ITERATOR_HPP_
#include <iterator>
#include <cstddef>
#include <type_traits>
#include "../config.hpp"
#include "../types/tuple.hpp"
/// \addtogroup iteratormodule
/// @{
BEGIN_ROCPRIM_NAMESPACE
namespace detail
{
template<class T>
struct tuple_of_references;
template<class... Types>
struct tuple_of_references<::rocprim::tuple<Types...>>
{
using type = ::rocprim::tuple<typename std::iterator_traits<Types>::reference...>;
};
template<class T>
struct tuple_of_values;
template<class... Types>
struct tuple_of_values<::rocprim::tuple<Types...>>
{
using type = ::rocprim::tuple<typename std::iterator_traits<Types>::value_type...>;
};
template<class... Types, class Function, size_t... Indices>
ROCPRIM_HOST_DEVICE inline
void for_each_in_tuple_impl(::rocprim::tuple<Types...>& t,
Function f,
::rocprim::index_sequence<Indices...>)
{
auto swallow = { (f(::rocprim::get<Indices>(t)), 0)... };
(void) swallow;
}
template<class... Types, class Function>
ROCPRIM_HOST_DEVICE inline
void for_each_in_tuple(::rocprim::tuple<Types...>& t, Function f)
{
for_each_in_tuple_impl(t, f, ::rocprim::index_sequence_for<Types...>());
}
struct increment_iterator
{
template<class Iterator>
ROCPRIM_HOST_DEVICE inline
void operator()(Iterator& it)
{
++it;
}
};
struct decrement_iterator
{
template<class Iterator>
ROCPRIM_HOST_DEVICE inline
void operator()(Iterator& it)
{
--it;
}
};
template<class Difference>
struct advance_iterator
{
ROCPRIM_HOST_DEVICE inline
advance_iterator(Difference distance)
: distance_(distance)
{
}
template<class Iterator>
ROCPRIM_HOST_DEVICE inline
void operator()(Iterator& it)
{
using it_distance_type = typename std::iterator_traits<Iterator>::difference_type;
it += static_cast<it_distance_type>(distance_);
}
private:
Difference distance_;
};
template<class ReferenceTuple, class... Types, size_t... Indices>
ROCPRIM_HOST_DEVICE inline
ReferenceTuple dereference_iterator_tuple_impl(const ::rocprim::tuple<Types...>& t,
::rocprim::index_sequence<Indices...>)
{
ReferenceTuple rt { *::rocprim::get<Indices>(t)... };
return rt;
}
template<class ReferenceTuple, class... Types>
ROCPRIM_HOST_DEVICE inline
ReferenceTuple dereference_iterator_tuple(const ::rocprim::tuple<Types...>& t)
{
return dereference_iterator_tuple_impl<ReferenceTuple>(
t, ::rocprim::index_sequence_for<Types...>()
);
}
} // end detail namespace
/// \class zip_iterator
/// \brief TBD
///
/// \par Overview
/// * TBD
///
/// \tparam IteratorTuple -
template<class IteratorTuple>
class zip_iterator
{
public:
/// \brief A reference type of the type iterated over.
///
/// The type of the tuple made of the reference types of the iterator
/// types in the IteratorTuple argument.
using reference = typename detail::tuple_of_references<IteratorTuple>::type;
/// The type of the value that can be obtained by dereferencing the iterator.
using value_type = typename detail::tuple_of_values<IteratorTuple>::type;
/// \brief A pointer type of the type iterated over (\p value_type).
using pointer = value_type*;
/// \brief A type used for identify distance between iterators.
///
/// The difference_type member of zip_iterator is the difference_type of
/// the first of the iterator types in the IteratorTuple argument.
using difference_type = typename std::iterator_traits<
typename ::rocprim::tuple_element<0, IteratorTuple>::type
>::difference_type;
/// The category of the iterator.
using iterator_category = std::random_access_iterator_tag;
ROCPRIM_HOST_DEVICE inline
~zip_iterator() = default;
/// \brief Creates a new zip_iterator.
///
/// \param iterator_tuple tuple of iterators
ROCPRIM_HOST_DEVICE inline
zip_iterator(IteratorTuple iterator_tuple)
: iterator_tuple_(iterator_tuple)
{
}
//! \skip_doxy_start
ROCPRIM_HOST_DEVICE inline
zip_iterator& operator++()
{
detail::for_each_in_tuple(iterator_tuple_, detail::increment_iterator());
return *this;
}
ROCPRIM_HOST_DEVICE inline
zip_iterator operator++(int)
{
zip_iterator old = *this;
++(*this);
return old;
}
ROCPRIM_HOST_DEVICE inline
zip_iterator& operator--()
{
detail::for_each_in_tuple(iterator_tuple_, detail::decrement_iterator());
return *this;
}
ROCPRIM_HOST_DEVICE inline
zip_iterator operator--(int)
{
zip_iterator old = *this;
--(*this);
return old;
}
ROCPRIM_HOST_DEVICE inline
reference operator*() const
{
return detail::dereference_iterator_tuple<reference>(iterator_tuple_);
}
ROCPRIM_HOST_DEVICE inline
pointer operator->() const
{
return &(*(*this));
}
ROCPRIM_HOST_DEVICE inline
reference operator[](difference_type distance) const
{
zip_iterator i = (*this) + distance;
return *i;
}
ROCPRIM_HOST_DEVICE inline
zip_iterator operator+(difference_type distance) const
{
zip_iterator copy = *this;
copy += distance;
return copy;
}
ROCPRIM_HOST_DEVICE inline
zip_iterator& operator+=(difference_type distance)
{
detail::for_each_in_tuple(
iterator_tuple_,
detail::advance_iterator<difference_type>(distance)
);
return *this;
}
ROCPRIM_HOST_DEVICE inline
zip_iterator operator-(difference_type distance) const
{
auto copy = *this;
copy -= distance;
return copy;
}
ROCPRIM_HOST_DEVICE inline
zip_iterator& operator-=(difference_type distance)
{
*this += -distance;
return *this;
}
ROCPRIM_HOST_DEVICE inline
difference_type operator-(zip_iterator other) const
{
return ::rocprim::get<0>(iterator_tuple_) - ::rocprim::get<0>(other.iterator_tuple_);
}
ROCPRIM_HOST_DEVICE inline
bool operator==(zip_iterator other) const
{
return iterator_tuple_ == other.iterator_tuple_;
}
ROCPRIM_HOST_DEVICE inline
bool operator!=(zip_iterator other) const
{
return !(*this == other);
}
ROCPRIM_HOST_DEVICE inline
bool operator<(zip_iterator other) const
{
return ::rocprim::get<0>(iterator_tuple_) < ::rocprim::get<0>(other.iterator_tuple_);
}
ROCPRIM_HOST_DEVICE inline
bool operator<=(zip_iterator other) const
{
return !(other < *this);
}
ROCPRIM_HOST_DEVICE inline
bool operator>(zip_iterator other) const
{
return other < *this;
}
ROCPRIM_HOST_DEVICE inline
bool operator>=(zip_iterator other) const
{
return !(*this < other);
}
friend std::ostream& operator<<(std::ostream& os, const zip_iterator& /* iter */)
{
return os;
}
//! \skip_doxy_end
private:
IteratorTuple iterator_tuple_;
};
template<class IteratorTuple>
ROCPRIM_HOST_DEVICE inline
zip_iterator<IteratorTuple>
operator+(typename zip_iterator<IteratorTuple>::difference_type distance,
const zip_iterator<IteratorTuple>& iterator)
{
return iterator + distance;
}
/// make_zip_iterator creates a zip_iterator using \p iterator_tuple as
/// the underlying tuple of iterator.
///
/// \tparam IteratorTuple - iterator tuple type
///
/// \param iterator_tuple - tuple of iterators to use
/// \return A new zip_iterator object
template<class IteratorTuple>
ROCPRIM_HOST_DEVICE inline
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple iterator_tuple)
{
return zip_iterator<IteratorTuple>(iterator_tuple);
}
/// @}
// end of group iteratormodule
END_ROCPRIM_NAMESPACE
#endif // ROCPRIM_ITERATOR_ZIP_ITERATOR_HPP_
// Copyright (c) 2017-2022 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ROCPRIM_HPP_
#define ROCPRIM_HPP_
/// \file
///
/// Meta-header to include rocPRIM API.
// Meta configuration for rocPRIM
#include "config.hpp"
#include "rocprim_version.hpp"
#include "intrinsics.hpp"
#include "functional.hpp"
#include "types.hpp"
#include "type_traits.hpp"
#include "iterator.hpp"
#include "warp/warp_reduce.hpp"
#include "warp/warp_scan.hpp"
#include "warp/warp_sort.hpp"
#include "block/block_discontinuity.hpp"
#include "block/block_exchange.hpp"
#include "block/block_histogram.hpp"
#include "block/block_load.hpp"
#include "block/block_radix_sort.hpp"
#include "block/block_scan.hpp"
#include "block/block_sort.hpp"
#include "block/block_store.hpp"
#include "device/device_adjacent_difference.hpp"
#include "device/device_binary_search.hpp"
#include "device/device_histogram.hpp"
#include "device/device_merge.hpp"
#include "device/device_merge_sort.hpp"
#include "device/device_partition.hpp"
#include "device/device_radix_sort.hpp"
#include "device/device_reduce_by_key.hpp"
#include "device/device_reduce.hpp"
#include "device/device_run_length_encode.hpp"
#include "device/device_scan_by_key.hpp"
#include "device/device_scan.hpp"
#include "device/device_segmented_radix_sort.hpp"
#include "device/device_segmented_reduce.hpp"
#include "device/device_segmented_scan.hpp"
#include "device/device_select.hpp"
#include "device/device_transform.hpp"
BEGIN_ROCPRIM_NAMESPACE
/// \brief Returns version of rocPRIM library.
/// \return version of rocPRIM library
ROCPRIM_HOST_DEVICE inline
unsigned int version()
{
return ROCPRIM_VERSION;
}
END_ROCPRIM_NAMESPACE
#endif // ROCPRIM_HPP_
// Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ROCPRIM_VERSION_HPP_
#define ROCPRIM_VERSION_HPP_
/// \def ROCPRIM_VERSION
/// \brief ROCPRIM library version
///
/// Version number may not be visible in the documentation.
///
/// ROCPRIM_VERSION % 100 is the patch level,
/// ROCPRIM_VERSION / 100 % 1000 is the minor version,
/// ROCPRIM_VERSION / 100000 is the major version.
///
/// For example, if ROCPRIM_VERSION is 100500, then the major version is 1,
/// the minor version is 5, and the patch level is 0.
#define ROCPRIM_VERSION 2 * 100000 + 11 * 100 + 1
#define ROCPRIM_VERSION_MAJOR 2
#define ROCPRIM_VERSION_MINOR 11
#define ROCPRIM_VERSION_PATCH 1
#endif // ROCPRIM_VERSION_HPP_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment