diff --git a/sycl/include/CL/sycl/detail/buffer_impl.hpp b/sycl/include/CL/sycl/detail/buffer_impl.hpp index 4da8134a94424..cc9d1ec302f1f 100644 --- a/sycl/include/CL/sycl/detail/buffer_impl.hpp +++ b/sycl/include/CL/sycl/detail/buffer_impl.hpp @@ -99,23 +99,52 @@ template class buffer_impl { } } + template struct is_const_iterator { + using pointer = typename std::iterator_traits::pointer; + static constexpr bool value = + std::is_const::type>::value; + }; + + template + using EnableIfConstIterator = + typename std::enable_if::value, + Iterator>::type; + + template + using EnableIfNotConstIterator = + typename std::enable_if::value, + Iterator>::type; + template - buffer_impl(InputIterator first, InputIterator last, const size_t sizeInBytes, - const property_list &propList, + buffer_impl(EnableIfNotConstIterator first, InputIterator last, + const size_t sizeInBytes, const property_list &propList, AllocatorT allocator = AllocatorT()) : SizeInBytes(sizeInBytes), Props(propList), MAllocator(allocator) { - if (Props.has_property()) { - // TODO next line looks unsafe - BufPtr = &*first; - } else { - BufData.resize(get_size()); - BufPtr = reinterpret_cast(BufData.data()); - // We need cast BufPtr to pointer to the iteration type to get correct - // offset in std::copy when it will increment destination pointer. - auto *Ptr = reinterpret_cast< - typename std::iterator_traits::pointer>(BufPtr); - std::copy(first, last, Ptr); - } + BufData.resize(get_size()); + BufPtr = reinterpret_cast(BufData.data()); + // We need cast BufPtr to pointer to the iteration type to get correct + // offset in std::copy when it will increment destination pointer. + auto *Ptr = + reinterpret_cast::pointer>( + BufPtr); + std::copy(first, last, Ptr); + // Data is written back if InputIterator is not a const iterator. + set_final_data(first); + } + + template + buffer_impl(EnableIfConstIterator first, InputIterator last, + const size_t sizeInBytes, const property_list &propList, + AllocatorT allocator = AllocatorT()) + : SizeInBytes(sizeInBytes), Props(propList), MAllocator(allocator) { + BufData.resize(get_size()); + BufPtr = reinterpret_cast(BufData.data()); + // We need cast BufPtr to pointer to the iteration type to get correct + // offset in std::copy when it will increment destination pointer. + typedef typename std::iterator_traits::value_type value; + auto *Ptr = reinterpret_cast::type>::type>(BufPtr); + std::copy(first, last, Ptr); } buffer_impl(cl_mem MemObject, const context &SyclContext, diff --git a/sycl/test/basic_tests/buffer/buffer.cpp b/sycl/test/basic_tests/buffer/buffer.cpp index 574d938fee1d5..9d8d6be64f7a0 100644 --- a/sycl/test/basic_tests/buffer/buffer.cpp +++ b/sycl/test/basic_tests/buffer/buffer.cpp @@ -403,8 +403,29 @@ int main() { range<1>{3}, [=](id<1> index) { B[index] = 20; }); }); } - // Data is not copied back in the desctruction of the buffer created from - // pair of iterators + // Data is copied back in the desctruction of the buffer created from + // pair of non-const iterators + for (int i = 0; i < 2; i++) + assert(data1[i] == -1); + for (int i = 2; i < 5; i++) + assert(data1[i] == 20); + for (int i = 5; i < 10; i++) + assert(data1[i] == -1); + } + + // Check that data is not copied back in the desctruction of the buffer + // created from pair of const iterators + { + std::vector data1(10, -1); + { + buffer b(data1.cbegin() + 2, data1.cbegin() + 5); + queue myQueue; + myQueue.submit([&](handler &cgh) { + auto B = b.get_access(cgh); + cgh.parallel_for( + range<1>{3}, [=](id<1> index) { B[index] = 20; }); + }); + } for (int i = 0; i < 10; i++) assert(data1[i] == -1); } @@ -435,9 +456,10 @@ int main() { // created from pair of iterators { std::vector data1(10, -1); + std::vector data2(10, -1); { buffer b(data1.begin() + 2, data1.begin() + 5); - b.set_final_data(data1.begin() + 2); + b.set_final_data(data2.begin() + 2); queue myQueue; myQueue.submit([&](handler &cgh) { auto B = b.get_access(cgh); @@ -445,14 +467,12 @@ int main() { range<1>{3}, [=](id<1> index) { B[index] = 20; }); }); } - // Data is not copied back in the desctruction of the buffer created from - // pair of iterators for (int i = 0; i < 2; i++) - assert(data1[i] == -1); + assert(data2[i] == -1); for (int i = 2; i < 5; i++) - assert(data1[i] == 20); + assert(data2[i] == 20); for (int i = 5; i < 10; i++) - assert(data1[i] == -1); + assert(data2[i] == -1); } // Check that data is copied back after forcing write-back using