xgboost
Public Types | Public Member Functions | List of all members
xgboost::common::Span< T, Extent > Class Template Reference

span class implementation, based on ISO++20 span<T>. The interface should be the same. More...

#include <span.h>

Collaboration diagram for xgboost::common::Span< T, Extent >:
Collaboration graph

Public Types

using element_type = T
 
using value_type = typename std::remove_cv< T >::type
 
using index_type = std::size_t
 
using difference_type = detail::ptrdiff_t
 
using pointer = T *
 
using reference = T &
 
using iterator = detail::SpanIterator< Span< T, Extent >, false >
 
using const_iterator = const detail::SpanIterator< Span< T, Extent >, true >
 
using reverse_iterator = std::reverse_iterator< iterator >
 
using const_reverse_iterator = const std::reverse_iterator< const_iterator >
 

Public Member Functions

constexpr Span () __span_noexcept=default
 
XGBOOST_DEVICE Span (pointer _ptr, index_type _count)
 
XGBOOST_DEVICE Span (pointer _first, pointer _last)
 
template<std::size_t N>
constexpr XGBOOST_DEVICE Span (element_type(&arr)[N]) __span_noexcept
 
template<class Container , class = typename std::enable_if< !std::is_const<element_type>::value && !detail::IsSpan<Container>::value && std::is_convertible<typename Container::pointer, pointer>::value && std::is_convertible<typename Container::pointer, decltype(std::declval<Container>().data())>::value, ::type >
 Span (Container &_cont)
 
template<class Container , class = typename std::enable_if< std::is_const<element_type>::value && !detail::IsSpan<Container>::value && std::is_convertible<typename Container::pointer, pointer>::value && std::is_convertible<typename Container::pointer, decltype(std::declval<Container>().data())>::value, ::type >
 Span (const Container &_cont)
 
template<class U , std::size_t OtherExtent, class = typename std::enable_if< detail::IsAllowedElementTypeConversion<U, T>::value && detail::IsAllowedExtentConversion<OtherExtent, Extent>::value>>
constexpr XGBOOST_DEVICE Span (const Span< U, OtherExtent > &_other) __span_noexcept
 
constexpr XGBOOST_DEVICE Span (const Span &_other) __span_noexcept
 
XGBOOST_DEVICE Spanoperator= (const Span &_other) __span_noexcept
 
XGBOOST_DEVICE ~Span () __span_noexcept
 
constexpr XGBOOST_DEVICE iterator begin () const __span_noexcept
 
constexpr XGBOOST_DEVICE iterator end () const __span_noexcept
 
constexpr XGBOOST_DEVICE const_iterator cbegin () const __span_noexcept
 
constexpr XGBOOST_DEVICE const_iterator cend () const __span_noexcept
 
constexpr reverse_iterator rbegin () const __span_noexcept
 
constexpr reverse_iterator rend () const __span_noexcept
 
constexpr XGBOOST_DEVICE const_reverse_iterator crbegin () const __span_noexcept
 
constexpr XGBOOST_DEVICE const_reverse_iterator crend () const __span_noexcept
 
XGBOOST_DEVICE reference front () const
 
XGBOOST_DEVICE reference back () const
 
XGBOOST_DEVICE reference operator[] (index_type _idx) const
 
XGBOOST_DEVICE reference operator() (index_type _idx) const
 
constexpr XGBOOST_DEVICE pointer data () const __span_noexcept
 
constexpr XGBOOST_DEVICE index_type size () const __span_noexcept
 
constexpr XGBOOST_DEVICE index_type size_bytes () const __span_noexcept
 
constexpr XGBOOST_DEVICE bool empty () const __span_noexcept
 
template<std::size_t Count>
XGBOOST_DEVICE Span< element_type, Count > first () const
 
XGBOOST_DEVICE Span< element_type, dynamic_extentfirst (std::size_t _count) const
 
template<std::size_t Count>
XGBOOST_DEVICE Span< element_type, Count > last () const
 
XGBOOST_DEVICE Span< element_type, dynamic_extentlast (std::size_t _count) const
 
template<std::size_t Offset, std::size_t Count = dynamic_extent>
XGBOOST_DEVICE auto subspan () const -> Span< element_type, detail::ExtentValue< Extent, Offset, Count >::value >
 
XGBOOST_DEVICE Span< element_type, dynamic_extentsubspan (index_type _offset, index_type _count=dynamic_extent) const
 

Detailed Description

template<typename T, std::size_t Extent = dynamic_extent>
class xgboost::common::Span< T, Extent >

span class implementation, based on ISO++20 span<T>. The interface should be the same.

What's different from span<T> in Guidelines Support Library (GSL)

Interface might be slightly different, we stick with ISO.

GSL uses C++14/17 features, which are not available here. GSL uses constexpr extensively, which is not possible with limitation of C++11. GSL doesn't concern about CUDA.

GSL is more thoroughly implemented and tested. GSL is more optimized, especially for static extent.

GSL uses __buildin_unreachable() when error, Span<T> uses dmlc LOG and customized CUDA logging.

What's different from span<T> in ISO++20 (ISO)

ISO uses functions/structs from std library, which might be not available in CUDA. Initializing from std::array is not supported.

ISO uses constexpr extensively, which is not possible with limitation of C++11. ISO uses C++14/17 features, which is not available here. ISO doesn't concern about CUDA.

ISO uses std::terminate(), Span<T> uses dmlc LOG and customized CUDA logging.

Limitations: With thrust: It's not adviced to initialize Span with host_vector directly, since host_vector::data() is a host function. It's not possible to initialize Span with device_vector directly, since device_vector::data() returns a wrapped pointer. It's unclear that what kind of thrust algorithm can be used without memory error. See the test case "GPUSpan.WithTrust"

Pass iterator to kernel: Not possible. Use subspan instead.

The underlying Span in SpanIterator is a pointer, but CUDA pass kernel parameter by value. If we were to hold a Span value instead of a pointer, the following snippet will crash, violating the safety purpose of Span:

Span<float> span {arr_a};
auto beg = span.begin();
Span<float> span_b = arr_b;
span = span_b;
delete arr_a;
beg++; // crash

While holding a pointer or reference should avoid the problem, it's a compromise. Since we have subspan, it's acceptable not to support passing iterator.

Member Typedef Documentation

◆ const_iterator

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::const_iterator = const detail::SpanIterator<Span<T, Extent>, true>

◆ const_reverse_iterator

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::const_reverse_iterator = const std::reverse_iterator<const_iterator>

◆ difference_type

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::difference_type = detail::ptrdiff_t

◆ element_type

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::element_type = T

◆ index_type

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::index_type = std::size_t

◆ iterator

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::iterator = detail::SpanIterator<Span<T, Extent>, false>

◆ pointer

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::pointer = T*

◆ reference

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::reference = T&

◆ reverse_iterator

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::reverse_iterator = std::reverse_iterator<iterator>

◆ value_type

template<typename T , std::size_t Extent = dynamic_extent>
using xgboost::common::Span< T, Extent >::value_type = typename std::remove_cv<T>::type

Constructor & Destructor Documentation

◆ Span() [1/8]

template<typename T , std::size_t Extent = dynamic_extent>
constexpr xgboost::common::Span< T, Extent >::Span ( )
constexprdefault

◆ Span() [2/8]

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE xgboost::common::Span< T, Extent >::Span ( pointer  _ptr,
index_type  _count 
)
inline

◆ Span() [3/8]

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE xgboost::common::Span< T, Extent >::Span ( pointer  _first,
pointer  _last 
)
inline

◆ Span() [4/8]

template<typename T , std::size_t Extent = dynamic_extent>
template<std::size_t N>
constexpr XGBOOST_DEVICE xgboost::common::Span< T, Extent >::Span ( element_type(&)  arr[N])
inlineconstexpr

◆ Span() [5/8]

template<typename T , std::size_t Extent = dynamic_extent>
template<class Container , class = typename std::enable_if< !std::is_const<element_type>::value && !detail::IsSpan<Container>::value && std::is_convertible<typename Container::pointer, pointer>::value && std::is_convertible<typename Container::pointer, decltype(std::declval<Container>().data())>::value, ::type >
xgboost::common::Span< T, Extent >::Span ( Container &  _cont)
inline

◆ Span() [6/8]

template<typename T , std::size_t Extent = dynamic_extent>
template<class Container , class = typename std::enable_if< std::is_const<element_type>::value && !detail::IsSpan<Container>::value && std::is_convertible<typename Container::pointer, pointer>::value && std::is_convertible<typename Container::pointer, decltype(std::declval<Container>().data())>::value, ::type >
xgboost::common::Span< T, Extent >::Span ( const Container &  _cont)
inline

◆ Span() [7/8]

template<typename T , std::size_t Extent = dynamic_extent>
template<class U , std::size_t OtherExtent, class = typename std::enable_if< detail::IsAllowedElementTypeConversion<U, T>::value && detail::IsAllowedExtentConversion<OtherExtent, Extent>::value>>
constexpr XGBOOST_DEVICE xgboost::common::Span< T, Extent >::Span ( const Span< U, OtherExtent > &  _other)
inlineconstexpr

◆ Span() [8/8]

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE xgboost::common::Span< T, Extent >::Span ( const Span< T, Extent > &  _other)
inlineconstexpr

◆ ~Span()

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE xgboost::common::Span< T, Extent >::~Span ( )
inline

Member Function Documentation

◆ back()

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE reference xgboost::common::Span< T, Extent >::back ( ) const
inline

◆ begin()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE iterator xgboost::common::Span< T, Extent >::begin ( ) const
inlineconstexpr

◆ cbegin()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE const_iterator xgboost::common::Span< T, Extent >::cbegin ( ) const
inlineconstexpr

◆ cend()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE const_iterator xgboost::common::Span< T, Extent >::cend ( ) const
inlineconstexpr

◆ crbegin()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE const_reverse_iterator xgboost::common::Span< T, Extent >::crbegin ( ) const
inlineconstexpr

◆ crend()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE const_reverse_iterator xgboost::common::Span< T, Extent >::crend ( ) const
inlineconstexpr

◆ data()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE pointer xgboost::common::Span< T, Extent >::data ( ) const
inlineconstexpr

◆ empty()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE bool xgboost::common::Span< T, Extent >::empty ( ) const
inlineconstexpr

◆ end()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE iterator xgboost::common::Span< T, Extent >::end ( ) const
inlineconstexpr

◆ first() [1/2]

template<typename T , std::size_t Extent = dynamic_extent>
template<std::size_t Count>
XGBOOST_DEVICE Span<element_type, Count> xgboost::common::Span< T, Extent >::first ( ) const
inline

◆ first() [2/2]

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE Span<element_type, dynamic_extent> xgboost::common::Span< T, Extent >::first ( std::size_t  _count) const
inline

◆ front()

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE reference xgboost::common::Span< T, Extent >::front ( ) const
inline

◆ last() [1/2]

template<typename T , std::size_t Extent = dynamic_extent>
template<std::size_t Count>
XGBOOST_DEVICE Span<element_type, Count> xgboost::common::Span< T, Extent >::last ( ) const
inline

◆ last() [2/2]

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE Span<element_type, dynamic_extent> xgboost::common::Span< T, Extent >::last ( std::size_t  _count) const
inline

◆ operator()()

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE reference xgboost::common::Span< T, Extent >::operator() ( index_type  _idx) const
inline

◆ operator=()

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE Span& xgboost::common::Span< T, Extent >::operator= ( const Span< T, Extent > &  _other)
inline

◆ operator[]()

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE reference xgboost::common::Span< T, Extent >::operator[] ( index_type  _idx) const
inline

◆ rbegin()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr reverse_iterator xgboost::common::Span< T, Extent >::rbegin ( ) const
inlineconstexpr

◆ rend()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr reverse_iterator xgboost::common::Span< T, Extent >::rend ( ) const
inlineconstexpr

◆ size()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE index_type xgboost::common::Span< T, Extent >::size ( ) const
inlineconstexpr

◆ size_bytes()

template<typename T , std::size_t Extent = dynamic_extent>
constexpr XGBOOST_DEVICE index_type xgboost::common::Span< T, Extent >::size_bytes ( ) const
inlineconstexpr

◆ subspan() [1/2]

template<typename T , std::size_t Extent = dynamic_extent>
template<std::size_t Offset, std::size_t Count = dynamic_extent>
XGBOOST_DEVICE auto xgboost::common::Span< T, Extent >::subspan ( ) const -> Span<element_type, detail::ExtentValue<Extent, Offset, Count>::value>
inline

If Count is std::dynamic_extent, r.size() == this->size() - Offset; Otherwise r.size() == Count.

◆ subspan() [2/2]

template<typename T , std::size_t Extent = dynamic_extent>
XGBOOST_DEVICE Span<element_type, dynamic_extent> xgboost::common::Span< T, Extent >::subspan ( index_type  _offset,
index_type  _count = dynamic_extent 
) const
inline

The documentation for this class was generated from the following file: