19#include <cuspatial/detail/functors.cuh>
23#include <cuspatial/traits.hpp>
25#include <thrust/binary_search.h>
26#include <thrust/detail/raw_reference_cast.h>
27#include <thrust/iterator/counting_iterator.h>
28#include <thrust/iterator/permutation_iterator.h>
29#include <thrust/iterator/transform_iterator.h>
30#include <thrust/iterator/transform_output_iterator.h>
31#include <thrust/iterator/zip_iterator.h>
32#include <thrust/tuple.h>
33#include <thrust/type_traits/is_contiguous_iterator.h>
44template <
typename IndexType,
typename UnaryFunction>
45inline CUSPATIAL_HOST_DEVICE
auto make_counting_transform_iterator(IndexType start, UnaryFunction f)
47 return thrust::make_transform_iterator(thrust::make_counting_iterator(start), f);
54template <
typename T,
typename VectorType = vec_2d<T>>
56 __device__ VectorType operator()(thrust::tuple<T, T>
const& pos)
58 return VectorType{thrust::get<0>(pos), thrust::get<1>(pos)};
66template <
typename T,
typename VectorType = vec_2d<T>>
68 __device__ thrust::tuple<T, T> operator()(VectorType
const& xy)
70 return thrust::make_tuple(xy.x, xy.y);
78template <
typename T,
typename Box = box<T>>
80 __device__ thrust::tuple<T, T, T, T> operator()(Box
const&
box)
82 return thrust::make_tuple(
box.v1.x,
box.v1.y,
box.v2.x,
box.v2.y);
90template <
typename T,
typename Vertex = vec_2d<T>>
92 __device__ box<T, Vertex> operator()(thrust::tuple<Vertex, Vertex> pair)
94 auto v1 = thrust::get<0>(pair);
95 auto v2 = thrust::get<1>(pair);
110template <
typename Iter,
typename Enable =
void>
112 using element_t =
typename std::iterator_traits<Iter>::value_type;
113 using value_type = vec_2d<element_t>;
117 CUSPATIAL_HOST_DEVICE value_type operator()(std::size_t i)
119 return vec_2d<element_t>{it[2 * i], it[2 * i + 1]};
132template <
typename Iter>
134 typename std::enable_if_t<thrust::is_contiguous_iterator_v<Iter>>> {
135 using element_t =
typename std::iterator_traits<Iter>::value_type;
136 using value_type = vec_2d<element_t>;
138 element_t
const* ptr;
143 "Misaligned interleaved data.");
146 CUSPATIAL_HOST_DEVICE value_type operator()(std::size_t i)
149 static_cast<element_t const*
>(__builtin_assume_aligned(ptr + 2 * i, 2 *
sizeof(element_t)));
150 return vec_2d<element_t>{aligned[0], aligned[1]};
160 auto __device__ operator()(std::size_t i) {
return i * stride; }
167template <
class IndexT,
class GeometryIter>
169 GeometryIter geometry_begin;
170 GeometryIter geometry_end;
173 : geometry_begin(begin), geometry_end(end)
177 CUSPATIAL_HOST_DEVICE
auto operator()(IndexT idx)
179 return thrust::distance(geometry_begin,
180 thrust::upper_bound(thrust::seq, geometry_begin, geometry_end, idx));
211template <
typename FirstIter,
typename SecondIter>
214 using T =
typename std::iterator_traits<FirstIter>::value_type;
215 static_assert(is_same<T, iterator_value_type<SecondIter>>(),
"Iterator value_type mismatch");
217 auto zipped = thrust::make_zip_iterator(first, second);
230template <
typename Iter>
257template <
typename FirstIter,
typename SecondIter>
260 using T =
typename std::iterator_traits<FirstIter>::value_type;
261 auto zipped_out = thrust::make_zip_iterator(thrust::make_tuple(first, second));
273template <
typename Iter>
276 using T =
typename std::iterator_traits<Iter>::value_type;
278 auto even_positions = thrust::make_permutation_iterator(
279 d_points_begin, detail::make_counting_transform_iterator(0, fixed_stride_2_functor));
280 auto odd_positions = thrust::make_permutation_iterator(
281 thrust::next(d_points_begin),
282 detail::make_counting_transform_iterator(0, fixed_stride_2_functor));
283 auto zipped_outputs =
284 thrust::make_zip_iterator(thrust::make_tuple(even_positions, odd_positions));
307template <
typename FirstIter,
typename SecondIter>
310 using Vertex =
typename cuspatial::iterator_value_type<FirstIter>;
311 using T =
typename Vertex::value_type;
313 static_assert(is_same<Vertex, cuspatial::iterator_value_type<SecondIter>>(),
314 "Iterator value_type mismatch");
316 auto zipped = thrust::make_zip_iterator(first, second);
347template <
typename MinXIter,
typename MinYIter,
typename MaxXIter,
typename MaxYIter>
350 using T =
typename std::iterator_traits<MinXIter>::value_type;
351 auto zipped_out = thrust::make_zip_iterator(min_x, min_y, max_x, max_y);
379template <
typename IndexT,
typename GeometryIter>
382 return detail::make_counting_transform_iterator(
414template <
typename IndexT,
typename GeometryIter,
typename PartIter>
416 GeometryIter geometry_offsets_end,
417 PartIter part_offsets_begin)
419 auto first_part_offsets_begin =
420 thrust::make_permutation_iterator(part_offsets_begin, geometry_offsets_begin);
422 return make_geometry_id_iterator<IndexT>(
423 first_part_offsets_begin,
424 thrust::next(first_part_offsets_begin,
425 std::distance(geometry_offsets_begin, geometry_offsets_end)));
428template <
typename OffsetIterator>
429auto make_count_iterator_from_offset_iterator(OffsetIterator it)
431 auto zipped_offsets_it = thrust::make_zip_iterator(it, thrust::next(it));
432 return thrust::make_transform_iterator(zipped_offsets_it, detail::offset_pair_to_count_functor{});
A generic axis-aligned box type.
#define CUSPATIAL_EXPECTS(cond, reason)
Macro for checking (pre-)conditions that throws an exception when a condition is violated.
auto make_box_iterator(FirstIter first, SecondIter second)
Create an iterator to box data from two input iterators of vec_2d.
auto make_geometry_id_iterator(GeometryIter offsets_begin, GeometryIter offsets_end)
Create an input iterator that generates zero-based sequential geometry IDs for each element based on ...
auto make_vec_2d_iterator(FirstIter first, SecondIter second)
Create an iterator to vec_2d data from two input iterators.
auto make_vec_2d_output_iterator(FirstIter first, SecondIter second)
Create an output iterator to vec_2d data from two output iterators.
auto make_box_output_iterator(MinXIter min_x, MinYIter min_y, MaxXIter max_x, MaxYIter max_y)
Create an output iterator to box data from multiple output iterators.