span class implementation, based on ISO++20 span<T>. The interface should be the same.
More...
|
constexpr | Span ()=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 > |
| Span (Container &_cont) |
|
template<class Container > |
| Span (const Container &_cont) |
|
template<class U , std::size_t OtherExtent, class = typename std::enable_if_t< detail::IsAllowedElementTypeConversion<U, T>::value && detail::IsAllowedExtentConversion<OtherExtent, Extent>::value>> |
constexpr XGBOOST_DEVICE | Span (const Span< U, OtherExtent > &_other) __span_noexcept |
|
constexpr | Span (Span const &_other) noexcept(true)=default |
|
constexpr Span & | operator= (Span const &_other) noexcept(true)=default |
|
constexpr | Span (Span &&_other) noexcept(true)=default |
|
constexpr Span & | operator= (Span &&_other) noexcept(true)=default |
|
| ~Span () noexcept(true)=default |
|
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_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 |
|
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++;
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.