From 78b61e9ba1df0608d3ef78fc4e8ce80902de4760 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Fri, 16 Apr 2021 19:12:35 -0700 Subject: [PATCH 01/14] [SYCL] add span support SYCL2020 spec adds span to the sycl namespace, even when not compiling C++20. I have adapted the Clang libcxx version of span here, divorcing it from its macros and private access to implementation details, but otherwise mostly intact. Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/stl.hpp | 1 + sycl/include/CL/sycl/sycl_span.hpp | 619 ++++++++++++++++++ .../test/basic_tests/image_accessor_types.cpp | 2 +- sycl/test/gdb/accessors.cpp | 2 +- sycl/test/gdb/printers.cpp | 2 +- sycl/test/separate-compile/test.cpp | 4 +- 6 files changed, 625 insertions(+), 5 deletions(-) create mode 100644 sycl/include/CL/sycl/sycl_span.hpp diff --git a/sycl/include/CL/sycl/stl.hpp b/sycl/include/CL/sycl/stl.hpp index 6a9b0b844d838..039655219f5d7 100644 --- a/sycl/include/CL/sycl/stl.hpp +++ b/sycl/include/CL/sycl/stl.hpp @@ -11,6 +11,7 @@ // 4.5 C++ Standard library classes required for the interface #include +#include #include #include diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp new file mode 100644 index 0000000000000..3d2f5305669e9 --- /dev/null +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -0,0 +1,619 @@ +// -*- C++ -*- +//===------------------------------ span ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _SYCL_SPAN +#define _SYCL_SPAN + +/* + Derived from libcxx span. + Original _LIBCPP macros replaced with _SYCLSPAN to avoid collisions. + + + span synopsis + +namespace std { + +// constants +inline constexpr size_t dynamic_extent = numeric_limits::max(); + +// [views.span], class template span +template + class span; + +// [span.objectrep], views of object representation +template + span as_bytes(span s) +noexcept; + +template + span< byte, ((Extent == dynamic_extent) ? dynamic_extent : + (sizeof(ElementType) * Extent))> as_writable_bytes(span s) noexcept; + + +namespace std { +template +class span { +public: + // constants and types + using element_type = ElementType; + using value_type = std::remove_cv_t; + using size_type = size_t; + using difference_type = ptrdiff_t; + using pointer = element_type*; + using const_pointer = const element_type*; + using reference = element_type&; + using const_reference = const element_type&; + using iterator = implementation-defined; + using reverse_iterator = std::reverse_iterator; + static constexpr size_type extent = Extent; + + // [span.cons], span constructors, copy, assignment, and destructor + constexpr span() noexcept; + constexpr explicit(Extent != dynamic_extent) span(pointer ptr, size_type +count); constexpr explicit(Extent != dynamic_extent) span(pointer firstElem, +pointer lastElem); template constexpr span(element_type (&arr)[N]) +noexcept; template constexpr span(array& arr) +noexcept; template constexpr span(const array& arr) +noexcept; template constexpr explicit(Extent != +dynamic_extent) span(Container& cont); template constexpr +explicit(Extent != dynamic_extent) span(const Container& cont); constexpr +span(const span& other) noexcept = default; template constexpr explicit(Extent != dynamic_extent) span(const +span& s) noexcept; ~span() noexcept = default; + constexpr span& operator=(const span& other) noexcept = default; + + // [span.sub], span subviews + template + constexpr span first() const; + template + constexpr span last() const; + template + constexpr span subspan() const; + + constexpr span first(size_type count) const; + constexpr span last(size_type count) const; + constexpr span subspan(size_type offset, +size_type count = dynamic_extent) const; + + // [span.obs], span observers + constexpr size_type size() const noexcept; + constexpr size_type size_bytes() const noexcept; + constexpr bool empty() const noexcept; + + // [span.elem], span element access + constexpr reference operator[](size_type idx) const; + constexpr reference front() const; + constexpr reference back() const; + constexpr pointer data() const noexcept; + + // [span.iterators], span iterator support + constexpr iterator begin() const noexcept; + constexpr iterator end() const noexcept; + constexpr reverse_iterator rbegin() const noexcept; + constexpr reverse_iterator rend() const noexcept; + +private: + pointer data_; // exposition only + size_type size_; // exposition only +}; + +template + span(T (&)[N]) -> span; + +template + span(array&) -> span; + +template + span(const array&) -> span; + +template + span(Container&) -> span; + +template + span(const Container&) -> span; + +} // namespace std + +*/ + +#include // for array +#include // for byte +#include // for iterators +#include // for remove_cv, etc + +#define _SYCLSPAN_TEMPLATE_VIS +#define _SYCLSPAN_INLINE_VISIBILITY inline + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { + +// byte is unsigned char at sycl/image.hpp:58 +using byte = unsigned char; + +// asserts suppressed for device compatibility. +// TODO: enable +#define _SYCLSPAN_ASSERT(x, m) ((void)0) + +inline constexpr size_t dynamic_extent = SIZE_MAX; +template class span; + +template struct __is_span_impl : public std::false_type {}; + +template +struct __is_span_impl> : public std::true_type {}; + +template +struct __is_span : public __is_span_impl> {}; + +template struct __is_std_array_impl : public std::false_type {}; + +template +struct __is_std_array_impl> : public std::true_type {}; + +template +struct __is_std_array : public __is_std_array_impl> {}; + +template +struct __is_span_compatible_container : public std::false_type {}; + +template +struct __is_span_compatible_container< + _Tp, _ElementType, + std::void_t< + // is not a specialization of span + typename std::enable_if::value, std::nullptr_t>::type, + // is not a specialization of array + typename std::enable_if::value, + std::nullptr_t>::type, + // is_array_v is false, + typename std::enable_if, std::nullptr_t>::type, + // data(cont) and size(cont) are well formed + decltype(data(std::declval<_Tp>())), + decltype(size(std::declval<_Tp>())), + // remove_pointer_t(*)[] is convertible to + // ElementType(*)[] + typename std::enable_if< + std::is_convertible_v()))> (*)[], + _ElementType (*)[]>, + std::nullptr_t>::type>> : public std::true_type {}; + +template class _SYCLSPAN_TEMPLATE_VIS span { +public: + // constants and types + using element_type = _Tp; + using value_type = std::remove_cv_t<_Tp>; + using size_type = size_t; + using difference_type = ptrdiff_t; + using pointer = _Tp *; + using const_pointer = const _Tp *; + using reference = _Tp &; + using const_reference = const _Tp &; + using iterator = pointer; + using rev_iterator = std::reverse_iterator; + + static constexpr size_type extent = _Extent; + + // [span.cons], span constructors, copy, assignment, and destructor + template = nullptr> + _SYCLSPAN_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {} + + constexpr span(const span &) noexcept = default; + constexpr span &operator=(const span &) noexcept = default; + + _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, + size_type __count) + : __data{__ptr} { + (void)__count; + _SYCLSPAN_ASSERT(_Extent == __count, + "size mismatch in span's constructor (ptr, len)"); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) + : __data{__f} { + (void)__l; + _SYCLSPAN_ASSERT(_Extent == distance(__f, __l), + "size mismatch in span's constructor (ptr, ptr)"); + } + + template , + std::nullptr_t> = nullptr> + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + std::array<_OtherElementType, _Extent> &__arr) noexcept + : __data{__arr.data()} {} + + template < + class _OtherElementType, + std::enable_if_t, + std::nullptr_t> = nullptr> + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + const std::array<_OtherElementType, _Extent> &__arr) noexcept + : __data{__arr.data()} {} + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span( + _Container &__c, + std::enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, + std::nullptr_t> = nullptr) + : __data{std::data(__c)} { + _SYCLSPAN_ASSERT(_Extent == std::size(__c), + "size mismatch in span's constructor (range)"); + } + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span( + const _Container &__c, + std::enable_if_t< + __is_span_compatible_container::value, + std::nullptr_t> = nullptr) + : __data{std::data(__c)} { + _SYCLSPAN_ASSERT(_Extent == std::size(__c), + "size mismatch in span's constructor (range)"); + } + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + const span<_OtherElementType, _Extent> &__other, + std::enable_if_t< + std::is_convertible_v<_OtherElementType (*)[], element_type (*)[]>, + std::nullptr_t> = nullptr) + : __data{__other.data()} {} + + // ~span() noexcept = default; + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span + first() const noexcept { + static_assert(_Count <= _Extent, "Count out of range in span::first()"); + return span{data(), _Count}; + } + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span + last() const noexcept { + static_assert(_Count <= _Extent, "Count out of range in span::last()"); + return span{data() + size() - _Count, _Count}; + } + + _SYCLSPAN_INLINE_VISIBILITY + constexpr span + first(size_type __count) const noexcept { + _SYCLSPAN_ASSERT(__count <= size(), + "Count out of range in span::first(count)"); + return {data(), __count}; + } + + _SYCLSPAN_INLINE_VISIBILITY + constexpr span + last(size_type __count) const noexcept { + _SYCLSPAN_ASSERT(__count <= size(), + "Count out of range in span::last(count)"); + return {data() + size() - __count, __count}; + } + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr auto subspan() const noexcept + -> span { + static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); + static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, + "Offset + count out of range in span::subspan()"); + + using _ReturnType = + span; + return _ReturnType{data() + _Offset, + _Count == dynamic_extent ? size() - _Offset : _Count}; + } + + _SYCLSPAN_INLINE_VISIBILITY + constexpr span + subspan(size_type __offset, + size_type __count = dynamic_extent) const noexcept { + _SYCLSPAN_ASSERT(__offset <= size(), + "Offset out of range in span::subspan(offset, count)"); + _SYCLSPAN_ASSERT(__count <= size() || __count == dynamic_extent, + "Count out of range in span::subspan(offset, count)"); + if (__count == dynamic_extent) + return {data() + __offset, size() - __offset}; + _SYCLSPAN_ASSERT( + __count <= size() - __offset, + "Offset + count out of range in span::subspan(offset, count)"); + return {data() + __offset, __count}; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept { + return _Extent; + } + _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { + return _Extent * sizeof(element_type); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr bool empty() const noexcept { + return _Extent == 0; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr reference + operator[](size_type __idx) const noexcept { + _SYCLSPAN_ASSERT(__idx < size(), "span[] index out of bounds"); + return __data[__idx]; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr reference front() const noexcept { + _SYCLSPAN_ASSERT(!empty(), "span::front() on empty span"); + return __data[0]; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr reference back() const noexcept { + _SYCLSPAN_ASSERT(!empty(), "span::back() on empty span"); + return __data[size() - 1]; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept { + return __data; + } + + // [span.iter], span iterator support + _SYCLSPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept { + return iterator(data()); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept { + return iterator(data() + size()); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept { + return rev_iterator(end()); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept { + return rev_iterator(begin()); + } + + _SYCLSPAN_INLINE_VISIBILITY span + __as_bytes() const noexcept { + return span{ + reinterpret_cast(data()), size_bytes()}; + } + + _SYCLSPAN_INLINE_VISIBILITY span + __as_writable_bytes() const noexcept { + return span{ + reinterpret_cast(data()), size_bytes()}; + } + +private: + pointer __data; +}; + +template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { +private: +public: + // constants and types + using element_type = _Tp; + using value_type = std::remove_cv_t<_Tp>; + using size_type = size_t; + using difference_type = ptrdiff_t; + using pointer = _Tp *; + using const_pointer = const _Tp *; + using reference = _Tp &; + using const_reference = const _Tp &; + using iterator = pointer; + using rev_iterator = std::reverse_iterator; + + static constexpr size_type extent = dynamic_extent; + + // [span.cons], span constructors, copy, assignment, and destructor + _SYCLSPAN_INLINE_VISIBILITY constexpr span() noexcept + : __data{nullptr}, __size{0} {} + + constexpr span(const span &) noexcept = default; + constexpr span &operator=(const span &) noexcept = default; + + _SYCLSPAN_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) + : __data{__ptr}, __size{__count} {} + _SYCLSPAN_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) + : __data{__f}, __size{static_cast(distance(__f, __l))} {} + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + element_type (&__arr)[_Sz]) noexcept + : __data{__arr}, __size{_Sz} {} + + template , + std::nullptr_t> = nullptr> + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + std::array<_OtherElementType, _Sz> &__arr) noexcept + : __data{__arr.data()}, __size{_Sz} {} + + template < + class _OtherElementType, size_t _Sz, + std::enable_if_t, + std::nullptr_t> = nullptr> + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + const std::array<_OtherElementType, _Sz> &__arr) noexcept + : __data{__arr.data()}, __size{_Sz} {} + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _Container &__c, + std::enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, + std::nullptr_t> = nullptr) + : __data{std::data(__c)}, __size{(size_type)std::size(__c)} {} + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + const _Container &__c, + std::enable_if_t< + __is_span_compatible_container::value, + std::nullptr_t> = nullptr) + : __data{std::data(__c)}, __size{(size_type)std::size(__c)} {} + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span( + const span<_OtherElementType, _OtherExtent> &__other, + std::enable_if_t< + std::is_convertible_v<_OtherElementType (*)[], element_type (*)[]>, + std::nullptr_t> = nullptr) noexcept + : __data{__other.data()}, __size{__other.size()} {} + + // ~span() noexcept = default; + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span + first() const noexcept { + _SYCLSPAN_ASSERT(_Count <= size(), "Count out of range in span::first()"); + return span{data(), _Count}; + } + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span + last() const noexcept { + _SYCLSPAN_ASSERT(_Count <= size(), "Count out of range in span::last()"); + return span{data() + size() - _Count, _Count}; + } + + _SYCLSPAN_INLINE_VISIBILITY + constexpr span + first(size_type __count) const noexcept { + _SYCLSPAN_ASSERT(__count <= size(), + "Count out of range in span::first(count)"); + return {data(), __count}; + } + + _SYCLSPAN_INLINE_VISIBILITY + constexpr span + last(size_type __count) const noexcept { + _SYCLSPAN_ASSERT(__count <= size(), + "Count out of range in span::last(count)"); + return {data() + size() - __count, __count}; + } + + template + _SYCLSPAN_INLINE_VISIBILITY constexpr span + subspan() const noexcept { + _SYCLSPAN_ASSERT(_Offset <= size(), + "Offset out of range in span::subspan()"); + _SYCLSPAN_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, + "Offset + count out of range in span::subspan()"); + return span{ + data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; + } + + constexpr span _SYCLSPAN_INLINE_VISIBILITY + subspan(size_type __offset, + size_type __count = dynamic_extent) const noexcept { + _SYCLSPAN_ASSERT(__offset <= size(), + "Offset out of range in span::subspan(offset, count)"); + _SYCLSPAN_ASSERT(__count <= size() || __count == dynamic_extent, + "count out of range in span::subspan(offset, count)"); + if (__count == dynamic_extent) + return {data() + __offset, size() - __offset}; + _SYCLSPAN_ASSERT( + __count <= size() - __offset, + "Offset + count out of range in span::subspan(offset, count)"); + return {data() + __offset, __count}; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept { + return __size; + } + _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { + return __size * sizeof(element_type); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr bool empty() const noexcept { + return __size == 0; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr reference + operator[](size_type __idx) const noexcept { + _SYCLSPAN_ASSERT(__idx < size(), "span[] index out of bounds"); + return __data[__idx]; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr reference front() const noexcept { + _SYCLSPAN_ASSERT(!empty(), "span[].front() on empty span"); + return __data[0]; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr reference back() const noexcept { + _SYCLSPAN_ASSERT(!empty(), "span[].back() on empty span"); + return __data[size() - 1]; + } + + _SYCLSPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept { + return __data; + } + + // [span.iter], span iterator support + _SYCLSPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept { + return iterator(data()); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept { + return iterator(data() + size()); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept { + return rev_iterator(end()); + } + _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept { + return rev_iterator(begin()); + } + + _SYCLSPAN_INLINE_VISIBILITY span + __as_bytes() const noexcept { + return {reinterpret_cast(data()), size_bytes()}; + } + + _SYCLSPAN_INLINE_VISIBILITY span + __as_writable_bytes() const noexcept { + return {reinterpret_cast(data()), size_bytes()}; + } + +private: + pointer __data; + size_type __size; +}; + +// as_bytes & as_writable_bytes +template +_SYCLSPAN_INLINE_VISIBILITY auto as_bytes(span<_Tp, _Extent> __s) noexcept + -> decltype(__s.__as_bytes()) { + return __s.__as_bytes(); +} + +template +_SYCLSPAN_INLINE_VISIBILITY auto +as_writable_bytes(span<_Tp, _Extent> __s) noexcept + -> std::enable_if_t, + decltype(__s.__as_writable_bytes())> { + return __s.__as_writable_bytes(); +} + +// Deduction guides +template span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; + +template span(std::array<_Tp, _Sz> &) -> span<_Tp, _Sz>; + +template +span(const std::array<_Tp, _Sz> &) -> span; + +template +span(_Container &) -> span; + +template +span(const _Container &) -> span; + +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) + +#endif // _SYCL_SPAN diff --git a/sycl/test/basic_tests/image_accessor_types.cpp b/sycl/test/basic_tests/image_accessor_types.cpp index 85e731c731192..5bcdc22357295 100644 --- a/sycl/test/basic_tests/image_accessor_types.cpp +++ b/sycl/test/basic_tests/image_accessor_types.cpp @@ -1,4 +1,4 @@ -// RUN: not %clangxx -fsyntax-only %s -I %sycl_include/sycl 2>&1 | FileCheck %s +// RUN: not %clangxx -fsyntax-only -std=c++17 %s -I %sycl_include/sycl 2>&1 | FileCheck %s #include #include diff --git a/sycl/test/gdb/accessors.cpp b/sycl/test/gdb/accessors.cpp index 8bb37bf4e99c0..da7cc84ecb2ea 100644 --- a/sycl/test/gdb/accessors.cpp +++ b/sycl/test/gdb/accessors.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -c -fno-color-diagnostics -I %sycl_include/sycl -Xclang -ast-dump %s | FileCheck %s +// RUN: %clangxx -c -fno-color-diagnostics -std=c++17 -I %sycl_include/sycl -Xclang -ast-dump %s | FileCheck %s // UNSUPPORTED: windows #include diff --git a/sycl/test/gdb/printers.cpp b/sycl/test/gdb/printers.cpp index 39336135bc662..58fda0db57034 100644 --- a/sycl/test/gdb/printers.cpp +++ b/sycl/test/gdb/printers.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -c -fno-color-diagnostics -I %sycl_include/sycl -Xclang -ast-dump %s | FileCheck %s +// RUN: %clangxx -c -fno-color-diagnostics -std=c++17 -I %sycl_include/sycl -Xclang -ast-dump %s | FileCheck %s // UNSUPPORTED: windows #include #include diff --git a/sycl/test/separate-compile/test.cpp b/sycl/test/separate-compile/test.cpp index a2666b79bf27b..df97ae177d5d1 100644 --- a/sycl/test/separate-compile/test.cpp +++ b/sycl/test/separate-compile/test.cpp @@ -7,13 +7,13 @@ // >> host compilation... // Driver automatically adds -D_DLL and -D_MT on Windows with -fsycl. // Add those defines required for Windows and harmless for Linux. -// RUN: %clangxx -D_DLL -D_MT -include sycl_ihdr_a.h -g -c %s -o a.o -I %sycl_include/sycl -Wno-sycl-strict +// RUN: %clangxx -D_DLL -D_MT -std=c++17 -include sycl_ihdr_a.h -g -c %s -o a.o -I %sycl_include/sycl -Wno-sycl-strict // // >> ---- compile src2 // >> device compilation... // RUN: %clangxx -DB_CPP=1 -fsycl-device-only -Xclang -fsycl-int-header=sycl_ihdr_b.h %s -c -o b_kernel.bc -Wno-sycl-strict // >> host compilation... -// RUN: %clangxx -DB_CPP=1 -D_DLL -D_MT -include sycl_ihdr_b.h -g -c %s -o b.o -I %sycl_include/sycl -Wno-sycl-strict +// RUN: %clangxx -DB_CPP=1 -D_DLL -D_MT -std=c++17 -include sycl_ihdr_b.h -g -c %s -o b.o -I %sycl_include/sycl -Wno-sycl-strict // // >> ---- bundle .o with .spv // >> run bundler From 1512d9640476accc84c7a7a33f7eae90b9f4f56d Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Fri, 16 Apr 2021 19:18:38 -0700 Subject: [PATCH 02/14] overlooked test. restored. Signed-off-by: Chris Perkins --- sycl/test/on-device/span/span.cpp | 105 ++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 sycl/test/on-device/span/span.cpp diff --git a/sycl/test/on-device/span/span.cpp b/sycl/test/on-device/span/span.cpp new file mode 100644 index 0000000000000..eb0251b5b2d0e --- /dev/null +++ b/sycl/test/on-device/span/span.cpp @@ -0,0 +1,105 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %CPU_RUN_PLACEHOLDER %t.out +// RUN: %GPU_RUN_PLACEHOLDER %t.out +// RUN: %ACC_RUN_PLACEHOLDER %t.out + +#include +#include + +using namespace sycl; + +void testSpanCapture() { + // This test creates spans that are backed by USM. + // ensures they can be captured by device lambda + // and that read and write operations function correctly + // across capture. + queue Q; + + constexpr long numReadTests = 2; + const range<1> NumberOfReadTestsRange(numReadTests); + buffer SpanRead(NumberOfReadTestsRange); + + // span from a vector + // We will create a vector, backed by a USM allocator. And a span from that. + typedef usm_allocator vec_alloc; + // Create allocator for device associated with q + vec_alloc myAlloc(Q); + // Create std vector with the allocator + std::vector vecUSM(4, myAlloc); + std::iota(vecUSM.begin(), vecUSM.end(), 1); + sycl::span vecUSM_span{vecUSM}; + vecUSM_span[0] += 100; // 101 modify first value using span affordance. + + // span from USM memory + int *usm_data = malloc_shared(4, Q); + sycl::span usm_span(usm_data, 4); + std::iota(usm_span.begin(), usm_span.end(), 1); + usm_span[0] += 100; // 101 modify first value using span affordance. + + event E = Q.submit([&](handler &cgh) { + auto span_read_acc = SpanRead.get_access(cgh); + cgh.single_task([=]() { + // read from the spans. + span_read_acc[0] = vecUSM_span[0]; + span_read_acc[1] = usm_span[0]; + + // write to the spans + vecUSM_span[1] += 1000; + usm_span[1] += 1000; + }); + }); + E.wait(); + + // check out the read operations, should have gotten 101 from each + auto span_read_acc = SpanRead.get_access(); + for (int i = 0; i < numReadTests; i++) { + assert(span_read_acc[i] == 101 && "read check should have gotten 100"); + } + + // were the spans successfully modified via write? + assert(vecUSM_span[1] == 1002 && + "vecUSM_span write check should have gotten 1001"); + assert(usm_span[1] == 1002 && "usm_span write check should have gotten 1001"); +} + +void set_all_span_values(sycl::span container, int v) { + for (auto &e : container) + e = v; +} + +void testSpanOnDevice() { + // this test creates a simple span on device, + // passes it to a function that operates on it + // and ensures it worked correctly + queue Q; + constexpr long numReadTests = 4; + const range<1> NumberOfReadTestsRange(numReadTests); + buffer SpanRead(NumberOfReadTestsRange); + + event E = Q.submit([&](handler &cgh) { + auto span_read_acc = SpanRead.get_access(cgh); + cgh.single_task([=]() { + // create a span on device, pass it to function that modifies it + // read values back out. + int a[]{1, 2, 3, 4}; + sycl::span a_span{a}; + set_all_span_values(a_span, 10); + for (int i = 0; i < numReadTests; i++) + span_read_acc[i] = a_span[i]; + }); + }); + E.wait(); + + // check out the read operations, should have gotten 10 from each + auto span_read_acc = SpanRead.get_access(); + for (int i = 0; i < numReadTests; i++) { + assert(span_read_acc[i] == 10 && "read check should have gotten 10"); + } +} + +int main() { + testSpanCapture(); + testSpanOnDevice(); + + return 0; +} \ No newline at end of file From b3b9a1a60c7ff5930c33bd3fb26ca45af98a459d Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Fri, 16 Apr 2021 21:16:41 -0700 Subject: [PATCH 03/14] clang format apparently doesn't like clang format Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 52 +++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index 3d2f5305669e9..c3e8e69bce21f 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -181,8 +181,8 @@ struct __is_span_compatible_container< // remove_pointer_t(*)[] is convertible to // ElementType(*)[] typename std::enable_if< - std::is_convertible_v()))> (*)[], + std::is_convertible_v()))> (*)[], _ElementType (*)[]>, std::nullptr_t>::type>> : public std::true_type {}; @@ -273,30 +273,30 @@ template class _SYCLSPAN_TEMPLATE_VIS span { // ~span() noexcept = default; template - _SYCLSPAN_INLINE_VISIBILITY constexpr span - first() const noexcept { + _SYCLSPAN_INLINE_VISIBILITY constexpr span first() const + noexcept { static_assert(_Count <= _Extent, "Count out of range in span::first()"); return span{data(), _Count}; } template - _SYCLSPAN_INLINE_VISIBILITY constexpr span - last() const noexcept { + _SYCLSPAN_INLINE_VISIBILITY constexpr span last() const + noexcept { static_assert(_Count <= _Extent, "Count out of range in span::last()"); return span{data() + size() - _Count, _Count}; } _SYCLSPAN_INLINE_VISIBILITY - constexpr span - first(size_type __count) const noexcept { + constexpr span first(size_type __count) const + noexcept { _SYCLSPAN_ASSERT(__count <= size(), "Count out of range in span::first(count)"); return {data(), __count}; } _SYCLSPAN_INLINE_VISIBILITY - constexpr span - last(size_type __count) const noexcept { + constexpr span last(size_type __count) const + noexcept { _SYCLSPAN_ASSERT(__count <= size(), "Count out of range in span::last(count)"); return {data() + size() - __count, __count}; @@ -319,8 +319,8 @@ template class _SYCLSPAN_TEMPLATE_VIS span { _SYCLSPAN_INLINE_VISIBILITY constexpr span - subspan(size_type __offset, - size_type __count = dynamic_extent) const noexcept { + subspan(size_type __offset, size_type __count = dynamic_extent) const + noexcept { _SYCLSPAN_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); _SYCLSPAN_ASSERT(__count <= size() || __count == dynamic_extent, @@ -470,30 +470,30 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { // ~span() noexcept = default; template - _SYCLSPAN_INLINE_VISIBILITY constexpr span - first() const noexcept { + _SYCLSPAN_INLINE_VISIBILITY constexpr span first() const + noexcept { _SYCLSPAN_ASSERT(_Count <= size(), "Count out of range in span::first()"); return span{data(), _Count}; } template - _SYCLSPAN_INLINE_VISIBILITY constexpr span - last() const noexcept { + _SYCLSPAN_INLINE_VISIBILITY constexpr span last() const + noexcept { _SYCLSPAN_ASSERT(_Count <= size(), "Count out of range in span::last()"); return span{data() + size() - _Count, _Count}; } _SYCLSPAN_INLINE_VISIBILITY - constexpr span - first(size_type __count) const noexcept { + constexpr span first(size_type __count) const + noexcept { _SYCLSPAN_ASSERT(__count <= size(), "Count out of range in span::first(count)"); return {data(), __count}; } _SYCLSPAN_INLINE_VISIBILITY - constexpr span - last(size_type __count) const noexcept { + constexpr span last(size_type __count) const + noexcept { _SYCLSPAN_ASSERT(__count <= size(), "Count out of range in span::last(count)"); return {data() + size() - __count, __count}; @@ -511,8 +511,8 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { } constexpr span _SYCLSPAN_INLINE_VISIBILITY - subspan(size_type __offset, - size_type __count = dynamic_extent) const noexcept { + subspan(size_type __offset, size_type __count = dynamic_extent) const + noexcept { _SYCLSPAN_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); _SYCLSPAN_ASSERT(__count <= size() || __count == dynamic_extent, @@ -600,15 +600,15 @@ as_writable_bytes(span<_Tp, _Extent> __s) noexcept } // Deduction guides -template span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; +template span(_Tp (&)[_Sz])->span<_Tp, _Sz>; -template span(std::array<_Tp, _Sz> &) -> span<_Tp, _Sz>; +template span(std::array<_Tp, _Sz> &)->span<_Tp, _Sz>; template -span(const std::array<_Tp, _Sz> &) -> span; +span(const std::array<_Tp, _Sz> &)->span; template -span(_Container &) -> span; +span(_Container &)->span; template span(const _Container &) -> span; From d1a32465de645997c1563ff8da39fc472995297a Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Fri, 16 Apr 2021 21:30:36 -0700 Subject: [PATCH 04/14] there can never be enough clang-format Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index c3e8e69bce21f..238f0a9d447df 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -273,14 +273,14 @@ template class _SYCLSPAN_TEMPLATE_VIS span { // ~span() noexcept = default; template - _SYCLSPAN_INLINE_VISIBILITY constexpr span first() const + _SYCLSPAN_INLINE_VISIBILITY constexpr span first() const noexcept { static_assert(_Count <= _Extent, "Count out of range in span::first()"); return span{data(), _Count}; } template - _SYCLSPAN_INLINE_VISIBILITY constexpr span last() const + _SYCLSPAN_INLINE_VISIBILITY constexpr span last() const noexcept { static_assert(_Count <= _Extent, "Count out of range in span::last()"); return span{data() + size() - _Count, _Count}; @@ -611,7 +611,7 @@ template span(_Container &)->span; template -span(const _Container &) -> span; +span(const _Container &)->span; } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) From 137d2a11106de525f857497240dd9dfd9e740e4c Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Mon, 19 Apr 2021 12:16:04 -0700 Subject: [PATCH 05/14] ternary expressions in templates confuse older MSVC. Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index 238f0a9d447df..8262cdb05543c 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -305,7 +305,7 @@ template class _SYCLSPAN_TEMPLATE_VIS span { template _SYCLSPAN_INLINE_VISIBILITY constexpr auto subspan() const noexcept -> span { + (_Count != dynamic_extent ? _Count : _Extent - _Offset)> { static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Offset + count out of range in span::subspan()"); From 86368de57360ee0c026fbb0eb7eb8deb37713627 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Mon, 19 Apr 2021 12:57:39 -0700 Subject: [PATCH 06/14] reviewer feedback Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 2 +- sycl/test/on-device/span/span.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index 8262cdb05543c..13098a24f4b7d 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -12,7 +12,7 @@ /* Derived from libcxx span. - Original _LIBCPP macros replaced with _SYCLSPAN to avoid collisions. + Original _LIBCPP macros replaced with _SYCL_SPAN to avoid collisions. span synopsis diff --git a/sycl/test/on-device/span/span.cpp b/sycl/test/on-device/span/span.cpp index eb0251b5b2d0e..a3e92a58671aa 100644 --- a/sycl/test/on-device/span/span.cpp +++ b/sycl/test/on-device/span/span.cpp @@ -21,7 +21,7 @@ void testSpanCapture() { // span from a vector // We will create a vector, backed by a USM allocator. And a span from that. - typedef usm_allocator vec_alloc; + using vec_alloc = usm_allocator; // Create allocator for device associated with q vec_alloc myAlloc(Q); // Create std vector with the allocator @@ -31,14 +31,14 @@ void testSpanCapture() { vecUSM_span[0] += 100; // 101 modify first value using span affordance. // span from USM memory - int *usm_data = malloc_shared(4, Q); + auto *usm_data = malloc_shared(4, Q); sycl::span usm_span(usm_data, 4); std::iota(usm_span.begin(), usm_span.end(), 1); usm_span[0] += 100; // 101 modify first value using span affordance. event E = Q.submit([&](handler &cgh) { auto span_read_acc = SpanRead.get_access(cgh); - cgh.single_task([=]() { + cgh.single_task([=] { // read from the spans. span_read_acc[0] = vecUSM_span[0]; span_read_acc[1] = usm_span[0]; @@ -78,7 +78,7 @@ void testSpanOnDevice() { event E = Q.submit([&](handler &cgh) { auto span_read_acc = SpanRead.get_access(cgh); - cgh.single_task([=]() { + cgh.single_task([=] { // create a span on device, pass it to function that modifies it // read values back out. int a[]{1, 2, 3, 4}; @@ -102,4 +102,4 @@ int main() { testSpanOnDevice(); return 0; -} \ No newline at end of file +} From 4038d8a070e9dc71529662209e1ca3bfeecd08d9 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Tue, 20 Apr 2021 11:34:14 -0700 Subject: [PATCH 07/14] reviewer feedback Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 7 +++---- sycl/test/on-device/span/span.cpp | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index 13098a24f4b7d..3c555c503f2f6 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -124,7 +124,8 @@ template */ -#include // for array +#include // for array +#include #include // for byte #include // for iterators #include // for remove_cv, etc @@ -138,9 +139,7 @@ namespace sycl { // byte is unsigned char at sycl/image.hpp:58 using byte = unsigned char; -// asserts suppressed for device compatibility. -// TODO: enable -#define _SYCLSPAN_ASSERT(x, m) ((void)0) +#define _SYCLSPAN_ASSERT(x, m) assert(x &&m) inline constexpr size_t dynamic_extent = SIZE_MAX; template class span; diff --git a/sycl/test/on-device/span/span.cpp b/sycl/test/on-device/span/span.cpp index a3e92a58671aa..2a5cdd8c5640d 100644 --- a/sycl/test/on-device/span/span.cpp +++ b/sycl/test/on-device/span/span.cpp @@ -37,11 +37,11 @@ void testSpanCapture() { usm_span[0] += 100; // 101 modify first value using span affordance. event E = Q.submit([&](handler &cgh) { - auto span_read_acc = SpanRead.get_access(cgh); + auto can_read_from_span_acc = SpanRead.get_access(cgh); cgh.single_task([=] { // read from the spans. - span_read_acc[0] = vecUSM_span[0]; - span_read_acc[1] = usm_span[0]; + can_read_from_span_acc[0] = vecUSM_span[0]; + can_read_from_span_acc[1] = usm_span[0]; // write to the spans vecUSM_span[1] += 1000; @@ -51,15 +51,18 @@ void testSpanCapture() { E.wait(); // check out the read operations, should have gotten 101 from each - auto span_read_acc = SpanRead.get_access(); + auto can_read_from_span_acc = SpanRead.get_access(); for (int i = 0; i < numReadTests; i++) { - assert(span_read_acc[i] == 101 && "read check should have gotten 100"); + assert(can_read_from_span_acc[i] == 101 && + "read check should have gotten 100"); } // were the spans successfully modified via write? assert(vecUSM_span[1] == 1002 && "vecUSM_span write check should have gotten 1001"); assert(usm_span[1] == 1002 && "usm_span write check should have gotten 1001"); + + free(usm_data, Q); } void set_all_span_values(sycl::span container, int v) { @@ -77,7 +80,7 @@ void testSpanOnDevice() { buffer SpanRead(NumberOfReadTestsRange); event E = Q.submit([&](handler &cgh) { - auto span_read_acc = SpanRead.get_access(cgh); + auto can_read_from_span_acc = SpanRead.get_access(cgh); cgh.single_task([=] { // create a span on device, pass it to function that modifies it // read values back out. @@ -85,15 +88,16 @@ void testSpanOnDevice() { sycl::span a_span{a}; set_all_span_values(a_span, 10); for (int i = 0; i < numReadTests; i++) - span_read_acc[i] = a_span[i]; + can_read_from_span_acc[i] = a_span[i]; }); }); E.wait(); // check out the read operations, should have gotten 10 from each - auto span_read_acc = SpanRead.get_access(); + auto can_read_from_span_acc = SpanRead.get_access(); for (int i = 0; i < numReadTests; i++) { - assert(span_read_acc[i] == 10 && "read check should have gotten 10"); + assert(can_read_from_span_acc[i] == 10 && + "read check should have gotten 10"); } } From ed050a8bdc83541619d4b3e72c2356fccb6d611b Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Tue, 20 Apr 2021 13:32:16 -0700 Subject: [PATCH 08/14] new test will need to be C++17 to work with span Signed-off-by: Chris Perkins --- sycl/test/regression/fsycl-host-compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/regression/fsycl-host-compiler.cpp b/sycl/test/regression/fsycl-host-compiler.cpp index 55f951358db1a..25b001896fed3 100644 --- a/sycl/test/regression/fsycl-host-compiler.cpp +++ b/sycl/test/regression/fsycl-host-compiler.cpp @@ -1,4 +1,4 @@ -// RUN: %clang++ -fsycl -fsycl-host-compiler=g++ -DDEFINE_CHECK -fsycl-host-compiler-options="-DDEFINE_CHECK" -o %t1.exe %s +// RUN: %clang++ -fsycl -fsycl-host-compiler=g++ -DDEFINE_CHECK -fsycl-host-compiler-options="-DDEFINE_CHECK -std=c++17" -o %t1.exe %s // RUN: %RUN_ON_HOST %t1.exe // REQUIRES: system-linux //==------- fsycl-host-compiler.cpp - external host compiler test ----------==// From 1be5267a9808133218f0abf9de487ef685e22b01 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Tue, 20 Apr 2021 15:28:59 -0700 Subject: [PATCH 09/14] windows apparently has its own test that needs updating Signed-off-by: Chris Perkins --- sycl/test/regression/fsycl-host-compiler-win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/regression/fsycl-host-compiler-win.cpp b/sycl/test/regression/fsycl-host-compiler-win.cpp index e3279231de95b..7031eb6a91d8a 100644 --- a/sycl/test/regression/fsycl-host-compiler-win.cpp +++ b/sycl/test/regression/fsycl-host-compiler-win.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cl -fsycl -fsycl-host-compiler=cl -DDEFINE_CHECK -fsycl-host-compiler-options="-DDEFINE_CHECK" /Fe%t1.exe %s +// RUN: %clang_cl -fsycl -fsycl-host-compiler=cl -DDEFINE_CHECK -fsycl-host-compiler-options="-DDEFINE_CHECK -std=c++17" /Fe%t1.exe %s // RUN: %RUN_ON_HOST %t1.exe // REQUIRES: system-windows // From 5e53de080d5e2540c2a61aaa4f9246667cabb9dc Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Wed, 21 Apr 2021 12:38:06 -0700 Subject: [PATCH 10/14] revisit win issue. c++17 flag is different Signed-off-by: Chris Perkins --- sycl/test/regression/fsycl-host-compiler-win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/regression/fsycl-host-compiler-win.cpp b/sycl/test/regression/fsycl-host-compiler-win.cpp index 7031eb6a91d8a..e0f643624d4b2 100644 --- a/sycl/test/regression/fsycl-host-compiler-win.cpp +++ b/sycl/test/regression/fsycl-host-compiler-win.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cl -fsycl -fsycl-host-compiler=cl -DDEFINE_CHECK -fsycl-host-compiler-options="-DDEFINE_CHECK -std=c++17" /Fe%t1.exe %s +// RUN: %clang_cl -fsycl -fsycl-host-compiler=cl -DDEFINE_CHECK -fsycl-host-compiler-options="-DDEFINE_CHECK /std:c++17" /Fe%t1.exe %s // RUN: %RUN_ON_HOST %t1.exe // REQUIRES: system-windows // From fdfa5d84f9086006571c0deb7cd2f9da2ca98fa9 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Wed, 21 Apr 2021 13:48:01 -0700 Subject: [PATCH 11/14] removing assert for CUDA test Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index 3c555c503f2f6..219e154e2a50e 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -125,7 +125,6 @@ template */ #include // for array -#include #include // for byte #include // for iterators #include // for remove_cv, etc @@ -139,7 +138,9 @@ namespace sycl { // byte is unsigned char at sycl/image.hpp:58 using byte = unsigned char; -#define _SYCLSPAN_ASSERT(x, m) assert(x &&m) +// asserts suppressed for device compatibility. +// TODO: enable +#define _SYCLSPAN_ASSERT(x, m) ((void)0) inline constexpr size_t dynamic_extent = SIZE_MAX; template class span; From be9fe1d6cb5dac3b5cd0352c419b87d86654e183 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Wed, 21 Apr 2021 14:02:01 -0700 Subject: [PATCH 12/14] ephemeral clang-format whims Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index 219e154e2a50e..13098a24f4b7d 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -124,7 +124,7 @@ template */ -#include // for array +#include // for array #include // for byte #include // for iterators #include // for remove_cv, etc From abf592d02ffb66e828b0d8397d81d38091189127 Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Thu, 22 Apr 2021 11:07:04 -0700 Subject: [PATCH 13/14] reviewer feedback and assert Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 220 +++++++++++++++-------------- 1 file changed, 113 insertions(+), 107 deletions(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index 13098a24f4b7d..e99e80c4c3706 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -125,12 +125,13 @@ template */ #include // for array +#include #include // for byte #include // for iterators #include // for remove_cv, etc -#define _SYCLSPAN_TEMPLATE_VIS -#define _SYCLSPAN_INLINE_VISIBILITY inline +#define _SYCL_SPAN_TEMPLATE_VIS +#define _SYCL_SPAN_INLINE_VISIBILITY inline __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { @@ -140,7 +141,11 @@ using byte = unsigned char; // asserts suppressed for device compatibility. // TODO: enable -#define _SYCLSPAN_ASSERT(x, m) ((void)0) +#if defined(__SYCL_DEVICE_ONLY__) +#define _SYCL_SPAN_ASSERT(x, m) ((void)0) +#else +#define _SYCL_SPAN_ASSERT(x, m) assert(x && m) +#endif inline constexpr size_t dynamic_extent = SIZE_MAX; template class span; @@ -186,7 +191,7 @@ struct __is_span_compatible_container< _ElementType (*)[]>, std::nullptr_t>::type>> : public std::true_type {}; -template class _SYCLSPAN_TEMPLATE_VIS span { +template class _SYCL_SPAN_TEMPLATE_VIS span { public: // constants and types using element_type = _Tp; @@ -205,30 +210,30 @@ template class _SYCLSPAN_TEMPLATE_VIS span { // [span.cons], span constructors, copy, assignment, and destructor template = nullptr> - _SYCLSPAN_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {} + _SYCL_SPAN_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {} constexpr span(const span &) noexcept = default; constexpr span &operator=(const span &) noexcept = default; - _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, - size_type __count) + _SYCL_SPAN_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, + size_type __count) : __data{__ptr} { (void)__count; - _SYCLSPAN_ASSERT(_Extent == __count, - "size mismatch in span's constructor (ptr, len)"); + _SYCL_SPAN_ASSERT(_Extent == __count, + "size mismatch in span's constructor (ptr, len)"); } - _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) + _SYCL_SPAN_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) : __data{__f} { (void)__l; - _SYCLSPAN_ASSERT(_Extent == distance(__f, __l), - "size mismatch in span's constructor (ptr, ptr)"); + _SYCL_SPAN_ASSERT(_Extent == distance(__f, __l), + "size mismatch in span's constructor (ptr, ptr)"); } template , std::nullptr_t> = nullptr> - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( std::array<_OtherElementType, _Extent> &__arr) noexcept : __data{__arr.data()} {} @@ -237,33 +242,33 @@ template class _SYCLSPAN_TEMPLATE_VIS span { std::enable_if_t, std::nullptr_t> = nullptr> - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( const std::array<_OtherElementType, _Extent> &__arr) noexcept : __data{__arr.data()} {} template - _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr explicit span( _Container &__c, std::enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, std::nullptr_t> = nullptr) : __data{std::data(__c)} { - _SYCLSPAN_ASSERT(_Extent == std::size(__c), - "size mismatch in span's constructor (range)"); + _SYCL_SPAN_ASSERT(_Extent == std::size(__c), + "size mismatch in span's constructor (range)"); } template - _SYCLSPAN_INLINE_VISIBILITY constexpr explicit span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr explicit span( const _Container &__c, std::enable_if_t< __is_span_compatible_container::value, std::nullptr_t> = nullptr) : __data{std::data(__c)} { - _SYCLSPAN_ASSERT(_Extent == std::size(__c), - "size mismatch in span's constructor (range)"); + _SYCL_SPAN_ASSERT(_Extent == std::size(__c), + "size mismatch in span's constructor (range)"); } template - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( const span<_OtherElementType, _Extent> &__other, std::enable_if_t< std::is_convertible_v<_OtherElementType (*)[], element_type (*)[]>, @@ -273,37 +278,37 @@ template class _SYCLSPAN_TEMPLATE_VIS span { // ~span() noexcept = default; template - _SYCLSPAN_INLINE_VISIBILITY constexpr span first() const - noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr span + first() const noexcept { static_assert(_Count <= _Extent, "Count out of range in span::first()"); return span{data(), _Count}; } template - _SYCLSPAN_INLINE_VISIBILITY constexpr span last() const - noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr span + last() const noexcept { static_assert(_Count <= _Extent, "Count out of range in span::last()"); return span{data() + size() - _Count, _Count}; } - _SYCLSPAN_INLINE_VISIBILITY + _SYCL_SPAN_INLINE_VISIBILITY constexpr span first(size_type __count) const noexcept { - _SYCLSPAN_ASSERT(__count <= size(), - "Count out of range in span::first(count)"); + _SYCL_SPAN_ASSERT(__count <= size(), + "Count out of range in span::first(count)"); return {data(), __count}; } - _SYCLSPAN_INLINE_VISIBILITY + _SYCL_SPAN_INLINE_VISIBILITY constexpr span last(size_type __count) const noexcept { - _SYCLSPAN_ASSERT(__count <= size(), - "Count out of range in span::last(count)"); + _SYCL_SPAN_ASSERT(__count <= size(), + "Count out of range in span::last(count)"); return {data() + size() - __count, __count}; } template - _SYCLSPAN_INLINE_VISIBILITY constexpr auto subspan() const noexcept + _SYCL_SPAN_INLINE_VISIBILITY constexpr auto subspan() const noexcept -> span { static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); @@ -317,73 +322,73 @@ template class _SYCLSPAN_TEMPLATE_VIS span { _Count == dynamic_extent ? size() - _Offset : _Count}; } - _SYCLSPAN_INLINE_VISIBILITY + _SYCL_SPAN_INLINE_VISIBILITY constexpr span subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { - _SYCLSPAN_ASSERT(__offset <= size(), - "Offset out of range in span::subspan(offset, count)"); - _SYCLSPAN_ASSERT(__count <= size() || __count == dynamic_extent, - "Count out of range in span::subspan(offset, count)"); + _SYCL_SPAN_ASSERT(__offset <= size(), + "Offset out of range in span::subspan(offset, count)"); + _SYCL_SPAN_ASSERT(__count <= size() || __count == dynamic_extent, + "Count out of range in span::subspan(offset, count)"); if (__count == dynamic_extent) return {data() + __offset, size() - __offset}; - _SYCLSPAN_ASSERT( + _SYCL_SPAN_ASSERT( __count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)"); return {data() + __offset, __count}; } - _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } - _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } - _SYCLSPAN_INLINE_VISIBILITY constexpr bool empty() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } - _SYCLSPAN_INLINE_VISIBILITY constexpr reference + _SYCL_SPAN_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept { - _SYCLSPAN_ASSERT(__idx < size(), "span[] index out of bounds"); + _SYCL_SPAN_ASSERT(__idx < size(), "span[] index out of bounds"); return __data[__idx]; } - _SYCLSPAN_INLINE_VISIBILITY constexpr reference front() const noexcept { - _SYCLSPAN_ASSERT(!empty(), "span::front() on empty span"); + _SYCL_SPAN_INLINE_VISIBILITY constexpr reference front() const noexcept { + _SYCL_SPAN_ASSERT(!empty(), "span::front() on empty span"); return __data[0]; } - _SYCLSPAN_INLINE_VISIBILITY constexpr reference back() const noexcept { - _SYCLSPAN_ASSERT(!empty(), "span::back() on empty span"); + _SYCL_SPAN_INLINE_VISIBILITY constexpr reference back() const noexcept { + _SYCL_SPAN_ASSERT(!empty(), "span::back() on empty span"); return __data[size() - 1]; } - _SYCLSPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } // [span.iter], span iterator support - _SYCLSPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } - _SYCLSPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } - _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept { return rev_iterator(end()); } - _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept { return rev_iterator(begin()); } - _SYCLSPAN_INLINE_VISIBILITY span + _SYCL_SPAN_INLINE_VISIBILITY span __as_bytes() const noexcept { return span{ reinterpret_cast(data()), size_bytes()}; } - _SYCLSPAN_INLINE_VISIBILITY span + _SYCL_SPAN_INLINE_VISIBILITY span __as_writable_bytes() const noexcept { return span{ reinterpret_cast(data()), size_bytes()}; @@ -393,7 +398,8 @@ template class _SYCLSPAN_TEMPLATE_VIS span { pointer __data; }; -template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { +template +class _SYCL_SPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { private: public: // constants and types @@ -411,19 +417,19 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { static constexpr size_type extent = dynamic_extent; // [span.cons], span constructors, copy, assignment, and destructor - _SYCLSPAN_INLINE_VISIBILITY constexpr span() noexcept + _SYCL_SPAN_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} constexpr span(const span &) noexcept = default; constexpr span &operator=(const span &) noexcept = default; - _SYCLSPAN_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) + _SYCL_SPAN_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}, __size{__count} {} - _SYCLSPAN_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) + _SYCL_SPAN_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast(distance(__f, __l))} {} template - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} @@ -431,7 +437,7 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { std::enable_if_t, std::nullptr_t> = nullptr> - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( std::array<_OtherElementType, _Sz> &__arr) noexcept : __data{__arr.data()}, __size{_Sz} {} @@ -440,19 +446,19 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { std::enable_if_t, std::nullptr_t> = nullptr> - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( const std::array<_OtherElementType, _Sz> &__arr) noexcept : __data{__arr.data()}, __size{_Sz} {} template - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( _Container &__c, std::enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, std::nullptr_t> = nullptr) : __data{std::data(__c)}, __size{(size_type)std::size(__c)} {} template - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( const _Container &__c, std::enable_if_t< __is_span_compatible_container::value, @@ -460,7 +466,7 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { : __data{std::data(__c)}, __size{(size_type)std::size(__c)} {} template - _SYCLSPAN_INLINE_VISIBILITY constexpr span( + _SYCL_SPAN_INLINE_VISIBILITY constexpr span( const span<_OtherElementType, _OtherExtent> &__other, std::enable_if_t< std::is_convertible_v<_OtherElementType (*)[], element_type (*)[]>, @@ -470,111 +476,111 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { // ~span() noexcept = default; template - _SYCLSPAN_INLINE_VISIBILITY constexpr span first() const - noexcept { - _SYCLSPAN_ASSERT(_Count <= size(), "Count out of range in span::first()"); + _SYCL_SPAN_INLINE_VISIBILITY constexpr span + first() const noexcept { + _SYCL_SPAN_ASSERT(_Count <= size(), "Count out of range in span::first()"); return span{data(), _Count}; } template - _SYCLSPAN_INLINE_VISIBILITY constexpr span last() const - noexcept { - _SYCLSPAN_ASSERT(_Count <= size(), "Count out of range in span::last()"); + _SYCL_SPAN_INLINE_VISIBILITY constexpr span + last() const noexcept { + _SYCL_SPAN_ASSERT(_Count <= size(), "Count out of range in span::last()"); return span{data() + size() - _Count, _Count}; } - _SYCLSPAN_INLINE_VISIBILITY + _SYCL_SPAN_INLINE_VISIBILITY constexpr span first(size_type __count) const noexcept { - _SYCLSPAN_ASSERT(__count <= size(), - "Count out of range in span::first(count)"); + _SYCL_SPAN_ASSERT(__count <= size(), + "Count out of range in span::first(count)"); return {data(), __count}; } - _SYCLSPAN_INLINE_VISIBILITY + _SYCL_SPAN_INLINE_VISIBILITY constexpr span last(size_type __count) const noexcept { - _SYCLSPAN_ASSERT(__count <= size(), - "Count out of range in span::last(count)"); + _SYCL_SPAN_ASSERT(__count <= size(), + "Count out of range in span::last(count)"); return {data() + size() - __count, __count}; } template - _SYCLSPAN_INLINE_VISIBILITY constexpr span + _SYCL_SPAN_INLINE_VISIBILITY constexpr span subspan() const noexcept { - _SYCLSPAN_ASSERT(_Offset <= size(), - "Offset out of range in span::subspan()"); - _SYCLSPAN_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, - "Offset + count out of range in span::subspan()"); + _SYCL_SPAN_ASSERT(_Offset <= size(), + "Offset out of range in span::subspan()"); + _SYCL_SPAN_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, + "Offset + count out of range in span::subspan()"); return span{ data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; } - constexpr span _SYCLSPAN_INLINE_VISIBILITY - subspan(size_type __offset, size_type __count = dynamic_extent) const - noexcept { - _SYCLSPAN_ASSERT(__offset <= size(), - "Offset out of range in span::subspan(offset, count)"); - _SYCLSPAN_ASSERT(__count <= size() || __count == dynamic_extent, - "count out of range in span::subspan(offset, count)"); + constexpr span _SYCL_SPAN_INLINE_VISIBILITY + subspan(size_type __offset, + size_type __count = dynamic_extent) const noexcept { + _SYCL_SPAN_ASSERT(__offset <= size(), + "Offset out of range in span::subspan(offset, count)"); + _SYCL_SPAN_ASSERT(__count <= size() || __count == dynamic_extent, + "count out of range in span::subspan(offset, count)"); if (__count == dynamic_extent) return {data() + __offset, size() - __offset}; - _SYCLSPAN_ASSERT( + _SYCL_SPAN_ASSERT( __count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)"); return {data() + __offset, __count}; } - _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size; } - _SYCLSPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size * sizeof(element_type); } - _SYCLSPAN_INLINE_VISIBILITY constexpr bool empty() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } - _SYCLSPAN_INLINE_VISIBILITY constexpr reference + _SYCL_SPAN_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept { - _SYCLSPAN_ASSERT(__idx < size(), "span[] index out of bounds"); + _SYCL_SPAN_ASSERT(__idx < size(), "span[] index out of bounds"); return __data[__idx]; } - _SYCLSPAN_INLINE_VISIBILITY constexpr reference front() const noexcept { - _SYCLSPAN_ASSERT(!empty(), "span[].front() on empty span"); + _SYCL_SPAN_INLINE_VISIBILITY constexpr reference front() const noexcept { + _SYCL_SPAN_ASSERT(!empty(), "span[].front() on empty span"); return __data[0]; } - _SYCLSPAN_INLINE_VISIBILITY constexpr reference back() const noexcept { - _SYCLSPAN_ASSERT(!empty(), "span[].back() on empty span"); + _SYCL_SPAN_INLINE_VISIBILITY constexpr reference back() const noexcept { + _SYCL_SPAN_ASSERT(!empty(), "span[].back() on empty span"); return __data[size() - 1]; } - _SYCLSPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } // [span.iter], span iterator support - _SYCLSPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } - _SYCLSPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } - _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept { return rev_iterator(end()); } - _SYCLSPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept { return rev_iterator(begin()); } - _SYCLSPAN_INLINE_VISIBILITY span + _SYCL_SPAN_INLINE_VISIBILITY span __as_bytes() const noexcept { return {reinterpret_cast(data()), size_bytes()}; } - _SYCLSPAN_INLINE_VISIBILITY span + _SYCL_SPAN_INLINE_VISIBILITY span __as_writable_bytes() const noexcept { return {reinterpret_cast(data()), size_bytes()}; } @@ -586,13 +592,13 @@ template class _SYCLSPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { // as_bytes & as_writable_bytes template -_SYCLSPAN_INLINE_VISIBILITY auto as_bytes(span<_Tp, _Extent> __s) noexcept +_SYCL_SPAN_INLINE_VISIBILITY auto as_bytes(span<_Tp, _Extent> __s) noexcept -> decltype(__s.__as_bytes()) { return __s.__as_bytes(); } template -_SYCLSPAN_INLINE_VISIBILITY auto +_SYCL_SPAN_INLINE_VISIBILITY auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept -> std::enable_if_t, decltype(__s.__as_writable_bytes())> { From e849131d73be6313544c119dc8223c9debf2957c Mon Sep 17 00:00:00 2001 From: Chris Perkins Date: Thu, 22 Apr 2021 11:22:29 -0700 Subject: [PATCH 14/14] clang-format is of two minds Signed-off-by: Chris Perkins --- sycl/include/CL/sycl/sycl_span.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sycl/include/CL/sycl/sycl_span.hpp b/sycl/include/CL/sycl/sycl_span.hpp index e99e80c4c3706..eb3566149fc95 100644 --- a/sycl/include/CL/sycl/sycl_span.hpp +++ b/sycl/include/CL/sycl/sycl_span.hpp @@ -125,7 +125,7 @@ template */ #include // for array -#include +#include // for assert #include // for byte #include // for iterators #include // for remove_cv, etc @@ -144,7 +144,7 @@ using byte = unsigned char; #if defined(__SYCL_DEVICE_ONLY__) #define _SYCL_SPAN_ASSERT(x, m) ((void)0) #else -#define _SYCL_SPAN_ASSERT(x, m) assert(x && m) +#define _SYCL_SPAN_ASSERT(x, m) assert((x && m)) #endif inline constexpr size_t dynamic_extent = SIZE_MAX; @@ -285,8 +285,8 @@ template class _SYCL_SPAN_TEMPLATE_VIS span { } template - _SYCL_SPAN_INLINE_VISIBILITY constexpr span - last() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr span last() const + noexcept { static_assert(_Count <= _Extent, "Count out of range in span::last()"); return span{data() + size() - _Count, _Count}; } @@ -483,8 +483,8 @@ class _SYCL_SPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { } template - _SYCL_SPAN_INLINE_VISIBILITY constexpr span - last() const noexcept { + _SYCL_SPAN_INLINE_VISIBILITY constexpr span last() const + noexcept { _SYCL_SPAN_ASSERT(_Count <= size(), "Count out of range in span::last()"); return span{data() + size() - _Count, _Count}; } @@ -517,8 +517,8 @@ class _SYCL_SPAN_TEMPLATE_VIS span<_Tp, dynamic_extent> { } constexpr span _SYCL_SPAN_INLINE_VISIBILITY - subspan(size_type __offset, - size_type __count = dynamic_extent) const noexcept { + subspan(size_type __offset, size_type __count = dynamic_extent) const + noexcept { _SYCL_SPAN_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); _SYCL_SPAN_ASSERT(__count <= size() || __count == dynamic_extent,