已合并
fix(softsign):修复精度问题,修复空tensor问题 #8479
yulianjie创建于 26 天前
fix(softsign):修复精度问题,修复空tensor问题 #8479
已合并
yulianjie创建于 26 天前
3 个文件变更+44-8
@@ -46,11 +46,11 @@ static ge::graphStatus RunEleTiling(gert::TilingContext* context, SoftsignTiling
46static ge::graphStatus DoTilingByDtype(gert::TilingContext* context, ge::DataType dtype, SoftsignTilingData* tilingData)46static ge::graphStatus DoTilingByDtype(gert::TilingContext* context, ge::DataType dtype, SoftsignTilingData* tilingData)
47{47{
48 if (dtype == ge::DT_FLOAT) {48 if (dtype == ge::DT_FLOAT) {
49- return RunEleTiling<SoftsignOp::GraphSoftsign<float, float>::OpDag>(context, tilingData);49+ return RunEleTiling<SoftsignOp::GraphSoftsignByDtype<float>::OpDag>(context, tilingData);
50 } else if (dtype == ge::DT_FLOAT16) {50 } else if (dtype == ge::DT_FLOAT16) {
51- return RunEleTiling<SoftsignOp::GraphSoftsign<half, float>::OpDag>(context, tilingData);51+ return RunEleTiling<SoftsignOp::GraphSoftsignByDtype<half>::OpDag>(context, tilingData);
52 } else if (dtype == ge::DT_BF16) {52 } else if (dtype == ge::DT_BF16) {
53- return RunEleTiling<SoftsignOp::GraphSoftsign<bfloat16_t, float>::OpDag>(context, tilingData);53+ return RunEleTiling<SoftsignOp::GraphSoftsignByDtype<bfloat16_t>::OpDag>(context, tilingData);
54 }54 }
55 OP_LOGE(context, "Softsign: unsupported dtype=%d", static_cast<int>(dtype));55 OP_LOGE(context, "Softsign: unsupported dtype=%d", static_cast<int>(dtype));
56 return ge::GRAPH_FAILED;56 return ge::GRAPH_FAILED;
@@ -21,10 +21,14 @@
21 * | -> Div -> CopyOut -> y (GM)21 * | -> Div -> CopyOut -> y (GM)
22 * -> Abs -> Adds(+1) -----/22 * -> Abs -> Adds(+1) -----/
23 *23 *
24- * 数据流 (FP16/BF16):24+ * 数据流 (FP16/BF16, 与 TensorFlow 的原 dtype 计算语义对齐):
25- * x (GM) -> CopyIn -> CastIn(→FP32) -> SaveX(Vec::Copy) -----\25+ * x (GM) -> CopyIn -> CastIn(→FP32) -> SaveX(Vec::Copy) ----------------------------\
26- * | -> Div -> CastOut(→U) -> CopyOut -> y (GM)26+ * | -> Div
27- * -> Abs -> Adds(+1) ---------/27+ * -> Abs -> Adds(+1) -> CastDenomOut(→U) -> CastDenomIn(→FP32) -/
28+ * Div -> CastOut(→U) -> CopyOut -> y (GM)
29+ *
30+ * TensorFlow 在 FP16/BF16 下会先将 (abs(x) + 1) 舍入到原 dtype。因此分母需要显式窄化后再拓宽,
31+ * 不能在 FP32 中一次性完成所有中间计算。
28 */32 */
29 33 
30#ifndef SOFTSIGN_DAG_H34#ifndef SOFTSIGN_DAG_H
@@ -62,6 +66,35 @@ struct GraphSoftsign {
62 using OpDag = DAGSch<Outputs>;66 using OpDag = DAGSch<Outputs>;
63};67};
64 68 
69+template <typename U, typename T = float>
70+struct GraphSoftsignLowPrecision {
71+ using ConstOne = MAKE_CONST(float, 1);
72+ 
73+ using OpCopyIn = Bind<Vec::CopyIn<U>, Placeholder::In0<U>>;
74+ using OpCastIn = Bind<Vec::Cast<T, U, 0>, OpCopyIn>;
75+ using OpSaveX = Bind<Vec::Copy<T>, OpCastIn>;
76+ using OpAbs = Bind<Vec::Abs<T>, OpCastIn>;
77+ using OpAdds = Bind<Vec::Adds<T>, OpAbs, ConstOne>;
78+ using OpCastDenomOut = Bind<Vec::Cast<U, T, 1>, OpAdds>;
79+ using OpCastDenomIn = Bind<Vec::Cast<T, U, 0>, OpCastDenomOut>;
80+ using OpDiv = Bind<Vec::Div<T>, OpSaveX, OpCastDenomIn>;
81+ using OpCastOut = Bind<Vec::Cast<U, T, 1>, OpDiv>;
82+ using OpCopyOut = Bind<Vec::CopyOut<U>, Placeholder::Out0<U>, OpCastOut>;
83+ 
84+ using Outputs = Elems<OpCopyOut>;
85+ using OpDag = DAGSch<Outputs>;
86+};
87+ 
88+template <typename U>
89+struct GraphSoftsignByDtype {
90+ using OpDag = typename GraphSoftsignLowPrecision<U, float>::OpDag;
91+};
92+ 
93+template <>
94+struct GraphSoftsignByDtype<float> {
95+ using OpDag = typename GraphSoftsign<float, float>::OpDag;
96+};
97+ 
65} // namespace SoftsignOp98} // namespace SoftsignOp
66 99 
67#endif // SOFTSIGN_DAG_H100#endif // SOFTSIGN_DAG_H
@@ -33,9 +33,12 @@ __global__ __aicore__ void softsign(GM_ADDR x, GM_ADDR y, GM_ADDR workspace, GM_
33 KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY);33 KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_AIV_ONLY);
34 REGISTER_TILING_DEFAULT(SoftsignTilingData);34 REGISTER_TILING_DEFAULT(SoftsignTilingData);
35 GET_TILING_DATA_WITH_STRUCT(SoftsignTilingData, tilingData, tiling);35 GET_TILING_DATA_WITH_STRUCT(SoftsignTilingData, tilingData, tiling);
36+ if (tilingData.baseTiling.blockNum == 0) {
37+ return;
38+ }
36 TPipe pipe;39 TPipe pipe;
37 using InputT = DTYPE_X;40 using InputT = DTYPE_X;
38- using OpDag = GraphSoftsign<InputT, float>::OpDag;41+ using OpDag = GraphSoftsignByDtype<InputT>::OpDag;
39 ElementwiseSch<0UL, OpDag> sch(&(tilingData.baseTiling), &pipe);42 ElementwiseSch<0UL, OpDag> sch(&(tilingData.baseTiling), &pipe);
40 sch.Init(x, y);43 sch.Init(x, y);
41 sch.Process();44 sch.Process();