近日发现难以做到日更,于是决定月更。
有关项目
总结一下RIF现在碰到的一些问题:
Segmentation Fault
对构建过程和报错进行了描述放在github issue 目前并没有什么头绪,出现了按照test构建,没有segmentation fault但是也出现了vfsgnj指令报错:有dataC未定义。 dataC无论在autogen/的文件里、spike的算法头文件里还是decode.hpp里都没有。 删掉CustomOperator.def里面的其他指令之后就不会报错没有dataC了。
vfsgnj(n/x)
Decode.hpp里面写了和spike一样的算法宏
#define F16_SIGN ((uint16_t)1 << 15)
#define F32_SIGN ((uint32_t)1 << 31)
#define F64_SIGN ((uint64_t)1 << 63)
#define fsgnj16(a, b, n, x) \
f16((f16(a).v & ~F16_SIGN) | ((((x) ? f16(a).v : (n) ? F16_SIGN : 0) ^ f16(b).v) & F16_SIGN))
#define fsgnj32(a, b, n, x) \
f32((f32(a).v & ~F32_SIGN) | ((((x) ? f32(a).v : (n) ? F32_SIGN : 0) ^ f32(b).v) & F32_SIGN))
#define fsgnj64(a, b, n, x) \
f64((f64(a).v & ~F64_SIGN) | ((((x) ? f64(a).v : (n) ? F64_SIGN : 0) ^ f64(b).v) & F64_SIGN))
生成的测试用例,有mask的话遵循ta=1s,ma=1s,但是rvv intrinsic计算结果不遵循,就算有v0.t = 0 也会正常计算所以报错了。 在没有mask的测试用例中,rif golden 算出来的值是0,需要修。
删掉CustomOperator.def里面的其他指令之后发现,autogen/compute{op_type}Op.h里面的头文件竟然不是根据CustomOperator.def 里面有多少个指令来的。 checkout 回很早之前的分支也无法找到指令了。
问题原因
RIF在遇到使用和常规指令不同的宏的指令时会先取消 decode.h 中定义的宏,在头文件中进行 push macro 和 pop macro 操作。
示例如下,此为 include/autogen/compute{op_type}Op.h 中的部分内容:
#pragma push_macro("VI_VFP_VV_LOOP")
#undef VI_VFP_VV_LOOP
#define VI_VFP_VV_LOOP(BODY16, BODY32, BODY64) \\
RIF::RawDatumOperand vd(dataA[i]); \\
RIF::RawDatumOperand vs1(dataB[i]); \\
RIF::RawDatumOperand vs2(dataC[i]); \\
switch (sew) { \\
case e16: \\
BODY16; \\
break; \\
case e32: \\
BODY32; \\
break; \\
case e64: \\
BODY64; \\
break; \\
default: \\
assert(0); \\
break; \\
} \\
dataOut[i] = vd;
#pragma push_macro("VI_VFP_VV_LOOP_WIDE")
#undef VI_VFP_VV_LOOP_WIDE
#define VI_VFP_VV_LOOP_WIDE(BODY16, BODY32) \\
RIF::RawDatumOperand vd(dataA[i]); \\
RIF::RawDatumOperand vs1(dataB[i]); \\
RIF::RawDatumOperand vs2(dataC[i]); \\
switch (sew) { \\
case e16: \\
vs2 = f16_to_f32(vs2); \\
vs1 = f16_to_f32(vs1); \\
BODY16; \\
break; \\
case e32: \\
vs2 = f32_to_f64(vs2); \\
vs1 = f32_to_f64(vs1); \\
BODY32; \\
break; \\
default: \\
assert(0); \\
break; \\
} \\
dataOut[i] = vd;
#pragma pop_macro("VI_VFP_VV_LOOP")
#pragma pop_macro("VI_VFP_VV_LOOP_WIDE")
decode.h 中的默认宏展开为:
#define VI_VFP_VV_LOOP(BODY16, BODY32, BODY64) \
RIF::RawDatumOperand vs2(dataA[i]); \
RIF::RawDatumOperand vs1(dataB[i]); \
RIF::RawDatumOperand vd; \
switch (sew) { \
case e16: \
BODY16; \
break; \
case e32: \
BODY32; \
break; \
case e64: \
BODY64; \
break; \
default: \
assert(0); \
break; \
} \
dataOut[i] = vd;
如果 #pragma push_macro 没有对应的 #pragma pop_macro 就会导致报错没有对应的数据类型,因为在复用上一个操作的宏。
Debug 方法
参加 AOSCC 时 ksco 老师教了我大量 debug 技巧,比如单步运行 make 找出报错的命令,使用 -E 参数 -o 指定文件位置和名字,查看宏展开之后的内容。 还有解读 ai agent 教我的使用 gdb bt 程序调用栈的报错。大学习,深表感谢。
未解之谜
不知道以下报错为何会发生,但现在已不会复现。
+ build/tool/random_gen --root=FmaccVV64VFloat64VBVFVFVFSS111111_m --nodes-to-gen=1 --length=5 --dot=FmaccVV64VFloat64VBVFVFVFSS111111_m.dot --code=FmaccVV64VFloat64VBVFVFVFSS111111_m.c --seed=3735928559 --march=rv64gcv_zfh_zvfh
Can not find root 'FmaccVV64VFloat64VBVFVFVFSS111111_m' in .def file, abort.
GEN FAIL
尝试了一下创建VFLiteral.py,根据_vf来生成,但还是 Can not find root 'FmaccVV64VFloat64VBVFVFVFSS111111_m' in .def file, abort., 问题出现在C++处理CustomOperator.def.