/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/ck/utility/sequence.hpp Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/ck/utility/sequence.hpp Source File#

Composable Kernel: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/ck/utility/sequence.hpp Source File
sequence.hpp
Go to the documentation of this file.
1 // Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
2 // SPDX-License-Identifier: MIT
3 
4 #pragma once
5 
6 #if !defined(__HIPCC_RTC__) || !defined(CK_CODE_GEN_RTC)
7 #include <ostream>
8 #endif
9 
11 #include "ck/utility/type.hpp"
13 #include "ck/utility/math.hpp"
14 
15 namespace ck {
16 
17 template <index_t, index_t, index_t>
18 struct static_for;
19 
20 template <index_t...>
21 struct Sequence;
22 
23 template <typename Seq, index_t I>
24 struct sequence_split;
25 
26 template <typename>
27 struct sequence_reverse;
28 
29 template <typename>
30 struct sequence_map_inverse;
31 
32 template <typename>
33 struct is_valid_sequence_map;
34 
35 template <index_t I, index_t... Is>
36 __host__ __device__ constexpr auto sequence_pop_front(Sequence<I, Is...>);
37 
38 template <typename Seq>
39 __host__ __device__ constexpr auto sequence_pop_back(Seq);
40 
41 template <index_t... Is>
42 struct Sequence
43 {
44  using Type = Sequence;
45  using data_type = index_t;
46 
47  static constexpr index_t mSize = sizeof...(Is);
48 
49  __host__ __device__ static constexpr auto Size() { return Number<mSize>{}; }
50 
51  __host__ __device__ static constexpr auto GetSize() { return Size(); }
52 
53  __host__ __device__ static constexpr index_t At(index_t I)
54  {
55  // the last dummy element is to prevent compiler complain about empty array, when mSize = 0
56  const index_t mData[mSize + 1] = {Is..., 0};
57  return mData[I];
58  }
59 
60  template <index_t I>
61  __host__ __device__ static constexpr auto At(Number<I>)
62  {
63  static_assert(I < mSize, "wrong! I too large");
64 
65  return Number<At(I)>{};
66  }
67 
68  template <index_t I>
69  __host__ __device__ static constexpr auto Get(Number<I>)
70  {
71  return At(Number<I>{});
72  }
73 
74  template <typename I>
75  __host__ __device__ constexpr auto operator[](I i) const
76  {
77  return At(i);
78  }
79 
80  template <index_t... IRs>
81  __host__ __device__ static constexpr auto ReorderGivenNew2Old(Sequence<IRs...> /*new2old*/)
82  {
83  static_assert(sizeof...(Is) == sizeof...(IRs),
84  "wrong! reorder map should have the same size as Sequence to be rerodered");
85 
86  static_assert(is_valid_sequence_map<Sequence<IRs...>>::value, "wrong! invalid reorder map");
87 
88  return Sequence<Type::At(Number<IRs>{})...>{};
89  }
90 
91  // MapOld2New is Sequence<...>
92  template <typename MapOld2New>
93  __host__ __device__ static constexpr auto ReorderGivenOld2New(MapOld2New)
94  {
95  static_assert(MapOld2New::Size() == Size(),
96  "wrong! reorder map should have the same size as Sequence to be rerodered");
97 
98  static_assert(is_valid_sequence_map<MapOld2New>::value, "wrong! invalid reorder map");
99 
101  }
102 
103  __host__ __device__ static constexpr auto Reverse()
104  {
105  return typename sequence_reverse<Type>::type{};
106  }
107 
108  __host__ __device__ static constexpr auto Front()
109  {
110  static_assert(mSize > 0, "wrong!");
111  return At(Number<0>{});
112  }
113 
114  __host__ __device__ static constexpr auto Back()
115  {
116  static_assert(mSize > 0, "wrong!");
117  return At(Number<mSize - 1>{});
118  }
119 
120  __host__ __device__ static constexpr auto PopFront() { return sequence_pop_front(Type{}); }
121 
122  __host__ __device__ static constexpr auto PopBack() { return sequence_pop_back(Type{}); }
123 
124  template <index_t... Xs>
125  __host__ __device__ static constexpr auto PushFront(Sequence<Xs...>)
126  {
127  return Sequence<Xs..., Is...>{};
128  }
129 
130  template <index_t... Xs>
131  __host__ __device__ static constexpr auto PushFront(Number<Xs>...)
132  {
133  return Sequence<Xs..., Is...>{};
134  }
135 
136  template <index_t... Xs>
137  __host__ __device__ static constexpr auto PushBack(Sequence<Xs...>)
138  {
139  return Sequence<Is..., Xs...>{};
140  }
141 
142  template <index_t... Xs>
143  __host__ __device__ static constexpr auto PushBack(Number<Xs>...)
144  {
145  return Sequence<Is..., Xs...>{};
146  }
147 
148  template <index_t... Ns>
149  __host__ __device__ static constexpr auto Extract(Number<Ns>...)
150  {
151  return Sequence<Type::At(Number<Ns>{})...>{};
152  }
153 
154  template <index_t... Ns>
155  __host__ __device__ static constexpr auto Extract(Sequence<Ns...>)
156  {
157  return Sequence<Type::At(Number<Ns>{})...>{};
158  }
159 
160  template <index_t I, index_t X>
161  __host__ __device__ static constexpr auto Modify(Number<I>, Number<X>)
162  {
163  static_assert(I < Size(), "wrong!");
164 
165  using seq_split = sequence_split<Type, I>;
166  constexpr auto seq_left = typename seq_split::left_type{};
167  constexpr auto seq_right = typename seq_split::right_type{}.PopFront();
168 
169  return seq_left.PushBack(Number<X>{}).PushBack(seq_right);
170  }
171 
172  template <typename F>
173  __host__ __device__ static constexpr auto Transform(F f)
174  {
175  return Sequence<f(Is)...>{};
176  }
177 
178  __host__ __device__ static void Print()
179  {
180  printf("{");
181  printf("size %d, ", index_t{Size()});
182  static_for<0, Size(), 1>{}([&](auto i) { printf("%d ", At(i).value); });
183  printf("}");
184  }
185 };
186 
187 namespace impl {
188 template <typename T, T... Ints>
190 
191 template <index_t... Ints>
192 struct __integer_sequence<index_t, Ints...>
193 {
194  using seq_type = Sequence<Ints...>;
195 };
196 } // namespace impl
197 
198 template <index_t N>
200  typename __make_integer_seq<impl::__integer_sequence, index_t, N>::seq_type;
201 
202 // merge sequence
203 template <typename Seq, typename... Seqs>
205 {
206  using type = typename sequence_merge<Seq, typename sequence_merge<Seqs...>::type>::type;
207 };
208 
209 template <index_t... Xs, index_t... Ys>
210 struct sequence_merge<Sequence<Xs...>, Sequence<Ys...>>
211 {
212  using type = Sequence<Xs..., Ys...>;
213 };
214 
215 template <typename Seq>
216 struct sequence_merge<Seq>
217 {
218  using type = Seq;
219 };
220 
221 // generate sequence
222 template <index_t NSize, typename F>
224 {
225  template <index_t IBegin, index_t NRemain, typename G>
227  {
228  static constexpr index_t NRemainLeft = NRemain / 2;
229  static constexpr index_t NRemainRight = NRemain - NRemainLeft;
230  static constexpr index_t IMiddle = IBegin + NRemainLeft;
231 
232  using type = typename sequence_merge<
235  };
236 
237  template <index_t I, typename G>
238  struct sequence_gen_impl<I, 1, G>
239  {
240  static constexpr index_t Is = G{}(Number<I>{});
242  };
243 
244  template <index_t I, typename G>
245  struct sequence_gen_impl<I, 0, G>
246  {
247  using type = Sequence<>;
248  };
249 
251 };
252 
253 // arithmetic sequence
254 template <index_t IBegin, index_t IEnd, index_t Increment>
256 {
257  struct F
258  {
259  __host__ __device__ constexpr index_t operator()(index_t i) const
260  {
261  return i * Increment + IBegin;
262  }
263  };
264 
265  using type0 = typename sequence_gen<(IEnd - IBegin) / Increment, F>::type;
266  using type1 = Sequence<>;
267 
268  static constexpr bool kHasContent =
269  (Increment > 0 && IBegin < IEnd) || (Increment < 0 && IBegin > IEnd);
270 
272 };
273 
274 template <index_t IEnd>
275 struct arithmetic_sequence_gen<0, IEnd, 1>
276 {
277  template <typename T, T... Ints>
278  struct WrapSequence
279  {
280  using type = Sequence<Ints...>;
281  };
282  // https://reviews.llvm.org/D13786
283  using type = typename __make_integer_seq<WrapSequence, index_t, IEnd>::type;
284 };
285 
286 // uniform sequence
287 template <index_t NSize, index_t I>
289 {
290  struct F
291  {
292  __host__ __device__ constexpr index_t operator()(index_t) const { return I; }
293  };
294 
296 };
297 
298 // reverse inclusive scan (with init) sequence
299 template <typename, typename, index_t>
301 
302 template <index_t I, index_t... Is, typename Reduce, index_t Init>
303 struct sequence_reverse_inclusive_scan<Sequence<I, Is...>, Reduce, Init>
304 {
305  using old_scan = typename sequence_reverse_inclusive_scan<Sequence<Is...>, Reduce, Init>::type;
306 
307  static constexpr index_t new_reduce = Reduce{}(I, old_scan{}.Front());
308 
310 };
311 
312 template <index_t I, typename Reduce, index_t Init>
314 {
315  using type = Sequence<Reduce{}(I, Init)>;
316 };
317 
318 template <typename Reduce, index_t Init>
320 {
321  using type = Sequence<>;
322 };
323 
324 // split sequence
325 template <typename Seq, index_t I>
327 {
328  static constexpr index_t NSize = Seq{}.Size();
329 
332 
333  using left_type = decltype(Seq::Extract(range0{}));
334  using right_type = decltype(Seq::Extract(range1{}));
335 };
336 
337 // reverse sequence
338 template <typename Seq>
340 {
341  static constexpr index_t NSize = Seq{}.Size();
342 
343  using seq_split = sequence_split<Seq, NSize / 2>;
344  using type = typename sequence_merge<
347 };
348 
349 template <index_t I>
351 {
352  using type = Sequence<I>;
353 };
354 
355 template <index_t I0, index_t I1>
356 struct sequence_reverse<Sequence<I0, I1>>
357 {
359 };
360 
361 #if 1
362 template <typename Reduce, typename Seq, typename... Seqs>
364 {
365  using type = typename sequence_reduce<Reduce,
366  Seq,
367  typename sequence_reduce<Reduce, Seqs...>::type>::type;
368 };
369 
370 template <typename Reduce, index_t... Xs, index_t... Ys>
371 struct sequence_reduce<Reduce, Sequence<Xs...>, Sequence<Ys...>>
372 {
373  using type = Sequence<Reduce{}(Xs, Ys)...>;
374 };
375 
376 template <typename Reduce, typename Seq>
377 struct sequence_reduce<Reduce, Seq>
378 {
379  using type = Seq;
380 };
381 #endif
382 
383 // Implement sequence_sort and sequence_unique_sort using constexpr functions (C++17)
384 namespace sort_impl {
385 
386 // Temporary arrays to hold values during operations with capacity N and mutable size.
387 template <index_t N>
389 {
390  index_t values[N > 0 ? N : 1];
391  index_t ids[N > 0 ? N : 1];
393 };
394 
395 template <index_t... Is>
397 {
398  constexpr index_t N = sizeof...(Is);
399  IndexedValueArray<N> result = {{Is...}, {}, N};
400  for(index_t i = 0; i < N; ++i)
401  {
402  result.ids[i] = i;
403  }
404  return result;
405 }
406 
407 enum class SortField
408 {
409  Values,
410  Ids
411 };
412 
413 // Perform an insertion sort on an IndexedValueArray.
414 template <index_t N, typename Compare>
415 constexpr auto insertion_sort(IndexedValueArray<N> arr, Compare comp)
416 {
417  for(index_t i = 1; i < arr.size; ++i)
418  {
419  index_t key_val = arr.values[i];
420  index_t key_id = arr.ids[i];
421  index_t j = i - 1;
422  while(j >= 0 && comp(key_val, arr.values[j]))
423  {
424  arr.values[j + 1] = arr.values[j];
425  arr.ids[j + 1] = arr.ids[j];
426  --j;
427  }
428  arr.values[j + 1] = key_val;
429  arr.ids[j + 1] = key_id;
430  }
431  return arr;
432 }
433 
434 // Remove duplicates from a sorted IndexedValueArray.
435 template <index_t N, typename Equal>
436 constexpr auto unique(const IndexedValueArray<N>& sorted, Equal eq)
437 {
438  IndexedValueArray<N> result{};
439  if constexpr(N == 0)
440  {
441  return result;
442  }
443  result.size = 1;
444  result.values[0] = sorted.values[0];
445  result.ids[0] = sorted.ids[0];
446  for(index_t i = 1; i < sorted.size; ++i)
447  {
448  if(!eq(sorted.values[i], sorted.values[i - 1]))
449  {
450  result.values[result.size] = sorted.values[i];
451  result.ids[result.size] = sorted.ids[i];
452  ++result.size;
453  }
454  }
455  return result;
456 }
457 
458 // Compute sorted (and optionally unique) IndexedValueArray from input Sequence.
459 template <bool Unique, typename Compare, typename Equal, index_t... Is>
460 constexpr auto compute_sorted(Sequence<Is...> seq, Compare comp, Equal eq)
461 {
462  auto sorted = insertion_sort(make_indexed_value_array(seq), comp);
463  return Unique ? unique(sorted, eq) : sorted;
464 }
465 
466 // Cache the sorted results to avoid recomputation.
467 template <bool Unique, typename Seq, typename Compare, typename Equal>
469 {
470  static constexpr auto data = compute_sorted<Unique>(Seq{}, Compare{}, Equal{});
471 };
472 
473 // Build sorted value and ID sequences from cached sorted data
474 template <SortField Field, bool Unique, typename Seq, typename Compare, typename Equal, index_t I>
476 {
477  constexpr auto& data = SortedCache<Unique, Seq, Compare, Equal>::data;
478  return (Field == SortField::Values) ? data.values[I] : data.ids[I];
479 }
480 
481 template <bool Unique, typename Seq, typename Compare, typename Equal, typename IndexSeq>
483 
484 template <bool Unique, typename Seq, typename Compare, typename Equal, index_t... Is>
485 struct SortedSequences<Unique, Seq, Compare, Equal, Sequence<Is...>>
486 {
487  using values_type =
489  using ids_type =
491 };
492 
493 template <bool Unique, typename Seq, typename Compare, typename Equal>
495  Unique,
496  Seq,
497  Compare,
498  Equal,
500  type>;
501 
502 using Equal = ck::math::equal<index_t>;
503 
504 } // namespace sort_impl
505 
506 template <typename Values, typename Compare>
508 {
510  using type = typename sorted_seqs::values_type;
511  using sorted2unsorted_map = typename sorted_seqs::ids_type;
512 };
513 
514 template <typename Values, typename Less, typename Equal>
516 {
518  using type = typename sorted_seqs::values_type;
519  using sorted2unsorted_map = typename sorted_seqs::ids_type;
520 };
521 
522 template <typename SeqMap>
523 struct is_valid_sequence_map : is_same<typename arithmetic_sequence_gen<0, SeqMap::Size(), 1>::type,
524  typename sequence_sort<SeqMap, math::less<index_t>>::type>
525 {
526 };
527 
528 template <typename SeqMap>
530 {
531  template <typename X2Y, typename WorkingY2X, index_t XBegin, index_t XRemain>
533  {
534  static constexpr auto new_y2x =
535  WorkingY2X::Modify(X2Y::At(Number<XBegin>{}), Number<XBegin>{});
536 
537  using type =
538  typename sequence_map_inverse_impl<X2Y, decltype(new_y2x), XBegin + 1, XRemain - 1>::
539  type;
540  };
541 
542  template <typename X2Y, typename WorkingY2X, index_t XBegin>
543  struct sequence_map_inverse_impl<X2Y, WorkingY2X, XBegin, 0>
544  {
545  using type = WorkingY2X;
546  };
547 
548  using type =
549  typename sequence_map_inverse_impl<SeqMap,
550  typename uniform_sequence_gen<SeqMap::Size(), 0>::type,
551  0,
552  SeqMap::Size()>::type;
553 };
554 
555 template <index_t... Xs, index_t... Ys>
556 __host__ __device__ constexpr bool operator==(Sequence<Xs...>, Sequence<Ys...>)
557 {
558  return ((Xs == Ys) && ...);
559 }
560 
561 template <index_t... Xs, index_t... Ys>
562 __host__ __device__ constexpr auto operator+(Sequence<Xs...>, Sequence<Ys...>)
563 {
564  static_assert(sizeof...(Xs) == sizeof...(Ys), "wrong! inconsistent size");
565 
566  return Sequence<(Xs + Ys)...>{};
567 }
568 
569 template <index_t... Xs, index_t... Ys>
570 __host__ __device__ constexpr auto operator-(Sequence<Xs...>, Sequence<Ys...>)
571 {
572  static_assert(sizeof...(Xs) == sizeof...(Ys), "wrong! inconsistent size");
573 
574  return Sequence<(Xs - Ys)...>{};
575 }
576 
577 template <index_t... Xs, index_t... Ys>
578 __host__ __device__ constexpr auto operator*(Sequence<Xs...>, Sequence<Ys...>)
579 {
580  static_assert(sizeof...(Xs) == sizeof...(Ys), "wrong! inconsistent size");
581 
582  return Sequence<(Xs * Ys)...>{};
583 }
584 
585 template <index_t... Xs, index_t... Ys>
586 __host__ __device__ constexpr auto operator/(Sequence<Xs...>, Sequence<Ys...>)
587 {
588  static_assert(sizeof...(Xs) == sizeof...(Ys), "wrong! inconsistent size");
589 
590  return Sequence<(Xs / Ys)...>{};
591 }
592 
593 template <index_t... Xs, index_t... Ys>
594 __host__ __device__ constexpr auto operator%(Sequence<Xs...>, Sequence<Ys...>)
595 {
596  static_assert(sizeof...(Xs) == sizeof...(Ys), "wrong! inconsistent size");
597 
598  return Sequence<(Xs % Ys)...>{};
599 }
600 
601 template <index_t... Xs, index_t Y>
602 __host__ __device__ constexpr auto operator+(Sequence<Xs...>, Number<Y>)
603 {
604  return Sequence<(Xs + Y)...>{};
605 }
606 
607 template <index_t... Xs, index_t Y>
608 __host__ __device__ constexpr auto operator-(Sequence<Xs...>, Number<Y>)
609 {
610  return Sequence<(Xs - Y)...>{};
611 }
612 
613 template <index_t... Xs, index_t Y>
614 __host__ __device__ constexpr auto operator*(Sequence<Xs...>, Number<Y>)
615 {
616  return Sequence<(Xs * Y)...>{};
617 }
618 
619 template <index_t... Xs, index_t Y>
620 __host__ __device__ constexpr auto operator/(Sequence<Xs...>, Number<Y>)
621 {
622  return Sequence<(Xs / Y)...>{};
623 }
624 
625 template <index_t... Xs, index_t Y>
626 __host__ __device__ constexpr auto operator%(Sequence<Xs...>, Number<Y>)
627 {
628  return Sequence<(Xs % Y)...>{};
629 }
630 
631 template <index_t Y, index_t... Xs>
632 __host__ __device__ constexpr auto operator+(Number<Y>, Sequence<Xs...>)
633 {
634  return Sequence<(Y + Xs)...>{};
635 }
636 
637 template <index_t Y, index_t... Xs>
638 __host__ __device__ constexpr auto operator-(Number<Y>, Sequence<Xs...>)
639 {
640  return Sequence<(Y - Xs)...>{};
641 }
642 
643 template <index_t Y, index_t... Xs>
644 __host__ __device__ constexpr auto operator*(Number<Y>, Sequence<Xs...>)
645 {
646  return Sequence<(Y * Xs)...>{};
647 }
648 
649 template <index_t Y, index_t... Xs>
650 __host__ __device__ constexpr auto operator/(Number<Y>, Sequence<Xs...>)
651 {
652  return Sequence<(Y / Xs)...>{};
653 }
654 
655 template <index_t Y, index_t... Xs>
656 __host__ __device__ constexpr auto operator%(Number<Y>, Sequence<Xs...>)
657 {
658  return Sequence<(Y % Xs)...>{};
659 }
660 
661 template <index_t I, index_t... Is>
662 __host__ __device__ constexpr auto sequence_pop_front(Sequence<I, Is...>)
663 {
664  return Sequence<Is...>{};
665 }
666 
667 template <typename Seq>
668 __host__ __device__ constexpr auto sequence_pop_back(Seq)
669 {
670  static_assert(Seq::Size() > 0, "wrong! cannot pop an empty Sequence!");
671  return sequence_pop_front(Seq::Reverse()).Reverse();
672 }
673 
674 template <typename... Seqs>
675 __host__ __device__ constexpr auto merge_sequences(Seqs...)
676 {
677  return typename sequence_merge<Seqs...>::type{};
678 }
679 
680 template <typename F, index_t... Xs>
681 __host__ __device__ constexpr auto transform_sequences(F f, Sequence<Xs...>)
682 {
683  return Sequence<f(Xs)...>{};
684 }
685 
686 template <typename F, index_t... Xs, index_t... Ys>
687 __host__ __device__ constexpr auto transform_sequences(F f, Sequence<Xs...>, Sequence<Ys...>)
688 {
689  static_assert(Sequence<Xs...>::mSize == Sequence<Ys...>::mSize, "Dim not the same");
690 
691  return Sequence<f(Xs, Ys)...>{};
692 }
693 
694 template <typename F, index_t... Xs, index_t... Ys, index_t... Zs>
695 __host__ __device__ constexpr auto
697 {
700  "Dim not the same");
701 
702  return Sequence<f(Xs, Ys, Zs)...>{};
703 }
704 
705 template <typename Seq, typename Reduce, index_t Init>
706 __host__ __device__ constexpr auto reverse_inclusive_scan_sequence(Seq, Reduce, Number<Init>)
707 {
709 }
710 
711 template <typename Seq, typename Reduce, index_t Init>
712 __host__ __device__ constexpr auto reverse_exclusive_scan_sequence(Seq, Reduce, Number<Init>)
713 {
714  return reverse_inclusive_scan_sequence(Seq::PopFront(), Reduce{}, Number<Init>{})
715  .PushBack(Number<Init>{});
716 }
717 
718 template <typename Seq, typename Reduce, index_t Init>
719 __host__ __device__ constexpr auto inclusive_scan_sequence(Seq, Reduce, Number<Init>)
720 {
721  return reverse_inclusive_scan_sequence(Seq{}.Reverse(), Reduce{}, Number<Init>{}).Reverse();
722 }
723 
724 template <typename Seq, index_t... Is>
725 __host__ __device__ constexpr auto pick_sequence_elements_by_ids(Seq, Sequence<Is...> /* ids */)
726 {
727  return Sequence<Seq::At(Number<Is>{})...>{};
728 }
729 
730 #if 1
731 namespace detail {
732 template <typename WorkSeq, typename RemainSeq, typename RemainMask>
734 {
735  using new_work_seq = typename conditional<RemainMask::Front(),
736  decltype(WorkSeq::PushBack(RemainSeq::Front())),
737  WorkSeq>::type;
738 
739  using type =
741  decltype(RemainSeq::PopFront()),
742  decltype(RemainMask::PopFront())>::type;
743 };
744 
745 template <typename WorkSeq>
747 {
748  using type = WorkSeq;
749 };
750 
751 } // namespace detail
752 
753 template <typename Seq, typename Mask>
754 __host__ __device__ constexpr auto pick_sequence_elements_by_mask(Seq, Mask)
755 {
756  static_assert(Seq::Size() == Mask::Size(), "wrong!");
757 
758  return typename detail::pick_sequence_elements_by_mask_impl<Sequence<>, Seq, Mask>::type{};
759 }
760 
761 namespace detail {
762 template <typename WorkSeq, typename RemainValues, typename RemainIds>
764 {
765  using new_work_seq = decltype(WorkSeq::Modify(RemainIds::Front(), RemainValues::Front()));
766 
767  using type =
769  decltype(RemainValues::PopFront()),
770  decltype(RemainIds::PopFront())>::type;
771 };
772 
773 template <typename WorkSeq>
775 {
776  using type = WorkSeq;
777 };
778 } // namespace detail
779 
780 template <typename Seq, typename Values, typename Ids>
781 __host__ __device__ constexpr auto modify_sequence_elements_by_ids(Seq, Values, Ids)
782 {
783  static_assert(Values::Size() == Ids::Size() && Seq::Size() >= Values::Size(), "wrong!");
784 
786 }
787 #endif
788 
789 template <typename Seq, typename Reduce, index_t Init>
790 __host__ __device__ constexpr index_t
791 reduce_on_sequence(Seq, Reduce f, Number<Init> /*initial_value*/)
792 {
793  index_t result = Init;
794 
795  for(index_t i = 0; i < Seq::Size(); ++i)
796  {
797  result = f(result, Seq::At(i));
798  }
799 
800  return result;
801 }
802 
803 // TODO: a generic any_of for any container
804 template <typename Seq, typename F>
805 __host__ __device__ constexpr bool sequence_any_of(Seq, F f)
806 {
807  bool flag = false;
808 
809  for(index_t i = 0; i < Seq::Size(); ++i)
810  {
811  flag = flag || f(Seq::At(i));
812  }
813 
814  return flag;
815 }
816 
817 // TODO: a generic all_of for any container
818 template <typename Seq, typename F>
819 __host__ __device__ constexpr bool sequence_all_of(Seq, F f)
820 {
821  bool flag = true;
822 
823  for(index_t i = 0; i < Seq::Size(); ++i)
824  {
825  flag = flag && f(Seq::At(i));
826  }
827 
828  return flag;
829 }
830 
831 template <typename Sx, typename Sy>
833 
834 template <index_t NSize, index_t I>
836 
837 } // namespace ck
838 
839 #if !defined(__HIPCC_RTC__) || !defined(CK_CODE_GEN_RTC)
840 template <ck::index_t... Is>
841 std::ostream& operator<<(std::ostream& os, const ck::Sequence<Is...>)
842 {
843  using S = ck::Sequence<Is...>;
844  os << "{";
845  ck::static_for<0, S::Size() - ck::Number<1>{}, 1>{}(
846  [&](auto i) { os << S::At(i).value << ", "; });
847  os << S::At(S::Size() - ck::Number<1>{}).value << "}";
848  return os;
849 }
850 #endif
constexpr auto compute_sorted(Sequence< Is... > seq, Compare comp, Equal eq)
Definition: sequence.hpp:460
SortField
Definition: sequence.hpp:408
ck::math::equal< index_t > Equal
Definition: sequence.hpp:502
constexpr auto unique(const IndexedValueArray< N > &sorted, Equal eq)
Definition: sequence.hpp:436
constexpr index_t get_sorted_field()
Definition: sequence.hpp:475
constexpr auto make_indexed_value_array(Sequence< Is... >)
Definition: sequence.hpp:396
constexpr auto insertion_sort(IndexedValueArray< N > arr, Compare comp)
Definition: sequence.hpp:415
Definition: ck.hpp:270
typename __make_integer_seq< impl::__integer_sequence, index_t, N >::seq_type make_index_sequence
Definition: sequence.hpp:200
__host__ constexpr __device__ auto operator+(const MultiIndex< NSize > &a, const T &b)
Definition: array_multi_index.hpp:50
typename uniform_sequence_gen< NSize, I >::type uniform_sequence_gen_t
Definition: sequence.hpp:835
__host__ constexpr __device__ auto operator/(integral_constant< TX, X >, integral_constant< TY, Y >)
Definition: integral_constant.hpp:46
__host__ constexpr __device__ index_t reduce_on_sequence(Seq, Reduce f, Number< Init >)
Definition: sequence.hpp:791
__host__ constexpr __device__ auto reverse_exclusive_scan_sequence(Seq, Reduce, Number< Init >)
Definition: sequence.hpp:712
__host__ constexpr __device__ auto modify_sequence_elements_by_ids(Seq, Values, Ids)
Definition: sequence.hpp:781
__host__ constexpr __device__ auto merge_sequences(Seqs...)
Definition: sequence.hpp:675
__host__ constexpr __device__ auto pick_sequence_elements_by_mask(Seq, Mask)
Definition: sequence.hpp:754
__host__ constexpr __device__ auto reverse_inclusive_scan_sequence(Seq, Reduce, Number< Init >)
Definition: sequence.hpp:706
__host__ constexpr __device__ auto operator-(const MultiIndex< NSize > &a, const T &b)
Definition: array_multi_index.hpp:60
__host__ constexpr __device__ bool sequence_any_of(Seq, F f)
Definition: sequence.hpp:805
__host__ constexpr __device__ bool operator==(Sequence< Xs... >, Sequence< Ys... >)
Definition: sequence.hpp:556
__host__ constexpr __device__ auto sequence_pop_back(Seq)
Definition: sequence.hpp:668
__host__ constexpr __device__ auto sequence_pop_front(Sequence< I, Is... >)
Definition: sequence.hpp:662
typename sequence_merge< Sx, Sy >::type sequence_merge_t
Definition: sequence.hpp:832
__host__ constexpr __device__ bool sequence_all_of(Seq, F f)
Definition: sequence.hpp:819
__host__ constexpr __device__ auto transform_sequences(F f, Sequence< Xs... >)
Definition: sequence.hpp:681
__host__ constexpr __device__ auto operator*(const MultiIndex< NSize > &a, const T &b)
Definition: array_multi_index.hpp:70
int32_t index_t
Definition: ck.hpp:301
__host__ constexpr __device__ auto pick_sequence_elements_by_ids(Seq, Sequence< Is... >)
Definition: sequence.hpp:725
__host__ constexpr __device__ auto inclusive_scan_sequence(Seq, Reduce, Number< Init >)
Definition: sequence.hpp:719
__host__ constexpr __device__ auto operator%(integral_constant< TX, X >, integral_constant< TY, Y >)
Definition: integral_constant.hpp:53
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1697
Definition: sequence.hpp:43
__host__ static constexpr __device__ auto PushBack(Sequence< Xs... >)
Definition: sequence.hpp:137
__host__ static constexpr __device__ auto GetSize()
Definition: sequence.hpp:51
index_t data_type
Definition: sequence.hpp:45
__host__ static constexpr __device__ auto Front()
Definition: sequence.hpp:108
__host__ static constexpr __device__ auto Get(Number< I >)
Definition: sequence.hpp:69
__host__ static constexpr __device__ auto PopBack()
Definition: sequence.hpp:122
__host__ static constexpr __device__ auto ReorderGivenOld2New(MapOld2New)
Definition: sequence.hpp:93
__host__ static constexpr __device__ auto Extract(Number< Ns >...)
Definition: sequence.hpp:149
__host__ static constexpr __device__ auto At(Number< I >)
Definition: sequence.hpp:61
__host__ static constexpr __device__ auto Back()
Definition: sequence.hpp:114
__host__ static constexpr __device__ index_t At(index_t I)
Definition: sequence.hpp:53
__host__ static constexpr __device__ auto PushBack(Number< Xs >...)
Definition: sequence.hpp:143
__host__ static constexpr __device__ auto ReorderGivenNew2Old(Sequence< IRs... >)
Definition: sequence.hpp:81
__host__ constexpr __device__ auto operator[](I i) const
Definition: sequence.hpp:75
__host__ static constexpr __device__ auto Reverse()
Definition: sequence.hpp:103
__host__ static constexpr __device__ auto PopFront()
Definition: sequence.hpp:120
__host__ static constexpr __device__ auto Modify(Number< I >, Number< X >)
Definition: sequence.hpp:161
static constexpr index_t mSize
Definition: sequence.hpp:47
__host__ static constexpr __device__ auto PushFront(Number< Xs >...)
Definition: sequence.hpp:131
__host__ static constexpr __device__ auto Extract(Sequence< Ns... >)
Definition: sequence.hpp:155
__host__ static constexpr __device__ auto Size()
Definition: sequence.hpp:49
__host__ static constexpr __device__ auto Transform(F f)
Definition: sequence.hpp:173
__host__ static constexpr __device__ auto PushFront(Sequence< Xs... >)
Definition: sequence.hpp:125
__host__ static __device__ void Print()
Definition: sequence.hpp:178
Definition: sequence.hpp:258
__host__ constexpr __device__ index_t operator()(index_t i) const
Definition: sequence.hpp:259
typename __make_integer_seq< WrapSequence, index_t, IEnd >::type type
Definition: sequence.hpp:283
Definition: sequence.hpp:256
static constexpr bool kHasContent
Definition: sequence.hpp:268
typename sequence_gen<(IEnd - IBegin)/Increment, F >::type type0
Definition: sequence.hpp:265
typename conditional< kHasContent, type0, type1 >::type type
Definition: sequence.hpp:271
Definition: functional.hpp:100
decltype(WorkSeq::Modify(RemainIds::Front(), RemainValues::Front())) new_work_seq
Definition: sequence.hpp:765
typename modify_sequence_elements_by_ids_impl< new_work_seq, decltype(RemainValues::PopFront()), decltype(RemainIds::PopFront())>::type type
Definition: sequence.hpp:770
typename pick_sequence_elements_by_mask_impl< new_work_seq, decltype(RemainSeq::PopFront()), decltype(RemainMask::PopFront())>::type type
Definition: sequence.hpp:742
typename conditional< RemainMask::Front(), decltype(WorkSeq::PushBack(RemainSeq::Front())), WorkSeq >::type new_work_seq
Definition: sequence.hpp:737
Definition: sequence.hpp:189
Definition: integral_constant.hpp:20
Definition: type.hpp:177
Definition: sequence.hpp:525
Definition: sequence.hpp:227
static constexpr index_t NRemainRight
Definition: sequence.hpp:229
static constexpr index_t IMiddle
Definition: sequence.hpp:230
static constexpr index_t NRemainLeft
Definition: sequence.hpp:228
typename sequence_merge< typename sequence_gen_impl< IBegin, NRemainLeft, G >::type, typename sequence_gen_impl< IMiddle, NRemainRight, G >::type >::type type
Definition: sequence.hpp:234
Definition: sequence.hpp:224
typename sequence_gen_impl< 0, NSize, F >::type type
Definition: sequence.hpp:250
static constexpr auto new_y2x
Definition: sequence.hpp:534
typename sequence_map_inverse_impl< X2Y, decltype(new_y2x), XBegin+1, XRemain - 1 >::type type
Definition: sequence.hpp:539
Definition: sequence.hpp:530
typename sequence_map_inverse_impl< SeqMap, typename uniform_sequence_gen< SeqMap::Size(), 0 >::type, 0, SeqMap::Size()>::type type
Definition: sequence.hpp:552
Seq type
Definition: sequence.hpp:218
Definition: sequence.hpp:205
typename sequence_merge< Seq, typename sequence_merge< Seqs... >::type >::type type
Definition: sequence.hpp:206
Seq type
Definition: sequence.hpp:379
Definition: sequence.hpp:364
typename sequence_reduce< Reduce, Seq, typename sequence_reduce< Reduce, Seqs... >::type >::type type
Definition: sequence.hpp:367
typename sequence_merge< Sequence< new_reduce >, old_scan >::type type
Definition: sequence.hpp:309
typename sequence_reverse_inclusive_scan< Sequence< Is... >, Reduce, Init >::type old_scan
Definition: sequence.hpp:305
Definition: sequence.hpp:300
Definition: sequence.hpp:340
typename sequence_merge< typename sequence_reverse< typename seq_split::right_type >::type, typename sequence_reverse< typename seq_split::left_type >::type >::type type
Definition: sequence.hpp:346
static constexpr index_t NSize
Definition: sequence.hpp:341
Definition: sequence.hpp:508
typename sorted_seqs::ids_type sorted2unsorted_map
Definition: sequence.hpp:511
typename sorted_seqs::values_type type
Definition: sequence.hpp:510
Definition: sequence.hpp:327
typename arithmetic_sequence_gen< 0, I, 1 >::type range0
Definition: sequence.hpp:330
decltype(Seq::Extract(range1{})) right_type
Definition: sequence.hpp:334
static constexpr index_t NSize
Definition: sequence.hpp:328
typename arithmetic_sequence_gen< I, NSize, 1 >::type range1
Definition: sequence.hpp:331
decltype(Seq::Extract(range0{})) left_type
Definition: sequence.hpp:333
Definition: sequence.hpp:516
typename sorted_seqs::values_type type
Definition: sequence.hpp:518
typename sorted_seqs::ids_type sorted2unsorted_map
Definition: sequence.hpp:519
Definition: sequence.hpp:389
index_t ids[N > 0 ? N :1]
Definition: sequence.hpp:391
index_t values[N > 0 ? N :1]
Definition: sequence.hpp:390
index_t size
Definition: sequence.hpp:392
Definition: sequence.hpp:469
static constexpr auto data
Definition: sequence.hpp:470
Definition: sequence.hpp:482
Definition: functional2.hpp:33
Definition: sequence.hpp:291
__host__ constexpr __device__ index_t operator()(index_t) const
Definition: sequence.hpp:292
Definition: sequence.hpp:289
typename sequence_gen< NSize, F >::type type
Definition: sequence.hpp:295
std::ostream & operator<<(std::ostream &os, const ck::Sequence< Is... >)
Definition: sequence.hpp:841