CUSP
Loading...
Searching...
No Matches
join_iterator.h
Go to the documentation of this file.
1/*
2 * Copyright 2008-2014 NVIDIA Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
21#pragma once
22
23#include <cusp/detail/config.h>
24
25#include <cusp/memory.h>
26
27#include <thrust/distance.h>
28#include <thrust/functional.h>
29
30#include <thrust/iterator/transform_iterator.h>
31
32namespace cusp
33{
34
36// Helper struct that does the actual work
37template <::cuda::std::size_t N, typename T, typename Indices = ::cuda::std::make_index_sequence<N>>
38struct make_tuple_of_impl;
39
40// Specialization that expands the index sequence into tuple parameters
41template <::cuda::std::size_t N, typename T, ::cuda::std::size_t... Is>
42struct make_tuple_of_impl<N, T, ::cuda::std::index_sequence<Is...>> {
43 // A helper that ignores its template argument and always yields T
44 template<::cuda::std::size_t>
45 using type_t = T;
46
47 // Expand the indices `Is...` to create a pack of N types T
48 using type = ::cuda::std::tuple<type_t<Is>...>;
49};
50
51// Final user-facing alias template
52template <::cuda::std::size_t N, typename T>
53using make_tuple_of = typename make_tuple_of_impl<N, T>::type;
54
55template<typename T, typename V, int SIZE>
56struct join_search
57{
58 template<typename SizesTuple, typename Tuple>
59 _CCCL_HOST_DEVICE
60 V operator()(const SizesTuple &t1, const Tuple& t2, const T i) const
61 {
62 return (i >= T(::cuda::std::get<SIZE-2>(t1))) ? V(::cuda::std::get<SIZE-1>(t2)[i]) : join_search<T,V,SIZE-1>()(t1,t2,i);
63 }
64};
65
66template<typename T, typename V>
67struct join_search<T,V,2>
68{
69 template<typename SizesTuple, typename Tuple>
70 _CCCL_HOST_DEVICE
71 V operator()(const SizesTuple &t1, const Tuple& t2, const T i) const
72 {
73 if (i >= T(::cuda::std::get<0>(t1)))
74 return ::cuda::std::get<1>(t2)[i];
75 else
76 return ::cuda::std::get<0>(t2)[i];
77 }
78};
143template <typename Tuple>
145{
146public:
147
149 typedef typename ::cuda::std::tuple_element<0,Tuple>::type Iterator1;
150 typedef typename ::cuda::std::iterator_traits<Iterator1>::value_type value_type;
151 typedef typename ::cuda::std::iterator_traits<Iterator1>::pointer pointer;
152 typedef typename ::cuda::std::iterator_traits<Iterator1>::reference reference;
153 typedef typename ::cuda::std::iterator_traits<Iterator1>::difference_type difference_type;
154 typedef typename ::cuda::std::iterator_traits<Iterator1>::difference_type size_type;
155 typedef typename thrust::iterator_system<Iterator1>::type space;
156 typedef typename cusp::iterator_system<space>::type memory_space;
157
158 const static size_t tuple_size = ::cuda::std::tuple_size<Tuple>::value;
159
160 // forward definition
161 struct join_select_functor;
162
163 typedef make_tuple_of<tuple_size-1,size_t> SizesTuple;
164 typedef typename ::cuda::std::tuple_element<tuple_size-1,Tuple>::type IndexIterator;
165 typedef thrust::transform_iterator<join_select_functor,IndexIterator> TransformIterator;
166
167 struct join_select_functor
168 {
169 SizesTuple t1;
170 Tuple t2;
171
172 _CCCL_HOST_DEVICE
173 join_select_functor(void) {}
174
175 _CCCL_HOST_DEVICE
176 join_select_functor(const SizesTuple& t1, const Tuple& t2)
177 : t1(t1), t2(t2) {}
178
179 _CCCL_HOST_DEVICE
180 value_type operator()(const difference_type& i)
181 {
182 return join_search<difference_type,value_type,tuple_size-1>()(t1,t2,i);
183 }
184 };
188 typedef TransformIterator iterator;
189
194 join_iterator(const SizesTuple& t1, const Tuple& t2) : t1(t1), t2(t2) {}
195
200 iterator begin(void) const
201 {
202 return TransformIterator(::cuda::std::get<tuple_size-1>(t2), join_select_functor(t1,t2));
203 }
204
209 iterator end(void) const
210 {
211 return begin() + ::cuda::std::get<tuple_size-2>(t1);
212 }
213
222 reference operator[](size_type n) const
223 {
224 return *(begin() + n);
225 }
226
227protected:
228
230 const SizesTuple& t1;
231 const Tuple& t2;
233};
234
236template <typename T1, typename T2, typename T3>
237typename join_iterator< ::cuda::std::tuple<T1,T2,T3> >::iterator
238make_join_iterator(const size_t s1, const size_t s2, const T1& t1, const T2& t2, const T3& t3)
239{
240 typedef ::cuda::std::tuple<T1,T2,T3> Tuple;
241 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2),
242 ::cuda::std::make_tuple(t1, t2-s1, t3)).begin();
243}
244
246template <typename T1, typename T2, typename T3, typename T4>
247typename join_iterator< ::cuda::std::tuple<T1,T2,T3,T4> >::iterator
248make_join_iterator(const size_t s1, const size_t s2, const size_t s3,
249 const T1& t1, const T2& t2, const T3& t3, const T4& t4)
250{
251 typedef ::cuda::std::tuple<T1,T2,T3,T4> Tuple;
252 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2, s1+s2+s3),
253 ::cuda::std::make_tuple(t1, t2-s1, t3-s1-s2, t4)).begin();
254}
255
257template <typename T1, typename T2, typename T3, typename T4, typename T5>
258typename join_iterator< ::cuda::std::tuple<T1,T2,T3,T4,T5> >::iterator
259make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4,
260 const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
261{
262 typedef ::cuda::std::tuple<T1,T2,T3,T4,T5> Tuple;
263 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4),
264 ::cuda::std::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5)).begin();
265}
266
268template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
269typename join_iterator< ::cuda::std::tuple<T1,T2,T3,T4,T5,T6> >::iterator
270make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5,
271 const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6)
272{
273 typedef ::cuda::std::tuple<T1,T2,T3,T4,T5,T6> Tuple;
274 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5),
275 ::cuda::std::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6)).begin();
276}
277
279template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
280typename join_iterator< ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7> >::iterator
281make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6,
282 const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7)
283{
284 typedef ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7> Tuple;
285 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6),
286 ::cuda::std::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7)).begin();
287}
288
290template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
291typename join_iterator< ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7,T8> >::iterator
292make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6, const size_t s7,
293 const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8)
294{
295 typedef ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7,T8> Tuple;
296 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6, s1+s2+s3+s4+s5+s6+s7),
297 ::cuda::std::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7-s1-s2-s3-s4-s5-s6, t8)).begin();
298}
299
301template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
302typename join_iterator< ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::iterator
303make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6, const size_t s7, const size_t s8,
304 const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9)
305{
306 typedef ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> Tuple;
307 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6, s1+s2+s3+s4+s5+s6+s7, s1+s2+s3+s4+s5+s6+s7+s8),
308 ::cuda::std::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7-s1-s2-s3-s4-s5-s6, t8-s1-s2-s3-s4-s5-s6-s7, t9)).begin();
309}
310
312template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
313typename join_iterator< ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> >::iterator
314make_join_iterator(const size_t s1, const size_t s2, const size_t s3, const size_t s4, const size_t s5, const size_t s6, const size_t s7, const size_t s8, const size_t s9,
315 const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10)
316{
317 typedef ::cuda::std::tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> Tuple;
318 return join_iterator<Tuple>(::cuda::std::make_tuple(s1, s1+s2, s1+s2+s3, s1+s2+s3+s4, s1+s2+s3+s4+s5, s1+s2+s3+s4+s5+s6, s1+s2+s3+s4+s5+s6+s7, s1+s2+s3+s4+s5+s6+s7+s8, s1+s2+s3+s4+s5+s6+s7+s8+s9),
319 ::cuda::std::make_tuple(t1, t2-s1, t3-s1-s2, t4-s1-s2-s3, t5-s1-s2-s3-s4, t6-s1-s2-s3-s4-s5, t7-s1-s2-s3-s4-s5-s6, t8-s1-s2-s3-s4-s5-s6-s7, t9-s1-s2-s3-s4-s5-s6-s7-s8, t10)).begin();
320}
321
325} // end namespace cusp
326
RandomAccessIterator for access to array entries from two concatenated iterators.
reference operator[](size_type n) const
Subscript access to the data contained in this iterator.
TransformIterator iterator
The type of the join_iterator.
iterator end(void) const
This method returns an iterator pointing to one element past the last of this joined sequence of perm...
join_iterator(const SizesTuple &t1, const Tuple &t2)
This constructor builds a join_iterator from a tuple of sizes and a tuple of iterators.
iterator begin(void) const
This method returns an iterator pointing to the beginning of this joined sequence of permuted entries...
join_iterator<::cuda::std::tuple< T1, T2, T3 > >::iterator make_join_iterator(const size_t s1, const size_t s2, const T1 &t1, const T2 &t2, const T3 &t3)
Convenience function to create a join_iterator from 2 ranges.