/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/docs-7.1.0/include/ck_tile/ops/epilogue/cshuffle_epilogue.hpp Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/docs-7.1.0/include/ck_tile/ops/epilogue/cshuffle_epilogue.hpp Source File#

Composable Kernel: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/docs-7.1.0/include/ck_tile/ops/epilogue/cshuffle_epilogue.hpp Source File
cshuffle_epilogue.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: MIT
2 // Copyright (c) 2018-2025, Advanced Micro Devices, Inc. All rights reserved.
3 
4 #pragma once
5 
6 #include "ck_tile/core.hpp"
9 
10 namespace ck_tile {
11 
12 template <typename ADataType_,
13  typename BDataType_,
14  typename DsDataType_,
15  typename AccDataType_,
16  typename ODataType_,
17  typename DsLayout_,
18  typename ELayout_,
19  typename CDElementwise_,
20  index_t kBlockSize_,
21  index_t kM_,
22  index_t kN_,
23  index_t MWave_,
24  index_t NWave_,
25  index_t MPerXdl_,
26  index_t NPerXdl_,
27  index_t KPerXdl_,
28  bool isCTransposed_,
29  memory_operation_enum MemoryOperation_,
30  index_t kNumWaveGroups_ = 1,
31  bool FixedVectorSize_ = false,
32  index_t VectorSizeC_ = 1>
34 {
43  static constexpr index_t kBlockSize = kBlockSize_;
44  static constexpr index_t kMPerBlock = kM_;
45  static constexpr index_t kNPerBlock = kN_;
46  static constexpr index_t MWave = MWave_;
47  static constexpr index_t NWave = NWave_;
48  static constexpr index_t MPerXdl = MPerXdl_;
49  static constexpr index_t NPerXdl = NPerXdl_;
50  static constexpr index_t KPerXdl = KPerXdl_;
51  static constexpr index_t isCTransposed = isCTransposed_;
52  static constexpr memory_operation_enum MemoryOperation = MemoryOperation_;
53  static constexpr bool FixedVectorSize = FixedVectorSize_;
54  static constexpr index_t VectorSizeC = VectorSizeC_;
55  static constexpr index_t kNumWaveGroups = kNumWaveGroups_;
56  static constexpr index_t NumDTensor = DsDataType::size();
57 
58  static_assert(NumDTensor == DsLayout::size(),
59  "The size of DsDataType and DsLayout should be the same");
60 };
61 
62 template <typename Problem_, typename Policy_ = void>
64 {
72  using ATypeToUse =
73  std::conditional_t<std::is_same_v<ADataType, pk_int4_t>, BDataType, ADataType>;
74  // Used for weight-only quantization kernel, B would be dequantized to the same data type as A
75  using BTypeToUse =
76  std::conditional_t<std::is_same_v<BDataType, pk_int4_t>, ADataType, BDataType>;
79  static constexpr memory_operation_enum MemoryOperation = Problem::MemoryOperation;
80  static constexpr index_t kBlockSize = Problem::kBlockSize;
81  static constexpr index_t kMPerBlock = Problem::kMPerBlock;
82  static constexpr index_t kNPerBlock = Problem::kNPerBlock;
83  static constexpr index_t MWave = Problem::MWave;
84  static constexpr index_t NWave = Problem::NWave;
85  static constexpr index_t MPerXdl = Problem::MPerXdl;
86  static constexpr index_t NPerXdl = Problem::NPerXdl;
87  static constexpr index_t KPerXdl = Problem::KPerXdl;
88  static constexpr index_t isCTransposed = Problem::isCTransposed;
89  static constexpr bool FixedVectorSize = Problem::FixedVectorSize;
90  static constexpr index_t VectorSizeC = Problem::VectorSizeC;
91  static constexpr index_t MPerIteration = MPerXdl * MWave;
92  static constexpr index_t NPerIteration = NPerXdl * NWave;
93  static constexpr index_t NumDTensor = Problem::NumDTensor;
94 
95  static_assert(NumDTensor == DsLayout::size(),
96  "The size of DsDataType and DsLayout should be the same");
108  {
109  if constexpr(FixedVectorSize)
110  {
111  return VectorSizeC;
112  }
113  constexpr index_t max_vector_size = 16;
114  if constexpr(std::is_same_v<ELayout, tensor_layout::gemm::RowMajor>)
115  {
116  return std::min(static_cast<int>(NPerIteration),
117  static_cast<int>(max_vector_size / sizeof(ODataType)));
118  }
119  else if constexpr(std::is_same_v<ELayout, tensor_layout::gemm::ColumnMajor>)
120  {
121  return std::min(static_cast<int>(MPerIteration),
122  static_cast<int>(max_vector_size / sizeof(ODataType)));
123  }
124  else
125  {
126  static_assert(false, "Unsupported ELayout!");
127  }
128  }
129 
135  template <index_t I>
137  {
138  constexpr index_t max_vector_size = 16;
139  using DiDataType = remove_cvref_t<std::tuple_element_t<index.value, DsDataType>>;
140  using DiLayout = remove_cvref_t<std::tuple_element_t<index.value, DsLayout>>;
141  if constexpr(std::is_same_v<DiLayout, tensor_layout::gemm::RowMajor>)
142  {
143  return std::min(static_cast<int>(NPerIteration),
144  static_cast<int>(max_vector_size / sizeof(DiDataType)));
145  }
146  else if constexpr(std::is_same_v<DiLayout, tensor_layout::gemm::ColumnMajor>)
147  {
148  return std::min(static_cast<int>(MPerIteration),
149  static_cast<int>(max_vector_size / sizeof(DiDataType)));
150  }
151  else
152  {
153  static_assert(false, "Unsupported DLayout!");
154  }
155  return max_vector_size / sizeof(DiDataType);
156  }
165  static constexpr auto shuffle_tile_tuple = [] {
166  constexpr index_t elem_per_thread = MPerXdl * NPerXdl / get_warp_size();
167  if constexpr(elem_per_thread >= GetVectorSizeC())
168  {
169  return std::make_tuple(1, 1);
170  }
171  else
172  {
173  constexpr index_t num_xdl_shuffles = GetVectorSizeC() / elem_per_thread;
174  if constexpr(std::is_same_v<ELayout, tensor_layout::gemm::RowMajor>)
175  {
176  static_assert((kMPerBlock % (MPerXdl * MWave) == 0) &&
177  (kMPerBlock % num_xdl_shuffles == 0),
178  "kMPerBlock must be divisible by MPerXdl*MWave and "
179  "num_xdl_shuffles for CShuffleEpilogue");
180  return std::make_tuple(min(num_xdl_shuffles, kMPerBlock / (MPerXdl * MWave)), 1);
181  }
182  else
183  {
184  static_assert((kNPerBlock % (NPerXdl * NWave) == 0) &&
185  (kNPerBlock % num_xdl_shuffles == 0),
186  "kNPerBlock must be divisible by NPerXdl*NWave and "
187  "num_xdl_shuffles for CShuffleEpilogue");
188  return std::make_tuple(1, min(num_xdl_shuffles, kNPerBlock / (NPerXdl * NWave)));
189  }
190  }
191  }();
192  static constexpr index_t NumMXdlPerWavePerShuffle = std::get<0>(shuffle_tile_tuple);
193  static constexpr index_t NumNXdlPerWavePerShuffle = std::get<1>(shuffle_tile_tuple);
194 
195  static constexpr auto MNPerIterationShuffle = [] {
196  constexpr index_t m_val = MPerXdl * MWave * NumMXdlPerWavePerShuffle;
197  constexpr index_t n_val = NPerXdl * NWave * NumNXdlPerWavePerShuffle;
198  if constexpr(kMPerBlock % m_val != 0 || kNPerBlock % n_val != 0)
200  else
201  return std::make_tuple(m_val, n_val);
202  }();
203  static constexpr index_t MPerIterationShuffle = std::get<0>(MNPerIterationShuffle);
204  static constexpr index_t NPerIterationShuffle = std::get<1>(MNPerIterationShuffle);
205 
207  BTypeToUse,
208  AccDataType,
209  MPerXdl,
210  NPerXdl,
211  KPerXdl,
212  isCTransposed>;
213 
214  using CWarpDstr = typename WG::CWarpDstr;
215  using CWarpTensor = typename WG::CWarpTensor;
216 
217  template <typename Problem>
219  {
220  // N is contiguous dimension
221  if constexpr(std::is_same_v<ELayout, tensor_layout::gemm::RowMajor>)
222  {
226  }
227  // M is contiguous dimension
228  else if constexpr(std::is_same_v<ELayout, tensor_layout::gemm::ColumnMajor>)
229  {
233  }
234  else
235  {
236  static_assert(false, "Unsupported ELayout!");
237  }
238  }
239 
241  {
242  constexpr auto block_outer_dstr_encoding =
249  sequence<0, 0>>{};
250  constexpr auto block_dstr_encoding = detail::make_embed_tile_distribution_encoding(
251  block_outer_dstr_encoding, typename CWarpDstr::DstrEncode{});
252 
253  return block_dstr_encoding;
254  }
255 
257  {
259  }
260 
261  template <typename ODramWindow, typename OAccTile, typename DsDramWindows>
262  CK_TILE_DEVICE auto operator()(ODramWindow& out_dram_window,
263  const OAccTile& o_acc_tile,
264  const DsDramWindows& ds_dram_windows,
265  void* p_smem)
266  {
267  constexpr auto LdsTileDistr = make_static_tile_distribution(MakeLdsDistributionEncode());
268 
269  auto lds_tile = make_static_distributed_tensor<AccDataType>(LdsTileDistr);
270 
271  constexpr auto lds_block_desc = MakeLdsBlockDescriptor<Problem>();
272  auto o_lds_block = make_tensor_view<address_space_enum::lds>(
273  static_cast<ODataType*>(p_smem), lds_block_desc);
274 
275  auto in_lds_window = make_tile_window(
276  o_lds_block,
278  {0, 0},
279  LdsTileDistr);
280 
281  auto out_lds_window = make_tile_window(
282  o_lds_block,
284  {0, 0});
285 
289  constexpr index_t num_access = SFC::get_num_of_access();
290 
291  static_assert(std::is_same_v<ELayout, tensor_layout::gemm::RowMajor>,
292  "Currently, the CShuffle Epilogue only supports the Row Major Output layout");
293 
294  using TileEncodingPattern =
298  GetVectorSizeC(),
300  Problem::kNumWaveGroups>;
301  constexpr auto dram_tile_distribution = TileEncodingPattern::Make2DStaticTileDistribution();
302 
303  auto d_dram_windows = generate_tuple(
304  [&](auto idx) {
305  return make_tile_window(ds_dram_windows[idx], dram_tile_distribution);
306  },
308 
309  constexpr auto c_warp_y_lengths =
310  to_sequence(CWarpDstr{}.get_ys_to_d_descriptor().get_lengths());
311  constexpr auto c_warp_y_index_zeros = uniform_sequence_gen_t<CWarpDstr::NDimY, 0>{};
312 
313  static_for<0, num_access, 1>{}([&](auto iAccess) {
314  block_sync_lds();
315  constexpr auto idx_y_start = SFC::get_index(iAccess);
316 
317  constexpr auto mIter = number<idx_y_start.at(number<0>{}) / (MPerIterationShuffle)>{};
318  constexpr auto nIter = number<idx_y_start.at(number<1>{}) / (NPerIterationShuffle)>{};
319 
320  lds_tile.get_thread_buffer() = o_acc_tile.get_y_sliced_thread_data(
323  c_warp_y_index_zeros),
325  c_warp_y_lengths));
326 
327  const auto c_warptile_in_tensor_casted = cast_tile<ODataType>(lds_tile);
328 
329  store_tile(in_lds_window, c_warptile_in_tensor_casted);
330  block_sync_lds();
331 
332  auto c_out_tensor = load_tile(make_tile_window(out_lds_window, dram_tile_distribution));
333 
334  const auto ds_tensor = generate_tuple(
335  [&](auto idx) { return load_tile(d_dram_windows[idx]); }, number<NumDTensor>{});
336 
337  const auto c_ds_tiles = concat_tuple_of_reference(
338  tie(c_out_tensor, c_out_tensor),
339  generate_tie([&](auto idx) -> const auto& { return ds_tensor[idx]; },
340  number<NumDTensor>{}));
341 
342  tile_elementwise_inout_unpack(typename Problem::CDElementwise{}, c_ds_tiles);
343 
344  if constexpr(MemoryOperation == memory_operation_enum::set)
345  {
346  store_tile(out_dram_window, c_out_tensor);
347  }
348  else
349  {
350  update_tile(out_dram_window, c_out_tensor);
351  }
352  if constexpr(iAccess != num_access - 1)
353  {
354  constexpr auto step = SFC::get_forward_step(iAccess);
355 
356  move_tile_window(out_dram_window, {step.at(number<0>{}), step.at(number<1>{})});
357 
358  static_for<0, NumDTensor, 1>{}([&](auto idx) {
359  move_tile_window(d_dram_windows[idx],
360  {step.at(number<0>{}), step.at(number<1>{})});
361  });
362  }
363  });
364  }
365 };
366 } // namespace ck_tile
#define CK_TILE_DEVICE
Definition: config.hpp:40
#define CK_TILE_HOST_DEVICE
Definition: config.hpp:41
__host__ constexpr __device__ T min(T x)
Definition: math.hpp:116
constexpr CK_TILE_HOST_DEVICE auto make_embed_tile_distribution_encoding(OuterDstr, InnerDstr)
Definition: tile_distribution_encoding.hpp:559
Definition: cluster_descriptor.hpp:13
typename impl::WarpGemmMfmaDispatcher< AType, BType, AccType, MPerWave, NPerWave, KPerWave, TransposeC, SwizzleA, UseStructuredSparsity, AttrNumAccess >::Type WarpGemmMfmaDispatcher
Definition: warp_gemm_dispatcher.hpp:150
constexpr CK_TILE_HOST_DEVICE auto make_naive_tensor_descriptor(const tuple< Lengths... > &lengths, const tuple< Strides... > &strides, number< GuaranteedLastDimensionVectorLength >=number<-1 >{}, number< GuaranteedLastDimensionVectorStride >=number<-1 >{})
Definition: tensor_descriptor.hpp:255
constexpr tuple< Args &... > tie(Args &... args) noexcept
Definition: tuple.hpp:359
int32_t index_t
Definition: integer.hpp:9
constexpr CK_TILE_HOST_DEVICE auto generate_tie(F &&f, number< N >)
Definition: tuple.hpp:418
remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Definition: type_traits.hpp:21
CK_TILE_DEVICE auto tile_elementwise_inout_unpack(const InElementFunc &in_element_func, const Tuple &t, std::index_sequence< I... >)
Template function that "unpacks" a tuple and applies an element-wise operation.
Definition: tile_elementwise.hpp:71
@ thread_raked
Thread raked pattern.
constexpr CK_TILE_HOST_DEVICE auto to_sequence(tuple< number< Is >... >)
Definition: sequence.hpp:1046
constexpr CK_TILE_HOST_DEVICE auto merge_sequences(Seqs...)
Definition: sequence.hpp:817
constexpr CK_TILE_DEVICE auto make_tile_window(null_tensor_view, const WindowLengths &window_lengths, const multi_index< WindowLengths::size()> &, Ts &&...)
Definition: null_tile_window.hpp:72
CK_TILE_DEVICE void move_tile_window(null_tile_window< WindowLengths > &, const typename null_tile_window< WindowLengths >::BottomTensorIndex &)
Definition: null_tile_window.hpp:92
constexpr CK_TILE_HOST_DEVICE auto generate_tuple(F &&f, number< N >)
Definition: tuple.hpp:412
constexpr CK_TILE_HOST_DEVICE auto make_tuple(Xs &&... xs)
Definition: tuple.hpp:343
constexpr CK_TILE_HOST_DEVICE auto concat_tuple_of_reference(const tuple< X &... > &tx, const tuple< Y &... > &ty)
Definition: tuple.hpp:426
CK_TILE_DEVICE void update_tile(tile_window_with_static_lengths< BottomTensorView_, WindowLengths_ > &tile_window_tmp, const static_distributed_tensor< DataType_, TileDistribution_ > &dstr_tensor)
Definition: update_tile.hpp:22
CK_TILE_DEVICE void store_tile(tile_window_with_static_lengths< BottomTensorView_, WindowLengths_ > &tile_window_tmp, const static_distributed_tensor< DataType_, TileDistribution_ > &dstr_tensor)
Definition: store_tile.hpp:23
constexpr CK_TILE_HOST_DEVICE T min(T x)
Definition: math.hpp:210
CK_TILE_DEVICE auto load_tile(const TileWindow_ &tile_window, number< i_access >={}, bool_constant< oob_conditional_check >={})
Definition: load_tile.hpp:22
constexpr CK_TILE_HOST_DEVICE auto make_static_tile_distribution(StaticTileDistributionEncoding_)
Definition: tile_distribution.hpp:498
typename uniform_sequence_gen< NSize, I >::type uniform_sequence_gen_t
Definition: sequence.hpp:1017
typename tuple_element< I, TTuple >::type tuple_element_t
Definition: tuple.hpp:208
__host__ constexpr __device__ index_t get_warp_size()
Definition: get_id.hpp:10
__host__ constexpr __device__ auto make_tuple(Xs &&... xs)
Definition: tuple.hpp:211
__device__ void block_sync_lds()
Definition: synchronization.hpp:10
Definition: cshuffle_epilogue.hpp:64
static constexpr index_t kBlockSize
Definition: cshuffle_epilogue.hpp:80
static constexpr CK_TILE_HOST_DEVICE auto MakeLdsBlockDescriptor()
Definition: cshuffle_epilogue.hpp:218
typename WG::CWarpTensor CWarpTensor
Definition: cshuffle_epilogue.hpp:215
remove_cvref_t< Problem_ > Problem
Definition: cshuffle_epilogue.hpp:65
static constexpr index_t MPerXdl
Definition: cshuffle_epilogue.hpp:85
static constexpr bool FixedVectorSize
Definition: cshuffle_epilogue.hpp:89
static constexpr CK_TILE_HOST_DEVICE index_t GetVectorSizeD(number< I > index)
Get the vector store size for Di tensor.
Definition: cshuffle_epilogue.hpp:136
remove_cvref_t< typename Problem::ODataType > ODataType
Definition: cshuffle_epilogue.hpp:69
static constexpr index_t kNPerBlock
Definition: cshuffle_epilogue.hpp:82
CK_TILE_DEVICE auto operator()(ODramWindow &out_dram_window, const OAccTile &o_acc_tile, const DsDramWindows &ds_dram_windows, void *p_smem)
Definition: cshuffle_epilogue.hpp:262
remove_cvref_t< typename Problem::ELayout > ELayout
Definition: cshuffle_epilogue.hpp:77
static constexpr memory_operation_enum MemoryOperation
Definition: cshuffle_epilogue.hpp:79
remove_cvref_t< typename Problem::DsLayout > DsLayout
Definition: cshuffle_epilogue.hpp:71
static constexpr CK_TILE_DEVICE auto MakeLdsDistributionEncode()
Definition: cshuffle_epilogue.hpp:240
static constexpr index_t MPerIteration
Definition: cshuffle_epilogue.hpp:91
static constexpr auto MNPerIterationShuffle
Definition: cshuffle_epilogue.hpp:195
static constexpr index_t isCTransposed
Definition: cshuffle_epilogue.hpp:88
static constexpr CK_TILE_HOST_DEVICE index_t GetSmemSize()
Definition: cshuffle_epilogue.hpp:256
static constexpr index_t MWave
Definition: cshuffle_epilogue.hpp:83
static constexpr CK_TILE_HOST_DEVICE index_t GetVectorSizeC()
Get the vector store size for C tensor.
Definition: cshuffle_epilogue.hpp:107
static constexpr index_t VectorSizeC
Definition: cshuffle_epilogue.hpp:90
remove_cvref_t< typename Problem::DsDataType > DsDataType
Definition: cshuffle_epilogue.hpp:70
std::conditional_t< std::is_same_v< BDataType, pk_int4_t >, ADataType, BDataType > BTypeToUse
Definition: cshuffle_epilogue.hpp:76
remove_cvref_t< typename Problem::CDElementwise > CDElementwise
Definition: cshuffle_epilogue.hpp:78
static constexpr index_t NPerIterationShuffle
Definition: cshuffle_epilogue.hpp:204
WarpGemmMfmaDispatcher< ATypeToUse, BTypeToUse, AccDataType, MPerXdl, NPerXdl, KPerXdl, isCTransposed > WG
Definition: cshuffle_epilogue.hpp:212
remove_cvref_t< typename Problem::AccDataType > AccDataType
Definition: cshuffle_epilogue.hpp:68
static constexpr index_t NumDTensor
Definition: cshuffle_epilogue.hpp:93
static constexpr index_t KPerXdl
Definition: cshuffle_epilogue.hpp:87
static constexpr index_t NumMXdlPerWavePerShuffle
Definition: cshuffle_epilogue.hpp:192
static constexpr index_t NumNXdlPerWavePerShuffle
Definition: cshuffle_epilogue.hpp:193
static constexpr index_t MPerIterationShuffle
Definition: cshuffle_epilogue.hpp:203
remove_cvref_t< typename Problem::BDataType > BDataType
Definition: cshuffle_epilogue.hpp:67
static constexpr auto shuffle_tile_tuple
Shuffle tile configuration parameters.
Definition: cshuffle_epilogue.hpp:165
static constexpr index_t NWave
Definition: cshuffle_epilogue.hpp:84
remove_cvref_t< typename Problem::ADataType > ADataType
Definition: cshuffle_epilogue.hpp:66
static constexpr index_t kMPerBlock
Definition: cshuffle_epilogue.hpp:81
static constexpr index_t NPerIteration
Definition: cshuffle_epilogue.hpp:92
static constexpr index_t NPerXdl
Definition: cshuffle_epilogue.hpp:86
typename WG::CWarpDstr CWarpDstr
Definition: cshuffle_epilogue.hpp:214
std::conditional_t< std::is_same_v< ADataType, pk_int4_t >, BDataType, ADataType > ATypeToUse
Definition: cshuffle_epilogue.hpp:73
Definition: cshuffle_epilogue.hpp:34
remove_cvref_t< AccDataType_ > AccDataType
Definition: cshuffle_epilogue.hpp:37
static constexpr index_t kNumWaveGroups
Definition: cshuffle_epilogue.hpp:55
remove_cvref_t< ODataType_ > ODataType
Definition: cshuffle_epilogue.hpp:38
remove_cvref_t< ELayout_ > ELayout
Definition: cshuffle_epilogue.hpp:41
remove_cvref_t< CDElementwise_ > CDElementwise
Definition: cshuffle_epilogue.hpp:42
static constexpr index_t NWave
Definition: cshuffle_epilogue.hpp:47
static constexpr index_t kBlockSize
Definition: cshuffle_epilogue.hpp:43
remove_cvref_t< ADataType_ > ADataType
Definition: cshuffle_epilogue.hpp:35
static constexpr index_t MWave
Definition: cshuffle_epilogue.hpp:46
static constexpr index_t kNPerBlock
Definition: cshuffle_epilogue.hpp:45
remove_cvref_t< DsDataType_ > DsDataType
Definition: cshuffle_epilogue.hpp:39
remove_cvref_t< DsLayout_ > DsLayout
Definition: cshuffle_epilogue.hpp:40
static constexpr index_t KPerXdl
Definition: cshuffle_epilogue.hpp:50
static constexpr bool FixedVectorSize
Definition: cshuffle_epilogue.hpp:53
static constexpr index_t kMPerBlock
Definition: cshuffle_epilogue.hpp:44
static constexpr index_t VectorSizeC
Definition: cshuffle_epilogue.hpp:54
static constexpr index_t NumDTensor
Definition: cshuffle_epilogue.hpp:56
static constexpr memory_operation_enum MemoryOperation
Definition: cshuffle_epilogue.hpp:52
remove_cvref_t< BDataType_ > BDataType
Definition: cshuffle_epilogue.hpp:36
static constexpr index_t isCTransposed
Definition: cshuffle_epilogue.hpp:51
static constexpr index_t NPerXdl
Definition: cshuffle_epilogue.hpp:49
static constexpr index_t MPerXdl
Definition: cshuffle_epilogue.hpp:48
Class creating 2D static tile distribution with different load/store patterns.
Definition: static_encoding_pattern.hpp:129
Definition: integral_constant.hpp:13
static constexpr value_type value
Definition: integral_constant.hpp:16
Definition: sequence.hpp:52
Definition: space_filling_curve.hpp:20
Definition: functional.hpp:43
Definition: tile_distribution_encoding.hpp:26
Definition: tuple.hpp:192