Skip to content

Commit baa3d73

Browse files
authored
[SYCL] Add [const]reverse_iterator to accessors (#7991)
Add `reverse_iterator` and `const_reverse_iterator` to `accessor`, `host_accessor` and `local_accessor`, and corresponding tests.
1 parent 33a4070 commit baa3d73

File tree

7 files changed

+1809
-8
lines changed

7 files changed

+1809
-8
lines changed

sycl/include/sycl/accessor.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,8 @@ class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(accessor) accessor :
12191219
using iterator = typename detail::accessor_iterator<value_type, Dimensions>;
12201220
using const_iterator =
12211221
typename detail::accessor_iterator<const value_type, Dimensions>;
1222+
using reverse_iterator = std::reverse_iterator<iterator>;
1223+
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
12221224
using difference_type =
12231225
typename std::iterator_traits<iterator>::difference_type;
12241226

@@ -2129,6 +2131,16 @@ class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(accessor) accessor :
21292131
get_offset());
21302132
}
21312133

2134+
reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
2135+
reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
2136+
2137+
const_reverse_iterator crbegin() const noexcept {
2138+
return const_reverse_iterator(cend());
2139+
}
2140+
const_reverse_iterator crend() const noexcept {
2141+
return const_reverse_iterator(cbegin());
2142+
}
2143+
21322144
private:
21332145
#ifdef __SYCL_DEVICE_ONLY__
21342146
size_t getTotalOffset() const {

sycl/test/basic_tests/accessor/iterator-member-types.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
// RUN: %clangxx -fsycl -fsyntax-only %s
22
//
3-
// Purpose of this test is to check that [accessor|host_accessor]::iterator and
4-
// ::const_iterator are aliased to the correct type.
5-
// FIXME: extend this test to also check ::reverse_iterator and
6-
// ::const_reverse_iterator
3+
// Purpose of this test is to check that [accessor|host_accessor]::iterator,
4+
// ::const_iterator, ::reverse_iterator and ::const_reverse_iterator are aliased
5+
// to the correct type.
76
#include <sycl/sycl.hpp>
87

98
#include <type_traits>
@@ -21,6 +20,16 @@ void check_accessor() {
2120
std::is_same_v<sycl::detail::accessor_iterator<
2221
const typename AccessorT::value_type, Dimensions>,
2322
typename AccessorT::const_iterator>);
23+
24+
static_assert(
25+
std::is_same_v<std::reverse_iterator<sycl::detail::accessor_iterator<
26+
typename AccessorT::value_type, Dimensions>>,
27+
typename AccessorT::reverse_iterator>);
28+
29+
static_assert(
30+
std::is_same_v<std::reverse_iterator<sycl::detail::accessor_iterator<
31+
const typename AccessorT::value_type, Dimensions>>,
32+
typename AccessorT::const_reverse_iterator>);
2433
}
2534

2635
template <typename DataT, int Dimensions, sycl::access_mode AccessMode>
@@ -34,6 +43,16 @@ void check_host_accessor() {
3443
std::is_same_v<sycl::detail::accessor_iterator<
3544
const typename AccessorT::value_type, Dimensions>,
3645
typename AccessorT::const_iterator>);
46+
47+
static_assert(
48+
std::is_same_v<std::reverse_iterator<sycl::detail::accessor_iterator<
49+
typename AccessorT::value_type, Dimensions>>,
50+
typename AccessorT::reverse_iterator>);
51+
52+
static_assert(
53+
std::is_same_v<std::reverse_iterator<sycl::detail::accessor_iterator<
54+
const typename AccessorT::value_type, Dimensions>>,
55+
typename AccessorT::const_reverse_iterator>);
3756
}
3857

3958
struct user_defined_t {

sycl/unittests/accessor/AccessorIterator.cpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ class AccessorIteratorTest : public ::testing::Test {
176176
// FIXME: consider turning this into parameterized test to check various
177177
// accessor types
178178
TEST_F(AccessorIteratorTest, IteratorTraits) {
179+
179180
using IteratorT = sycl::accessor<int>::iterator;
180181
ASSERT_TRUE(
181182
(std::is_same_v<sycl::accessor<int>::difference_type,
@@ -194,6 +195,7 @@ TEST_F(AccessorIteratorTest, IteratorTraits) {
194195
// Based on requirements listed at
195196
// https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
196197
TEST_F(AccessorIteratorTest, LegacyRandomAccessIteratorRequirements) {
198+
197199
using IteratorT = sycl::accessor<int>::iterator;
198200
IteratorT It;
199201
auto &RefToIt = It;
@@ -435,10 +437,8 @@ TEST_F(AccessorIteratorTest, PartialCopyWithOffset3D) {
435437
sycl::range<3>{7, 7, 7}, sycl::range<3>{3, 3, 3}, sycl::id<3>{2, 2, 2}));
436438
ASSERT_NO_FATAL_FAILURE(checkPartialCopyThroughIterator(
437439
sycl::range<3>{8, 8, 8}, sycl::range<3>{4, 4, 4}, sycl::id<3>{4, 4, 4}));
438-
// FIXME: figure out why the test below fails
439-
// ASSERT_NO_FATAL_FAILURE(checkPartialCopyThroughIterator(
440-
// sycl::range<3>{7, 7, 7}, sycl::range<3>{3, 3, 3}, sycl::id<3>{4, 4,
441-
// 4}));
440+
ASSERT_NO_FATAL_FAILURE(checkPartialCopyThroughIterator(
441+
sycl::range<3>{7, 7, 7}, sycl::range<3>{3, 3, 3}, sycl::id<3>{4, 4, 4}));
442442
ASSERT_NO_FATAL_FAILURE(checkPartialCopyThroughIterator(
443443
sycl::range<3>{7, 7, 7}, sycl::range<3>{3, 4, 5}, sycl::id<3>{3, 2, 1}));
444444
ASSERT_NO_FATAL_FAILURE(checkPartialCopyThroughIterator(
@@ -525,3 +525,49 @@ TEST_F(AccessorIteratorTest, PartialWriteWithOffset3D) {
525525
ASSERT_NO_FATAL_FAILURE(checkWriteThroughIterator(
526526
sycl::range<3>{3, 6, 4}, sycl::range<3>{1, 3, 2}, sycl::id<3>{1, 3, 2}));
527527
}
528+
529+
TEST_F(AccessorIteratorTest, IteratorEquivalentIncrements) {
530+
std::vector<int> reference(6);
531+
std::iota(reference.begin(), reference.end(), 0);
532+
sycl::buffer<int> buffer(reference.data(), sycl::range<1>{reference.size()});
533+
auto accessor = buffer.template get_access<sycl::access_mode::read_write>();
534+
auto a = accessor.begin();
535+
auto b = accessor.begin();
536+
a++;
537+
++b;
538+
ASSERT_TRUE(a == b);
539+
}
540+
541+
TEST_F(AccessorIteratorTest, IteratorEquivalentDecrements) {
542+
std::vector<int> reference(6);
543+
std::iota(reference.begin(), reference.end(), 0);
544+
sycl::buffer<int> buffer(reference.data(), sycl::range<1>{reference.size()});
545+
auto accessor = buffer.template get_access<sycl::access_mode::read_write>();
546+
auto a = accessor.begin();
547+
auto b = accessor.begin();
548+
a--;
549+
--b;
550+
ASSERT_TRUE(a == b);
551+
}
552+
553+
TEST_F(AccessorIteratorTest, IteratorSubscriptOperator) {
554+
std::vector<int> reference(6);
555+
std::iota(reference.begin(), reference.end(), 0);
556+
sycl::buffer<int> buffer(reference.data(), sycl::range<1>{reference.size()});
557+
auto accessor = buffer.template get_access<sycl::access_mode::read_write>();
558+
auto a = accessor.begin();
559+
auto b = accessor.begin();
560+
ASSERT_TRUE(a[3] == *(3 + b));
561+
}
562+
563+
TEST_F(AccessorIteratorTest, IteratorInequalitiesOperators) {
564+
std::vector<int> reference(6);
565+
std::iota(reference.begin(), reference.end(), 0);
566+
sycl::buffer<int> buffer(reference.data(), sycl::range<1>{reference.size()});
567+
auto accessor = buffer.template get_access<sycl::access_mode::read_write>();
568+
auto a = accessor.begin();
569+
auto b = accessor.begin();
570+
ASSERT_FALSE(a > b);
571+
ASSERT_TRUE(a <= b);
572+
ASSERT_TRUE(a >= b);
573+
}

0 commit comments

Comments
 (0)