Medial Code Documentation
|
span class implementation, based on ISO++20 span<T>. The interface should be the same. More...
#include <span.h>
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 | |
XGBOOST_DEVICE | Span (pointer _ptr, index_type _count) |
XGBOOST_DEVICE | Span (pointer _first, pointer _last) |
template<std::size_t N> | |
XGBOOST_DEVICE constexpr | 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>> | |
XGBOOST_DEVICE constexpr | Span (const Span< U, OtherExtent > &_other) __span_noexcept |
XGBOOST_DEVICE constexpr | Span (const Span &_other) __span_noexcept |
XGBOOST_DEVICE Span & | operator= (const Span &_other) __span_noexcept |
XGBOOST_DEVICE constexpr iterator | begin () const __span_noexcept |
XGBOOST_DEVICE constexpr iterator | end () const __span_noexcept |
XGBOOST_DEVICE constexpr const_iterator | cbegin () const __span_noexcept |
XGBOOST_DEVICE constexpr const_iterator | cend () const __span_noexcept |
constexpr reverse_iterator | rbegin () const __span_noexcept |
constexpr reverse_iterator | rend () const __span_noexcept |
XGBOOST_DEVICE constexpr const_reverse_iterator | crbegin () const __span_noexcept |
XGBOOST_DEVICE constexpr 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 |
XGBOOST_DEVICE constexpr pointer | data () const __span_noexcept |
XGBOOST_DEVICE constexpr index_type | size () const __span_noexcept |
XGBOOST_DEVICE constexpr index_type | size_bytes () const __span_noexcept |
XGBOOST_DEVICE constexpr bool | empty () const __span_noexcept |
template<std::size_t Count> | |
XGBOOST_DEVICE Span< element_type, Count > | first () const |
XGBOOST_DEVICE Span< element_type, dynamic_extent > | first (std::size_t _count) const |
template<std::size_t Count> | |
XGBOOST_DEVICE Span< element_type, Count > | last () const |
XGBOOST_DEVICE Span< element_type, dynamic_extent > | last (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_extent > | subspan (index_type _offset, index_type _count=dynamic_extent) const |
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:
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.
|
inline |
If Count is std::dynamic_extent, r.size() == this->size() - Offset; Otherwise r.size() == Count.