#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_B(
Copy_Atom<SM75_U32x1_LDSM_N, half_t>{}, mma);
auto copy_x2 = make_tiled_copy_B(
Copy_Atom<SM75_U32x2_LDSM_N, half_t>{}, mma);
using TC = decltype(tiled_copy);
// 主机占位存储:只检查布局,不执行设备加载或读取 fragment 的值。
half_t storage[128]{};
auto sB = make_tensor(
make_smem_ptr(storage),
make_layout(make_shape(_8{}, _16{}), make_stride(_16{}, _1{})));
auto coordB = make_identity_tensor(make_shape(_8{}, _16{}));
show("TiledLayout_TV: ", typename TC::TiledLayout_TV{});
show("Tiler_NK: ", typename TC::Tiler_MN{});
show("TiledNumVal: ", typename TC::TiledNumVal{});
show("AtomNumVal: ", typename TC::AtomNumVal{});
int checked_dst = 0;
int checked_src = 0;
int checked_x2 = 0;
for (int lane = 0; lane < 32; ++lane) {
auto thr_mma = mma.get_slice(lane);
auto thr_copy = tiled_copy.get_slice(lane);
auto tCrB = thr_mma.partition_fragment_B(sB);
auto mma_coords = thr_mma.partition_B(coordB);
auto tXsB = thr_copy.partition_S(sB);
auto tXrB = thr_copy.retile_D(tCrB);
auto copy_coords = thr_copy.partition_D(coordB);
auto src_coords = thr_copy.partition_S(coordB);
auto retiled_coords = thr_copy.retile_D(mma_coords);
auto direct_zip = zipped_divide(tCrB, make_layout(_2{}));
auto direct_mode = logical_divide(
tCrB, make_tile(make_layout(_2{})));
for (int b = 0; b < 2; ++b) {
for (int a = 0; a < 2; ++a) {
int v = a + 2*b;
auto expected = make_coord(lane/4, 2*(lane%4) + a + 8*b);
auto mma_coord = mma_coords(v,0,0);
auto copy_coord = copy_coords(make_coord(a,b),0,0);
auto retiled_coord = retiled_coords(make_coord(a,b),0,0);
int slot = int(tXrB.layout()(make_coord(a,b),0,0));
if (!(expected == mma_coord && mma_coord == copy_coord &&
copy_coord == retiled_coord) || slot != v ||
int(direct_zip.layout()(a,b)) != slot ||
int(direct_mode.layout()(make_coord(a,b),0,0)) != slot) {
std::printf("B destination mismatch: lane=%d a=%d b=%d\n",
lane,a,b);
return 1;
++checked_dst;
for (int u = 0; u < 8; ++u) {
auto expected = make_coord(lane%8, u+8*b);
int ref_lane = 4*(lane%8)+u/2;
auto ref_coords = mma.get_slice(ref_lane).partition_B(coordB);
auto src_coord = src_coords(make_coord(u,b),0,0);
if (!(src_coord == expected &&
src_coord == ref_coords(u%2+2*b,0,0))) {
std::printf("B source mismatch: lane=%d u=%d b=%d\n",
lane,u,b);
++checked_src;
auto thr_x2 = copy_x2.get_slice(lane);
auto tXrB_x2 = thr_x2.retile_D(tCrB);
auto x2_coords = thr_x2.partition_D(coordB);
for (int v = 0; v < 4; ++v) {
if (!(x2_coords(make_coord(v,0),0,0) == mma_coords(v,0,0)) ||
int(tXrB_x2.layout()(make_coord(v,0),0,0)) != v) {
std::printf("B x2 destination mismatch: lane=%d v=%d\n",lane,v);
++checked_x2;
if (lane >= 2) {
continue;
std::printf("lane %d\n",lane);
show("tCrB: ",tCrB.layout());
show("tXsB: ",tXsB.layout());
show("tXrB: ",tXrB.layout());
show("direct_zip: ",direct_zip.layout());
show("direct_mode: ",direct_mode.layout());
show("tXrB_x2: ",tXrB_x2.layout());
if (lane == 0) {
constexpr int R = decltype(tCrB)::rank;
auto V = size<0>(tCrB);
auto mn = right_inverse(typename TC::TiledLayout_TV{})
.with_shape(shape(typename TC::Tiler_MN{}));
auto fmn = upcast<TC::TiledNumThr{} * V>(mn);
auto gather = right_inverse(fmn);
auto values = logical_product(make_layout(V),gather);
auto fv = zipped_divide(values,make_layout(typename TC::AtomNumVal{}));
auto tile = prepend(product_each(shape(fmn)),V);
auto tt = zipped_divide(tCrB.layout(),tile);
auto vt = tt.compose(fv,_);
auto selection = append<R>(Int<0>{},_);
show("inverse with NK shape: ",mn);
show("frg_layout_nk: ",fmn);
show("gather shape: ",product_each(shape(fmn)));
show("inverse frg_layout_nk: ",gather);
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: ",vt(_,selection));
std::printf("Source group 0: ");
cute::print(src_coords(make_coord(u,0),0,0));
cute::print(" ");
std::printf("r[%d] -> B",v);
cute::print(mma_coords(v,0,0));
std::printf("Copy group %d:",b);
std::printf(" r[%d]",int(tXrB.layout()(make_coord(a,b),0,0)));
std::printf("\n");
std::printf("Verified %d B destination matches and %d source references; "
"%d x2 destination matches.\n",checked_dst,checked_src,checked_x2);