用户开发完TIK算子之后,建议使用TIK调试工具进行算子调试,这样可以通过模拟算子运行的过程,解决算子的绝大部分功能问题(例如数据越界)。
TIK功能调试用于调试TIK DSL的执行行为。该调试功能通过TIK模块的tik.tikdb对象提供。tik.tikdb对象通过tik.Tik对象的tik_instance.tikdb()方法获得,并针对这个TIK对象进行调试。
tikdb提供类似pdb(The Python Debugger)的调试命令行界面。调试者通过tikdb.start_debug()函数启动一个调试过程(需要给定用于测试的TIK DSL程序的输入参数,详细可参考start_debug),tikdb将根据TIK的Dprofile启动一个本地的模拟器,模拟执行TIK定义的执行过程。执行过程遇到断点,tikdb会进入调试命令行界面,详细可参考4。
Atlas 200/300/500 推理产品
Atlas 训练系列产品
Atlas 推理系列产品
Atlas A2训练系列产品
tik_instance = tik.Tik(disable_debug=False)
注意:开启调试功能会影响算子性能,开发者完成功能调试后可以删除disable_debug参数或将disable_debug参数手动置为True,禁用调试功能,可以降低编译时间时长,提升部分性能。
更多接口介绍请参考功能调试。
可以通过numpy生成随机数或者从文件中读取。
完整代码示例参考如下,文件名以simple_add.py为例。
import numpy as np from tbe import tik from tbe.common.platform import set_current_compile_soc_info def simple_add(): tik_instance = tik.Tik(disable_debug=False) kernel_name = "tik_vec_add_128_float32" dst_ub = tik_instance.Tensor("float32", [128], tik.scope_ubuf, "dst_ub") dst_gm = tik_instance.Tensor("float32", (128,), tik.scope_gm, "dst_gm") src0_gm = tik_instance.Tensor("float32", (128,), tik.scope_gm, "src0_gm") src0_ub = tik_instance.Tensor("float32", (128,), tik.scope_ubuf, "src0_ub") src1_gm = tik_instance.Tensor("float32", (128,), tik.scope_gm, "src1_gm") src1_ub = tik_instance.Tensor("float32", (128,), tik.scope_ubuf, "src1_ub") tik_instance.data_move(src0_ub, src0_gm, 0, 1, 16, 0, 0) tik_instance.data_move(src1_ub, src1_gm, 0, 1, 16, 0, 0) tik_instance.vec_add(64, dst_ub, src0_ub, src1_ub, 2, 8, 8, 8) tik_instance.data_move(dst_gm, dst_ub, 0, 1, 16, 0, 0) tik_instance.BuildCCE(kernel_name, [src0_gm, src1_gm], [dst_gm]) return tik_instance if __name__=='__main__': # 请根据实际昇腾AI处理器型号进行设置 soc_version="xxx" set_current_compile_soc_info(soc_version) # 请根据AI处理器实际版本设置,具体请参考set_current_compile_soc_info接口说明 tik_instance = simple_add() data_x = np.ones((128,)).astype("float32") data_y = np.ones((128,)).astype("float32") feed_dict = {'src0_gm': data_x, 'src1_gm': data_y} model_data, = tik_instance.tikdb.start_debug(feed_dict=feed_dict,interactive=True) print(model_data)
调用tikdb.start_debug()函数且interactive参数为True后,运行算子文件进入TIK调试器的交互命令行,此时调试器会停止在执行第一条TIK DSL之前。如下图所示。
com(mand) param1 [param2]
调试器命令行模式下包括如下几种命令:
该TIK DSL定义函数所在的文件名:该TIK DSL定义函数所在函数的行号
若不设置任何参数,则直接列出所有已设置断点的信息,包含断点的编号,断点的使能状态,断点对应的tag。其中断点的编号从“0”开始按照设置先后顺序递增。
需要注意:若设置断点格式不准确或者断点处语句非TIK DSL语句均会提示断点设置失败。支持设置断点的语句包括Tensor定义、if-else语句、for语句以及所有的指令(如data_move、vadd等)。
完整代码示例参考如下,文件名以tik_multi_core_debug.py为例。
import numpy as np from tbe.common.platform import set_current_compile_soc_info from tbe import tik def simple_add_multi_core(): tik_instance = tik.Tik(disable_debug=False) kernel_name = "tik_multi_core_debug" dtype = "float16" block_nums = 3 dst_gm = tik_instance.Tensor(dtype, (block_nums*128,), tik.scope_gm, "dst_gm") src0_gm = tik_instance.Tensor(dtype, (block_nums*128,), tik.scope_gm, "src0_gm") src1_gm = tik_instance.Tensor(dtype, (block_nums*128,), tik.scope_gm, "src1_gm") with tik_instance.for_range(0, block_nums, block_num=block_nums) as blk_idx: dst_ub = tik_instance.Tensor(dtype, (128,), tik.scope_ubuf, "dst_ub") src0_ub = tik_instance.Tensor(dtype, (128,), tik.scope_ubuf, "src0_ub") src1_ub = tik_instance.Tensor(dtype, (128,), tik.scope_ubuf, "src1_ub") tik_instance.data_move(src0_ub, src0_gm[blk_idx*128], 0, 1, 8, 0, 0) tik_instance.data_move(src1_ub, src1_gm[blk_idx*128], 0, 1, 8, 0, 0) tik_instance.vec_add(128, dst_ub, src0_ub, src1_ub, 1, 8, 8, 8) tik_instance.data_move(dst_gm[blk_idx*128], dst_ub, 0, 8, 1, 0, 0) tik_instance.BuildCCE(kernel_name, [src0_gm, src1_gm], [dst_gm]) return tik_instance if __name__ == '__main__': # 请根据实际昇腾AI处理器型号进行设置 soc_version="xxx" set_current_compile_soc_info(soc_version) # 请根据AI处理器实际版本设置,具体请参考set_current_compile_soc_info接口说明 tik_instance = simple_add_multi_core() data_x = np.ones((3*128,)).astype("float16") data_y = np.ones((3*128,)).astype("float16") feed_dict = {'src0_gm': data_x, 'src1_gm': data_y} model_data, = tik_instance.tikdb.start_debug(feed_dict=feed_dict, interactive=True) print(model_data)
如果断点不指定核,默认对所有核打断点。
单步调试及多核切换,单步调试过程中只有当前核会执行代码,其它核保持原位置不变。
在进入多核for_range循环(tik_instance.for_range(0, block_nums, block_num=block_nums))之前,如果设置断点,会对所有的核生效,并且会将所有核设置进入交互模式;
如果已经进入多核for_range循环,设置断点默认对所有可交互核生效,“Running”、“Finished”状态的核无效;
如果只想对特定的核设置断点,可以通过字符“block index1 index2 …”指定核编号;
断点0对所有核生效,断点1只对核0、1生效,断点2只对核1、2生效。
断点只对核1、2生效,执行c,可以看到执行到断点处停止,同时核0状态为“Finished”,表示执行结束,不会进入交互模式。
设置断点指定核0、1、2,核0已经处于“Finished”状态,不能设置断点,给出告警提示信息,其它两个核设置断点成功。
对于断点disable、enable、clear与设置断点指令类似,在此不再赘述。
进入多核交互模式之后,continue命令只会对当前核生效,如果想所有核都继续执行,输入命令“continue -a” or “continue -all”or “c -a”or “c -all”。
quit命令直接退出执行。