printf
功能说明
打印Scalar、Expr、ScalarArray、Tensor值。支持功能调试环境start_debug上的打印。
函数原型
def printf(format_string, *arg)
参数说明
参数名称 |
输入/输出 |
含义 |
---|---|---|
format_string |
输入 |
待打印的字符串,包括字符和格式字符。 支持的数据类型:立即数(string) 注意:该字段不能为空。 字符串最大长度不能超过128个字符,如果在printf之前使用了set_printf_params接口,还需满足长度不能超过single_print_length-32。 示例: "scalar is: %d\n" 上例中格式字符为:%d。 格式字符配置格式为:%[flag][width][.precision]type |
*arg |
输入 |
参数值,参数个数可变,最多支持6个参数。 每个参数支持如下几种数据类型:
|
格式字符 |
含义 |
---|---|
%d |
有符号十进制整数 |
%o |
有符号的八进制数,不可打印float数据 |
%x |
有符号十六进制数,不可打印float数据 |
%f |
浮点数十进制格式 |
%s |
输出字符串 |
%c |
输出单个字符, 数据范围在[0, 255], 否则会解析出错,不可打印float数据 |
%% |
输出一个 '%' 字符 |
支持的型号
Atlas 200/300/500 推理产品
Atlas 训练系列产品
Atlas 推理系列产品(Ascend 310P处理器)
Atlas A2训练系列产品/Atlas 800I A2推理产品
Atlas 200/500 A2推理产品
返回值
无
注意事项
- 每一条printf语句打印的内容,总的长度不能超过“set_printf_params”接口中设置的“single_print_length”, 默认值是512字节,可以通过“set_printf_prams”接口修改默认值,如果超过,被截断。总的打印长度计算公式如下:
- 总的print数据长度 = print 头长度 +format 字符串长度+ 待打印数据长度。
- print头长度:固定32 Byte。
- format_string 字符串长度: 如果format_length不是32字节对齐,则format_length按照32字节对齐。
- 待打印数据长度 = 第一个待打印数据头长度+ 第一个待打印数据长度+ 第二个待打印数据头长度+ 第二个待打印数据长度 + ... + 第n个待打印数据头长度+ 第n个待打印数据长度.
- 第一个待打印数据头长度, 第二个待打印数据头长度, .... ,第n个待打印数据头长度: 待打印数据的头,固定32字节。
- 第一个待打印数据长度, 第二个待打印数据长度, ... , 第n个待打印数据长度: 待打印数据长度。如果待打印的数据不是32字节对齐,则按照32字节对齐。
- 每条printf语句会额外使用UB空间。UB空间占用情况如下:
- 参数类型为Tensor,scope 为L1、 UB、 Global Memory及参数类型为Scalar: 284字节。
- 参数类型为Tensor,scope为L1_out: 256字节 + 256* Tensor的数据类型大小。
- 每一条printf 可能会额外插入同步,可能改变语句执行顺序。
- 每一条printf 语句都增加额外操作,可能导致性能下降。执行时间可能会比不加printf长。
- printf功能支持功能调试。
- 当由于所打印数据长度无法在前端评估长度时,在解析时,会出现warning: discard xxx args字样,其中“xxx”表示丢弃的数据量。
- 所有核的printf空间大小固定(可以通过set_printf_prams接口修改默认值,默认值128M),每个核均匀切分printf空间。当printf的总大小超过printf空间时,老的printf内容被覆盖。当发现老的printf内容被覆盖时,通过“warning: discard xxx args”打印得知多少空间被覆盖。然后通过set_printf_prams接口增加printf空间大小。
- 每一条printf语句会生成IR,多个printf可能导致超出IR限制。如果报超出IR限制导致编译失败,请减少printf语句。
- printf语句会导致算子编译时间增加。
- 当在算子文件中存在多核for循环时,不允许在多核for循环内使用printf进行打印。
- 请注意,在功能调试环境运行printf时:
- 当所需打印内容的总长度超过single_print_length时,仍可打出所有数据内容。
- 当printf内容超出print_workspace_size大小时,不会覆盖老的printf内容。
- printf的待打印的参数,如果是tensor,并且有offset,offset需要遵守如下对齐规则:
- 如果tensor的scope是UB或者Global Memory, 则offset需要和Tensor的数据类型大小(单位Byte)对齐。
- 如果tensor的scope是L1,需要32字节对齐。
- 如果tensor的scope是L1_out, 则offset需要和256 * Tensor数据类型大小(单位Byte)对齐。
调用示例
- 打印一个Scalar值。
from tbe import tik tik_instance = tik.Tik() scalar = tik_instance.Scalar("int8", init_value=-128) // 需要的空间为 32B 头空间 + 32B 字符串空间 + 32<每个参数的TL占用空间>*1 +32B<每个数据需要向上补齐到32B> tik_instance.printf("scalar is: %d\n", scalar) tik_instance.BuildCCE(inputs=[], outputs=[], kernel_name="print_scalar") tik_instance.tikdb.start_debug({}) 输入 [] 输出 scalar is: -128
- 打印某个UB Buffer的值。
tik_instance = tik.Tik() ub_tensor = tik_instance.Tensor("int16", [16, 16], tik.scope_ubuf, 'ub_tensor') scalar = tik_instance.Scalar(dtype="int16",init_value=6) ub_tensor[15].set_as(scalar) tik_instance.printf("ubtensor[15:16] is: %d\n", ub_tensor[15:16]) tik_instance.BuildCCE(inputs=[], outputs=[], kernel_name="printf_ub") tik_instance.tikdb.start_debug({}) 输入 [] 输出 ubtensor[15:16] is: 6
- 打印一段Global Memory的值。
tik_instance = tik.Tik() gm_tensor = tik_instance.Tensor("float16", [256, ], tik.scope_gm, "gm_tensor") tik_instance.printf("%f\n", gm_tensor[0:32]) tik_instance.BuildCCE(inputs=[gm_tensor], outputs=[], kernel_name="printf_gm") data = np.random.uniform(-65504, 65504, [256, ]).astype(np.float16) tik_instance.tikdb.start_debug(feed_dict={'gm_tensor': data}) 输入 [-13288 46208 52448 -6488 -3364 55264 49376 3840 ...] 输出 -13288.000000 46208.000000 52448.000000 -6488.000000 -3364.000000 55264.000000 49376.000000 3840.000000 ...
父主题: 功能调试