---
title: make_tiled_copy
description: "创建tiled_copy策略。其中对于转置Copy操作而言，CopyAtom Ops转置矩阵大小与atom_shape相应m和n相乘所得乘积表示实际转置矩阵大小；对于预取Copy操作而言，CopyAtom Ops预取矩阵大小与atom_shape相应m相乘所得乘积表示实际预取矩阵大小。"
url: https://www.hikunpeng.com/document/detail/zh/kunpenghpcs/hpckit/devg/KunpengHPCKit_developer_111.html
sourcePath: /source/zh/kunpenghpcs/hpckit/devg/KunpengHPCKit_developer_111.html
indexId: befd01a69ea32d9d8fc6013c4d3d4b236483d582e8962cef234c5c8a6ab12ae067
---
# make_tiled_copy

创建tiled_copy策略。其中对于转置Copy操作而言，CopyAtom Ops转置矩阵大小与atom_shape相应m和n相乘所得乘积表示实际转置矩阵大小；对于预取Copy操作而言，CopyAtom Ops预取矩阵大小与atom_shape相应m相乘所得乘积表示实际预取矩阵大小。

当前atom_shape中m/n不支持任意扩展，对于不同的CopyAtom Ops存在不同的限制，具体见下表2参数定义中描述。

#### 接口定义

template<typename CopyAtom, typename Shape>

TiledCopy<CopyAtom, Shape> make_tiled_copy( CopyAtom copy_atom, Shape atom_shape);


#### 模板参数


**表1 模板参数定义**

| 参数名 | 类型 | 描述 |
| --- | --- | --- |
| CopyAtom | typename | copy原子策略类型。 |
| Shape | typename | 形状类型。 |


#### 参数


**表2 参数定义**

| 参数名 | 类型 | 描述 | 输入/输出 |
| --- | --- | --- | --- |
| copy\_atom | CopyAtom，Ops<枚举copy\_atom\_t> | copy原子策略，当前copy\_atom\_t可设置为： KP36\_32x1\_F64\_TRANS\_RM2CM，表示转置原子尺寸为32 \* 1、转置精度为float64的copy原子行为，其中源矩阵的排布为行主序，步幅可以描述为Stride<shape\_n，1>；目的矩阵的排布为列主序，步幅可以描述为Stride<1，32>。约束：对于该原子方法，shape\_n % 8 = 0 KP36\_1x16\_F64\_TRANS\_CM2RM，表示转置原子尺寸为1 \* 16、转置精度为float64的copy原子行为，其中源矩阵的排布为列主序，步幅可以描述为Stride<1，shape\_m>；目的矩阵的排布为行主序，步幅可以描述为Stride<16，1>。约束：对于该原子方法，shape\_m % 8 = 0 KP36\_16x2\_BF16\_TRANS\_RM2ZZ，表示转置原子尺寸为16 \* 2、转置精度为bfloat16的copy原子行为，其中源矩阵的排布为行主序，步幅可以描述为Stride<2 \* shape\_n，1>；目的矩阵的排布为ZZ峰形，步幅可以描述为Stride<2，Stride<1, 32>>。约束：对于该原子方法，shape\_n % 16 = 0 KP36\_2x64\_BF16\_TRANS\_CM2NN，表示转置原子尺寸为2 \* 64、转置精度为bfloat16的copy原子行为，其中源矩阵的排布为列主序，步幅可以描述为Stride<1，2 \* shape\_m>；目的矩阵的排布为NN峰形，步幅可以描述为Stride<Stride<1, 128>, 2>。约束：对于该原子方法，shape\_m % 16 = 0 KP36\_16x1\_BF16\_TRANS\_RM2CM，表示转置原子尺寸为16 \* 1、转置精度为bfloat16的copy原子行为，其中源矩阵的排布为行主序，步幅可以描述为Stride<shape\_n，1>；目的矩阵的排布为列主序，步幅可以描述为Stride<1，16> KP36\_1x64\_BF16\_TRANS\_CM2RM，表示转置原子尺寸为1 \* 64、转置精度为bfloat16的copy原子行为，其中源矩阵的排布为列主序，步幅可以描述为Stride<1，shape\_m>；目的矩阵的排布为行主序，步幅可以描述为Stride<64，1> KP36\_16x4\_INT8\_TRANS\_RM2ZZ，表示转置原子尺寸为16 \* 4、转置精度为int8的copy原子行为，其中源矩阵的排布为行主序，步幅可以描述为Stride<4 \* shape\_n，1>；目的矩阵的排布为ZZ峰形，步幅可以描述为Stride<4，Stride<1, 64>>。约束：对于该原子方法，shape\_n % 16 = 0 KP36\_4x64\_INT8\_TRANS\_CM2NN，表示转置原子尺寸为4 \* 64、转置精度为int8的copy原子行为，其中源矩阵的排布为列主序，步幅可以描述为Stride<1，4 \* shape\_m>；目的矩阵的排布为NN峰形，步幅可以描述为Stride<Stride<1, 256>, 4>。约束：对于该原子方法，shape\_m % 16 = 0 KP36\_32x4\_INT8\_TRANS\_RM2ZZ，表示转置原子尺寸为32 \* 4、转置精度为int8的copy原子行为，其中源矩阵的排布为行主序，步幅可以描述为Stride<4 \* shape\_n，1>；目的矩阵的排布为ZZ峰形，步幅可以描述为Stride<4，Stride<1, 128>>。约束：对于该原子方法，shape\_n % 16 = 0 KP36\_4x32\_INT8\_TRANS\_CM2NN，表示转置原子尺寸为4 \* 32、转置精度为int8的copy原子行为，其中源矩阵的排布为列主序，步幅可以描述为Stride<1，4 \* shape\_m>；目的矩阵的排布为NN峰形，步幅可以描述为Stride<Stride<1, 128>, 4>。约束：对于该原子方法，shape\_m % 16 = 0 KP36\_PREFETCH\_L1，表示针对tensor对象的L1 cache预取操作。鲲鹏CPU中一次预取指令会处理64字节的内存，因此对于不同的精度tensor对象，KP36\_PREFETCH\_L1处理不同的shape大小，例如针对double精度而言，处理形状为Shape<8>，处理步幅为Stride<1>；而针对bfloat16精度而言，处理形状为Shape<32>，处理步幅为Stride<1>。约束：对于该原子方式，atom shape\_m无法扩展，始终为1 KP36\_PREFETCH\_L2，表示针对tensor对象的L2 cache预取操作。鲲鹏CPU中一次预取指令会处理64字节的内存，因此对于不同的精度tensor对象，KP36\_PREFETCH\_L2处理不同的shape大小，例如针对double精度而言，处理形状为Shape<8>，处理步幅为Stride<1>；而针对bfloat16精度而言，处理形状为Shape<32>，处理步幅为Stride<1>。约束：对于该原子方式，atom shape\_m无法扩展，始终为1 | 输入 |
| atom\_shape | Shape | 原子策略在各维度执行次数，针对转置原子方法而言包含m和n两个数值，针对预取原子方法而言包含m一个数值 | 输入 |


#### 返回值

返回TiledCopy<StoreCopy, Shape>对象


#### 示例

```
#include <stdio.h>
#include <stdlib.h>
#include "kupl_mma.h"
using namespace kupl::tensor;

int main()
{
    constexpr int MATRIX_M = 32;
    constexpr int MATRIX_N = 512;
    double *dst = (double*)malloc(sizeof(double) * MATRIX_M * MATRIX_N);
    double *src = (double*)malloc(sizeof(double) * MATRIX_M * MATRIX_N);
    for (int i = 0; i < MATRIX_M; i++) {
        for (int j = 0; j < MATRIX_N; j++) {
            dst[i * MATRIX_N + j] = 0.0;
            src[i * MATRIX_N + j] = i * MATRIX_N + j;
        }
    }

    auto shape_d = make_shape(Int<MATRIX_M>{}, Int<MATRIX_N>{});
    auto shape_s = make_shape(Int<MATRIX_M>{}, Int<MATRIX_N>{});

    auto stride_d = make_stride(Int<1>{}, Int<MATRIX_M>{});
    auto stride_s = make_stride(Int<MATRIX_N>{}, Int<1>{});

    auto layout_d = make_layout(shape_d, stride_d);
    auto layout_s = make_layout(shape_s, stride_s);

    auto atom_copy_shape = make_shape(Int<1>{}, Int<MATRIX_N>{});
    auto tiled_copy = make_tiled_copy(Ops<KP36_32x1_F64_TRANS_RM2CM>{}, atom_copy_shape);

    auto tensor_d = make_tensor(dst, layout_d);
    auto tensor_s = make_tensor(src, layout_s);
    copy(tiled_copy, tensor_d, tensor_s);

    free(src);
    free(dst);
    return 0;
}
```

上述示例演示了基于32*512_F64矩阵形状从行主序到列主序的copy流程，其中通过make_tiled_copy创建copy tile策略，具体选择的原子方法为COPY_32x1_F64_RM2CM，atom_shape为shape<1, 512>。
