#include <cute/tensor.hpp>
#include <cute/atom/copy_atom.hpp>
#include <cute/atom/copy_traits_sm75.hpp>
#include <cstdio>
using namespace cute;
template <class T>
void show(char const* label, T const& value)
{
std::printf("%s", label);
cute::print(value);
cute::print("\n");
}
int main()
auto mma = make_tiled_mma(SM80_16x8x16_F32F16F16F32_TN{});
auto tiled_copy = make_tiled_copy_A(
Copy_Atom<SM75_U32x1_LDSM_N, half_t>{}, mma);
using TC = decltype(tiled_copy);
// 主机占位存储:仅用于构造 tensor,不执行设备加载。
half_t storage[256]{};
auto sA = make_tensor(
make_smem_ptr(storage),
make_layout(make_shape(_16{}, _16{}),
make_stride(_16{}, _1{})));
auto coordA = make_identity_tensor(make_shape(_16{}, _16{}));
auto dst_to_ref = right_inverse(typename TC::AtomLayoutRef{})
.compose(typename TC::AtomLayoutDst{});
auto split_tv = zipped_divide(
typename TC::TiledLayout_TV{},
make_shape(typename TC::AtomNumThr{}, typename TC::AtomNumVal{}));
auto destination_tv = coalesce(
zip(split_tv.compose(dst_to_ref, _)), Shape<_1,Shape<_1,_1>>{});
show("AtomLayoutSrc: ", typename TC::AtomLayoutSrc{});
show("AtomLayoutDst: ", typename TC::AtomLayoutDst{});
show("AtomLayoutRef: ", typename TC::AtomLayoutRef{});
show("DstToRef: ", dst_to_ref);
show("TiledLayout_TV: ", typename TC::TiledLayout_TV{});
show("Destination grouped TV: ", destination_tv);
int checked_dst = 0;
int checked_src = 0;
for (int lane = 0; lane < 32; ++lane) {
auto thr_mma = mma.get_slice(lane);
auto thr_copy = tiled_copy.get_slice(lane);
auto tCrA = thr_mma.partition_fragment_A(sA);
auto coords = thr_mma.partition_A(coordA);
auto tXsA = thr_copy.partition_S(sA);
auto tXrA = thr_copy.retile_D(tCrA);
auto direct_zip = zipped_divide(tCrA, make_layout(_2{}));
auto direct_mode = logical_divide(
tCrA, make_tile(make_layout(_2{})));
auto copy_coords = thr_copy.partition_D(coordA);
auto src_coords = thr_copy.partition_S(coordA);
auto retiled_coords = thr_copy.retile_D(coords);
for (int b = 0; b < 4; ++b) {
for (int a = 0; a < 2; ++a) {
auto x = coords(a+2*b, 0, 0);
auto y = copy_coords(make_coord(a,b), 0, 0);
auto z = retiled_coords(make_coord(a,b), 0, 0);
auto slot = tXrA.layout()(make_coord(a,b), 0, 0);
auto zip_slot = direct_zip.layout()(a,b);
auto mode_slot = direct_mode.layout()(make_coord(a,b),0,0);
if (!(x == y && y == z) || int(slot) != a+2*b ||
int(zip_slot) != int(slot) || int(mode_slot) != int(slot)) {
std::printf("Destination mismatch: lane=%d a=%d b=%d\n",
lane, a, b);
return 1;
++checked_dst;
for (int u = 0; u < 8; ++u) {
int ref_lane = 4*(lane%8)+u/2;
int ref_value = u%2+2*b;
auto ref_coords = mma.get_slice(ref_lane).partition_A(coordA);
auto x = src_coords(make_coord(u,b), 0, 0);
auto y = ref_coords(ref_value, 0, 0);
if (!(x == y)) {
std::printf("Source mismatch: lane=%d u=%d b=%d\n",
lane, u, b);
++checked_src;
// 只打印前两个 lane;全部 32 个 lane 都执行上面的检查。
if (lane >= 2) {
continue;
std::printf("lane %d\n", lane);
show("tCrA: ", tCrA.layout());
show("tXsA: ", tXsA.layout());
show("tXrA: ", tXrA.layout());
show("direct_zip: ", direct_zip.layout());
show("direct_mode: ", direct_mode.layout());
if (lane == 0) {
constexpr int R = decltype(tCrA)::rank;
auto V = size<0>(tCrA);
auto inv = right_inverse(typename TC::TiledLayout_TV{});
auto mn = inv.with_shape(shape(typename TC::Tiler_MN{}));
auto fmn = upcast<TC::TiledNumThr{} * V>(mn);
auto inv_fmn = right_inverse(fmn);
auto values = logical_product(make_layout(V), inv_fmn);
auto fv = zipped_divide(
values, make_layout(typename TC::AtomNumVal{}));
auto tile = prepend(product_each(shape(fmn)), V);
auto tt = zipped_divide(tCrA.layout(), tile);
auto vt = tt.compose(fv, _);
auto selection = append<R>(Int<0>{}, _);
auto result = vt(_, selection);
show("inverse with MN shape: ", mn);
show("frg_layout_mn: ", fmn);
show("inverse frg_layout_mn: ", inv_fmn);
show("logical_product: ", values);
show("frg_layout_v: ", fv);
show("tile: ", tile);
show("t_tensor: ", tt);
show("v_tensor: ", vt);
show("selection: ", selection);
show("result: ", result);
std::printf("Source group 0: ");
cute::print(src_coords(make_coord(u,0), 0, 0));
cute::print(" ");
for (int v = 0; v < size<0>(tCrA); ++v) {
std::printf("r[%d] -> A", v);
cute::print(coords(v, 0, 0));
std::printf("Copy group %d:", b);
auto slot = tXrA.layout()(make_coord(a, b), 0, 0);
std::printf(" r[%d]", int(slot));
std::printf("Verified %d destination matches and %d source references.\n",
checked_dst, checked_src);