20 template <
typename Distribution>
27 template <
index_t... PartialHsLengths>
38 template <
index_t... PartialHsIndices>
64 template <
typename PsYs2XsAdaptor_,
65 typename Ys2DDescriptor_,
66 typename StaticTileDistributionEncoding_,
67 typename TileDistributionDetail_>
77 "wrong! should be static");
79 static constexpr
index_t NDimX = PsYs2XsAdaptor::get_num_of_bottom_dimension();
80 static constexpr
index_t NDimY = Ys2DDescriptor::get_num_of_top_dimension();
82 static constexpr
index_t NDimR = StaticTileDistributionEncoding_::NDimR;
95 static_assert(
NDimP == 1 or
NDimP == 2,
"wrong!");
97 if constexpr(
NDimP == 1)
101 else if constexpr(
NDimP == 2)
139 template <
typename PartitionIndex>
142 static_assert(PartitionIndex::size() ==
NDimP,
"wrong!");
151 constexpr
index_t ndim_low = DstrEncode::ps_to_rhss_major_[idim_p].size();
154 constexpr
index_t rh_major = DstrEncode::ps_to_rhss_major_[idim_p][i];
155 constexpr
index_t rh_minor = DstrEncode::ps_to_rhss_minor_[idim_p][i];
158 if constexpr(rh_major == 0)
160 constexpr
index_t adaptor_hidden_id =
161 DstrDetail::rh_major_minor_to_adaptor_hidden_idss_[rh_major][rh_minor];
164 rs_idx(rh_minor) = dummy_adaptor_coord.get_hidden_index()[adaptor_hidden_id];
173 template <
typename PartitionIndex = decltype(get_partition_index())>
178 const auto window_adaptor_thread_coord_tmp =
180 return window_adaptor_thread_coord_tmp.get_bottom_index();
185 constexpr
auto distributed_spans_impl = DstrEncode::detail::distributed_spans_lengthss_;
186 constexpr
auto ndims_spans_minor = DstrEncode::detail::ndims_distributed_spans_minor_;
190 constexpr
auto span_impl = distributed_spans_impl[i];
191 constexpr
index_t ndim_span_minor = ndims_spans_minor[i];
201 template <
typename DistributedIndices>
205 constexpr
auto ys_idx_arr = [] {
209 constexpr
index_t span_major = DstrEncode::detail::ys_to_span_major_[i];
210 constexpr
index_t span_minor = DstrEncode::detail::ys_to_span_minor_[i];
214 ys_idx(i) = dstr_index.impl_[span_minor];
231 template <
typename T>
235 template <
typename PsYs2XsAdaptor,
236 typename Ys2DDescriptor,
237 typename StaticTileDistributionEncoding,
238 typename TileDistributionDetail>
241 StaticTileDistributionEncoding,
245 template <
typename T>
250 template <index_t NDimMax>
255 for(
index_t i = 0; i < iend - ibegin; ++i)
264 template <
typename StaticTileDistributionEncoding_>
268 using RsLengths =
typename StaticTileDistributionEncoding_::RsLengths;
269 using HsLengthss =
typename StaticTileDistributionEncoding_::HsLengthss;
270 using Ps2RHssMajor =
typename StaticTileDistributionEncoding_::Ps2RHssMajor;
271 using Ps2RHssMinor =
typename StaticTileDistributionEncoding_::Ps2RHssMinor;
272 using Ys2RHsMajor =
typename StaticTileDistributionEncoding_::Ys2RHsMajor;
273 using Ys2RHsMinor =
typename StaticTileDistributionEncoding_::Ys2RHsMinor;
276 constexpr
index_t kMaxNumTransforms = 20;
277 constexpr
index_t kMaxMetaDataSize = 128;
278 constexpr
index_t kMaxNumDim = 10;
289 constexpr
index_t ndim_x = HsLengthss::size();
298 index_t hidden_dim_cnt = ndim_x;
302 constexpr
index_t ndim_r_minor = RsLengths::size();
304 constexpr
auto r_minor_lengths = RsLengths{};
306 trans(num_tran++) = {
308 MetaData{to_array<index_t, ndim_r_minor>(r_minor_lengths)},
311 NumDim{ndim_r_minor},
312 make_sequential_index<kMaxNumDim>(hidden_dim_cnt, hidden_dim_cnt + ndim_r_minor)};
314 for(
index_t i = 0; i < ndim_r_minor; ++i)
316 rh_major_minor_to_hidden_ids(0)(i) = hidden_dim_cnt;
317 rh_major_minor_to_hidden_lengths(0)(i) = r_minor_lengths[i];
327 &rh_major_minor_to_hidden_ids,
328 &rh_major_minor_to_hidden_lengths](
auto idim_x) {
330 constexpr
auto h_minor_lengths =
331 HsLengthss{}.get(idim_x);
334 constexpr
index_t ndim_h_minor = h_minor_lengths.size();
336 trans(num_tran++) = {
338 MetaData{to_array<index_t, ndim_h_minor>(h_minor_lengths)},
341 NumDim{ndim_h_minor},
342 make_sequential_index<kMaxNumDim>(hidden_dim_cnt, hidden_dim_cnt + ndim_h_minor)};
344 for(
index_t i = 0; i < ndim_h_minor; ++i)
346 rh_major_minor_to_hidden_ids(idim_x + 1)(i) = hidden_dim_cnt;
347 rh_major_minor_to_hidden_lengths(idim_x + 1)(i) = h_minor_lengths[i];
354 constexpr
index_t ndim_p = Ps2RHssMajor::size();
356 Dims hidden_dim_id_ps;
360 index_t hidden_dim_id_p = hidden_dim_cnt++;
362 hidden_dim_id_ps(iDimP) = hidden_dim_id_p;
364 constexpr
auto p2RHsMajor = Ps2RHssMajor{}[iDimP];
365 constexpr
auto p2RHsMinor = Ps2RHssMinor{}[iDimP];
367 static_assert(p2RHsMajor.size() == p2RHsMinor.size(),
"wrong!");
369 constexpr
index_t ndim_low = p2RHsMajor.size();
374 for(
index_t i = 0; i < ndim_low; ++i)
376 index_t rh_major = p2RHsMajor[i];
377 index_t rh_minor = p2RHsMinor[i];
378 low_dims(i) = rh_major_minor_to_hidden_ids[rh_major][rh_minor];
379 low_lengths(i) = rh_major_minor_to_hidden_lengths[rh_major][rh_minor];
383 MetaData{to_array<index_t, ndim_low>(low_lengths)},
387 Dims{hidden_dim_id_p}};
390 constexpr
index_t ndim_bottom = ndim_x;
392 constexpr
auto bottom_dim_ids = make_sequential_index<kMaxNumDim>(0, ndim_bottom);
394 constexpr
auto ys_to_rhs_major = Ys2RHsMajor{};
395 constexpr
auto ys_to_rhs_minor = Ys2RHsMinor{};
397 constexpr
index_t ndim_y = Ys2RHsMajor::size();
398 constexpr
index_t ndim_top = ndim_p + ndim_y;
400 auto top_dim_ids = hidden_dim_id_ps;
403 for(
index_t i = 0; i < ndim_y; ++i)
405 index_t rh_major = ys_to_rhs_major[i];
406 index_t rh_minor = ys_to_rhs_minor[i];
407 top_dim_ids(ndim_p + i) = rh_major_minor_to_hidden_ids[rh_major][rh_minor];
412 const auto ps_ys_to_xs_adaptor_encoding =
413 make_tuple(trans, num_tran, bottom_dim_ids, ndim_bottom, top_dim_ids, ndim_top);
419 for(
index_t i = 0; i < ndim_y; ++i)
421 index_t rh_major = ys_to_rhs_major[i];
422 index_t rh_minor = ys_to_rhs_minor[i];
423 index_t y_length = rh_major_minor_to_hidden_lengths[rh_major][rh_minor];
424 y_lengths(i) = y_length;
425 d_length *= y_length;
429 MetaData{to_array<index_t, ndim_y>(y_lengths)},
433 make_sequential_index<kMaxNumDim>(1, ndim_y + 1));
435 const auto ys_to_d_adaptor_encoding =
make_tuple(
436 make_tuple(tran), 1, Dims{0}, 1, make_sequential_index<kMaxNumDim>(1, ndim_y + 1), ndim_y);
438 return make_tuple(ps_ys_to_xs_adaptor_encoding,
439 ys_to_d_adaptor_encoding,
441 rh_major_minor_to_hidden_ids);
445 template <
typename RhMajorMinor2AdaptorH
iddenIdss>
456 template <
typename StaticTileDistributionEncoding_>
459 using DstrEncode = remove_cvref_t<StaticTileDistributionEncoding_>;
461 constexpr
auto adaptor_impl =
464 constexpr
auto ps_ys_to_xs_adaptor_impl = adaptor_impl.template at<0>();
465 constexpr
auto ys_to_d_adaptor_impl = adaptor_impl.template at<1>();
466 constexpr
index_t d_length = adaptor_impl.template at<2>();
467 constexpr
auto rh_major_minor_to_hidden_ids_impl = adaptor_impl.template at<3>();
469 constexpr
auto ps_ys_to_xs_adaptor =
474 constexpr
auto ys_to_d_descriptor =
478 constexpr
index_t ndim_rh_major = DstrEncode::detail::ndim_rh_major_;
479 constexpr
auto ndims_rhs_minor = DstrEncode::detail::ndims_rhs_minor_;
481 constexpr
auto rh_major_minor_to_hidden_ids =
484 return tile_distribution<
487 remove_cvref_t<DstrEncode>,
488 detail::tile_distribution_detail<
remove_cvref_t<decltype(rh_major_minor_to_hidden_ids)>>>{
489 ps_ys_to_xs_adaptor, ys_to_d_descriptor};
494 template <
typename StaticTileDistributionEncoding_>
499 constexpr
auto adaptor_impl =
502 constexpr
auto ps_ys_to_xs_adaptor_impl = adaptor_impl.template at<0>();
503 constexpr
auto ys_to_d_adaptor_impl = adaptor_impl.template at<1>();
504 constexpr
index_t d_length = adaptor_impl.template at<2>();
505 constexpr
auto rh_major_minor_to_hidden_ids_impl = adaptor_impl.template at<3>();
507 constexpr
auto ps_ys_to_xs_adaptor =
510 constexpr
auto ys_to_d_adaptor =
513 constexpr
auto ys_to_d_descriptor =
517 constexpr
index_t ndim_rh_major = DstrEncode::detail::ndim_rh_major_;
518 constexpr
auto ndims_rhs_minor = DstrEncode::detail::ndims_rhs_minor_;
520 constexpr
auto rh_major_minor_to_hidden_ids =
528 ps_ys_to_xs_adaptor, ys_to_d_descriptor};
568 template <
typename Distribution,
index_t... XSliceBegins,
index_t... XSliceEnds>
574 using Encoding = decltype(Distribution::get_static_tile_distribution_encoding());
576 static_assert(
sizeof...(XSliceBegins) ==
sizeof...(XSliceEnds));
577 static_assert(
sizeof...(XSliceBegins) == Encoding::NDimX,
"only support slice over h, not r");
579 constexpr
auto p_len_over_h = Encoding::detail::get_uniformed_p_dim_lengths_over_h();
583 if constexpr(x_slice_ends[i] == -1)
586 constexpr
auto x_length_ =
592 return x_slice_ends[i];
597 constexpr
auto x_slice_lengths = x_slice_ends_ - x_slice_begins;
600 [&](
auto i) constexpr {
601 constexpr
auto len_ = x_slice_lengths[i];
602 static_assert(len_ % p_len_over_h[i] == 0,
603 "slice length must be dividable by p_len_over_h");
604 return number<len_ / p_len_over_h[i]>{};
606 number<x_slice_lengths.size()>{});
608 constexpr
auto src_h_prefix_sum = Encoding::detail::get_h_dim_lengths_prefix_sum();
609 constexpr
auto src_y_info = Encoding::detail::get_sorted_y_to_h_info();
610 constexpr
auto src_y_dims = src_y_info[
number<0>{}];
611 constexpr
auto src_y_maps = src_y_info[
number<1>{}];
612 constexpr
auto src_y_prefix_sum = src_y_info[
number<2>{}];
614 constexpr
auto sliced_hlen_yidx_ylen = [&]() constexpr {
615 auto y_slice_sorted_origins = make_zero_multi_index<Encoding::NDimY>();
616 auto y_slice_lengths = Encoding::detail::ys_lengths_;
617 constexpr
auto y_to_h_masks = Encoding::detail::get_y_to_h_masks();
623 [&](
auto h_len,
auto id) {
625 h_len,
number<x_slice_lengths_without_p[
id]>{}, y_to_h_masks[id]);
627 constexpr
auto sliced_h_lens = sliced_h[
number<0>{}];
628 constexpr
auto sliced_h_index = sliced_h[
number<2>{}];
632 constexpr
auto found_y_index =
container_find(src_y_dims, uniformed_h_index);
633 constexpr
auto y_to_h_dim_end = src_y_prefix_sum[
id + 1];
635 static_assert(found_y_index >= 0 && found_y_index < src_y_dims.size(),
636 "not sliced at y dim, please check");
639 constexpr
auto sliced_y_to_h_lens =
641 constexpr
auto sliced_y_to_h_dims = sliced_y_to_h_lens.size();
643 y_slice_lengths(src_y_maps[y_to_h_dim_end - 1 - i]) =
644 sliced_y_to_h_lens[sliced_y_to_h_dims - 1 - i];
651 constexpr
auto y_origin = [&]() {
653 constexpr
auto y_to_h_len =
655 constexpr
auto y_to_h_dims = y_to_h_len.size();
659 constexpr
auto y_begin_ = x_slice_begins[id] / p_len_over_h[id];
662 auto y_origin_ = make_zero_multi_index<Encoding::NDimY>();
665 y_origin_(y_to_h_dim_end - 1 - i) = h_origin_[y_to_h_dims - 1 - i];
671 src_y_prefix_sum[
id + 1],
676 return sliced_h_lens;
678 typename Encoding::HsLengthss{},
683 return make_tuple(new_h_lengths, y_slice_origins, y_slice_lengths);
686 constexpr
auto sliced_h_lengths = sliced_hlen_yidx_ylen[
number<0>{}];
687 constexpr
auto sliced_y_origins_array = sliced_hlen_yidx_ylen[
number<1>{}];
688 constexpr
auto sliced_y_origins_size = sliced_y_origins_array.size();
689 constexpr
auto sliced_y_lengths_array = sliced_hlen_yidx_ylen[
number<2>{}];
690 constexpr
auto sliced_y_lengths_size = sliced_y_lengths_array.size();
692 constexpr
auto sliced_y_origins =
TO_SEQUENCE(sliced_y_origins_array, sliced_y_origins_size);
693 constexpr
auto sliced_y_lengths =
TO_SEQUENCE(sliced_y_lengths_array, sliced_y_lengths_size);
701 typename Encoding::Ps2RHssMajor,
702 typename Encoding::Ps2RHssMinor,
703 typename Encoding::Ys2RHsMajor,
704 typename Encoding::Ys2RHsMinor>{}),
712 template <
typename PsYs2XsAdaptor_,
713 typename Ys2DDescriptor_,
714 typename StaticTileDistributionEncoding_,
715 typename TileDistributionDetail_>
718 StaticTileDistributionEncoding_,
719 TileDistributionDetail_>& distribution)
721 printf(
"tile_distribution{");
722 printf(
"tile_distribution_encoding: ");
723 print(StaticTileDistributionEncoding_{});
725 printf(
"ps_ys_to_xs_: ");
726 print(distribution.ps_ys_to_xs_);
728 printf(
"ys_to_d_: ");
729 print(distribution.ys_to_d_);
Concept for encoding of Unicode characters.
#define CK_TILE_HOST_DEVICE
Definition: config.hpp:46
constexpr CK_TILE_HOST_DEVICE auto make_sequential_index(index_t ibegin, index_t iend)
Definition: tile_distribution.hpp:251
constexpr CK_TILE_HOST_DEVICE auto make_tile_distributed_span(sequence< Is... >)
Definition: tile_distribution.hpp:51
constexpr CK_TILE_HOST_DEVICE auto slice_distribution_from_x(Distribution, sequence< XSliceBegins... > x_slice_begins, sequence< XSliceEnds... > x_slice_ends)
Definition: tile_distribution.hpp:569
constexpr CK_TILE_HOST_DEVICE auto make_tile_distributed_index(sequence< Is... >)
Definition: tile_distribution.hpp:57
constexpr CK_TILE_HOST_DEVICE auto make_adaptor_encoding_for_tile_distribution(StaticTileDistributionEncoding_)
Definition: tile_distribution.hpp:266
Definition: cluster_descriptor.hpp:13
constexpr CK_TILE_HOST_DEVICE auto make_zero_multi_index()
Definition: multi_index.hpp:26
constexpr CK_TILE_HOST_DEVICE auto container_reorder_given_old2new(const array< TData, NSize > &old_array, sequence< IRs... > old2new)
Definition: container_helper.hpp:48
constexpr CK_TILE_HOST_DEVICE auto container_reduce(const Container &x, Reduce reduce, Init init, number< IBegin >=number< 0 >{}, number< IEnd >=number< Container::size()>{}, number< IStep >=number< 1 >{})
Definition: container_helper.hpp:198
coord_transform_enum
Definition: coordinate_transform.hpp:17
constexpr CK_TILE_HOST_DEVICE auto pick_sequence_elements_by_mask(Seq, Mask)
Definition: sequence.hpp:956
constexpr CK_TILE_HOST_DEVICE void set_container_subset(array< T, N > &y, sequence< Is... > picks, const array< T, sizeof...(Is)> &x)
Definition: container_helper.hpp:420
constexpr CK_TILE_HOST_DEVICE auto make_tensor_adaptor_coordinate(const Adaptor &adaptor, const TopIndex &idx_top)
Definition: tensor_adaptor_coordinate.hpp:56
constexpr auto reverse_slice_sequence(Seq, number< SliceSize >, Mask=typename uniform_sequence_gen< Seq::size(), 1 >::type{})
Definition: sequence.hpp:1234
constexpr CK_TILE_HOST_DEVICE auto to_array_of_array(tuple< Seqs... > t_of_s)
Definition: tuple.hpp:630
int32_t index_t
Definition: integer.hpp:9
CK_TILE_HOST_DEVICE void print(const tile_distribution_encoding_pattern_2d< BlockSize, YPerTile, XPerTile, VecSize, DistributionPattern, NumWaveGroups > &)
Definition: static_encoding_pattern.hpp:341
remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Definition: type_traits.hpp:21
constexpr CK_TILE_HOST_DEVICE auto generate_sequence_v2(F &&f, number< N >)
Definition: sequence.hpp:1056
constexpr CK_TILE_HOST_DEVICE auto make_tensor_descriptor_from_adaptor(const Adaptor &adaptor, const ElementSpaceSize &element_space_size)
Definition: tensor_descriptor.hpp:183
constexpr CK_TILE_HOST_DEVICE auto make_merge_transform_v3_division_mod(const LowLengths &low_lengths)
Definition: coordinate_transform.hpp:1609
CK_TILE_HOST_DEVICE auto get_partition_index(Distribution)
Definition: tile_distribution.hpp:21
constexpr CK_TILE_HOST_DEVICE auto generate_tuple(F &&f, number< N >)
Definition: tuple.hpp:429
constexpr index_t container_find(sequence< Is... > seq, index_t value)
Definition: container_helper.hpp:447
constexpr CK_TILE_HOST_DEVICE auto make_tuple(Xs &&... xs)
Definition: tuple.hpp:360
constexpr CK_TILE_HOST_DEVICE auto get_container_subset(const array< T, N > &arr, sequence< Is... >)
Definition: container_helper.hpp:389
constexpr CK_TILE_HOST_DEVICE auto make_static_tile_distribution(StaticTileDistributionEncoding_)
Definition: tile_distribution.hpp:495
impl::is_static_impl< remove_cvref_t< T > > is_static
Definition: type_traits.hpp:87
constexpr CK_TILE_HOST_DEVICE auto container_concat(const X &x, const Ys &... ys)
Definition: container_helper.hpp:363
constexpr CK_TILE_HOST_DEVICE auto transform_tuples(F f, const X &x)
Definition: tuple.hpp:505
constexpr bool is_tile_distribution_v
Definition: tile_distribution.hpp:246
bool_constant< false > false_type
Definition: integral_constant.hpp:63
bool_constant< true > true_type
Definition: integral_constant.hpp:62
Definition: sequence.hpp:298
A fixed-size array container similar to std::array with additional utilities.
Definition: array.hpp:43
Definition: integral_constant.hpp:13
Definition: tile_distribution.hpp:447
static constexpr auto rh_major_minor_to_adaptor_hidden_idss_
Definition: tile_distribution.hpp:448
Definition: tile_distribution.hpp:233
Definition: sequence.hpp:49
static constexpr CK_TILE_HOST_DEVICE index_t size()
Definition: sequence.hpp:53
Definition: functional.hpp:43
Definition: tile_distribution.hpp:40
static constexpr CK_TILE_HOST_DEVICE bool is_static()
Definition: tile_distribution.hpp:45
static constexpr auto impl_
Definition: tile_distribution.hpp:43
Definition: tile_distribution.hpp:29
static constexpr auto impl_
Definition: tile_distribution.hpp:32
static constexpr CK_TILE_HOST_DEVICE bool is_static()
Definition: tile_distribution.hpp:34
Definition: tile_distribution_encoding.hpp:26
Definition: tile_distribution.hpp:70
remove_cvref_t< Ys2DDescriptor_ > Ys2DDescriptor
Definition: tile_distribution.hpp:72
PsYs2XsAdaptor ps_ys_to_xs_
Definition: tile_distribution.hpp:84
static constexpr CK_TILE_HOST_DEVICE auto get_distributed_spans()
Definition: tile_distribution.hpp:183
constexpr CK_TILE_HOST_DEVICE const auto & get_ps_ys_to_xs_adaptor() const
Definition: tile_distribution.hpp:124
static constexpr index_t NDimY
Definition: tile_distribution.hpp:80
remove_cvref_t< StaticTileDistributionEncoding_ > DstrEncode
Definition: tile_distribution.hpp:73
remove_cvref_t< TileDistributionDetail_ > DstrDetail
Definition: tile_distribution.hpp:74
static constexpr CK_TILE_HOST_DEVICE auto get_lengths()
Definition: tile_distribution.hpp:107
static constexpr index_t NDimP
Definition: tile_distribution.hpp:81
static constexpr CK_TILE_HOST_DEVICE index_t get_num_of_dimension_x()
Definition: tile_distribution.hpp:87
static constexpr CK_TILE_HOST_DEVICE auto get_y_indices_from_distributed_indices(DistributedIndices)
Definition: tile_distribution.hpp:203
CK_TILE_HOST_DEVICE auto calculate_rs_index_from_ps_index(const PartitionIndex &ps_idx) const
Definition: tile_distribution.hpp:140
static constexpr CK_TILE_HOST_DEVICE index_t get_num_of_dimension_p()
Definition: tile_distribution.hpp:89
constexpr CK_TILE_HOST_DEVICE const auto & get_ys_to_d_descriptor() const
Definition: tile_distribution.hpp:129
remove_cvref_t< PsYs2XsAdaptor_ > PsYs2XsAdaptor
Definition: tile_distribution.hpp:71
static constexpr CK_TILE_HOST_DEVICE index_t get_num_of_dimension_r()
Definition: tile_distribution.hpp:90
CK_TILE_HOST_DEVICE auto calculate_index(const PartitionIndex &ps_idx=get_partition_index()) const
Definition: tile_distribution.hpp:175
static constexpr index_t NDimR
Definition: tile_distribution.hpp:82
static constexpr CK_TILE_HOST_DEVICE bool is_static()
Definition: tile_distribution.hpp:225
Ys2DDescriptor ys_to_d_
Definition: tile_distribution.hpp:85
static CK_TILE_HOST_DEVICE auto get_partition_index()
Definition: tile_distribution.hpp:92
static constexpr index_t NDimX
Definition: tile_distribution.hpp:79
static constexpr CK_TILE_HOST_DEVICE index_t get_num_of_dimension_y()
Definition: tile_distribution.hpp:88
static constexpr CK_TILE_HOST_DEVICE auto get_static_tile_distribution_encoding()
Definition: tile_distribution.hpp:131
#define TO_TUPLE_OF_SEQUENCE(a_of_b_impl, a_size, bs_sizes)
Definition: container_helper.hpp:486
#define CONSTRUCT_STATIC_TENSOR_ADAPTOR_FROM_ENCODING(encoded_tensor_adaptor)
Definition: tensor_adaptor.hpp:840
#define CONSTRUCT_TENSOR_ADAPTOR_FROM_ENCODING(encoded_tensor_adaptor)
Definition: tensor_adaptor.hpp:716
#define TO_SEQUENCE(a, n)
Definition: to_sequence.hpp:10