From b8edacc9891b747a295ebbac5b6bb4e70bc726a2 Mon Sep 17 00:00:00 2001 From: Roland Schulz Date: Fri, 25 Oct 2019 16:59:52 -0700 Subject: [PATCH 1/3] [SYCL] Add buffer container constructor Prototype of a proposal to add a buffer constructor which takes a contiguous buffer as an argument to simplify usage. Signed-off-by: Roland Schulz --- sycl/include/CL/sycl/buffer.hpp | 39 +++++++++++++++++-- .../CL/sycl/detail/stl_type_traits.hpp | 8 ++-- sycl/test/basic_tests/buffer/buffer.cpp | 6 +-- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/sycl/include/CL/sycl/buffer.hpp b/sycl/include/CL/sycl/buffer.hpp index 641e53e798278..442b6b1de4036 100644 --- a/sycl/include/CL/sycl/buffer.hpp +++ b/sycl/include/CL/sycl/buffer.hpp @@ -30,7 +30,18 @@ class buffer { using allocator_type = AllocatorT; template using EnableIfOneDimension = typename std::enable_if<1 == dims>::type; - + // using same requirement for contiguous container as std::span + template + using EnableIfContiguous = + detail::void_t().data())> (*)[], + T (*)[]>::value>, + decltype(std::declval().size())>; + template + using EnableIfItInputIterator = detail::enable_if_t< + std::is_convertible::iterator_category, + std::input_iterator_tag>::value>; template using EnableIfSameNonConstIterators = typename std::enable_if::value && @@ -107,7 +118,8 @@ class buffer { } template > + typename = EnableIfOneDimension, + typename = EnableIfItInputIterator> buffer(InputIterator first, InputIterator last, AllocatorT allocator, const property_list &propList = {}) : Range(range<1>(std::distance(first, last))) { @@ -117,7 +129,8 @@ class buffer { } template > + typename = EnableIfOneDimension, + typename = EnableIfItInputIterator> buffer(InputIterator first, InputIterator last, const property_list &propList = {}) : Range(range<1>(std::distance(first, last))) { @@ -126,6 +139,26 @@ class buffer { detail::getNextPowerOfTwo(sizeof(T)), propList); } + // This constructor is a prototype for a future SYCL specification + template , + typename = EnableIfContiguous> + buffer(Container &container, AllocatorT allocator, + const property_list &propList = {}) + : Range(range<1>(container.size())) { + impl = std::make_shared>( + container.data(), container.data() + container.size(), + get_count() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), propList, + allocator); + } + + // This constructor is a prototype for a future SYCL specification + template , + typename = EnableIfContiguous> + buffer(Container &container, const property_list &propList = {}) + : buffer(container, {}, propList) {} + buffer(buffer &b, const id &baseIndex, const range &subRange) : impl(b.impl), Range(subRange), diff --git a/sycl/include/CL/sycl/detail/stl_type_traits.hpp b/sycl/include/CL/sycl/detail/stl_type_traits.hpp index 5541f5eef72df..d6a63d76d8531 100644 --- a/sycl/include/CL/sycl/detail/stl_type_traits.hpp +++ b/sycl/include/CL/sycl/detail/stl_type_traits.hpp @@ -53,15 +53,15 @@ template using iterator_to_const_type_t = std::is_const>::type>; -template using requirements_list = void; +template using void_t = void; // TODO Align with C++ named requirements: LegacyOutputIterator // https://en.cppreference.com/w/cpp/named_req/OutputIterator template using output_iterator_requirements = - requirements_list, - decltype(*std::declval() = - std::declval>())>; + void_t, + decltype(*std::declval() = + std::declval>())>; template struct is_output_iterator { static constexpr bool value = false; diff --git a/sycl/test/basic_tests/buffer/buffer.cpp b/sycl/test/basic_tests/buffer/buffer.cpp index 72065129781b8..99078a2d05a9f 100644 --- a/sycl/test/basic_tests/buffer/buffer.cpp +++ b/sycl/test/basic_tests/buffer/buffer.cpp @@ -556,7 +556,7 @@ int main() { std::vector data2(10, -2); { buffer a(data1.data(), range<1>(10)); - buffer b(data2.data(), range<1>(10)); + buffer b(data2); program prog(myQueue.get_context()); prog.build_with_source("kernel void override_source(global int* Acc) " @@ -581,7 +581,7 @@ int main() { std::vector data2(10, -2); { buffer a(data1.data(), range<1>(10)); - buffer b(data2.data(), range<1>(10)); + buffer b(data2); accessor A(a); @@ -609,7 +609,7 @@ int main() { std::vector data2(10, -2); { buffer a(data1.data(), range<1>(10)); - buffer b(data2.data(), range<1>(10)); + buffer b(data2); accessor A(a); From 31ef4c3b4b1992a426cfed7899d79b982fd36bc5 Mon Sep 17 00:00:00 2001 From: Roland Schulz Date: Fri, 25 Oct 2019 23:04:15 -0700 Subject: [PATCH 2/3] [SYCL] Add buffer deduction guides Signed-off-by: Roland Schulz --- sycl/include/CL/sycl/buffer.hpp | 26 ++++++++++++- sycl/test/basic_tests/buffer/buffer_ctad.cpp | 40 ++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 sycl/test/basic_tests/buffer/buffer_ctad.cpp diff --git a/sycl/include/CL/sycl/buffer.hpp b/sycl/include/CL/sycl/buffer.hpp index 442b6b1de4036..ee0cdec382003 100644 --- a/sycl/include/CL/sycl/buffer.hpp +++ b/sycl/include/CL/sycl/buffer.hpp @@ -36,7 +36,7 @@ class buffer { detail::void_t().data())> (*)[], - T (*)[]>::value>, + const T (*)[]>::value>, decltype(std::declval().size())>; template using EnableIfItInputIterator = detail::enable_if_t< @@ -350,6 +350,30 @@ class buffer { return newRange[1] == parentRange[1] && newRange[2] == parentRange[2]; } }; + +#ifdef __cpp_deduction_guides +template +buffer(InputIterator, InputIterator, AllocatorT, const property_list & = {}) + ->buffer::value_type, 1, + AllocatorT>; +template +buffer(InputIterator, InputIterator, const property_list & = {}) + ->buffer::value_type, 1>; +template +buffer(Container &, AllocatorT, const property_list & = {}) + ->buffer; +template +buffer(Container &, const property_list & = {}) + ->buffer; +template +buffer(const T *, const range &, AllocatorT, + const property_list & = {}) + ->buffer; +template +buffer(const T *, const range &, const property_list & = {}) + ->buffer; +#endif // __cpp_deduction_guides + } // namespace sycl } // namespace cl diff --git a/sycl/test/basic_tests/buffer/buffer_ctad.cpp b/sycl/test/basic_tests/buffer/buffer_ctad.cpp new file mode 100644 index 0000000000000..d7b9d38415ad3 --- /dev/null +++ b/sycl/test/basic_tests/buffer/buffer_ctad.cpp @@ -0,0 +1,40 @@ +// RUN: %clangxx -std=c++17 -fsyntax-only -Xclang -verify %s +// expected-no-diagnostics +//==------------------- buffer_ctad.cpp - SYCL buffer CTAD test ----------------==// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +using namespace cl::sycl; + +int main() { + std::vector v(5, 1); + const std::vector cv(5, 1); + buffer b1(v.data(), range<1>(5)); + static_assert(std::is_same_v>); + buffer b1a(v.data(), range<1>(5), std::allocator()); + static_assert( + std::is_same_v>>); + buffer b1b(cv.data(), range<1>(5)); + static_assert(std::is_same_v>); + buffer b1c(v.data(), range<2>(2, 2)); + static_assert(std::is_same_v>); + buffer b2(v.begin(), v.end()); + static_assert(std::is_same_v>); + buffer b2a(v.cbegin(), v.cend()); + static_assert(std::is_same_v>); + buffer b3(v); + static_assert(std::is_same_v>); + buffer b3a(cv); + static_assert(std::is_same_v>); + shared_ptr_class ptr{new int[5], [](int *p) { delete[] p; }}; + buffer b4(ptr, range<1>(5)); + static_assert(std::is_same_v>); +} From bff7061c273b06b2f9189eb69163502101216e5e Mon Sep 17 00:00:00 2001 From: Roland Schulz Date: Tue, 5 Nov 2019 15:09:41 -0800 Subject: [PATCH 3/3] [SYCL] Comment which C++ version adds traits Signed-off-by: Roland Schulz --- .../CL/sycl/detail/stl_type_traits.hpp | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/sycl/include/CL/sycl/detail/stl_type_traits.hpp b/sycl/include/CL/sycl/detail/stl_type_traits.hpp index d6a63d76d8531..eba4e7b5baa22 100644 --- a/sycl/include/CL/sycl/detail/stl_type_traits.hpp +++ b/sycl/include/CL/sycl/detail/stl_type_traits.hpp @@ -16,14 +16,9 @@ namespace cl { namespace sycl { namespace detail { -template using bool_constant = std::integral_constant; - -template -using allocator_value_type_t = typename std::allocator_traits::value_type; - -template -using allocator_pointer_t = typename std::allocator_traits::pointer; - +// Type traits identical to those in std in newer versions. Can be removed when +// SYCL requires a newer version of the C++ standard. +// C++14 template using enable_if_t = typename std::enable_if::type; @@ -40,6 +35,18 @@ using remove_reference_t = typename std::remove_reference::type; template using add_pointer_t = typename std::add_pointer::type; +// C++17 +template using bool_constant = std::integral_constant; + +template using void_t = void; + +// Custom type traits +template +using allocator_value_type_t = typename std::allocator_traits::value_type; + +template +using allocator_pointer_t = typename std::allocator_traits::pointer; + template using iterator_category_t = typename std::iterator_traits::iterator_category; @@ -53,8 +60,6 @@ template using iterator_to_const_type_t = std::is_const>::type>; -template using void_t = void; - // TODO Align with C++ named requirements: LegacyOutputIterator // https://en.cppreference.com/w/cpp/named_req/OutputIterator template