Skip to content

Commit

Permalink
Implement __bounded_iter (#540)
Browse files Browse the repository at this point in the history
This is an internal helper wrapper that is used for span debug iterations
  • Loading branch information
miscco authored Oct 11, 2023
1 parent df0c9ff commit 83fe7eb
Show file tree
Hide file tree
Showing 13 changed files with 1,040 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//===----------------------------------------------------------------------===//
//
// 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
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// template <class _Iterator>
// struct __bounded_iter;
//
// Arithmetic operators

#include <cuda/std/cstddef>
#include <cuda/std/iterator>

#include "test_iterators.h"
#include "test_macros.h"

template <class Iter>
__host__ __device__ TEST_CONSTEXPR_CXX14 bool tests() {
int array[] = {40, 41, 42, 43, 44};
int* b = array + 0;
int* e = array + 5;

// ++it
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter>& result = ++iter;
assert(&result == &iter);
assert(*iter == 41);
}
// it++
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> result = iter++;
assert(*result == 40);
assert(*iter == 41);
}
// --it
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter>& result = --iter;
assert(&result == &iter);
assert(*iter == 42);
}
// it--
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> result = iter--;
assert(*result == 43);
assert(*iter == 42);
}
// it += n
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter>& result = (iter += 3);
assert(&result == &iter);
assert(*iter == 43);
}
// it + n
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> result = iter + 3;
assert(*iter == 40);
assert(*result == 43);
}
// n + it
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> result = 3 + iter;
assert(*iter == 40);
assert(*result == 43);
}
// it -= n
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter>& result = (iter -= 3);
assert(&result == &iter);
assert(*iter == 40);
}
// it - n
{
cuda::std::__bounded_iter<Iter> iter = cuda::std::__make_bounded_iter(Iter(b + 3), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> result = iter - 3;
assert(*iter == 43);
assert(*result == 40);
}
// it - it
{
cuda::std::__bounded_iter<Iter> iter1 = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> iter2 = cuda::std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
cuda::std::ptrdiff_t result = iter2 - iter1;
assert(result == 5);
}

return true;
}

int main(int, char**) {
tests<int*>();
#if TEST_STD_VER > 11
static_assert(tests<int*>(), "");
#endif

#if TEST_STD_VER > 17
tests<contiguous_iterator<int*> >();
static_assert(tests<contiguous_iterator<int*> >(), "");
#endif

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//===----------------------------------------------------------------------===//
//
// 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
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// template <class _Iterator>
// struct __bounded_iter;
//
// Comparison operators

#include <cuda/std/iterator>

#include "test_iterators.h"
#include "test_macros.h"

template <class Iter>
__host__ __device__ TEST_CONSTEXPR_CXX14 bool tests() {
int array[] = {0, 1, 2, 3, 4};
int* b = array + 0;
int* e = array + 5;
cuda::std::__bounded_iter<Iter> const iter1 = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> const iter2 = cuda::std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));

// operator==
{
assert(iter1 == iter1);
assert(!(iter1 == iter2));
}
// operator!=
{
assert(iter1 != iter2);
assert(!(iter1 != iter1));
}
// operator<
{
assert(iter1 < iter2);
assert(!(iter2 < iter1));
assert(!(iter1 < iter1));
}
// operator>
{
assert(iter2 > iter1);
assert(!(iter1 > iter2));
assert(!(iter1 > iter1));
}
// operator<=
{
assert(iter1 <= iter2);
assert(!(iter2 <= iter1));
assert(iter1 <= iter1);
}
// operator>=
{
assert(iter2 >= iter1);
assert(!(iter1 >= iter2));
assert(iter1 >= iter1);
}

return true;
}

int main(int, char**) {
tests<int*>();
#if TEST_STD_VER > 11
static_assert(tests<int*>(), "");
#endif

#if TEST_STD_VER > 17
tests<contiguous_iterator<int*> >();
static_assert(tests<contiguous_iterator<int*> >(), "");
#endif

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//===----------------------------------------------------------------------===//
//
// 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
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// template <class _Iterator>
// struct __bounded_iter;
//
// Dereference and indexing operators

// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCUDACXX_ENABLE_ASSERTIONS=1

#include <cuda/std/iterator>

#include "check_assertion.h"
#include "test_iterators.h"
#include "test_macros.h"

struct Foo {
int x;
__host__ __device__ TEST_CONSTEXPR bool operator==(Foo const& other) const { return x == other.x; }
};

template <class Iter>
__host__ __device__ TEST_CONSTEXPR_CXX14 bool tests() {
Foo array[] = {Foo{40}, Foo{41}, Foo{42}, Foo{43}, Foo{44}};
Foo* b = array + 0;
Foo* e = array + 5;
cuda::std::__bounded_iter<Iter> const iter1 = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> const iter2 = cuda::std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));

// operator*
assert(*iter1 == Foo{40});
// operator->
assert(iter1->x == 40);
// operator[]
assert(iter1[0] == Foo{40});
assert(iter1[1] == Foo{41});
assert(iter1[2] == Foo{42});
assert(iter2[-1] == Foo{44});
assert(iter2[-2] == Foo{43});

return true;
}

template <class Iter>
__host__ __device__ void test_death() {
Foo array[] = {Foo{0}, Foo{1}, Foo{2}, Foo{3}, Foo{4}};
Foo* b = array + 0;
Foo* e = array + 5;
cuda::std::__bounded_iter<Iter> const iter = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> const oob = cuda::std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));

// operator*
TEST_LIBCUDACXX_ASSERT_FAILURE(*oob, "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator");
// operator->
TEST_LIBCUDACXX_ASSERT_FAILURE(oob->x, "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator");
// operator[]
TEST_LIBCUDACXX_ASSERT_FAILURE(iter[-1], "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
TEST_LIBCUDACXX_ASSERT_FAILURE(iter[5], "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
TEST_LIBCUDACXX_ASSERT_FAILURE(oob[0], "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
TEST_LIBCUDACXX_ASSERT_FAILURE(oob[1], "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
TEST_LIBCUDACXX_ASSERT_FAILURE(oob[-6], "__bounded_iter::operator[]: Attempt to index an iterator out-of-range");
}

int main(int, char**) {
tests<Foo*>();
test_death<Foo*>();
#if TEST_STD_VER > 11
static_assert(tests<Foo*>(), "");
#endif

#if TEST_STD_VER > 17
tests<contiguous_iterator<Foo*> >();
test_death<contiguous_iterator<Foo*> >();
static_assert(tests<contiguous_iterator<Foo*> >(), "");
#endif

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//===----------------------------------------------------------------------===//
//
// 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
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// template <class _Iterator>
// struct __bounded_iter;
//
// cuda::std::pointer_traits specialization

#include <cuda/std/cassert>
#include <cuda/std/cstddef>
#include <cuda/std/iterator>
#include <cuda/std/type_traits>

#include "test_iterators.h"
#include "test_macros.h"

template <class Iter>
__host__ __device__ TEST_CONSTEXPR_CXX14 bool tests() {
using BoundedIter = cuda::std::__bounded_iter<Iter>;
using PointerTraits = cuda::std::pointer_traits<BoundedIter>;
using BasePointerTraits = cuda::std::pointer_traits<Iter>;
static_assert(cuda::std::is_same<typename PointerTraits::pointer, BoundedIter>::value, "");
static_assert(cuda::std::is_same<typename PointerTraits::element_type, typename BasePointerTraits::element_type>::value, "");
static_assert(cuda::std::is_same<typename PointerTraits::difference_type, typename BasePointerTraits::difference_type>::value, "");

{
int array[] = {0, 1, 2, 3, 4};
int* b = array + 0;
int* e = array + 5;
cuda::std::__bounded_iter<Iter> const iter1 = cuda::std::__make_bounded_iter(Iter(b), Iter(b), Iter(e));
cuda::std::__bounded_iter<Iter> const iter2 = cuda::std::__make_bounded_iter(Iter(e), Iter(b), Iter(e));
assert(cuda::std::__to_address(iter1) == b); // in-bounds iterator
assert(cuda::std::__to_address(iter2) == e); // out-of-bounds iterator
#if TEST_STD_VER > 17
assert(cuda::std::to_address(iter1) == b); // in-bounds iterator
assert(cuda::std::to_address(iter2) == e); // out-of-bounds iterator
#endif
}

return true;
}

int main(int, char**) {
tests<int*>();
#if TEST_STD_VER > 11
static_assert(tests<int*>(), "");
#endif

#if TEST_STD_VER > 17
tests<contiguous_iterator<int*> >();
static_assert(tests<contiguous_iterator<int*> >(), "");
#endif

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// 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
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

// template <class _Iterator>
// struct __bounded_iter;
//
// Nested types

#include <cuda/std/cstddef>
#include <cuda/std/iterator>
#include <cuda/std/type_traits>

#include "test_macros.h"

#if TEST_STD_VER > 17
struct Iterator {
struct value_type {};
using difference_type = int;
struct pointer {};
using reference = value_type&;
struct iterator_category : cuda::std::random_access_iterator_tag {};
using iterator_concept = cuda::std::contiguous_iterator_tag;
};

using BoundedIter1 = cuda::std::__bounded_iter<Iterator>;
static_assert(cuda::std::is_same<BoundedIter1::value_type, Iterator::value_type>::value, "");
static_assert(cuda::std::is_same<BoundedIter1::difference_type, Iterator::difference_type>::value, "");
static_assert(cuda::std::is_same<BoundedIter1::pointer, Iterator::pointer>::value, "");
static_assert(cuda::std::is_same<BoundedIter1::reference, Iterator::reference>::value, "");
static_assert(cuda::std::is_same<BoundedIter1::iterator_category, Iterator::iterator_category>::value, "");
static_assert(cuda::std::is_same<BoundedIter1::iterator_concept, Iterator::iterator_concept>::value, "");
#endif


using BoundedIter2 = cuda::std::__bounded_iter<int*>;
static_assert(cuda::std::is_same<BoundedIter2::value_type, int>::value, "");
static_assert(cuda::std::is_same<BoundedIter2::difference_type, cuda::std::ptrdiff_t>::value, "");
static_assert(cuda::std::is_same<BoundedIter2::pointer, int*>::value, "");
static_assert(cuda::std::is_same<BoundedIter2::reference, int&>::value, "");
static_assert(cuda::std::is_same<BoundedIter2::iterator_category, cuda::std::random_access_iterator_tag>::value, "");
#if TEST_STD_VER > 17
static_assert(cuda::std::is_same<BoundedIter2::iterator_concept, cuda::std::contiguous_iterator_tag>::value, "");
#endif

int main(int, char**) {
return 0;
}
Loading

0 comments on commit 83fe7eb

Please sign in to comment.