智能计算系统 实验五

智能计算系统实验五 自定义算子

这个实验真是越做越气,在这里把坑记录下来。
注意这里只记录了实验手册上没有写的坑,手册还是要看的。

一、自定义PowerDifference算子

0.环境配置

和之前一样,在.bashrc里source env和tensorflow下的env.sh

1. Bangc实现

这一步没什么特别需要注意的,按照说明把输入分段然后实现即可。
需要注意最后一段不足ONELINE个的时候不要向原内存中拷贝多了,会段错误。

2.集成至tensorflow

调用时的流程大概是:cwise_op_power_difference_mlu.h → mlu_stream.h → power_difference.cc → mlu_lib_ops.cc → /bangc/PluginPowerDifferenceOp/plugin_power_difference_op.cc → …

倒着按照这个顺序抄env/tensorflow-v1.10/tensorflow/core/kernels下其他类似运算的实现基本没什么大问题。
其他文件主要是注册用的,照着抄就行,有的甚至已经写好了不用改。

另外建议写一个移动文件的脚本,这样可以避免每次修改之后都要把所有文件都分别移动到对应目录里去的繁琐操作。

有问题的地方很多:

  • tensorflow中的BUILD文件需要修改,参考上一次实验
  • plugin_power_difference_op.cc和cnplugin.h中,按照实验手册的流程来是不需要cnmlCreatePluginPowerDifferenceOpParam和cnmlDestroyPluginPowerDifferenceOpParam这两个函数的,请注意。
  • 指定幂次的那个变量是通过输入tensor的大小确定的,比如计算平方会输入一个形状为(2,)的tensor作为第三个参数,需要在cwise_op_power_difference_mlu.h中获取第三个变量的元素个数pow_c.NumElements(),然后再向下传递。

3.在线测试

有问题的地方:

  • power_difference_test_bcl.py中的数据生成,生成的两个tensor不是一个形状,建议是在这里手动生成同样形状的数据,否则就要去修改之前的代码额外实现一个广播操作。如果选择修改生成数据,那么还要注意power_diff_numpy.py中的numpy实现实在不像是人能写出来的,需要将第二个tensor展开至一维再传入才能保证没问题。(或者你自己在power_difference_test_bcl.py里自己写一个output = np.power(input_x - input_y, input_z),不import他原来的代码)
  • transform_mlu.py可以参考实验4.4中的transform_cpu.py,另外保存离线模型只要添加config.mlu_options.save_offline_model = True这样一句话即可。

4.离线测试

可以参考code_chap_5_1_student/src/bangc/PluginPowerDifferenceOp/powerDiff.cpp官方离线文档一起做。
千万记得,在Inference::run最开始加一句cnrtInit(0);
有问题的地方:

  • 本函数的输入中,input_data是(3, 256, 256)的float,而模型的输入需要是(256, 256, 3)的half,记得转一下。参考cnrtConvertFloatToHalfArraycnrtTransDataOrder,在vscode里用c++插件可以方便的查看到这两个函数的定义,能知道怎么用。另外记得在MLU和CPU之间切换数据 🙂
  • 输出也记得要改啊,后面需要的输出是(3, 256, 256)的float,而模型的输出是(256, 256, 3)的half

最后再吐槽一下,这个输入是人能干出来的事吗,opencv读进来的时候本来就是(256, 256, 3)的,他加载数据的时候莫名其妙地非要转成(3, 256, 256)的,搞得不匹配还要再转回去。

二、并行矩阵乘法

有大佬在这里我就不献丑了233

三、BPL实现PowerDifference

有了之前的坑这个本来应该没什么大问题了,就是用python生成我们之前写的.mlu文件,然后像之前一样编译,本来应该是这样的……

结果因为之前形状不一致需要广播的问题是通过修改power_difference_test_bcl.py里数据生成部分解决的,而这次虽然仍然要提交这个文件,但测试的时候似乎没用,所以不得不实现对输入尺寸不同的情况的处理。

本来应该像add之类的操作实现广播,但实在是太麻烦了,几乎要把之前的全部推倒重写,而且没有手册很容易出错,所以我选择了额外传递一个len2参数,代表第二个向量的长度,在.mlu文件中特殊处理不等长度的情况。具体来说就是把input2放入一个新的ONELINE*3长的数组里去,循环填充整个数组,每次用这里的数据来计算。(注意对齐,256不是3的倍数,所以这里开了三倍长)

就结果而言还是没调出来最后20分,放弃了233

Leave a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注