已合并
适配双输出场景 #9254
适配双输出场景 #9254
已合并
YuanTianyi创建于 13 天前
26 个文件变更+723-225
@@ -53,6 +53,7 @@ enum OpTypeV2 : size_t {
53 kConv3DBackpropInputV2,53 kConv3DBackpropInputV2,
54 kConv3DTransposeV2,54 kConv3DTransposeV2,
55 kExtendConvTranspose,55 kExtendConvTranspose,
56+ kExtendConvTransposeV2,
cheng_gao
cheng_gaocheng_gao8 天前

与TBE解耦,该枚举续迁移到conv目录

likedislike
56};57};
57 58 
58// 兼容opp整包、静态库和子包场景,向算子业务侧代码屏蔽差异:59// 兼容opp整包、静态库和子包场景,向算子业务侧代码屏蔽差异:
@@ -75,4 +76,4 @@ using optiling::GetTbeTiling;
75} // namespace NN76} // namespace NN
76} // namespace Ops77} // namespace Ops
77 78 
78-#endif // TBE_TILING_API_H79+#endif // TBE_TILING_API_H
@@ -64,6 +64,8 @@ ge::graphStatus Conv3DDXV2InnerProductTiling::GetPlatformInfo() { return ge::GRA
64 64 
65void Conv3DDXV2InnerProductTiling::Reset()65void Conv3DDXV2InnerProductTiling::Reset()
66{66{
67+ hasBiasFlag_ = false;
Y
Yyuxin511 天前

这次合入代码比较多,存在多个函数超长,建议统一排查下是否可以拆解下。

likedislike
68+ hasDualOutput_ = false;
67 OP_TILING_CHECK(memset_s(context_->GetRawTilingData()->GetData(), context_->GetRawTilingData()->GetCapacity(), 1,69 OP_TILING_CHECK(memset_s(context_->GetRawTilingData()->GetData(), context_->GetRawTilingData()->GetCapacity(), 1,
68 context_->GetRawTilingData()->GetCapacity()) != EOK,70 context_->GetRawTilingData()->GetCapacity()) != EOK,
69 CUBE_INNER_ERR_REPORT(opName_, "Fail to clear tiling data"), return);71 CUBE_INNER_ERR_REPORT(opName_, "Fail to clear tiling data"), return);
@@ -90,7 +92,8 @@ void Conv3DDXV2InnerProductTiling::Reset()
90 dxt.set_isBiasFullLoad(1);92 dxt.set_isBiasFullLoad(1);
91 dxt.set_enableVecTrans(1);93 dxt.set_enableVecTrans(1);
92 dxt.set_enableFullLoad(0);94 dxt.set_enableFullLoad(0);
93- dxt.set_quantMode(0);95+ dxt.set_quantMode0(0);
96+ dxt.set_quantMode1(0);
94 dxt.set_batch(1);97 dxt.set_batch(1);
95 dxt.set_cin(1);98 dxt.set_cin(1);
96 dxt.set_cout(1);99 dxt.set_cout(1);
@@ -200,6 +203,25 @@ ge::graphStatus Conv3DDXV2InnerProductTiling::GetLargeHkWkTilingMode()
200 return ge::GRAPH_SUCCESS;203 return ge::GRAPH_SUCCESS;
201}204}
202 205 
206+void Conv3DDXV2InnerProductTiling::SetFuseTilingRunInfo()
207+{
208+ const auto fixedShiftVal = context_->GetAttrs()->GetAttrPointer<int64_t>(FIXED_SHIFT_VAL_INDEX);
209+ const auto fixedShiftValDefault = runInfo_.b_dtype_bytes == 1 ? DEFAULT_FIXED_SHIFT_VAL_A16W8 :
210+ DEFAULT_FIXED_SHIFT_VAL;
211+ if (fixedShiftVal == nullptr || *fixedShiftVal <= 0 ||
212+ *fixedShiftVal > static_cast<int64_t>(fixedShiftValDefault)) {
213+ runInfo_.fixedShiftVal = fixedShiftValDefault;
214+ } else {
215+ runInfo_.fixedShiftVal = static_cast<uint8_t>(*fixedShiftVal);
216+ }
217+ 
218+ if (opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) {
219+ const auto dualOutput = context_->GetAttrs()->GetAttrPointer<bool>(DUAL_OUTPUT_EXTEND_CONV_TRANSPOSE_INDEX);
220+ hasDualOutput_ = dualOutput != nullptr && *dualOutput;
221+ tilingData_.set_dualOutput(hasDualOutput_);
222+ }
223+}
224+ 
203ge::graphStatus Conv3DDXV2InnerProductTiling::GetPublicShapeAttrsInfo()225ge::graphStatus Conv3DDXV2InnerProductTiling::GetPublicShapeAttrsInfo()
204{226{
205 // 输入输出 dtype校验等227 // 输入输出 dtype校验等
@@ -214,29 +236,27 @@ ge::graphStatus Conv3DDXV2InnerProductTiling::GetPublicShapeAttrsInfo()
214 }236 }
215 237 
216 auto biasShape = context_->GetOptionalInputShape(BAIS_INDEX);238 auto biasShape = context_->GetOptionalInputShape(BAIS_INDEX);
217- auto scaleShape = context_->GetOptionalInputShape(SCALE_INDEX);239+ auto scale0Shape = context_->GetOptionalInputShape(SCALE0_INDEX);
240+ const auto scale1Shape = opType_ == optiling::OpTypeV2::kExtendConvTransposeV2 ?
241+ context_->GetOptionalInputShape(SCALE1_INDEX) :
242+ nullptr;
218 hasBiasFlag_ = biasShape != nullptr && biasShape->GetStorageShape().GetShapeSize() != 0;243 hasBiasFlag_ = biasShape != nullptr && biasShape->GetStorageShape().GetShapeSize() != 0;
219- hasScaleFlag_ = scaleShape != nullptr && scaleShape->GetStorageShape().GetShapeSize() != 0;244+ if (scale0Shape != nullptr && scale0Shape->GetStorageShape().GetShapeSize() != 0) {
220- if (hasScaleFlag_) {245+ runInfo_.quantMode0 = scale0Shape->GetStorageShape().GetDim(0) == 1 ?
221- if (scaleShape->GetStorageShape().GetDim(0) == 1) {246+ static_cast<uint8_t>(QuantMode::SCALAR_QUANT) :
222- runInfo_.quantMode = static_cast<uint8_t>(QuantMode::SCALAR_QUANT);247+ static_cast<uint8_t>(QuantMode::VECTOR_QUANT);
223- } else {248+ }
224- runInfo_.quantMode = static_cast<uint8_t>(QuantMode::VECTOR_QUANT);249+ if (scale1Shape != nullptr && scale1Shape->GetStorageShape().GetShapeSize() != 0) {
225- }250+ runInfo_.quantMode1 = scale1Shape->GetStorageShape().GetDim(0) == 1 ?
251+ static_cast<uint8_t>(QuantMode::SCALAR_QUANT) :
252+ static_cast<uint8_t>(QuantMode::VECTOR_QUANT);
226 }253 }
227 254 
228 const auto offset = context_->GetAttrs()->GetAttrPointer<int64_t>(OFFSET_X_INDEX);255 const auto offset = context_->GetAttrs()->GetAttrPointer<int64_t>(OFFSET_X_INDEX);
229 runInfo_.offsetX = (offset != nullptr) ? static_cast<int8_t>(*offset) : 0;256 runInfo_.offsetX = (offset != nullptr) ? static_cast<int8_t>(*offset) : 0;
230 runInfo_.fixedShiftVal = 0;257 runInfo_.fixedShiftVal = 0;
231 if (IsSocVersionFuse(context_)) {258 if (IsSocVersionFuse(context_)) {
232- auto fixedShiftVal = context_->GetAttrs()->GetAttrPointer<int64_t>(FIXED_SHIFT_VAL_INDEX);259+ SetFuseTilingRunInfo();
233- auto fixedShiftValDefault = runInfo_.b_dtype_bytes == 1 ? DEFAULT_FIXED_SHIFT_VAL_A16W8 :
234- DEFAULT_FIXED_SHIFT_VAL;
235- if (fixedShiftVal == nullptr || static_cast<uint8_t>(*fixedShiftVal) == 0) {
236- runInfo_.fixedShiftVal = fixedShiftValDefault;
237- } else {
238- runInfo_.fixedShiftVal = static_cast<uint8_t>(*fixedShiftVal);
239- }
240 }260 }
241 blockSize_ = BYTE_BLOCK / runInfo_.b_dtype_bytes;261 blockSize_ = BYTE_BLOCK / runInfo_.b_dtype_bytes;
242 dtypeByteL0a_ = runInfo_.a_dtype_bytes;262 dtypeByteL0a_ = runInfo_.a_dtype_bytes;
@@ -250,7 +270,6 @@ ge::graphStatus Conv3DDXV2InnerProductTiling::GetPublicShapeAttrsInfo()
250 coreNum_),270 coreNum_),
251 return ge::GRAPH_FAILED);271 return ge::GRAPH_FAILED);
252 SetRunInfoTiling(tilingData_);272 SetRunInfoTiling(tilingData_);
253- 
254 return ge::GRAPH_SUCCESS;273 return ge::GRAPH_SUCCESS;
255}274}
256 275 
@@ -353,7 +372,8 @@ bool Conv3DDXV2InnerProductTiling::GetShapeFormatInfo()
353 size_t aMatrixIndex = OUTPUT_BP_INDEX;372 size_t aMatrixIndex = OUTPUT_BP_INDEX;
354 size_t bMatrixIndex = FILTER_INDEX;373 size_t bMatrixIndex = FILTER_INDEX;
355 374 
356- if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose) {375+ if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
376+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) {
357 aMatrixIndex = FILTER_INDEX;377 aMatrixIndex = FILTER_INDEX;
358 bMatrixIndex = OUTPUT_BP_INDEX;378 bMatrixIndex = OUTPUT_BP_INDEX;
359 }379 }
@@ -444,7 +464,8 @@ bool Conv3DDXV2InnerProductTiling::AnalyzeDtype() const
444 size_t outputBackpropIndex = OUTPUT_BP_INDEX;464 size_t outputBackpropIndex = OUTPUT_BP_INDEX;
445 size_t filterIndex = FILTER_INDEX;465 size_t filterIndex = FILTER_INDEX;
446 466 
447- if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose) {467+ if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
468+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) {
448 outputBackpropIndex = FILTER_INDEX;469 outputBackpropIndex = FILTER_INDEX;
449 filterIndex = OUTPUT_BP_INDEX;470 filterIndex = OUTPUT_BP_INDEX;
450 }471 }
@@ -478,7 +499,8 @@ bool Conv3DDXV2InnerProductTiling::AnalyzeDtype() const
478 }499 }
479 500 
480 OP_TILING_CHECK(501 OP_TILING_CHECK(
481- (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose) &&502+ (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
503+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) &&
482 inputSizeDtype != ge::DT_INT32 && inputSizeDtype != ge::DT_INT64,504 inputSizeDtype != ge::DT_INT32 && inputSizeDtype != ge::DT_INT64,
483 OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON(opName_, "input_size",505 OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON(opName_, "input_size",
484 ge::TypeUtils::DataTypeToSerialString(inputSizeDtype).c_str(),506 ge::TypeUtils::DataTypeToSerialString(inputSizeDtype).c_str(),
@@ -1006,7 +1028,7 @@ void Conv3DDXV2InnerProductTiling::TranslateTilingData(
1006 dxt.set_isBiasFullLoad(tunerTiling->isBiasFullLoad);1028 dxt.set_isBiasFullLoad(tunerTiling->isBiasFullLoad);
1007 dxt.set_enableVecTrans(tunerTiling->enableVecTrans);1029 dxt.set_enableVecTrans(tunerTiling->enableVecTrans);
1008 dxt.set_enableFullLoad(tunerTiling->enableFullLoad);1030 dxt.set_enableFullLoad(tunerTiling->enableFullLoad);
1009- dxt.set_quantMode(tunerTiling->quantMode);1031+ dxt.set_quantMode0(tunerTiling->quantMode0);
1010 dxt.set_cinG(tunerTiling->cinG);1032 dxt.set_cinG(tunerTiling->cinG);
1011 dxt.set_coutG(tunerTiling->coutG);1033 dxt.set_coutG(tunerTiling->coutG);
1012 dxt.set_cout1(tunerTiling->cout1);1034 dxt.set_cout1(tunerTiling->cout1);
@@ -1030,7 +1052,7 @@ void Conv3DDXV2InnerProductTiling::TranslateTilingData(
1030 dxt.set_singleIterateDk(tunerTiling->singleIterateDk);1052 dxt.set_singleIterateDk(tunerTiling->singleIterateDk);
1031 dxt.set_singleCoreBatch(tunerTiling->singleCoreBatch);1053 dxt.set_singleCoreBatch(tunerTiling->singleCoreBatch);
1032 dxt.set_singleCoreM(tunerTiling->singleCoreM);1054 dxt.set_singleCoreM(tunerTiling->singleCoreM);
1033- dxt.set_enRelu(tunerTiling->enRelu);1055+ dxt.set_enRelu0(tunerTiling->enRelu0);
1034 dxt.set_kSegment(tunerTiling->kSegment);1056 dxt.set_kSegment(tunerTiling->kSegment);
1035 dxt.set_kSegmentTail(tunerTiling->kSegmentTail);1057 dxt.set_kSegmentTail(tunerTiling->kSegmentTail);
1036 dxt.set_kValueSegment(tunerTiling->kValueSegment);1058 dxt.set_kValueSegment(tunerTiling->kValueSegment);
@@ -1228,8 +1250,9 @@ bool Conv3DDXV2InnerProductTiling::IsL1ParamsValid(const L1TilingParams& l1Param
1228 1250 
1229 uint64_t biasSize = 0;1251 uint64_t biasSize = 0;
1230 uint64_t scaleSize = 0;1252 uint64_t scaleSize = 0;
1231- if (hasScaleFlag_ && runInfo_.quantMode == static_cast<uint8_t>(QuantMode::VECTOR_QUANT)) {1253+ const uint32_t vectorScaleCount = GetVectorScaleCount();
1232- scaleSize = ge::GetSizeByDataType(ge::DT_INT64) * l0Params.baseN;1254+ if (vectorScaleCount != 0U) {
1255+ scaleSize = ge::GetSizeByDataType(ge::DT_INT64) * l0Params.baseN * vectorScaleCount;
1233 }1256 }
1234 if (hasBiasFlag_) {1257 if (hasBiasFlag_) {
1235 uint64_t dtypeByteBtBuffer = (runInfo_.a_dtype_bytes == ge::GetSizeByDataType(ge::DT_INT8)) ?1258 uint64_t dtypeByteBtBuffer = (runInfo_.a_dtype_bytes == ge::GetSizeByDataType(ge::DT_INT8)) ?
@@ -1286,8 +1309,8 @@ void Conv3DDXV2InnerProductTiling::InitBaseMNK(L0TilingParams& l0Params)
1286 if (runInfo_.kernel_h == ENABLE_TILING_HK_WK && runInfo_.kernel_w == ENABLE_TILING_HK_WK &&1309 if (runInfo_.kernel_h == ENABLE_TILING_HK_WK && runInfo_.kernel_w == ENABLE_TILING_HK_WK &&
1287 l0Params.baseM == BASIC_BLOCK_SIZE_512 && l0Params.baseK <= BASIC_BLOCK_SIZE_16 &&1310 l0Params.baseM == BASIC_BLOCK_SIZE_512 && l0Params.baseK <= BASIC_BLOCK_SIZE_16 &&
1288 totalCnt >= coreNum_ * TOTAL_CNT_LOWER_RATIO && totalCnt <= coreNum_ * TOTAL_CNT_UPPER_RATIO) {1311 totalCnt >= coreNum_ * TOTAL_CNT_LOWER_RATIO && totalCnt <= coreNum_ * TOTAL_CNT_UPPER_RATIO) {
1289- if ((opType_ != optiling::OpTypeV2::kConv3DTransposeV2 &&1312+ if ((opType_ != optiling::OpTypeV2::kConv3DTransposeV2 && opType_ != optiling::OpTypeV2::kExtendConvTranspose &&
1290- opType_ != optiling::OpTypeV2::kExtendConvTranspose) &&1313+ opType_ != optiling::OpTypeV2::kExtendConvTransposeV2) &&
1291 hwi >= BASIC_BLOCK_SIZE_512 &&1314 hwi >= BASIC_BLOCK_SIZE_512 &&
1292 (alignedWiAl1 * mCnt < tilingRunInfo_.mValue || alignedWiAl1 >= BASIC_BLOCK_SIZE_512)) {1315 (alignedWiAl1 * mCnt < tilingRunInfo_.mValue || alignedWiAl1 >= BASIC_BLOCK_SIZE_512)) {
1293 l0Params.baseM = BASIC_BLOCK_SIZE_256;1316 l0Params.baseM = BASIC_BLOCK_SIZE_256;
@@ -1856,8 +1879,10 @@ void Conv3DDXV2InnerProductTiling::SetRunInfoTiling(optiling::Conv3DBackpropInpu
1856 dxt.set_initOutputFlag(runInfo_.initOutputFlag);1879 dxt.set_initOutputFlag(runInfo_.initOutputFlag);
1857 dxt.set_isBiasFullLoad(isBiasFullLoad_);1880 dxt.set_isBiasFullLoad(isBiasFullLoad_);
1858 dxt.set_singleIterateDk(singleIterateDk_);1881 dxt.set_singleIterateDk(singleIterateDk_);
1859- dxt.set_enRelu(runInfo_.enRelu);1882+ dxt.set_enRelu0(runInfo_.enRelu0);
1860- dxt.set_quantMode(runInfo_.quantMode);1883+ dxt.set_enRelu1(runInfo_.enRelu1);
1884+ dxt.set_quantMode0(runInfo_.quantMode0);
1885+ dxt.set_quantMode1(runInfo_.quantMode1);
1861 dxt.set_offsetX(runInfo_.offsetX);1886 dxt.set_offsetX(runInfo_.offsetX);
1862 dxt.set_fixedShiftVal(runInfo_.fixedShiftVal);1887 dxt.set_fixedShiftVal(runInfo_.fixedShiftVal);
1863}1888}
@@ -1939,11 +1964,13 @@ bool Conv3DDXV2InnerProductTiling::PrintInputsAttrs(optiling::Conv3DBackpropInpu
1939{1964{
1940 const auto op_name = context_->GetNodeName();1965 const auto op_name = context_->GetNodeName();
1941 size_t weight_index = (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 ||1966 size_t weight_index = (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 ||
1942- opType_ == optiling::OpTypeV2::kExtendConvTranspose) ?1967+ opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
1968+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) ?
1943 TRANSPOSE_FILTER_INDEX :1969 TRANSPOSE_FILTER_INDEX :
1944 FILTER_INDEX; // dx filter idx 1 | transpose filter idx 21970 FILTER_INDEX; // dx filter idx 1 | transpose filter idx 2
1945 size_t dedy_x_index = (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 ||1971 size_t dedy_x_index = (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 ||
1946- opType_ == optiling::OpTypeV2::kExtendConvTranspose) ?1972+ opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
1973+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) ?
1947 TRANSPOSE_X_INDEX :1974 TRANSPOSE_X_INDEX :
1948 OUTPUT_BP_INDEX; // dx dedy idx 2 | transpose x idx 11975 OUTPUT_BP_INDEX; // dx dedy idx 2 | transpose x idx 1
1949 auto inputSizeInfo = GetTensorInfo(context_, INPUT_SIZE_INDEX, true, kInputSizeDim); // input_size dim=11976 auto inputSizeInfo = GetTensorInfo(context_, INPUT_SIZE_INDEX, true, kInputSizeDim); // input_size dim=1
@@ -1986,24 +2013,26 @@ void Conv3DDXV2InnerProductTiling::PrintOpAttrs(const std::string& opName,
1986 auto attrs = context_->GetAttrs();2013 auto attrs = context_->GetAttrs();
1987 const auto groups = attrs->GetAttrPointer<int64_t>(groupIndex);2014 const auto groups = attrs->GetAttrPointer<int64_t>(groupIndex);
1988 size_t enable_hf32_index = (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 ||2015 size_t enable_hf32_index = (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 ||
1989- opType_ == optiling::OpTypeV2::kExtendConvTranspose) ?2016+ opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
2017+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) ?
1990 TRANSPOSE_ENABLE_HF32_INDEX :2018 TRANSPOSE_ENABLE_HF32_INDEX :
1991 ENABLE_HF32_INDEX; // dx hf32 idx 5 | transpose hf32 idx 72019 ENABLE_HF32_INDEX; // dx hf32 idx 5 | transpose hf32 idx 7
1992 const auto enableHf32 = attrs->GetAttrPointer<bool>(enable_hf32_index);2020 const auto enableHf32 = attrs->GetAttrPointer<bool>(enable_hf32_index);
1993 OP_CHECK_IF(groups == nullptr, CUBE_INNER_ERR_REPORT(opName, "get groups from context fail."), return);2021 OP_CHECK_IF(groups == nullptr, CUBE_INNER_ERR_REPORT(opName, "get groups from context fail."), return);
1994 if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2) {2022 if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2) {
1995 auto output_paddingShape = GetAttrVector(context_, OUTPUT_PADDING_INDEX, kConv3DbpDim, "output_padding");2023 auto output_paddingShape = GetAttrVector(context_, OUTPUT_PADDING_INDEX, kConv3DbpDim, "output_padding");
1996- const auto offset = attrs->GetAttrPointer<bool>(OFFSET_X_INDEX);2024+ const auto offset = attrs->GetAttrPointer<int64_t>(OFFSET_X_INDEX);
1997 OP_LOGD(2025 OP_LOGD(
1998 opName,2026 opName,
1999 "Attrs stride: %s, pads: %s, dilation: %s, groups: %ld, enable_hf32: %d, output_padding: %s, offset_x: %ld",2027 "Attrs stride: %s, pads: %s, dilation: %s, groups: %ld, enable_hf32: %d, output_padding: %s, offset_x: %ld",
2000 DebugString(stridesShape).c_str(), DebugString(padsShape).c_str(), DebugString(dilationsShape).c_str(),2028 DebugString(stridesShape).c_str(), DebugString(padsShape).c_str(), DebugString(dilationsShape).c_str(),
2001 *groups, *enableHf32, DebugString(output_paddingShape).c_str(), *offset);2029 *groups, *enableHf32, DebugString(output_paddingShape).c_str(), *offset);
2002- } else if (opType_ == optiling::OpTypeV2::kExtendConvTranspose) {2030+ } else if (opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
2031+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) {
2003 auto output_paddingShape = GetAttrVector(context_, OUTPUT_PADDING_INDEX, kConv3DbpDim, "output_padding");2032 auto output_paddingShape = GetAttrVector(context_, OUTPUT_PADDING_INDEX, kConv3DbpDim, "output_padding");
2004- const auto offset = attrs->GetAttrPointer<bool>(OFFSET_X_INDEX);2033+ const auto offset = attrs->GetAttrPointer<int64_t>(OFFSET_X_INDEX);
2005- const auto fusion_mode = attrs->GetAttrPointer<int32_t>(K_FUSION_MODE_CONV3D_TRANSPOSE_IDX);2034+ const auto fusion_mode = attrs->GetAttrPointer<int64_t>(K_FUSION_MODE_CONV3D_TRANSPOSE_IDX);
2006- const auto y_quant_mode = attrs->GetAttrPointer<int32_t>(K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX);2035+ const auto y_quant_mode = attrs->GetAttrPointer<int64_t>(K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX);
2007 OP_LOGD(opName,2036 OP_LOGD(opName,
2008 "Attrs stride: %s, pads: %s, dilation: %s, groups: %ld, output_padding: %s, offset_x: %ld, "2037 "Attrs stride: %s, pads: %s, dilation: %s, groups: %ld, output_padding: %s, offset_x: %ld, "
2009 "fusion_mode: %s, y_quant_mode: %s",2038 "fusion_mode: %s, y_quant_mode: %s",
@@ -2049,7 +2078,6 @@ void Conv3DDXV2InnerProductTiling::PrintTilingData()
2049 << " enableVecTrans: " << static_cast<uint32_t>(tiling.get_enableVecTrans())2078 << " enableVecTrans: " << static_cast<uint32_t>(tiling.get_enableVecTrans())
2050 << " kSCoutFullLoad: " << tiling.get_kSCoutFullLoad() << " kSUseWorkSpace: " << tiling.get_kSUseWorkSpace()2079 << " kSCoutFullLoad: " << tiling.get_kSCoutFullLoad() << " kSUseWorkSpace: " << tiling.get_kSUseWorkSpace()
2051 << " enableFullLoad: " << static_cast<uint32_t>(tiling.get_enableFullLoad())2080 << " enableFullLoad: " << static_cast<uint32_t>(tiling.get_enableFullLoad())
2052- << " quantMode: " << static_cast<uint32_t>(tiling.get_quantMode()) << " enRelu: " << tiling.get_enRelu()
2053 << " enableSplitK: " << static_cast<uint32_t>(tiling.get_enableSplitK())2081 << " enableSplitK: " << static_cast<uint32_t>(tiling.get_enableSplitK())
2054 << " useUbAccumForSplitK: " << static_cast<uint32_t>(tiling.get_useUbAccumForSplitK())2082 << " useUbAccumForSplitK: " << static_cast<uint32_t>(tiling.get_useUbAccumForSplitK())
2055 << " kSegment: " << tiling.get_kSegment() << " kSegmentTail: " << tiling.get_kSegmentTail()2083 << " kSegment: " << tiling.get_kSegment() << " kSegmentTail: " << tiling.get_kSegmentTail()
@@ -2079,8 +2107,13 @@ void Conv3DDXV2InnerProductTiling::PrintRunInfoData()
2079 << " dilation_w:" << runInfo_.dilation_w << " enlarge: " << runInfo_.enlarge2107 << " dilation_w:" << runInfo_.dilation_w << " enlarge: " << runInfo_.enlarge
2080 << " hf32_flag: " << runInfo_.hf32_flag << " a_dtype_bytes:" << runInfo_.a_dtype_bytes2108 << " hf32_flag: " << runInfo_.hf32_flag << " a_dtype_bytes:" << runInfo_.a_dtype_bytes
2081 << " b_dtype_bytes: " << runInfo_.b_dtype_bytes << " c_dtype_bytes: " << runInfo_.c_dtype_bytes2109 << " b_dtype_bytes: " << runInfo_.b_dtype_bytes << " c_dtype_bytes: " << runInfo_.c_dtype_bytes
2082- << " initOutputFlag: " << runInfo_.initOutputFlag << " enRelu: " << static_cast<uint32_t>(runInfo_.enRelu)2110+ << " initOutputFlag: " << runInfo_.initOutputFlag << " enRelu0: " << static_cast<uint32_t>(runInfo_.enRelu0)
2083- << " quantMode: " << static_cast<uint32_t>(runInfo_.quantMode)2111+ << " enRelu1: " << static_cast<uint32_t>(runInfo_.enRelu1)
2112+ << " quantMode0: " << static_cast<uint32_t>(runInfo_.quantMode0)
2113+ << " quantMode1: " << static_cast<uint32_t>(runInfo_.quantMode1)
2114+ << " hasDualOutput: " << static_cast<uint32_t>(hasDualOutput_)
2115+ << " offsetX: " << static_cast<int32_t>(runInfo_.offsetX)
2116+ << " fixedShiftVal: " << static_cast<uint32_t>(runInfo_.fixedShiftVal)
2084 << " outBackpropFormat: " << static_cast<uint32_t>(runInfo_.outBackpropFormat)2117 << " outBackpropFormat: " << static_cast<uint32_t>(runInfo_.outBackpropFormat)
2085 << " filterFormat: " << static_cast<uint32_t>(runInfo_.filterFormat)2118 << " filterFormat: " << static_cast<uint32_t>(runInfo_.filterFormat)
2086 << " yFormat: " << static_cast<uint32_t>(runInfo_.yFormat)2119 << " yFormat: " << static_cast<uint32_t>(runInfo_.yFormat)
@@ -50,14 +50,17 @@ const size_t OUTPUT_BP_INDEX = 2;
50const size_t TRANSPOSE_X_INDEX = 1;50const size_t TRANSPOSE_X_INDEX = 1;
51const size_t TRANSPOSE_FILTER_INDEX = 2;51const size_t TRANSPOSE_FILTER_INDEX = 2;
52const size_t BAIS_INDEX = 3;52const size_t BAIS_INDEX = 3;
53-const size_t SCALE_INDEX = 4;53+const size_t SCALE0_INDEX = 4;
54+const size_t SCALE1_INDEX = 5; // MDC双输出场景下的第二个output对应的Scale1 input索引
54const size_t ENABLE_HF32_INDEX = 5;55const size_t ENABLE_HF32_INDEX = 5;
55const size_t OUTPUT_PADDING_INDEX = 5;56const size_t OUTPUT_PADDING_INDEX = 5;
56const size_t OFFSET_X_INDEX = 6;57const size_t OFFSET_X_INDEX = 6;
57const size_t TRANSPOSE_ENABLE_HF32_INDEX = 7;58const size_t TRANSPOSE_ENABLE_HF32_INDEX = 7;
58const size_t K_FUSION_MODE_CONV3D_TRANSPOSE_IDX = 7;59const size_t K_FUSION_MODE_CONV3D_TRANSPOSE_IDX = 7;
59const size_t K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX = 8;60const size_t K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX = 8;
60-const size_t FIXED_SHIFT_VAL_INDEX = 10;61+ 
62+const size_t FIXED_SHIFT_VAL_INDEX = 10; // MDC定点数量化fixedShiftVal Attr索引
63+const size_t DUAL_OUTPUT_EXTEND_CONV_TRANSPOSE_INDEX = 11; // MDC双输出场景标识符 Attr索引
61 64 
62struct DtypeFlags {65struct DtypeFlags {
63 bool hif8flag = false;66 bool hif8flag = false;
@@ -110,6 +113,7 @@ protected:
110 bool GetShapeFormatInfo();113 bool GetShapeFormatInfo();
111 bool AnalyzeDtype() const;114 bool AnalyzeDtype() const;
112 ge::graphStatus GetPublicShapeAttrsInfo();115 ge::graphStatus GetPublicShapeAttrsInfo();
116+ void SetFuseTilingRunInfo();
113 bool CheckDtypeFormatAttrs(size_t aMatrixesIndex, size_t bMatrixesIndex, bool hif8flag, bool fp8e4m3flag) const;117 bool CheckDtypeFormatAttrs(size_t aMatrixesIndex, size_t bMatrixesIndex, bool hif8flag, bool fp8e4m3flag) const;
114 void EqualL1MatchStepMNKCore(L1TilingParams& l1Params, const L0TilingParams& l0Params, uint64_t curHiWiSize,118 void EqualL1MatchStepMNKCore(L1TilingParams& l1Params, const L0TilingParams& l0Params, uint64_t curHiWiSize,
115 bool isNeedShrinkStepKa = false);119 bool isNeedShrinkStepKa = false);
@@ -164,12 +168,18 @@ protected:
164 void PrintTilingSummary();168 void PrintTilingSummary();
165 bool PrintInputsAttrs(optiling::Conv3DBackpropInputArch35TilingData& tiling);169 bool PrintInputsAttrs(optiling::Conv3DBackpropInputArch35TilingData& tiling);
166 void PrintOpAttrs(const std::string& opName, optiling::Conv3DBackpropInputArch35TilingData& tiling);170 void PrintOpAttrs(const std::string& opName, optiling::Conv3DBackpropInputArch35TilingData& tiling);
171+ uint32_t GetVectorScaleCount() const
172+ {
173+ const uint32_t scale0Count = runInfo_.quantMode0 == static_cast<uint8_t>(QuantMode::VECTOR_QUANT) ? 1U : 0U;
174+ const uint32_t scale1Count = runInfo_.quantMode1 == static_cast<uint8_t>(QuantMode::VECTOR_QUANT) ? 1U : 0U;
175+ return scale0Count + scale1Count;
176+ }
167 177 
168 bool a1DbFlag_ = false;178 bool a1DbFlag_ = false;
169 bool b1DbFlag_ = false;179 bool b1DbFlag_ = false;
170 bool c0DbFlag_ = false;180 bool c0DbFlag_ = false;
171 bool hasBiasFlag_ = false;181 bool hasBiasFlag_ = false;
172- bool hasScaleFlag_ = false;182+ bool hasDualOutput_ = false;
173 uint8_t loadB2Condition_ = 0;183 uint8_t loadB2Condition_ = 0;
174 uint8_t loadB1Condition_ = 0;184 uint8_t loadB1Condition_ = 0;
175 uint8_t kernelSplitMode_ = 0;185 uint8_t kernelSplitMode_ = 0;
@@ -245,8 +245,9 @@ bool Conv3DDXV2KernelSplitTiling::IsBaseShapeFitKernelSplitHW(const uint32_t bes
245 availableL1size -= biasSize;245 availableL1size -= biasSize;
246 }246 }
247 247 
248- if (hasScaleFlag_ && runInfo_.quantMode == static_cast<uint8_t>(QuantMode::VECTOR_QUANT)) {248+ const uint32_t vectorScaleCount = GetVectorScaleCount();
249- uint64_t scaleSize = ge::GetSizeByDataType(ge::DT_INT64) * runInfo_.dedx_cin_g;249+ if (vectorScaleCount != 0U) {
250+ uint64_t scaleSize = ge::GetSizeByDataType(ge::DT_INT64) * runInfo_.dedx_cin_g * vectorScaleCount;
250 availableL1size -= scaleSize;251 availableL1size -= scaleSize;
251 }252 }
252 253 
@@ -348,7 +349,8 @@ bool Conv3DDXV2KernelSplitTiling::CheckDtypeCompatibility()
348 349 
349 size_t filterIndex = FILTER_INDEX;350 size_t filterIndex = FILTER_INDEX;
350 size_t outputBackpropIndex = OUTPUT_BP_INDEX;351 size_t outputBackpropIndex = OUTPUT_BP_INDEX;
351- if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose) {352+ if (opType_ == optiling::OpTypeV2::kConv3DTransposeV2 || opType_ == optiling::OpTypeV2::kExtendConvTranspose ||
353+ opType_ == optiling::OpTypeV2::kExtendConvTransposeV2) {
352 outputBackpropIndex = FILTER_INDEX;354 outputBackpropIndex = FILTER_INDEX;
353 filterIndex = OUTPUT_BP_INDEX;355 filterIndex = OUTPUT_BP_INDEX;
354 }356 }
@@ -454,7 +456,8 @@ bool Conv3DDXV2KernelSplitTiling::CheckKernelSplitEnable()
454 456 
455 constexpr uint32_t bestBaseMN = 256;457 constexpr uint32_t bestBaseMN = 256;
456 458 
457- if (TryKernelSplitHW(bestBaseMN)) {459+ // 开启双输出不支持KernelSplitHW场景
460+ if (!hasDualOutput_ && TryKernelSplitHW(bestBaseMN)) {
458 return true;461 return true;
459 }462 }
460 463 
@@ -686,8 +689,9 @@ bool Conv3DDXV2KernelSplitTiling::IsL1ParamsValid(const L1TilingParams& l1Params
686 // biasL1 size 需按 64B 对齐:kernel 侧 InitBiasTque 按 64B 分配(L1→BT DataCopy 按 64B 粒度)。689 // biasL1 size 需按 64B 对齐:kernel 侧 InitBiasTque 按 64B 分配(L1→BT DataCopy 按 64B 粒度)。
687 biasSize = Ops::Base::CeilAlign(dtypeByteBtBuffer * runInfo_.dedx_cin_g, BYTE_64);690 biasSize = Ops::Base::CeilAlign(dtypeByteBtBuffer * runInfo_.dedx_cin_g, BYTE_64);
688 }691 }
689- if (hasScaleFlag_ && runInfo_.quantMode == static_cast<uint8_t>(QuantMode::VECTOR_QUANT)) {692+ const uint32_t vectorScaleCount = GetVectorScaleCount();
690- scaleSize = ge::GetSizeByDataType(ge::DT_INT64) * runInfo_.dedx_cin_g;693+ if (vectorScaleCount != 0U) {
694+ scaleSize = ge::GetSizeByDataType(ge::DT_INT64) * runInfo_.dedx_cin_g * vectorScaleCount;
691 }695 }
692 return aL1Size + bL1Size + biasSize + scaleSize <= platformInfo_.l1_size;696 return aL1Size + bL1Size + biasSize + scaleSize <= platformInfo_.l1_size;
693}697}
@@ -323,8 +323,9 @@ uint64_t Conv3DDXV2SmallKernelTiling::CalcSmallKernelL1FixedSize() const
323 biasSize = Ops::Base::CeilAlign(cinAlign * dtypeByteBtBuffer, BYTE_64);323 biasSize = Ops::Base::CeilAlign(cinAlign * dtypeByteBtBuffer, BYTE_64);
324 }324 }
325 uint64_t scaleSize = 0;325 uint64_t scaleSize = 0;
326- if (hasScaleFlag_ && runInfo_.quantMode == static_cast<uint8_t>(QuantMode::VECTOR_QUANT)) {326+ const uint32_t vectorScaleCount = GetVectorScaleCount();
327- scaleSize = cinAlign * ge::GetSizeByDataType(ge::DT_INT64);327+ if (vectorScaleCount != 0U) {
328+ scaleSize = cinAlign * ge::GetSizeByDataType(ge::DT_INT64) * vectorScaleCount;
328 }329 }
329 return b1Size + biasSize + scaleSize;330 return b1Size + biasSize + scaleSize;
330}331}
@@ -314,17 +314,17 @@ bool CheckTransposeAttr(gert::TilingContext* context, OtherParams& otherParams)
314 }314 }
315 if (IsSocVersionFuse(context)) {315 if (IsSocVersionFuse(context)) {
316 if (attrs->GetAttrNum() > K_FUSION_MODE_CONV3D_TRANSPOSE_IDX) {316 if (attrs->GetAttrNum() > K_FUSION_MODE_CONV3D_TRANSPOSE_IDX) {
317- const auto fusion_mode = attrs->GetAttrPointer<int32_t>(K_FUSION_MODE_CONV3D_TRANSPOSE_IDX);317+ const auto fusion_mode = attrs->GetAttrPointer<int64_t>(K_FUSION_MODE_CONV3D_TRANSPOSE_IDX);
S

common下面的改动,都要确认对A2/A3的影响

likedislike
YuanTianyi
11 天前 评论:
318 OP_CHECK_IF(fusion_mode == nullptr,318 OP_CHECK_IF(fusion_mode == nullptr,
319 CUBE_INNER_ERR_REPORT(context->GetNodeName(), "failed to get fusion_mode attrs"), return false);319 CUBE_INNER_ERR_REPORT(context->GetNodeName(), "failed to get fusion_mode attrs"), return false);
320- OP_CHECK_IF(*fusion_mode != 0 && *fusion_mode != 1,320+ OP_CHECK_IF(*fusion_mode < 0 || *fusion_mode > 3,
321 OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(context->GetNodeName(), "fusion_mode",321 OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(context->GetNodeName(), "fusion_mode",
322 std::to_string(*fusion_mode).c_str(),322 std::to_string(*fusion_mode).c_str(),
323- "The value of fusion_mode must be in {0, 1}"),323+ "The value of fusion_mode must be in {0, 1, 2, 3}"),
324 return false);324 return false);
325 }325 }
326 if (attrs->GetAttrNum() > K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX) {326 if (attrs->GetAttrNum() > K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX) {
327- const auto y_quant_mode = attrs->GetAttrPointer<int32_t>(K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX);327+ const auto y_quant_mode = attrs->GetAttrPointer<int64_t>(K_Y_QUANT_MODE_CONV3D_TRANSPOSE_IDX);
328 OP_CHECK_IF(y_quant_mode == nullptr,328 OP_CHECK_IF(y_quant_mode == nullptr,
329 CUBE_INNER_ERR_REPORT(context->GetNodeName(), "failed to get quant_mode attrs"), return false);329 CUBE_INNER_ERR_REPORT(context->GetNodeName(), "failed to get quant_mode attrs"), return false);
330 OP_CHECK_IF(*y_quant_mode != 0,330 OP_CHECK_IF(*y_quant_mode != 0,
@@ -407,7 +407,8 @@ bool UpdateDtypeParams(const gert::TilingContext* context, Conv3dBpInputV2RunInf
407{407{
408 const auto op_name = context->GetNodeName();408 const auto op_name = context->GetNodeName();
409 409 
410- if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose) {410+ if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose ||
411+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
411 // Conv3DTranspose, index of x is 1, index of filter is 2412 // Conv3DTranspose, index of x is 1, index of filter is 2
412 otherParams.a_dtype = context->GetInputDesc(FILTER_INDEX)->GetDataType();413 otherParams.a_dtype = context->GetInputDesc(FILTER_INDEX)->GetDataType();
413 otherParams.b_dtype = context->GetInputDesc(OUT_BACKPROP_INDEX)->GetDataType();414 otherParams.b_dtype = context->GetInputDesc(OUT_BACKPROP_INDEX)->GetDataType();
@@ -510,7 +511,9 @@ bool CheckStorageFormat(const gert::TilingContext* context, size_t filter_input_
510 const auto op_name = context->GetNodeName();511 const auto op_name = context->GetNodeName();
511 512 
512 std::unordered_set<ge::Format> valid_out_bp_format;513 std::unordered_set<ge::Format> valid_out_bp_format;
513- if ((IsArchAfter35(context) || IsSocVersionFuse(context)) && op_type == optiling::OpTypeV2::kExtendConvTranspose) {514+ if ((IsArchAfter35(context) || IsSocVersionFuse(context)) &&
515+ (op_type == optiling::OpTypeV2::kExtendConvTranspose ||
516+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2)) {
514 valid_out_bp_format = {ge::FORMAT_NCDHW};517 valid_out_bp_format = {ge::FORMAT_NCDHW};
515 } else {518 } else {
516 valid_out_bp_format = {ge::FORMAT_NCDHW, ge::FORMAT_NDHWC};519 valid_out_bp_format = {ge::FORMAT_NCDHW, ge::FORMAT_NDHWC};
@@ -519,14 +522,17 @@ bool CheckStorageFormat(const gert::TilingContext* context, size_t filter_input_
519 std::unordered_set<ge::Format> valid_filter_format;522 std::unordered_set<ge::Format> valid_filter_format;
520 if (IsSocVersionFuse(context)) {523 if (IsSocVersionFuse(context)) {
521 valid_filter_format = {ge::FORMAT_NDHWC, ge::FORMAT_FRACTAL_Z};524 valid_filter_format = {ge::FORMAT_NDHWC, ge::FORMAT_FRACTAL_Z};
522- } else if (op_type == optiling::OpTypeV2::kExtendConvTranspose) {525+ } else if (op_type == optiling::OpTypeV2::kExtendConvTranspose ||
526+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
523 valid_filter_format = {ge::FORMAT_NCDHW};527 valid_filter_format = {ge::FORMAT_NCDHW};
524 } else {528 } else {
525 valid_filter_format = {ge::FORMAT_NCDHW, ge::FORMAT_NDHWC, ge::FORMAT_DHWCN};529 valid_filter_format = {ge::FORMAT_NCDHW, ge::FORMAT_NDHWC, ge::FORMAT_DHWCN};
526 }530 }
527 531 
528 std::unordered_set<ge::Format> valid_y_format;532 std::unordered_set<ge::Format> valid_y_format;
529- if ((IsArchAfter35(context) || IsSocVersionFuse(context)) && op_type == optiling::OpTypeV2::kExtendConvTranspose) {533+ if ((IsArchAfter35(context) || IsSocVersionFuse(context)) &&
534+ (op_type == optiling::OpTypeV2::kExtendConvTranspose ||
535+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2)) {
530 valid_y_format = {ge::FORMAT_NCDHW};536 valid_y_format = {ge::FORMAT_NCDHW};
531 } else {537 } else {
532 valid_y_format = {ge::FORMAT_NCDHW, ge::FORMAT_NDHWC};538 valid_y_format = {ge::FORMAT_NCDHW, ge::FORMAT_NDHWC};
@@ -702,7 +708,8 @@ bool GetShapeParams(gert::TilingContext* context, Conv3dBpInputV2RunInfo& runInf
702 size_t out_backprop_input_index = static_cast<size_t>(OUT_BACKPROP_INDEX);708 size_t out_backprop_input_index = static_cast<size_t>(OUT_BACKPROP_INDEX);
703 size_t filter_input_index = static_cast<size_t>(FILTER_INDEX);709 size_t filter_input_index = static_cast<size_t>(FILTER_INDEX);
704 // 转置的话,filter和out_backprop进行交换710 // 转置的话,filter和out_backprop进行交换
705- if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose) {711+ if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose ||
712+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
706 out_backprop_input_index = FILTER_INDEX;713 out_backprop_input_index = FILTER_INDEX;
707 filter_input_index = OUT_BACKPROP_INDEX;714 filter_input_index = OUT_BACKPROP_INDEX;
708 }715 }
@@ -764,7 +771,8 @@ bool GetShapeParams(gert::TilingContext* context, Conv3dBpInputV2RunInfo& runInf
764 "The formats of out_backprop and filter must be NDC1HWC0 and FRACTAL_Z_3D"),771 "The formats of out_backprop and filter must be NDC1HWC0 and FRACTAL_Z_3D"),
765 return false);772 return false);
766 if (!isV2Impl || op_type == optiling::OpTypeV2::kConv3DTransposeV2 ||773 if (!isV2Impl || op_type == optiling::OpTypeV2::kConv3DTransposeV2 ||
767- op_type == optiling::OpTypeV2::kExtendConvTranspose) {774+ op_type == optiling::OpTypeV2::kExtendConvTranspose ||
775+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
768 OP_CHECK_IF(y_format != ge::FORMAT_NDC1HWC0,776 OP_CHECK_IF(y_format != ge::FORMAT_NDC1HWC0,
769 OP_LOGE_FOR_INVALID_FORMAT(op_name, "y", ge::TypeUtils::FormatToSerialString(y_format).c_str(),777 OP_LOGE_FOR_INVALID_FORMAT(op_name, "y", ge::TypeUtils::FormatToSerialString(y_format).c_str(),
770 "NDC1HWC0"),778 "NDC1HWC0"),
@@ -946,7 +954,8 @@ bool CheckCalPads(const gert::TilingContext* context, const Conv3dBpInputV2RunIn
946 runInfoV2.stride_w +954 runInfoV2.stride_w +
947 1;955 1;
948 std::string check_input_name = (op_type == optiling::OpTypeV2::kConv3DTransposeV2 ||956 std::string check_input_name = (op_type == optiling::OpTypeV2::kConv3DTransposeV2 ||
949- op_type == optiling::OpTypeV2::kExtendConvTranspose) ?957+ op_type == optiling::OpTypeV2::kExtendConvTranspose ||
958+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) ?
950 "x" :959 "x" :
951 "out_backprop";960 "out_backprop";
952 OP_CHECK_IF(961 OP_CHECK_IF(
@@ -978,7 +987,8 @@ bool CalPads(gert::TilingContext* context, Conv3dBpInputV2RunInfo& runInfoV2, op
978{987{
979 auto attrs = context->GetAttrs();988 auto attrs = context->GetAttrs();
980 size_t padding_attr_idx = kPaddingConv3dBpInputIdx;989 size_t padding_attr_idx = kPaddingConv3dBpInputIdx;
981- if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose) {990+ if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose ||
991+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
982 if (IsSocVersionFuse(context)) {992 if (IsSocVersionFuse(context)) {
983 padding_attr_idx = kPaddingExtendConvTransposeIdx;993 padding_attr_idx = kPaddingExtendConvTransposeIdx;
984 } else {994 } else {
@@ -1019,7 +1029,8 @@ bool CalPads(gert::TilingContext* context, Conv3dBpInputV2RunInfo& runInfoV2, op
1019 runInfoV2.pad_r = pad_right;1029 runInfoV2.pad_r = pad_right;
1020 }1030 }
1021 1031 
1022- if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose) {1032+ if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose ||
1033+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
1023 OP_CHECK_IF(!HandleConv3DTranspose(context, runInfoV2, otherParams),1034 OP_CHECK_IF(!HandleConv3DTranspose(context, runInfoV2, otherParams),
1024 OP_LOGE(context, "Failed to process Conv3DTranspose."), return false);1035 OP_LOGE(context, "Failed to process Conv3DTranspose."), return false);
1025 }1036 }
@@ -1548,7 +1559,8 @@ bool GetAttrAndDtypeParams(gert::TilingContext* context, Conv3dBpInputV2RunInfo&
1548 Shape strides_ncdhw;1559 Shape strides_ncdhw;
1549 Shape dilations_ncdhw;1560 Shape dilations_ncdhw;
1550 ge::Format data_format = context->GetInputDesc(OUT_BACKPROP_INDEX)->GetOriginFormat();1561 ge::Format data_format = context->GetInputDesc(OUT_BACKPROP_INDEX)->GetOriginFormat();
1551- if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose) {1562+ if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose ||
1563+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
1552 OP_CHECK_IF(!CheckTransposeAttr(context, otherParams), OP_LOGW(context, "check transpose attr failed"),1564 OP_CHECK_IF(!CheckTransposeAttr(context, otherParams), OP_LOGW(context, "check transpose attr failed"),
1553 return false);1565 return false);
1554 data_format = context->GetInputDesc(FILTER_INDEX)->GetOriginFormat();1566 data_format = context->GetInputDesc(FILTER_INDEX)->GetOriginFormat();
@@ -1564,7 +1576,8 @@ bool GetAttrAndDtypeParams(gert::TilingContext* context, Conv3dBpInputV2RunInfo&
1564 OP_LOGE_FOR_INVALID_VALUE(op_name, "strides C", std::to_string(strides_ncdhw.c), "1"), return false);1576 OP_LOGE_FOR_INVALID_VALUE(op_name, "strides C", std::to_string(strides_ncdhw.c), "1"), return false);
1565 1577 
1566 SetConvAttrs(runInfoV2, pads_data, strides_ncdhw, dilations_ncdhw, groups, otherParams);1578 SetConvAttrs(runInfoV2, pads_data, strides_ncdhw, dilations_ncdhw, groups, otherParams);
1567- if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose) {1579+ if (op_type == optiling::OpTypeV2::kConv3DTransposeV2 || op_type == optiling::OpTypeV2::kExtendConvTranspose ||
1580+ op_type == optiling::OpTypeV2::kExtendConvTransposeV2) {
1568 OP_CHECK_IF(!CheckTransposeOutputdingRange(context, runInfoV2, otherParams),1581 OP_CHECK_IF(!CheckTransposeOutputdingRange(context, runInfoV2, otherParams),
1569 OP_LOGW(context, "check transpose attr failed"), return false);1582 OP_LOGW(context, "check transpose attr failed"), return false);
1570 }1583 }
@@ -1578,7 +1591,8 @@ bool GetInputOutputFormat(const gert::TilingContext* context, Conv3dBpInputV2Run
1578 size_t bMatrixIndex = FILTER_INDEX;1591 size_t bMatrixIndex = FILTER_INDEX;
1579 const char* opName = context->GetNodeName(); // 日志打印用,允许为空1592 const char* opName = context->GetNodeName(); // 日志打印用,允许为空
1580 1593 
1581- if (opType == optiling::OpTypeV2::kConv3DTransposeV2 || opType == optiling::OpTypeV2::kExtendConvTranspose) {1594+ if (opType == optiling::OpTypeV2::kConv3DTransposeV2 || opType == optiling::OpTypeV2::kExtendConvTranspose ||
1595+ opType == optiling::OpTypeV2::kExtendConvTransposeV2) {
1582 aMatrixIndex = FILTER_INDEX;1596 aMatrixIndex = FILTER_INDEX;
1583 bMatrixIndex = OUT_BACKPROP_INDEX;1597 bMatrixIndex = OUT_BACKPROP_INDEX;
1584 }1598 }
@@ -1686,7 +1700,8 @@ bool SetRunInfoToV2(gert::TilingContext* context, Conv3dBpInputV2RunInfo& runInf
1686 return false;1700 return false;
1687 }1701 }
1688 1702 
1689- if ((opType == optiling::OpTypeV2::kConv3DTransposeV2 || opType == optiling::OpTypeV2::kExtendConvTranspose) &&1703+ if ((opType == optiling::OpTypeV2::kConv3DTransposeV2 || opType == optiling::OpTypeV2::kExtendConvTranspose ||
1704+ opType == optiling::OpTypeV2::kExtendConvTransposeV2) &&
1690 (!CheckTranspose(context->GetNodeName(), context) || !CheckBiasParams(context, otherParams))) {1705 (!CheckTranspose(context->GetNodeName(), context) || !CheckBiasParams(context, otherParams))) {
1691 OP_LOGW(context, "params is invalid");1706 OP_LOGW(context, "params is invalid");
1692 return false;1707 return false;
@@ -88,8 +88,10 @@ struct Conv3dBpInputV2RunInfo {
88 int32_t b_dtype_bytes = 2;88 int32_t b_dtype_bytes = 2;
89 int32_t c_dtype_bytes = 2;89 int32_t c_dtype_bytes = 2;
90 int32_t initOutputFlag = 0;90 int32_t initOutputFlag = 0;
91- uint8_t enRelu = 0;91+ uint8_t enRelu0 = 0;
92- uint8_t quantMode = 0;92+ uint8_t enRelu1 = 0;
93+ uint8_t quantMode0 = 0;
94+ uint8_t quantMode1 = 0;
93 int8_t offsetX = 0;95 int8_t offsetX = 0;
94 uint8_t fixedShiftVal = 0;96 uint8_t fixedShiftVal = 0;
95 97 
@@ -82,7 +82,7 @@ TUNING_TILING_DATA_FIELD_DEF(uint8_t, initOutputFlag);
82TUNING_TILING_DATA_FIELD_DEF(uint8_t, isBiasFullLoad);82TUNING_TILING_DATA_FIELD_DEF(uint8_t, isBiasFullLoad);
83TUNING_TILING_DATA_FIELD_DEF(uint8_t, enableVecTrans);83TUNING_TILING_DATA_FIELD_DEF(uint8_t, enableVecTrans);
84TUNING_TILING_DATA_FIELD_DEF(uint8_t, enableFullLoad);84TUNING_TILING_DATA_FIELD_DEF(uint8_t, enableFullLoad);
85-TUNING_TILING_DATA_FIELD_DEF(uint8_t, quantMode);85+TUNING_TILING_DATA_FIELD_DEF(uint8_t, quantMode0);
86TUNING_TILING_DATA_FIELD_DEF(uint32_t, cinG);86TUNING_TILING_DATA_FIELD_DEF(uint32_t, cinG);
87TUNING_TILING_DATA_FIELD_DEF(uint32_t, coutG);87TUNING_TILING_DATA_FIELD_DEF(uint32_t, coutG);
88TUNING_TILING_DATA_FIELD_DEF(uint32_t, cout1);88TUNING_TILING_DATA_FIELD_DEF(uint32_t, cout1);
@@ -106,7 +106,7 @@ TUNING_TILING_DATA_FIELD_DEF(uint32_t, stepKb);
106TUNING_TILING_DATA_FIELD_DEF(uint32_t, singleIterateDk);106TUNING_TILING_DATA_FIELD_DEF(uint32_t, singleIterateDk);
107TUNING_TILING_DATA_FIELD_DEF(uint64_t, singleCoreBatch);107TUNING_TILING_DATA_FIELD_DEF(uint64_t, singleCoreBatch);
108TUNING_TILING_DATA_FIELD_DEF(uint64_t, singleCoreM);108TUNING_TILING_DATA_FIELD_DEF(uint64_t, singleCoreM);
109-TUNING_TILING_DATA_FIELD_DEF(uint64_t, enRelu);109+TUNING_TILING_DATA_FIELD_DEF(uint64_t, enRelu0);
110TUNING_TILING_DATA_FIELD_DEF(uint64_t, coreNum);110TUNING_TILING_DATA_FIELD_DEF(uint64_t, coreNum);
111TUNING_TILING_DATA_FIELD_DEF(uint32_t, kSCoutFullLoad);111TUNING_TILING_DATA_FIELD_DEF(uint32_t, kSCoutFullLoad);
112TUNING_TILING_DATA_FIELD_DEF(uint32_t, kSUseWorkSpace);112TUNING_TILING_DATA_FIELD_DEF(uint32_t, kSUseWorkSpace);
@@ -144,7 +144,7 @@ DECLARE_SCHEMA(
144 FIELD(Conv3DBackpropInputTunerTiling, c0BitsA), FIELD(Conv3DBackpropInputTunerTiling, c0BitsB),144 FIELD(Conv3DBackpropInputTunerTiling, c0BitsA), FIELD(Conv3DBackpropInputTunerTiling, c0BitsB),
145 FIELD(Conv3DBackpropInputTunerTiling, enlarge), FIELD(Conv3DBackpropInputTunerTiling, initOutputFlag),145 FIELD(Conv3DBackpropInputTunerTiling, enlarge), FIELD(Conv3DBackpropInputTunerTiling, initOutputFlag),
146 FIELD(Conv3DBackpropInputTunerTiling, isBiasFullLoad), FIELD(Conv3DBackpropInputTunerTiling, enableVecTrans),146 FIELD(Conv3DBackpropInputTunerTiling, isBiasFullLoad), FIELD(Conv3DBackpropInputTunerTiling, enableVecTrans),
147- FIELD(Conv3DBackpropInputTunerTiling, enableFullLoad), FIELD(Conv3DBackpropInputTunerTiling, quantMode),147+ FIELD(Conv3DBackpropInputTunerTiling, enableFullLoad), FIELD(Conv3DBackpropInputTunerTiling, quantMode0),
148 FIELD(Conv3DBackpropInputTunerTiling, cinG), FIELD(Conv3DBackpropInputTunerTiling, coutG),148 FIELD(Conv3DBackpropInputTunerTiling, cinG), FIELD(Conv3DBackpropInputTunerTiling, coutG),
149 FIELD(Conv3DBackpropInputTunerTiling, cout1), FIELD(Conv3DBackpropInputTunerTiling, cin1),149 FIELD(Conv3DBackpropInputTunerTiling, cout1), FIELD(Conv3DBackpropInputTunerTiling, cin1),
150 FIELD(Conv3DBackpropInputTunerTiling, cout1G), FIELD(Conv3DBackpropInputTunerTiling, cin1G),150 FIELD(Conv3DBackpropInputTunerTiling, cout1G), FIELD(Conv3DBackpropInputTunerTiling, cin1G),
@@ -156,7 +156,7 @@ DECLARE_SCHEMA(
156 FIELD(Conv3DBackpropInputTunerTiling, baseK), FIELD(Conv3DBackpropInputTunerTiling, baseN),156 FIELD(Conv3DBackpropInputTunerTiling, baseK), FIELD(Conv3DBackpropInputTunerTiling, baseN),
157 FIELD(Conv3DBackpropInputTunerTiling, stepKa), FIELD(Conv3DBackpropInputTunerTiling, stepKb),157 FIELD(Conv3DBackpropInputTunerTiling, stepKa), FIELD(Conv3DBackpropInputTunerTiling, stepKb),
158 FIELD(Conv3DBackpropInputTunerTiling, singleIterateDk), FIELD(Conv3DBackpropInputTunerTiling, singleCoreBatch),158 FIELD(Conv3DBackpropInputTunerTiling, singleIterateDk), FIELD(Conv3DBackpropInputTunerTiling, singleCoreBatch),
159- FIELD(Conv3DBackpropInputTunerTiling, singleCoreM), FIELD(Conv3DBackpropInputTunerTiling, enRelu),159+ FIELD(Conv3DBackpropInputTunerTiling, singleCoreM), FIELD(Conv3DBackpropInputTunerTiling, enRelu0),
160 FIELD(Conv3DBackpropInputTunerTiling, coreNum), FIELD(Conv3DBackpropInputTunerTiling, kSCoutFullLoad),160 FIELD(Conv3DBackpropInputTunerTiling, coreNum), FIELD(Conv3DBackpropInputTunerTiling, kSCoutFullLoad),
161 FIELD(Conv3DBackpropInputTunerTiling, kSUseWorkSpace), FIELD(Conv3DBackpropInputTunerTiling, loadB2Condition),161 FIELD(Conv3DBackpropInputTunerTiling, kSUseWorkSpace), FIELD(Conv3DBackpropInputTunerTiling, loadB2Condition),
162 FIELD(Conv3DBackpropInputTunerTiling, loadB1Condition), FIELD(Conv3DBackpropInputTunerTiling, kernelSplitMode),162 FIELD(Conv3DBackpropInputTunerTiling, loadB1Condition), FIELD(Conv3DBackpropInputTunerTiling, kernelSplitMode),
@@ -41,7 +41,7 @@ TILING_DATA_FIELD_DEF(uint8_t, initOutputFlag);
41TILING_DATA_FIELD_DEF(uint8_t, isBiasFullLoad);41TILING_DATA_FIELD_DEF(uint8_t, isBiasFullLoad);
42TILING_DATA_FIELD_DEF(uint8_t, enableVecTrans);42TILING_DATA_FIELD_DEF(uint8_t, enableVecTrans);
43TILING_DATA_FIELD_DEF(uint8_t, enableFullLoad);43TILING_DATA_FIELD_DEF(uint8_t, enableFullLoad);
44-TILING_DATA_FIELD_DEF(uint8_t, quantMode);44+TILING_DATA_FIELD_DEF(uint8_t, quantMode0);
45TILING_DATA_FIELD_DEF(uint32_t, batch);45TILING_DATA_FIELD_DEF(uint32_t, batch);
46TILING_DATA_FIELD_DEF(uint32_t, cin);46TILING_DATA_FIELD_DEF(uint32_t, cin);
47TILING_DATA_FIELD_DEF(uint32_t, cout);47TILING_DATA_FIELD_DEF(uint32_t, cout);
@@ -91,7 +91,7 @@ TILING_DATA_FIELD_DEF(uint32_t, stepKb);
91TILING_DATA_FIELD_DEF(uint32_t, singleIterateDk);91TILING_DATA_FIELD_DEF(uint32_t, singleIterateDk);
92TILING_DATA_FIELD_DEF(uint64_t, singleCoreBatch);92TILING_DATA_FIELD_DEF(uint64_t, singleCoreBatch);
93TILING_DATA_FIELD_DEF(uint64_t, singleCoreM);93TILING_DATA_FIELD_DEF(uint64_t, singleCoreM);
94-TILING_DATA_FIELD_DEF(uint64_t, enRelu);94+TILING_DATA_FIELD_DEF(uint64_t, enRelu0);
95TILING_DATA_FIELD_DEF(uint64_t, kSegment);95TILING_DATA_FIELD_DEF(uint64_t, kSegment);
96TILING_DATA_FIELD_DEF(uint64_t, kSegmentTail);96TILING_DATA_FIELD_DEF(uint64_t, kSegmentTail);
97TILING_DATA_FIELD_DEF(uint64_t, kValueSegment);97TILING_DATA_FIELD_DEF(uint64_t, kValueSegment);
@@ -107,12 +107,16 @@ TILING_DATA_FIELD_DEF(uint32_t, woExpand);
107TILING_DATA_FIELD_DEF(uint64_t, dkHkWk);107TILING_DATA_FIELD_DEF(uint64_t, dkHkWk);
108TILING_DATA_FIELD_DEF(uint64_t, hkWk);108TILING_DATA_FIELD_DEF(uint64_t, hkWk);
109TILING_DATA_FIELD_DEF(uint8_t, fixedShiftVal);109TILING_DATA_FIELD_DEF(uint8_t, fixedShiftVal);
110-TILING_DATA_FIELD_DEF_ARR(uint8_t, 8, reserved);110+TILING_DATA_FIELD_DEF(uint8_t, dualOutput);
111+TILING_DATA_FIELD_DEF(uint8_t, enRelu1);
112+TILING_DATA_FIELD_DEF(uint8_t, quantMode1);
113+TILING_DATA_FIELD_DEF_ARR(uint8_t, 5, reserved);
111END_TILING_DATA_DEF;114END_TILING_DATA_DEF;
112 115 
113REGISTER_TILING_DATA_CLASS(Conv3DBackpropInputV2, Conv3DBackpropInputArch35TilingData);116REGISTER_TILING_DATA_CLASS(Conv3DBackpropInputV2, Conv3DBackpropInputArch35TilingData);
114REGISTER_TILING_DATA_CLASS(Conv3DTransposeV2, Conv3DBackpropInputArch35TilingData);117REGISTER_TILING_DATA_CLASS(Conv3DTransposeV2, Conv3DBackpropInputArch35TilingData);
115REGISTER_TILING_DATA_CLASS(ExtendConvTranspose, Conv3DBackpropInputArch35TilingData);118REGISTER_TILING_DATA_CLASS(ExtendConvTranspose, Conv3DBackpropInputArch35TilingData);
119+REGISTER_TILING_DATA_CLASS(ExtendConvTransposeV2, Conv3DBackpropInputArch35TilingData);
116} // namespace optiling120} // namespace optiling
117 121 
118#endif // OPS_BUILT_IN_OP_TILING_RUNTIME_CONV3D_BACKPROP_INPUT_V2_TILING_DATA_ARCH35_H122#endif // OPS_BUILT_IN_OP_TILING_RUNTIME_CONV3D_BACKPROP_INPUT_V2_TILING_DATA_ARCH35_H
@@ -20,12 +20,13 @@
20 20 
21namespace Convolution3DBackprop {21namespace Convolution3DBackprop {
22 22 
23-template <class A, class B, class C, class D, class E, class F, const Conv3dConfig& CONV3D_CONFIG = CONV3D_CFG_DEFAULT>23+template <class A, class B, class C, class D, class E, class F, const Conv3dConfig& CONV3D_CONFIG = CONV3D_CFG_DEFAULT,
24-struct Conv3DBpInputCfg : public ConvBpContext<A, B, C, D, E, F> {24+ class G = D, class H = F>
25+struct Conv3DBpInputCfg : public ConvBpContext<A, B, C, D, E, F, G, H> {
25public:26public:
26 __aicore__ inline Conv3DBpInputCfg() {}27 __aicore__ inline Conv3DBpInputCfg() {}
27 28 
28- using ContextData = struct _ : public ConvBpContext<A, B, C, D, E, F>::ContextData {29+ using ContextData = struct _ : public ConvBpContext<A, B, C, D, E, F, G, H>::ContextData {
29 __aicore__ inline _() {}30 __aicore__ inline _() {}
30 };31 };
31 constexpr static Conv3dConfig conv3dConfig_ = CONV3D_CONFIG;32 constexpr static Conv3dConfig conv3dConfig_ = CONV3D_CONFIG;
@@ -62,32 +62,40 @@ __aicore__ inline constexpr Convolution3DBackprop::CubeFormat GetScaleFormat(int
62 62 
63template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,63template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,
64 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,64 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,
65- uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scaleType = uint64_t,65+ uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scale0Type = uint64_t,
66- int scaleFormat = FORMAT_MAX>66+ int scale0Format = FORMAT_MAX, typename y1Type = yType, typename scale1Type = scale0Type,
67+ int scale1Format = scale0Format>
67class Conv3dDxBase {68class Conv3dDxBase {
68protected:69protected:
69 static constexpr Convolution3DBackprop::CubeFormat filterCubeFormat = GetFormat(filterFormat);70 static constexpr Convolution3DBackprop::CubeFormat filterCubeFormat = GetFormat(filterFormat);
70 static constexpr Convolution3DBackprop::CubeFormat dedyCubeFormat = GetFormat(dedyFormat);71 static constexpr Convolution3DBackprop::CubeFormat dedyCubeFormat = GetFormat(dedyFormat);
71 static constexpr Convolution3DBackprop::CubeFormat yCubeFormat = GetFormat(yFormat);72 static constexpr Convolution3DBackprop::CubeFormat yCubeFormat = GetFormat(yFormat);
72 static constexpr Convolution3DBackprop::CubeFormat biasCubeFormat = GetFormat(biasFormat);73 static constexpr Convolution3DBackprop::CubeFormat biasCubeFormat = GetFormat(biasFormat);
73- static constexpr Convolution3DBackprop::CubeFormat scaleCubeFormat = GetScaleFormat(scaleFormat);
74 using filterDxType = Convolution3DBackprop::ConvType<TPosition::GM, filterCubeFormat, filterType>;74 using filterDxType = Convolution3DBackprop::ConvType<TPosition::GM, filterCubeFormat, filterType>;
75 using inputSizeDxType = Convolution3DBackprop::ConvType<TPosition::GM, Convolution3DBackprop::CubeFormat::ND,75 using inputSizeDxType = Convolution3DBackprop::ConvType<TPosition::GM, Convolution3DBackprop::CubeFormat::ND,
76 int32_t>;76 int32_t>;
77 using dedyDxType = Convolution3DBackprop::ConvType<TPosition::GM, dedyCubeFormat, dedyType>;77 using dedyDxType = Convolution3DBackprop::ConvType<TPosition::GM, dedyCubeFormat, dedyType>;
78 using yDxType = Convolution3DBackprop::ConvType<TPosition::GM, yCubeFormat, yType>;78 using yDxType = Convolution3DBackprop::ConvType<TPosition::GM, yCubeFormat, yType>;
79+ using y1DxType = Convolution3DBackprop::ConvType<TPosition::GM, yCubeFormat, y1Type>;
79 using biasDxType = Convolution3DBackprop::ConvType<TPosition::GM, biasCubeFormat, biasType>;80 using biasDxType = Convolution3DBackprop::ConvType<TPosition::GM, biasCubeFormat, biasType>;
80- using scaleDxType = Convolution3DBackprop::ConvType<TPosition::GM, scaleCubeFormat, scaleType>;81+ using scale0DxType = Convolution3DBackprop::ConvType<TPosition::GM, GetScaleFormat(scale0Format), scale0Type>;
82+ using scale1DxType = Convolution3DBackprop::ConvType<TPosition::GM, GetScaleFormat(scale1Format), scale1Type>;
81 static constexpr Conv3dConfig conv3dConfig = {b2Condition, kernelSplitMode, groupMode, b1Condition, enableC04Flag};83 static constexpr Conv3dConfig conv3dConfig = {b2Condition, kernelSplitMode, groupMode, b1Condition, enableC04Flag};
82 Convolution3DBackprop::Conv3DBackpropInput<filterDxType, inputSizeDxType, dedyDxType, yDxType, biasDxType,84 Convolution3DBackprop::Conv3DBackpropInput<filterDxType, inputSizeDxType, dedyDxType, yDxType, biasDxType,
83- scaleDxType, conv3dConfig>85+ scale0DxType, conv3dConfig, y1DxType, scale1DxType>
84 dedx_;86 dedx_;
85 87 
86 GlobalTensor<filterType> filterGm_;88 GlobalTensor<filterType> filterGm_;
87 GlobalTensor<dedyType> dedyGm_;89 GlobalTensor<dedyType> dedyGm_;
88 GlobalTensor<yType> yGm_;90 GlobalTensor<yType> yGm_;
91+#ifdef DTYPE_Y1
92+ GlobalTensor<y1Type> y1Gm_;
93+#endif
89 GlobalTensor<biasType> biasGm_;94 GlobalTensor<biasType> biasGm_;
90- GlobalTensor<scaleType> scaleGm_;95+ GlobalTensor<scale0Type> scale0Gm_;
96+#ifdef DTYPE_Y1
97+ GlobalTensor<scale1Type> scale1Gm_;
98+#endif
91 99 
92 uint64_t batchStrideA_ = 1;100 uint64_t batchStrideA_ = 1;
93 uint64_t batchStrideC_ = 1;101 uint64_t batchStrideC_ = 1;
@@ -122,6 +130,9 @@ protected:
122 bool hasBias_ = false;130 bool hasBias_ = false;
123 bool fullLoadBiasFlag_ = false;131 bool fullLoadBiasFlag_ = false;
124 bool freeBiasFlag_ = false;132 bool freeBiasFlag_ = false;
133+#ifdef DTYPE_Y1
134+ bool hasSecondOutput_ = false;
135+#endif
125 136 
126 const Conv3DBackpropInputArch35TilingData* tiling_;137 const Conv3DBackpropInputArch35TilingData* tiling_;
127 138 
@@ -263,10 +274,12 @@ protected:
263 274 
264 __aicore__ inline void CalcScaleOffset(uint32_t groupIdx)275 __aicore__ inline void CalcScaleOffset(uint32_t groupIdx)
265 {276 {
266- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {277+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT ||
267- if (tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {278+ GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
279+ if (tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT) ||
280+ tiling_->quantMode1 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
268 offsetScale_ = static_cast<uint64_t>(nCoreIdx_) * tiling_->singleCoreCin + groupIdx * tiling_->cinG;281 offsetScale_ = static_cast<uint64_t>(nCoreIdx_) * tiling_->singleCoreCin + groupIdx * tiling_->cinG;
269- } else if (tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::SCALAR_QUANT)) {282+ } else {
270 offsetScale_ = 0;283 offsetScale_ = 0;
271 }284 }
272 }285 }
@@ -21,16 +21,18 @@
21namespace AscendC {21namespace AscendC {
22template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,22template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,
23 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,23 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,
24- uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scaleType = uint64_t,24+ uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scale0Type = uint64_t,
25- int scaleFormat = FORMAT_MAX>25+ int scale0Format = FORMAT_MAX, typename y1Type = yType, typename scale1Type = scale0Type,
26-class Conv3dDxKsBlock : public Conv3dDxOswBlock<filterType, filterFormat, dedyType, dedyFormat, yType, yFormat,26+ int scale1Format = scale0Format>
27- biasType, biasFormat, b2Condition, kernelSplitMode, groupMode,27+class Conv3dDxKsBlock
28- b1Condition, enableC04Flag, scaleType, scaleFormat> {28+ : public Conv3dDxOswBlock<filterType, filterFormat, dedyType, dedyFormat, yType, yFormat, biasType, biasFormat,
29+ b2Condition, kernelSplitMode, groupMode, b1Condition, enableC04Flag, scale0Type,
30+ scale0Format, y1Type, scale1Type, scale1Format> {
29public:31public:
30 __aicore__ inline Conv3dDxKsBlock(){};32 __aicore__ inline Conv3dDxKsBlock(){};
31 __aicore__ inline void Init(GM_ADDR filter, GM_ADDR dedy, GM_ADDR y, GM_ADDR workSpace,33 __aicore__ inline void Init(GM_ADDR filter, GM_ADDR dedy, GM_ADDR y, GM_ADDR workSpace,
32 const Conv3DBackpropInputArch35TilingData& tilingData, GM_ADDR bias = nullptr,34 const Conv3DBackpropInputArch35TilingData& tilingData, GM_ADDR bias = nullptr,
33- GM_ADDR scale = nullptr)35+ GM_ADDR scale0 = nullptr, GM_ADDR y1 = nullptr, GM_ADDR scale1 = nullptr)
34 {36 {
35 if constexpr (kernelSplitMode != TPL_SPLIT_KERNEL_HW) {37 if constexpr (kernelSplitMode != TPL_SPLIT_KERNEL_HW) {
36 if ASCEND_IS_AIV_SHOULD_RETURN {38 if ASCEND_IS_AIV_SHOULD_RETURN {
@@ -50,16 +52,33 @@ public:
50 }52 }
51 this->dedyGm_.SetGlobalBuffer((__gm__ dedyType*)dedy);53 this->dedyGm_.SetGlobalBuffer((__gm__ dedyType*)dedy);
52 this->yGm_.SetGlobalBuffer((__gm__ yType*)y);54 this->yGm_.SetGlobalBuffer((__gm__ yType*)y);
55+#ifdef DTYPE_Y1
56+ if (tilingData.dualOutput != 0 && y1 != nullptr) {
57+ this->y1Gm_.SetGlobalBuffer((__gm__ y1Type*)y1);
58+ this->hasSecondOutput_ = true;
59+ }
60+#endif
53 61 
54 if (unlikely(bias != nullptr)) {62 if (unlikely(bias != nullptr)) {
55 this->hasBias_ = true;63 this->hasBias_ = true;
56 this->biasGm_.SetGlobalBuffer((__gm__ biasType*)bias);64 this->biasGm_.SetGlobalBuffer((__gm__ biasType*)bias);
57 }65 }
58 66 
59- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {67+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
60- this->scaleGm_.SetGlobalBuffer((__gm__ scaleType*)scale);68+ this->scale0Gm_.SetGlobalBuffer((__gm__ scale0Type*)scale0);
61 }69 }
70+#ifdef DTYPE_Y1
71+ if constexpr (GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
72+ if (scale1 != nullptr) {
73+ this->scale1Gm_.SetGlobalBuffer((__gm__ scale1Type*)scale1);
74+ }
75+ }
76+#endif
77+#ifdef DTYPE_Y1
78+ this->dedx_.Init(tilingData, this->hasBias_, this->hasSecondOutput_);
79+#else
62 this->dedx_.Init(tilingData, this->hasBias_);80 this->dedx_.Init(tilingData, this->hasBias_);
81+#endif
63 82 
64#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 3510) || __DAV_35_FAMILY__83#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 3510) || __DAV_35_FAMILY__
65 InitMixCoreBuffer(workSpace);84 InitMixCoreBuffer(workSpace);
@@ -290,9 +309,16 @@ protected:
290 this->dedx_.SetBias(this->biasGm_[this->offsetBias_]);309 this->dedx_.SetBias(this->biasGm_[this->offsetBias_]);
291 }310 }
292 311 
293- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {312+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
294- this->dedx_.SetScale(this->scaleGm_[this->offsetScale_]);313+ this->dedx_.SetScale(this->scale0Gm_[this->offsetScale_]);
295 }314 }
315+#ifdef DTYPE_Y1
316+ if constexpr (GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
317+ if (this->hasSecondOutput_) {
318+ this->dedx_.SetScale1(this->scale1Gm_[this->offsetScale_]);
319+ }
320+ }
321+#endif
296 }322 }
297 323 
298 __aicore__ inline void CalBasicBlockCoreForSplitH(uint64_t blockIdx, uint64_t blockNum)324 __aicore__ inline void CalBasicBlockCoreForSplitH(uint64_t blockIdx, uint64_t blockNum)
@@ -330,7 +356,15 @@ protected:
330 if (unlikely(this->hasBias_)) {356 if (unlikely(this->hasBias_)) {
331 this->IterateAllForBias(firstloadbias);357 this->IterateAllForBias(firstloadbias);
332 } else {358 } else {
333- this->dedx_.IterateAll(this->yGm_[this->offsetC_], 0, false, false);359+#ifdef DTYPE_Y1
360+ if (this->hasSecondOutput_) {
361+ this->dedx_.IterateAll(this->yGm_[this->offsetC_], this->y1Gm_[this->offsetC_], 0, false, false);
362+ } else {
363+#endif
364+ this->dedx_.IterateAll(this->yGm_[this->offsetC_], 0, false, false);
365+#ifdef DTYPE_Y1
366+ }
367+#endif
334 }368 }
335 }369 }
336 }370 }
@@ -28,16 +28,18 @@ constexpr int BLOCK_CUBE_ALIGN_BITS = 4;
28 28 
29template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,29template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,
30 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,30 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,
31- uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scaleType = uint64_t,31+ uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scale0Type = uint64_t,
32- int scaleFormat = FORMAT_MAX>32+ int scale0Format = FORMAT_MAX, typename y1Type = yType, typename scale1Type = scale0Type,
33+ int scale1Format = scale0Format>
33class Conv3dDxOswBlock34class Conv3dDxOswBlock
34 : public Conv3dDxBase<filterType, filterFormat, dedyType, dedyFormat, yType, yFormat, biasType, biasFormat,35 : public Conv3dDxBase<filterType, filterFormat, dedyType, dedyFormat, yType, yFormat, biasType, biasFormat,
35- b2Condition, kernelSplitMode, groupMode, b1Condition, enableC04Flag, scaleType, scaleFormat> {36+ b2Condition, kernelSplitMode, groupMode, b1Condition, enableC04Flag, scale0Type, scale0Format,
37+ y1Type, scale1Type, scale1Format> {
36public:38public:
37 __aicore__ inline Conv3dDxOswBlock(){};39 __aicore__ inline Conv3dDxOswBlock(){};
38 __aicore__ inline void Init(GM_ADDR filter, GM_ADDR dedy, GM_ADDR y, GM_ADDR workSpace,40 __aicore__ inline void Init(GM_ADDR filter, GM_ADDR dedy, GM_ADDR y, GM_ADDR workSpace,
39 const Conv3DBackpropInputArch35TilingData& tilingData, GM_ADDR bias = nullptr,41 const Conv3DBackpropInputArch35TilingData& tilingData, GM_ADDR bias = nullptr,
40- GM_ADDR scale = nullptr)42+ GM_ADDR scale0 = nullptr, GM_ADDR y1 = nullptr, GM_ADDR scale1 = nullptr)
41 {43 {
42 InitTilingData(tilingData);44 InitTilingData(tilingData);
43 45 
@@ -66,9 +68,22 @@ public:
66 }68 }
67 this->dedyGm_.SetGlobalBuffer((__gm__ dedyType*)dedy);69 this->dedyGm_.SetGlobalBuffer((__gm__ dedyType*)dedy);
68 this->yGm_.SetGlobalBuffer((__gm__ yType*)y);70 this->yGm_.SetGlobalBuffer((__gm__ yType*)y);
69- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {71+#ifdef DTYPE_Y1
70- this->scaleGm_.SetGlobalBuffer((__gm__ scaleType*)scale);72+ if (tilingData.dualOutput != 0 && y1 != nullptr) {
73+ this->y1Gm_.SetGlobalBuffer((__gm__ y1Type*)y1);
74+ this->hasSecondOutput_ = true;
71 }75 }
76+#endif
77+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
78+ this->scale0Gm_.SetGlobalBuffer((__gm__ scale0Type*)scale0);
79+ }
80+#ifdef DTYPE_Y1
81+ if constexpr (GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
82+ if (scale1 != nullptr) {
83+ this->scale1Gm_.SetGlobalBuffer((__gm__ scale1Type*)scale1);
84+ }
85+ }
86+#endif
72 87 
73 if (unlikely(bias != nullptr)) {88 if (unlikely(bias != nullptr)) {
74 this->hasBias_ = true;89 this->hasBias_ = true;
@@ -77,7 +92,11 @@ public:
77#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 3510) || __DAV_35_FAMILY__92#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 3510) || __DAV_35_FAMILY__
78 InitMixCoreBuffer(workSpace);93 InitMixCoreBuffer(workSpace);
79#endif94#endif
95+#ifdef DTYPE_Y1
96+ this->dedx_.Init(tilingData, this->hasBias_, this->hasSecondOutput_);
97+#else
80 this->dedx_.Init(tilingData, this->hasBias_);98 this->dedx_.Init(tilingData, this->hasBias_);
99+#endif
81 }100 }
82 101 
83 __aicore__ inline void Process()102 __aicore__ inline void Process()
@@ -321,7 +340,16 @@ protected:
321 {340 {
322 this->CalcBiasFullLoadFlag();341 this->CalcBiasFullLoadFlag();
323 this->freeBiasFlag_ = this->fullLoadBiasFlag_ && firstloadbias;342 this->freeBiasFlag_ = this->fullLoadBiasFlag_ && firstloadbias;
324- this->dedx_.IterateAll(this->yGm_[this->offsetC_], 0, this->fullLoadBiasFlag_, this->freeBiasFlag_);343+#ifdef DTYPE_Y1
344+ if (this->hasSecondOutput_) {
345+ this->dedx_.IterateAll(this->yGm_[this->offsetC_], this->y1Gm_[this->offsetC_], 0, this->fullLoadBiasFlag_,
346+ this->freeBiasFlag_);
347+ } else {
348+#endif
349+ this->dedx_.IterateAll(this->yGm_[this->offsetC_], 0, this->fullLoadBiasFlag_, this->freeBiasFlag_);
350+#ifdef DTYPE_Y1
351+ }
352+#endif
325 if (this->fullLoadBiasFlag_) {353 if (this->fullLoadBiasFlag_) {
326 firstloadbias = true;354 firstloadbias = true;
327 }355 }
@@ -366,9 +394,16 @@ protected:
366 394 
367 this->CheckFullLoadEnable();395 this->CheckFullLoadEnable();
368 396 
369- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {397+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
370- this->dedx_.SetScale(this->scaleGm_[this->offsetScale_]);398+ this->dedx_.SetScale(this->scale0Gm_[this->offsetScale_]);
371 }399 }
400+#ifdef DTYPE_Y1
401+ if constexpr (GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
402+ if (this->hasSecondOutput_) {
403+ this->dedx_.SetScale1(this->scale1Gm_[this->offsetScale_]);
404+ }
405+ }
406+#endif
372 407 
373 if (j == 0) {408 if (j == 0) {
374 this->CrossCoreWaitVecTrans();409 this->CrossCoreWaitVecTrans();
@@ -378,7 +413,15 @@ protected:
378 this->dedx_.SetBias(this->biasGm_[this->offsetBias_]);413 this->dedx_.SetBias(this->biasGm_[this->offsetBias_]);
379 this->IterateAllForBias(firstloadbias);414 this->IterateAllForBias(firstloadbias);
380 } else {415 } else {
381- this->dedx_.IterateAll(this->yGm_[this->offsetC_], 0, false, false);416+#ifdef DTYPE_Y1
417+ if (this->hasSecondOutput_) {
418+ this->dedx_.IterateAll(this->yGm_[this->offsetC_], this->y1Gm_[this->offsetC_], 0, false, false);
419+ } else {
420+#endif
421+ this->dedx_.IterateAll(this->yGm_[this->offsetC_], 0, false, false);
422+#ifdef DTYPE_Y1
423+ }
424+#endif
382 }425 }
383 }426 }
384 }427 }
@@ -39,8 +39,9 @@ constexpr uint32_t SMALL_KERNEL_BIAS_L1_ALIGN_BYTES = 64;
39 39 
40template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,40template <typename filterType, int filterFormat, typename dedyType, int dedyFormat, typename yType, int yFormat,
41 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,41 typename biasType, int biasFormat, uint8_t b2Condition, uint8_t kernelSplitMode, uint8_t groupMode,
42- uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scaleType = uint64_t,42+ uint8_t b1Condition = TPL_GM_TO_L1, bool enableC04Flag = false, typename scale0Type = uint64_t,
43- int scaleFormat = FORMAT_MAX>43+ int scale0Format = FORMAT_MAX, typename y1Type = yType, typename scale1Type = scale0Type,
44+ int scale1Format = scale0Format>
44class Conv3dDxSmallKernel {45class Conv3dDxSmallKernel {
45public:46public:
46 using L0cT = typename Convolution3DBackprop::GetDstType<dedyType>::Type;47 using L0cT = typename Convolution3DBackprop::GetDstType<dedyType>::Type;
@@ -49,7 +50,7 @@ public:
49 50 
50 __aicore__ inline void Init(GM_ADDR filter, GM_ADDR dedy, GM_ADDR y, GM_ADDR workSpace,51 __aicore__ inline void Init(GM_ADDR filter, GM_ADDR dedy, GM_ADDR y, GM_ADDR workSpace,
51 const Conv3DBackpropInputArch35TilingData& tilingData, GM_ADDR bias = nullptr,52 const Conv3DBackpropInputArch35TilingData& tilingData, GM_ADDR bias = nullptr,
52- GM_ADDR scale = nullptr)53+ GM_ADDR scale0 = nullptr, GM_ADDR y1 = nullptr, GM_ADDR scale1 = nullptr)
53 {54 {
54 (void)workSpace;55 (void)workSpace;
55 hasBias_ = bias != nullptr;56 hasBias_ = bias != nullptr;
@@ -57,11 +58,20 @@ public:
57 filterGm_.SetGlobalBuffer((__gm__ filterType*)filter);58 filterGm_.SetGlobalBuffer((__gm__ filterType*)filter);
58 dedyGm_.SetGlobalBuffer((__gm__ dedyType*)dedy);59 dedyGm_.SetGlobalBuffer((__gm__ dedyType*)dedy);
59 yGm_.SetGlobalBuffer((__gm__ yType*)y);60 yGm_.SetGlobalBuffer((__gm__ yType*)y);
61+ if (tilingData.dualOutput != 0 && y1 != nullptr) {
62+ y1Gm_.SetGlobalBuffer((__gm__ y1Type*)y1);
63+ hasSecondOutput_ = true;
64+ }
60 if (unlikely(hasBias_)) {65 if (unlikely(hasBias_)) {
61 biasGm_.SetGlobalBuffer((__gm__ biasType*)bias);66 biasGm_.SetGlobalBuffer((__gm__ biasType*)bias);
62 }67 }
63- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {68+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
64- scaleGm_.SetGlobalBuffer((__gm__ scaleType*)scale);69+ scale0Gm_.SetGlobalBuffer((__gm__ scale0Type*)scale0);
70+ }
71+ if constexpr (GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
72+ if (scale1 != nullptr) {
73+ scale1Gm_.SetGlobalBuffer((__gm__ scale1Type*)scale1);
74+ }
65 }75 }
66 ComputeScalarTiling();76 ComputeScalarTiling();
67 }77 }
@@ -86,10 +96,13 @@ private:
86 GlobalTensor<filterType> filterGm_;96 GlobalTensor<filterType> filterGm_;
87 GlobalTensor<dedyType> dedyGm_;97 GlobalTensor<dedyType> dedyGm_;
88 GlobalTensor<yType> yGm_;98 GlobalTensor<yType> yGm_;
99+ GlobalTensor<y1Type> y1Gm_;
89 GlobalTensor<biasType> biasGm_;100 GlobalTensor<biasType> biasGm_;
90- GlobalTensor<scaleType> scaleGm_;101+ GlobalTensor<scale0Type> scale0Gm_;
102+ GlobalTensor<scale1Type> scale1Gm_;
91 103 
92 bool hasBias_ = false;104 bool hasBias_ = false;
105+ bool hasSecondOutput_ = false;
93 uint64_t hiWi_ = 0;106 uint64_t hiWi_ = 0;
94 uint64_t diHiWi_ = 0;107 uint64_t diHiWi_ = 0;
95 uint64_t doHoWo_ = 0;108 uint64_t doHoWo_ = 0;
@@ -172,13 +185,24 @@ private:
172 185 
173 __aicore__ inline uint32_t GetBiasL1ElemCount() const { return GetBiasL1SizeBytes() / sizeof(biasType); }186 __aicore__ inline uint32_t GetBiasL1ElemCount() const { return GetBiasL1SizeBytes() / sizeof(biasType); }
174 187 
175- __aicore__ inline uint32_t GetScaleL1OffBytes() const188+ __aicore__ inline uint32_t GetScale0L1OffBytes() const
176 {189 {
177 uint32_t biasL1OffBytes = GetBiasL1OffBytes();190 uint32_t biasL1OffBytes = GetBiasL1OffBytes();
178 uint32_t afterBias = hasBias_ ? biasL1OffBytes + GetBiasL1SizeBytes() : biasL1OffBytes;191 uint32_t afterBias = hasBias_ ? biasL1OffBytes + GetBiasL1SizeBytes() : biasL1OffBytes;
179 return (afterBias + ONE_BLK_SIZE - 1) / ONE_BLK_SIZE * ONE_BLK_SIZE;192 return (afterBias + ONE_BLK_SIZE - 1) / ONE_BLK_SIZE * ONE_BLK_SIZE;
180 }193 }
181 194 
195+ __aicore__ inline uint32_t GetScale1L1OffBytes() const
196+ {
197+ uint32_t afterScale0 = GetScale0L1OffBytes();
198+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
199+ if (tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
200+ afterScale0 += tiling_->singleCoreCin * sizeof(scale0Type);
201+ }
202+ }
203+ return (afterScale0 + ONE_BLK_SIZE - 1) / ONE_BLK_SIZE * ONE_BLK_SIZE;
204+ }
205+ 
182 __aicore__ inline void InitStaticL1(uint32_t nIdx)206 __aicore__ inline void InitStaticL1(uint32_t nIdx)
183 {207 {
184 uint32_t nStart = nIdx * tiling_->singleCoreCin;208 uint32_t nStart = nIdx * tiling_->singleCoreCin;
@@ -316,11 +340,13 @@ private:
316 if (hasBias_) {340 if (hasBias_) {
317 LoadBiasToBT(curN);341 LoadBiasToBT(curN);
318 }342 }
319- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {343+ bool hasVectorScale = tiling_->quantMode0 ==
320- if (tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {344+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT) ||
321- SetFlag<HardEvent::MTE2_FIX>(EVENT_ID_MTE2_FIX);345+ tiling_->quantMode1 ==
322- WaitFlag<HardEvent::MTE2_FIX>(EVENT_ID_MTE2_FIX);346+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT);
323- }347+ if (hasVectorScale) {
348+ SetFlag<HardEvent::MTE2_FIX>(EVENT_ID_MTE2_FIX);
349+ WaitFlag<HardEvent::MTE2_FIX>(EVENT_ID_MTE2_FIX);
324 }350 }
325 }351 }
326 352 
@@ -115,19 +115,26 @@ __aicore__ constexpr Conv3dConfig GetDefaultConfig()
115constexpr Conv3dConfig CONV3D_CFG_DEFAULT = GetDefaultConfig();115constexpr Conv3dConfig CONV3D_CFG_DEFAULT = GetDefaultConfig();
116 116 
117// 打包字段,内部实现的上下文,包含了用户构造的ConvBpParam117// 打包字段,内部实现的上下文,包含了用户构造的ConvBpParam
118-template <class A, class B, class C, class D, class E, class F>118+template <class A, class B, class C, class D, class E, class F, class G = D, class H = F>
119struct ConvBpContext {119struct ConvBpContext {
120+ // 标识当前 Intf 是否对应第二路输出(y1)。基类为 false,Output1Intf 覆盖为 true。
121+ // Kernel 写回路径据此区分 enRelu(0)/enRelu1(1),实现 y0/y1 独立 relu 控制。
122+ constexpr static bool IsSecondOutput = false;
120 using xType = A;123 using xType = A;
121 using cType = C;124 using cType = C;
122 using dType = D;125 using dType = D;
123 using eType = E;126 using eType = E;
124 using fType = F;127 using fType = F;
128+ using f1Type = H;
125 using SrcT = typename A::Type;129 using SrcT = typename A::Type;
126 using SrcAT = typename C::Type; // dedy Type130 using SrcAT = typename C::Type; // dedy Type
127 using SrcBT = typename A::Type; // filter Type131 using SrcBT = typename A::Type; // filter Type
128 using DstT = typename D::Type;132 using DstT = typename D::Type;
129 using BiasT = typename E::Type;133 using BiasT = typename E::Type;
130- using ScaleT = typename F::Type;134+ using ScaleT0 = typename F::Type;
135+ using Scale1T = typename H::Type;
136+ using Dst1T = typename G::Type;
137+ using d1Type = G;
131 using L0cT = typename GetDstType<SrcAT>::Type;138 using L0cT = typename GetDstType<SrcAT>::Type;
132 139 
133 constexpr static auto formatA = A::format;140 constexpr static auto formatA = A::format;
@@ -148,5 +155,36 @@ struct ConvBpContext {
148 __aicore__ inline _() {}155 __aicore__ inline _() {}
149 };156 };
150};157};
158+ 
159+template <class Intf>
160+struct Output1Config : public Intf::Config {
161+ using DstT = typename Intf::Dst1T;
162+ using dType = typename Intf::Config::d1Type;
163+ using fType = typename Intf::Config::f1Type;
164+ using ScaleT0 = typename Intf::Scale1T;
165+};
166+ 
167+template <class Intf>
168+struct Output1Intf {
169+ // 第二路输出(y1)视图:复用基类 ctx 内存,但 relu 控制走 tiling_->enRelu1。
170+ constexpr static bool IsSecondOutput = true;
171+ using Config = Output1Config<Intf>;
172+ using SrcT = typename Intf::SrcT;
173+ using SrcAT = typename Intf::SrcAT;
174+ using SrcBT = typename Intf::SrcBT;
175+ using DstT = typename Intf::Dst1T;
176+ using L0cT = typename Intf::L0cT;
177+ using BiasT = typename Intf::BiasT;
178+ using ScaleT0 = typename Intf::Scale1T;
179+ using ContextData = typename Intf::ContextData;
180+ ContextData ctx;
181+ constexpr static Conv3dConfig conv3dConfig = Intf::conv3dConfig;
182+};
183+ 
184+template <class Intf>
185+__aicore__ inline uint8_t GetOutputQuantMode(const Intf* self)
186+{
187+ return Intf::IsSecondOutput ? self->ctx.tiling_->quantMode1 : self->ctx.tiling_->quantMode0;
188+}
151} // namespace Convolution3DBackprop189} // namespace Convolution3DBackprop
152#endif190#endif
@@ -394,12 +394,23 @@ __aicore__ inline void InitBiasTque(Intf* self)
394template <class Intf>394template <class Intf>
395__aicore__ inline void InitScaleTque(Intf* self)395__aicore__ inline void InitScaleTque(Intf* self)
396{396{
397- if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&397+ uint32_t scaleSize = DivCeil(self->ctx.tiling_->singleCoreCin * sizeof(typename Intf::ScaleT0), ONE_BLK_SIZE) *
398- self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {398+ ONE_BLK_SIZE;
399- uint32_t scaleSize = DivCeil(self->ctx.tiling_->singleCoreCin * sizeof(typename Intf::ScaleT), ONE_BLK_SIZE) *399+ if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
400- ONE_BLK_SIZE;400+ if (self->ctx.tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
401- self->ctx.pipe_.InitBuffer(self->ctx.scaleL1Que_, 1, scaleSize);401+ self->ctx.pipe_.InitBuffer(self->ctx.scale0L1Que_, 1, scaleSize);
402+ }
402 }403 }
404+#ifdef DTYPE_Y1
405+ using Intf1 = Convolution3DBackprop::Output1Intf<Intf>;
406+ if constexpr (Intf1::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
407+ if (self->ctx.hasSecondOutput_) {
408+ if (self->ctx.tiling_->quantMode1 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
409+ self->ctx.pipe_.InitBuffer(self->ctx.scale1L1Que_, 1, scaleSize);
410+ }
411+ }
412+ }
413+#endif
403}414}
404 415 
405template <class Intf>416template <class Intf>
@@ -747,13 +758,24 @@ static __aicore__ inline void CalcInWorkspace(Intf* self, const GlobalTensor<typ
747template <class Intf>758template <class Intf>
748static __aicore__ inline void SetDequantScale(Intf* self)759static __aicore__ inline void SetDequantScale(Intf* self)
749{760{
761+ bool hasVectorScale = false;
750 if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {762 if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
751- if (self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {763+ hasVectorScale = self->ctx.tiling_->quantMode0 ==
752- event_t eventId = static_cast<event_t>(self->ctx.pipe_.FetchEventID(HardEvent::FIX_MTE2));764+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT);
753- SetFlag<HardEvent::FIX_MTE2>(eventId);765+ }
754- WaitFlag<HardEvent::FIX_MTE2>(eventId);766+#ifdef DTYPE_Y1
755- Convolution3DBackpropFunc::FullLoadToScaleL1<Intf>(self);767+ using Intf1 = Convolution3DBackprop::Output1Intf<Intf>;
756- }768+ if constexpr (Intf1::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
769+ hasVectorScale = hasVectorScale || (self->ctx.hasSecondOutput_ &&
770+ self->ctx.tiling_->quantMode1 ==
771+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT));
772+ }
773+#endif
774+ if (hasVectorScale) {
775+ event_t eventId = static_cast<event_t>(self->ctx.pipe_.FetchEventID(HardEvent::FIX_MTE2));
776+ SetFlag<HardEvent::FIX_MTE2>(eventId);
777+ WaitFlag<HardEvent::FIX_MTE2>(eventId);
778+ Convolution3DBackpropFunc::FullLoadToScaleL1<Intf>(self);
757 }779 }
758}780}
759 781 
@@ -795,9 +817,12 @@ struct Init {
795 // 定义call函数的默认重载函数,支持任意类型任意数量的参数817 // 定义call函数的默认重载函数,支持任意类型任意数量的参数
796 DECLARE_DEFAULT_OVERLOADING_FUN(Intf, Convolution3DBackpropFunc);818 DECLARE_DEFAULT_OVERLOADING_FUN(Intf, Convolution3DBackpropFunc);
797 static __aicore__ inline void call(Intf* self, const Conv3DBackpropInputArch35TilingData& tiling,819 static __aicore__ inline void call(Intf* self, const Conv3DBackpropInputArch35TilingData& tiling,
798- const bool hasBias)820+ const bool hasBias, const bool hasSecondOutput = false)
799 {821 {
800 self->ctx.hasBias_ = hasBias;822 self->ctx.hasBias_ = hasBias;
823+#ifdef DTYPE_Y1
824+ self->ctx.hasSecondOutput_ = hasSecondOutput;
825+#endif
801 // kernel侧通过ctx持有tiling指针,供后续全流程访问,避免向kernel内部逐层传递引用826 // kernel侧通过ctx持有tiling指针,供后续全流程访问,避免向kernel内部逐层传递引用
802 self->ctx.tiling_ = &(tiling);827 self->ctx.tiling_ = &(tiling);
803 self->ctx.curEnableFullLoad_ = self->ctx.tiling_->enableFullLoad;828 self->ctx.curEnableFullLoad_ = self->ctx.tiling_->enableFullLoad;
@@ -854,9 +879,9 @@ struct SetBias {
854template <class Intf>879template <class Intf>
855struct SetScale {880struct SetScale {
856 DECLARE_DEFAULT_OVERLOADING_FUN(Intf, Convolution3DBackpropFunc);881 DECLARE_DEFAULT_OVERLOADING_FUN(Intf, Convolution3DBackpropFunc);
857- static __aicore__ inline void call(Intf* self, const GlobalTensor<typename Intf::ScaleT>& scale)882+ static __aicore__ inline void call(Intf* self, const GlobalTensor<typename Intf::ScaleT0>& scale)
858 {883 {
859- self->ctx.scaleGlobal_ = scale;884+ self->ctx.scale0Global_ = scale;
860 }885 }
861};886};
862 887 
@@ -1082,11 +1107,23 @@ struct IterateAll {
1082 self->template IterateAllForKernelSplit<sync>(output, enAtomic);1107 self->template IterateAllForKernelSplit<sync>(output, enAtomic);
1083 }1108 }
1084 1109 
1085- if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&1110+ if ASCEND_IS_AIC_SCALAR {
1086- self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {1111+ if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
1087- if ASCEND_IS_AIC_SCALAR {1112+ if (self->ctx.tiling_->quantMode0 ==
1088- self->ctx.scaleL1Que_.FreeTensor(self->ctx.scaleL1Buf_);1113+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
1114+ self->ctx.scale0L1Que_.FreeTensor(self->ctx.scale0L1Buf_);
1115+ }
1089 }1116 }
1117+#ifdef DTYPE_Y1
1118+ using Intf1 = Convolution3DBackprop::Output1Intf<Intf>;
1119+ if constexpr (Intf1::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
1120+ if (self->ctx.hasSecondOutput_ &&
1121+ self->ctx.tiling_->quantMode1 ==
1122+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
1123+ self->ctx.scale1L1Que_.FreeTensor(self->ctx.scale1L1Buf_);
1124+ }
1125+ }
1126+#endif
1090 }1127 }
1091 self->ctx.isFirstIter_ = true;1128 self->ctx.isFirstIter_ = true;
1092 }1129 }
@@ -1171,10 +1208,20 @@ struct End {
1171 self->ctx.biasBTQue_.FreeAllEvent();1208 self->ctx.biasBTQue_.FreeAllEvent();
1172 }1209 }
1173 1210 
1174- if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&1211+ if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
1175- self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {1212+ if (self->ctx.tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
1176- self->ctx.scaleL1Que_.FreeAllEvent();1213+ self->ctx.scale0L1Que_.FreeAllEvent();
1214+ }
1177 }1215 }
1216+#ifdef DTYPE_Y1
1217+ using Intf1 = Convolution3DBackprop::Output1Intf<Intf>;
1218+ if constexpr (Intf1::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
1219+ if (self->ctx.hasSecondOutput_ &&
1220+ self->ctx.tiling_->quantMode1 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
1221+ self->ctx.scale1L1Que_.FreeAllEvent();
1222+ }
1223+ }
1224+#endif
1178 1225 
1179 if (self->ctx.tiling_->hf32Flag) {1226 if (self->ctx.tiling_->hf32Flag) {
1180 SetHF32Mode(false);1227 SetHF32Mode(false);
@@ -79,7 +79,10 @@ public:
79 DEFINE_STUCT_TEMPLATE_FIELD(TQue, l0cPong_, TPosition::CO1, 1);79 DEFINE_STUCT_TEMPLATE_FIELD(TQue, l0cPong_, TPosition::CO1, 1);
80 DEFINE_STUCT_FIELD(uint8_t, l0cPingPongFlag_);80 DEFINE_STUCT_FIELD(uint8_t, l0cPingPongFlag_);
81 DEFINE_STUCT_TEMPLATE_FIELD(TQue, biasL1Que_, TPosition::A1, 1);81 DEFINE_STUCT_TEMPLATE_FIELD(TQue, biasL1Que_, TPosition::A1, 1);
82- DEFINE_STUCT_TEMPLATE_FIELD(TQue, scaleL1Que_, TPosition::A1, 1);82+ DEFINE_STUCT_TEMPLATE_FIELD(TQue, scale0L1Que_, TPosition::A1, 1);
83+#ifdef DTYPE_Y1
84+ DEFINE_STUCT_TEMPLATE_FIELD(TQue, scale1L1Que_, TPosition::A1, 1);
85+#endif
83 DEFINE_STUCT_TEMPLATE_FIELD(TQue, biasBTQue_, TPosition::C2, 1);86 DEFINE_STUCT_TEMPLATE_FIELD(TQue, biasBTQue_, TPosition::C2, 1);
84 DEFINE_STUCT_TEMPLATE_FIELD(TBuf, l0aBuf_, TPosition::A2);87 DEFINE_STUCT_TEMPLATE_FIELD(TBuf, l0aBuf_, TPosition::A2);
85 DEFINE_STUCT_TEMPLATE_FIELD(TBuf, l0bBuf_, TPosition::B2);88 DEFINE_STUCT_TEMPLATE_FIELD(TBuf, l0bBuf_, TPosition::B2);
@@ -173,8 +176,15 @@ public:
173 DEFINE_STUCT_FIELD(GlobalTensor<typename Intf::BiasT>, biasGlobal_);176 DEFINE_STUCT_FIELD(GlobalTensor<typename Intf::BiasT>, biasGlobal_);
174 DEFINE_STUCT_FIELD(LocalTensor<typename Intf::BiasT>, biasL1Buf_);177 DEFINE_STUCT_FIELD(LocalTensor<typename Intf::BiasT>, biasL1Buf_);
175 DEFINE_STUCT_FIELD(LocalTensor<typename Intf::L0cT>, biasBTBuf_);178 DEFINE_STUCT_FIELD(LocalTensor<typename Intf::L0cT>, biasBTBuf_);
176- DEFINE_STUCT_FIELD(GlobalTensor<typename Intf::ScaleT>, scaleGlobal_);179+ DEFINE_STUCT_FIELD(GlobalTensor<typename Intf::ScaleT0>, scale0Global_);
177- DEFINE_STUCT_FIELD(LocalTensor<typename Intf::ScaleT>, scaleL1Buf_);180+#ifdef DTYPE_Y1
181+ DEFINE_STUCT_FIELD(GlobalTensor<typename Intf::Scale1T>, scale1Global_);
182+#endif
183+ DEFINE_STUCT_FIELD(LocalTensor<typename Intf::ScaleT0>, scale0L1Buf_);
184+#ifdef DTYPE_Y1
185+ DEFINE_STUCT_FIELD(LocalTensor<typename Intf::Scale1T>, scale1L1Buf_);
186+ DEFINE_STUCT_FIELD(bool, hasSecondOutput_);
187+#endif
178 DEFINE_STUCT_FIELD(GlobalTensor<float>, l0cOutGm_); // tmp workspace to store result data with fp32188 DEFINE_STUCT_FIELD(GlobalTensor<float>, l0cOutGm_); // tmp workspace to store result data with fp32
179 DEFINE_STUCT_FIELD(GlobalTensor<typename Intf::DstT>, l0cOutWorkspace_); // tmp workspace for kernel split189 DEFINE_STUCT_FIELD(GlobalTensor<typename Intf::DstT>, l0cOutWorkspace_); // tmp workspace for kernel split
180#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 3510) || __DAV_35_FAMILY__190#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 3510) || __DAV_35_FAMILY__
@@ -27,13 +27,17 @@ template <class Config_, template <typename, class> class Impl>
27struct ConvBpIntf {27struct ConvBpIntf {
28 using Config = Config_;28 using Config = Config_;
29 using Ext = Impl<ConvBpIntf, Config>;29 using Ext = Impl<ConvBpIntf, Config>;
30+ // 透传 Config 的 IsSecondOutput(基类 ConvBpContext 为 false;Output1Intf 覆盖为 true)。
31+ constexpr static bool IsSecondOutput = Config::IsSecondOutput;
30 using SrcT = typename Config::SrcT;32 using SrcT = typename Config::SrcT;
31 using SrcBT = typename Config::SrcBT;33 using SrcBT = typename Config::SrcBT;
32 using SrcAT = typename Config::SrcAT;34 using SrcAT = typename Config::SrcAT;
33 using DstT = typename Config::DstT;35 using DstT = typename Config::DstT;
36+ using Dst1T = typename Config::Dst1T;
34 using L0cT = typename Config::L0cT;37 using L0cT = typename Config::L0cT;
35 using BiasT = typename Config::BiasT;38 using BiasT = typename Config::BiasT;
36- using ScaleT = typename Config::ScaleT;39+ using ScaleT0 = typename Config::ScaleT0;
40+ using Scale1T = typename Config::Scale1T;
37 using IndexT = typename AscendC::Conditional<AscendC::IsSameType<SrcBT, float>::value, uint32_t, uint16_t>::type;41 using IndexT = typename AscendC::Conditional<AscendC::IsSameType<SrcBT, float>::value, uint32_t, uint16_t>::type;
38 using ContextData = typename Ext::ContextData;42 using ContextData = typename Ext::ContextData;
39 43 
@@ -44,12 +48,13 @@ public:
44public:48public:
45 __aicore__ inline ConvBpIntf() {}49 __aicore__ inline ConvBpIntf() {}
46 50 
47- __aicore__ inline void Init(const Conv3DBackpropInputArch35TilingData& tiling, const bool hasBias = false)51+ __aicore__ inline void Init(const Conv3DBackpropInputArch35TilingData& tiling, const bool hasBias = false,
52+ const bool hasSecondOutput = false)
48 {53 {
49 using Local = typename Ext::Init;54 using Local = typename Ext::Init;
50 // CheckFun检查impl是否实现了Init的call函数55 // CheckFun检查impl是否实现了Init的call函数
51- if constexpr (CHECK_FUN(Local, Convolution3DBackpropFunc, this, tiling, hasBias)) {56+ if constexpr (CHECK_FUN(Local, Convolution3DBackpropFunc, this, tiling, hasBias, hasSecondOutput)) {
52- Local::call(this, tiling, hasBias);57+ Local::call(this, tiling, hasBias, hasSecondOutput);
53 }58 }
54 }59 }
55 60 
@@ -85,7 +90,7 @@ public:
85 }90 }
86 }91 }
87 92 
88- __aicore__ inline void SetScale(const GlobalTensor<ScaleT>& scale)93+ __aicore__ inline void SetScale(const GlobalTensor<ScaleT0>& scale)
89 {94 {
90 using Local = typename Ext::SetScale;95 using Local = typename Ext::SetScale;
91 if constexpr (CHECK_FUN(Local, Convolution3DBackpropFunc, this, scale)) {96 if constexpr (CHECK_FUN(Local, Convolution3DBackpropFunc, this, scale)) {
@@ -93,6 +98,14 @@ public:
93 }98 }
94 }99 }
95 100 
101+ __aicore__ inline void SetScale1(const GlobalTensor<Scale1T>& scale)
102+ {
103+#ifdef DTYPE_Y1
104+ ctx.scale1Global_ = scale;
105+ ctx.hasSecondOutput_ = true;
106+#endif
107+ }
108+ 
96 __aicore__ inline void SetKernelSplitParams(uint32_t kSCoutFullLoad, uint32_t kSUseWorkSpace)109 __aicore__ inline void SetKernelSplitParams(uint32_t kSCoutFullLoad, uint32_t kSUseWorkSpace)
97 {110 {
98 using Local = typename Ext::SetKernelSplitParams;111 using Local = typename Ext::SetKernelSplitParams;
@@ -192,6 +205,58 @@ public:
192 }205 }
193 }206 }
194 207 
208+ template <bool sync = true>
209+ __aicore__ inline void IterateAll(const GlobalTensor<DstT>& output0, const GlobalTensor<Dst1T>& output1,
210+ uint8_t enAtomic = 0, bool fullLoadBiasFlag_ = false, bool freeBiasFlag_ = false)
211+ {
212+ bool hasBias = ctx.hasBias_;
213+ if (unlikely(hasBias && ctx.tiling_->isBiasFullLoad)) {
214+ if (freeBiasFlag_) {
215+ FreeBiasTensor();
216+ }
217+ if (fullLoadBiasFlag_) {
218+ Convolution3DBackpropFunc::FullLoadBias<ConvBpIntf<Config_, Impl>>(this);
219+ }
220+ }
221+ Convolution3DBackpropFunc::SetDequantScale<ConvBpIntf<Config_, Impl>>(this);
222+ if (ctx.enableSplitK_) {
223+ Convolution3DBackpropFunc::CalcSplitK_<ConvBpIntf<Config_, Impl>, sync>(this, enAtomic, output0, hasBias);
224+ if (ctx.useUbAccumForSplitK_ && ctx.needComputeFlag_) {
225+ using Intf1 = Convolution3DBackprop::Output1Intf<ConvBpIntf<Config_, Impl>>;
226+ auto* self1 = reinterpret_cast<Intf1*>(this);
227+ Convolution3DBackpropFunc::AccumulateSegmentOnWorkspace<Intf1>(self1, output1);
228+ }
229+ } else {
230+ while (Iterate<sync>(false, hasBias)) {
231+ VecPreProcess<sync>(output0, enAtomic);
232+ GetTensorC<sync>(output0, output1, enAtomic);
233+ VecPostProcess<sync>(output0, enAtomic);
234+ }
235+ }
236+ if ASCEND_IS_AIC_SCALAR {
237+ if constexpr (Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
238+ if (ctx.tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
239+ ctx.scale0L1Que_.FreeTensor(ctx.scale0L1Buf_);
240+ }
241+ }
242+ using Intf1 = Convolution3DBackprop::Output1Intf<ConvBpIntf<Config_, Impl>>;
243+ if constexpr (Intf1::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
244+ if (ctx.hasSecondOutput_ &&
245+ ctx.tiling_->quantMode1 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
246+ ctx.scale1L1Que_.FreeTensor(ctx.scale1L1Buf_);
247+ }
248+ }
249+ }
250+ ctx.isFirstIter_ = true;
251+ }
252+ 
253+ template <bool sync = true>
254+ __aicore__ inline void GetTensorC(const GlobalTensor<DstT>& output0, const GlobalTensor<Dst1T>& output1,
255+ uint8_t enAtomic = 0, bool enSequentialWrite = false)
256+ {
257+ Convolution3DBackpropFunc::LoadL0c2GmDual(this, output0, output1, enAtomic, enSequentialWrite);
258+ }
259+ 
195 template <bool sync = true>260 template <bool sync = true>
196 __aicore__ inline void VecPreProcess(const GlobalTensor<DstT>& output, uint8_t enAtomic = 0,261 __aicore__ inline void VecPreProcess(const GlobalTensor<DstT>& output, uint8_t enAtomic = 0,
197 bool enSequentialWrite = false)262 bool enSequentialWrite = false)
@@ -22,9 +22,9 @@
22 22 
23namespace Convolution3DBackprop {23namespace Convolution3DBackprop {
24// 注册,通过别名定义用户接口24// 注册,通过别名定义用户接口
25-#define REGISTER_DX_IMPL(name, context, impl, intf) \25+#define REGISTER_DX_IMPL(name, context, impl, intf) \
26- template <class X_T, class W_TYPE, class DEDY_T, class Y_T, class BIAS_T, class SCALE_T, \26+ template <class X_T, class W_TYPE, class DEDY_T, class Y_T, class BIAS_T, class SCALE_T, \
27- const Conv3dConfig& CONV3D_CONFIG = CONV3D_CFG_DEFAULT> \27+ const Conv3dConfig& CONV3D_CONFIG = CONV3D_CFG_DEFAULT, class Y1_T = Y_T, class SCALE1_T = SCALE_T> \
28- using name = intf<context<X_T, W_TYPE, DEDY_T, Y_T, BIAS_T, SCALE_T, CONV3D_CONFIG>, impl>28+ using name = intf<context<X_T, W_TYPE, DEDY_T, Y_T, BIAS_T, SCALE_T, CONV3D_CONFIG, Y1_T, SCALE1_T>, impl>
29} // namespace Convolution3DBackprop29} // namespace Convolution3DBackprop
30#endif30#endif
@@ -143,10 +143,17 @@ __aicore__ inline void LoadBiasScaleL1(uint32_t nStart, uint32_t curN)
143 LocalTensor<biasType> biasL1(TPosition::A1, GetBiasL1OffBytes(), GetBiasL1ElemCount());143 LocalTensor<biasType> biasL1(TPosition::A1, GetBiasL1OffBytes(), GetBiasL1ElemCount());
144 LoadChannelWiseL1<biasType>(biasL1, biasGm_[nStart], curN);144 LoadChannelWiseL1<biasType>(biasL1, biasGm_[nStart], curN);
145 }145 }
146- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {146+ if constexpr (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
147- if (tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {147+ if (tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
148- LocalTensor<scaleType> scaleL1(TPosition::A1, GetScaleL1OffBytes(), tiling_->singleCoreCin);148+ LocalTensor<scale0Type> scaleL1(TPosition::A1, GetScale0L1OffBytes(), tiling_->singleCoreCin);
149- LoadChannelWiseL1<scaleType>(scaleL1, scaleGm_[nStart], curN);149+ LoadChannelWiseL1<scale0Type>(scaleL1, scale0Gm_[nStart], curN);
150+ }
151+ }
152+ if constexpr (GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
153+ if (hasSecondOutput_ &&
154+ tiling_->quantMode1 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
155+ LocalTensor<scale1Type> scale1L1(TPosition::A1, GetScale1L1OffBytes(), tiling_->singleCoreCin);
156+ LoadChannelWiseL1<scale1Type>(scale1L1, scale1Gm_[nStart], curN);
150 }157 }
151 }158 }
152}159}
@@ -243,36 +250,43 @@ __aicore__ inline void LoadBL0(LocalTensor<filterType>& b0, const LocalTensor<fi
243 }250 }
244}251}
245 252 
253+template <bool output1>
254+__aicore__ inline auto GetFixpipeDeqScalar()
255+{
256+ if constexpr (output1) {
257+ return scale1Gm_.GetValue(0);
258+ } else {
259+ return scale0Gm_.GetValue(0);
260+ }
261+}
262+ 
263+template <bool output1, QuantMode_t vectorMode, QuantMode_t scalarMode>
264+__aicore__ inline void SetFixpipeScaleQuant(FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR>& params)
265+{
266+ constexpr auto scaleFormat = output1 ? GetScaleFormat(scale1Format) : GetScaleFormat(scale0Format);
267+ params.quantPre = scalarMode;
268+ params.deqScalar = CONV3D_DX_SMALL_DQ_SCALAR_QF_ONE;
269+ if constexpr (scaleFormat != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
270+ const uint8_t quantMode = output1 ? tiling_->quantMode1 : tiling_->quantMode0;
271+ if (quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
272+ params.quantPre = vectorMode;
273+ } else if (quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::SCALAR_QUANT)) {
274+ params.deqScalar = GetFixpipeDeqScalar<output1>();
275+ }
276+ }
277+}
278+ 
279+template <typename outputType, bool output1 = false>
246__aicore__ inline void SetFixpipeQuant(FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR>& params)280__aicore__ inline void SetFixpipeQuant(FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR>& params)
247{281{
248- if constexpr (std::is_same<yType, bfloat16_t>::value) {282+ if constexpr (std::is_same<outputType, bfloat16_t>::value) {
249 params.quantPre = QuantMode_t::F322BF16;283 params.quantPre = QuantMode_t::F322BF16;
250- } else if constexpr (std::is_same<yType, half>::value && std::is_same<L0cT, int32_t>::value) {284+ } else if constexpr (std::is_same<outputType, half>::value && std::is_same<L0cT, int32_t>::value) {
251- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {285+ SetFixpipeScaleQuant<output1, QuantMode_t::VDEQF16, QuantMode_t::DEQF16>(params);
252- if (tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {286+ } else if constexpr (std::is_same<outputType, half>::value) {
253- params.quantPre = QuantMode_t::VDEQF16;
254- } else {
255- params.quantPre = QuantMode_t::DEQF16;
256- params.deqScalar = scaleGm_.GetValue(0);
257- }
258- } else {
259- params.quantPre = QuantMode_t::DEQF16;
260- params.deqScalar = CONV3D_DX_SMALL_DQ_SCALAR_QF_ONE;
261- }
262- } else if constexpr (std::is_same<yType, half>::value) {
263 params.quantPre = QuantMode_t::F322F16;287 params.quantPre = QuantMode_t::F322F16;
264- } else if constexpr (std::is_same<yType, int8_t>::value) {288+ } else if constexpr (std::is_same<outputType, int8_t>::value) {
265- if constexpr (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT) {289+ SetFixpipeScaleQuant<output1, QuantMode_t::VREQ8, QuantMode_t::REQ8>(params);
266- if (tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
267- params.quantPre = QuantMode_t::VREQ8;
268- } else {
269- params.quantPre = QuantMode_t::REQ8;
270- params.deqScalar = scaleGm_.GetValue(0);
271- }
272- } else {
273- params.quantPre = QuantMode_t::REQ8;
274- params.deqScalar = CONV3D_DX_SMALL_DQ_SCALAR_QF_ONE;
275- }
276 } else {290 } else {
277 params.quantPre = QuantMode_t::NoQuant;291 params.quantPre = QuantMode_t::NoQuant;
278 }292 }
@@ -291,21 +305,36 @@ __aicore__ inline void CopyOut(const LocalTensor<L0cT>& c0, uint32_t batchIdx, u
291 params.srcStride = curMAlign;305 params.srcStride = curMAlign;
292 params.dstStride = diHiWi_;306 params.dstStride = diHiWi_;
293#if __FIXED_POINT_ONLY_CUBE_TO_L0C__307#if __FIXED_POINT_ONLY_CUBE_TO_L0C__
294- params.preReluMode = static_cast<ReluMode>(tiling_->enRelu);308+ params.preReluMode = static_cast<ReluMode>(tiling_->enRelu0);
295 if constexpr (std::is_same<dedyType, half>::value && std::is_same<filterType, half>::value) {309 if constexpr (std::is_same<dedyType, half>::value && std::is_same<filterType, half>::value) {
296 params.fixShiftVal = SHIFT_VALUE_LEN - static_cast<uint8_t>(tiling_->fixedShiftVal);310 params.fixShiftVal = SHIFT_VALUE_LEN - static_cast<uint8_t>(tiling_->fixedShiftVal);
297 }311 }
298#endif312#endif
299- SetFixpipeQuant(params);313+ SetFixpipeQuant<yType>(params);
300 uint64_t batchOffset = static_cast<uint64_t>(batchIdx) * tiling_->cin * diHiWi_;314 uint64_t batchOffset = static_cast<uint64_t>(batchIdx) * tiling_->cin * diHiWi_;
301 uint64_t dstOffset = batchOffset + static_cast<uint64_t>(nStart) * diHiWi_ + mStart;315 uint64_t dstOffset = batchOffset + static_cast<uint64_t>(nStart) * diHiWi_ + mStart;
302- if (GetScaleFormat(scaleFormat) != Convolution3DBackprop::CubeFormat::UNSUPPORT &&316+ if (GetScaleFormat(scale0Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT &&
303- tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {317+ tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
304- LocalTensor<scaleType> scaleL1(TPosition::A1, GetScaleL1OffBytes(), tiling_->singleCoreCin);318+ LocalTensor<scale0Type> scaleL1(TPosition::A1, GetScale0L1OffBytes(), tiling_->singleCoreCin);
305 Fixpipe<yType, L0cT, CFG_COLUMN_MAJOR>(yGm_[dstOffset], c0, scaleL1, params);319 Fixpipe<yType, L0cT, CFG_COLUMN_MAJOR>(yGm_[dstOffset], c0, scaleL1, params);
306 } else {320 } else {
307 Fixpipe<yType, L0cT, CFG_COLUMN_MAJOR>(yGm_[dstOffset], c0, params);321 Fixpipe<yType, L0cT, CFG_COLUMN_MAJOR>(yGm_[dstOffset], c0, params);
308 }322 }
323+ if (hasSecondOutput_) {
324+ FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR> params1 = params;
325+ SetFixpipeQuant<y1Type, true>(params1);
326+#if __FIXED_POINT_ONLY_CUBE_TO_L0C__
327+ // 第二路输出(y1)独立 relu:覆盖为 enRelu1(params 继承的是 y0 的 enRelu)。
328+ params1.preReluMode = static_cast<ReluMode>(tiling_->enRelu1);
329+#endif
330+ if (GetScaleFormat(scale1Format) != Convolution3DBackprop::CubeFormat::UNSUPPORT &&
331+ tiling_->quantMode1 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
332+ LocalTensor<scale1Type> scale1L1(TPosition::A1, GetScale1L1OffBytes(), tiling_->singleCoreCin);
333+ Fixpipe<y1Type, L0cT, CFG_COLUMN_MAJOR>(y1Gm_[dstOffset], c0, scale1L1, params1);
334+ } else {
335+ Fixpipe<y1Type, L0cT, CFG_COLUMN_MAJOR>(y1Gm_[dstOffset], c0, params1);
336+ }
337+ }
309}338}
310 339 
311#endif // CONV3D_BP_SMALL_KERNEL_FUNC_ADVANCE_H340#endif // CONV3D_BP_SMALL_KERNEL_FUNC_ADVANCE_H
@@ -279,15 +279,33 @@ __aicore__ inline void FullLoadToScaleL1(Intf* self)
279 if ASCEND_IS_AIV_SHOULD_RETURN {279 if ASCEND_IS_AIV_SHOULD_RETURN {
280 return;280 return;
281 }281 }
282- LocalTensor<typename Intf::ScaleT> useScaleL1 = self->ctx.scaleL1Que_.template AllocTensor<typename Intf::ScaleT>();282+ uint16_t blockLen = self->ctx.singleShapeCin_ * sizeof(typename Intf::ScaleT0);
283- uint16_t blockLen = self->ctx.singleShapeCin_ * sizeof(typename Intf::ScaleT);
284 DataCopyParams dataCopyParams(1, blockLen, 0, 0);283 DataCopyParams dataCopyParams(1, blockLen, 0, 0);
285 // 4 is B64 data num per block, currently scale is always uint64284 // 4 is B64 data num per block, currently scale is always uint64
286 uint8_t rightPadding = DivCeil(self->ctx.singleShapeCin_, 4) * 4 - self->ctx.singleShapeCin_;285 uint8_t rightPadding = DivCeil(self->ctx.singleShapeCin_, 4) * 4 - self->ctx.singleShapeCin_;
287 DataCopyPadParams padParams(true, 0, rightPadding, 0);286 DataCopyPadParams padParams(true, 0, rightPadding, 0);
288- DataCopyPad<typename Intf::ScaleT>(useScaleL1, self->ctx.scaleGlobal_, dataCopyParams, padParams);287+ if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
289- self->ctx.scaleL1Que_.EnQue(useScaleL1);288+ if (self->ctx.tiling_->quantMode0 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
290- self->ctx.scaleL1Buf_ = self->ctx.scaleL1Que_.template DeQue<typename Intf::ScaleT>();289+ LocalTensor<typename Intf::ScaleT0> useScaleL1 = self->ctx.scale0L1Que_
290+ .template AllocTensor<typename Intf::ScaleT0>();
291+ DataCopyPad<typename Intf::ScaleT0>(useScaleL1, self->ctx.scale0Global_, dataCopyParams, padParams);
292+ self->ctx.scale0L1Que_.EnQue(useScaleL1);
293+ self->ctx.scale0L1Buf_ = self->ctx.scale0L1Que_.template DeQue<typename Intf::ScaleT0>();
294+ }
295+ }
296+#ifdef DTYPE_Y1
297+ using Intf1 = Convolution3DBackprop::Output1Intf<Intf>;
298+ if constexpr (Intf1::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
299+ if (self->ctx.hasSecondOutput_ &&
300+ self->ctx.tiling_->quantMode1 == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
301+ LocalTensor<typename Intf::Scale1T> useScale1L1 = self->ctx.scale1L1Que_
302+ .template AllocTensor<typename Intf::Scale1T>();
303+ DataCopyPad<typename Intf::Scale1T>(useScale1L1, self->ctx.scale1Global_, dataCopyParams, padParams);
304+ self->ctx.scale1L1Que_.EnQue(useScale1L1);
305+ self->ctx.scale1L1Buf_ = self->ctx.scale1L1Que_.template DeQue<typename Intf::Scale1T>();
306+ }
307+ }
308+#endif
291}309}
292 310 
293} // namespace Convolution3DBackpropFunc311} // namespace Convolution3DBackpropFunc
@@ -167,9 +167,10 @@ static __aicore__ inline void LoadL0c2OutForKernelSplitHW(Intf* self, const Loca
167 SetFixPipeQuantVal<Intf>(self, fixPipeParams);167 SetFixPipeQuantVal<Intf>(self, fixPipeParams);
168 fixPipeParams.params.srcNzC0Stride = 1; // src M stride, loop0_src_stride (unit: 32B)168 fixPipeParams.params.srcNzC0Stride = 1; // src M stride, loop0_src_stride (unit: 32B)
169 fixPipeParams.nSize = self->ctx.baseUseN_; // N: cin169 fixPipeParams.nSize = self->ctx.baseUseN_; // N: cin
170- fixPipeParams.reluEn = self->ctx.tiling_->enRelu;170+ fixPipeParams.reluEn = Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 : self->ctx.tiling_->enRelu0;
171#if __FIXED_POINT_ONLY_CUBE_TO_L0C__171#if __FIXED_POINT_ONLY_CUBE_TO_L0C__
172- fixPipeParams.preReluMode = static_cast<ReluMode>(self->ctx.tiling_->enRelu);172+ fixPipeParams.preReluMode = static_cast<ReluMode>(Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 :
173+ self->ctx.tiling_->enRelu0);
173#endif174#endif
174 // loop1_src_stride, c0_size, cin1175 // loop1_src_stride, c0_size, cin1
175 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)176 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)
@@ -89,9 +89,10 @@ static __aicore__ inline void LoadL0c2GmForNz2Dn(Intf* self, const GlobalTensor<
89 fixPipeParams.nSize = self->ctx.baseUseN_; // N: cin89 fixPipeParams.nSize = self->ctx.baseUseN_; // N: cin
90 // loop1_src_stride, c0_size, cin190 // loop1_src_stride, c0_size, cin1
91 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)91 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)
92- fixPipeParams.reluEn = self->ctx.tiling_->enRelu;92+ fixPipeParams.reluEn = Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 : self->ctx.tiling_->enRelu0;
93#if __FIXED_POINT_ONLY_CUBE_TO_L0C__93#if __FIXED_POINT_ONLY_CUBE_TO_L0C__
94- fixPipeParams.preReluMode = static_cast<ReluMode>(self->ctx.tiling_->enRelu);94+ fixPipeParams.preReluMode = static_cast<ReluMode>(Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 :
95+ self->ctx.tiling_->enRelu0);
95#endif96#endif
96 uint64_t dstOffset = ComputeDstOffset(self, fixPipeParams);97 uint64_t dstOffset = ComputeDstOffset(self, fixPipeParams);
97 if (self->ctx.enableSplitDk_ || self->ctx.useUbAccumForSplitK_) {98 if (self->ctx.enableSplitDk_ || self->ctx.useUbAccumForSplitK_) {
@@ -183,10 +184,11 @@ static __aicore__ inline void LoadL0c2GmRowForKernelSplitHFixPipe(
183 LocalTensor<typename Intf::L0cT>& useC1Buf, FixpipeParamsArch3510<CO2Layout::ROW_MAJOR>& fixPipeParams)184 LocalTensor<typename Intf::L0cT>& useC1Buf, FixpipeParamsArch3510<CO2Layout::ROW_MAJOR>& fixPipeParams)
184{185{
185 if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&186 if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&
186- self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {187+ Convolution3DBackprop::GetOutputQuantMode<Intf>(self) ==
188+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
187 uint64_t scaleAddr = self->ctx.curNIdx_ * self->ctx.tiling_->baseN;189 uint64_t scaleAddr = self->ctx.curNIdx_ * self->ctx.tiling_->baseN;
188 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_ROW_MAJOR>(190 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_ROW_MAJOR>(
189- output[dstOffset], useC1Buf[srcOffset], self->ctx.scaleL1Buf_[scaleAddr], fixPipeParams);191+ output[dstOffset], useC1Buf[srcOffset], GetScaleL1Buf<Intf>(self)[scaleAddr], fixPipeParams);
190 } else {192 } else {
191 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_ROW_MAJOR>(output[dstOffset], useC1Buf[srcOffset],193 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_ROW_MAJOR>(output[dstOffset], useC1Buf[srcOffset],
192 fixPipeParams);194 fixPipeParams);
@@ -216,9 +218,10 @@ static __aicore__ inline void LoadL0c2GmDnForKernelSplitH(Intf* self, const Glob
216 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)218 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)
217 // loop2_dst_stride, element, c219 // loop2_dst_stride, element, c
218 fixPipeParams.dstStride = self->ctx.diHiWi_; // dst N stride, loop2_dst_stride (unit: element)220 fixPipeParams.dstStride = self->ctx.diHiWi_; // dst N stride, loop2_dst_stride (unit: element)
219- fixPipeParams.reluEn = self->ctx.tiling_->enRelu;221+ fixPipeParams.reluEn = Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 : self->ctx.tiling_->enRelu0;
220#if __FIXED_POINT_ONLY_CUBE_TO_L0C__222#if __FIXED_POINT_ONLY_CUBE_TO_L0C__
221- fixPipeParams.preReluMode = static_cast<ReluMode>(self->ctx.tiling_->enRelu);223+ fixPipeParams.preReluMode = static_cast<ReluMode>(Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 :
224+ self->ctx.tiling_->enRelu0);
222#endif225#endif
223 int64_t srcOffset = 0;226 int64_t srcOffset = 0;
224 // fixpipe->gm 需要分首块,中间块,尾块分别对齐到16,然后再搬到gm227 // fixpipe->gm 需要分首块,中间块,尾块分别对齐到16,然后再搬到gm
@@ -278,9 +281,10 @@ static __aicore__ inline void LoadL0c2GmNdForKernelSplitH(Intf* self, const Glob
278 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)281 fixPipeParams.srcStride = AlignUp16(self->ctx.baseUseM_); // src N stride, loop1_src_stride (unit: 32B)
279 // loop2_dst_stride, element, c282 // loop2_dst_stride, element, c
280 fixPipeParams.dstStride = self->ctx.tiling_->cin; // dst N stride, loop2_dst_stride (unit: element)283 fixPipeParams.dstStride = self->ctx.tiling_->cin; // dst N stride, loop2_dst_stride (unit: element)
281- fixPipeParams.reluEn = self->ctx.tiling_->enRelu;284+ fixPipeParams.reluEn = Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 : self->ctx.tiling_->enRelu0;
282#if __FIXED_POINT_ONLY_CUBE_TO_L0C__285#if __FIXED_POINT_ONLY_CUBE_TO_L0C__
283- fixPipeParams.preReluMode = static_cast<ReluMode>(self->ctx.tiling_->enRelu);286+ fixPipeParams.preReluMode = static_cast<ReluMode>(Intf::IsSecondOutput ? self->ctx.tiling_->enRelu1 :
287+ self->ctx.tiling_->enRelu0);
284#endif288#endif
285 int64_t srcOffset = 0;289 int64_t srcOffset = 0;
286 if (self->ctx.headWi_ != 0) { // 需要首块290 if (self->ctx.headWi_ != 0) { // 需要首块
@@ -124,7 +124,8 @@ static __aicore__ inline void LoadL0c2Gm(Intf* self, const GlobalTensor<typename
124 LocalTensor<typename Intf::L0cT> useC1Buf;124 LocalTensor<typename Intf::L0cT> useC1Buf;
125 L0CDeQue<Intf>(self, useC1Buf);125 L0CDeQue<Intf>(self, useC1Buf);
126 SetEnAtomic<Intf>(self, enAtomic);126 SetEnAtomic<Intf>(self, enAtomic);
127- if (self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {127+ if (Convolution3DBackprop::GetOutputQuantMode<Intf>(self) ==
128+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
128 event_t eventId = static_cast<event_t>(self->ctx.pipe_.FetchEventID(HardEvent::MTE2_FIX));129 event_t eventId = static_cast<event_t>(self->ctx.pipe_.FetchEventID(HardEvent::MTE2_FIX));
129 SetFlag<HardEvent::MTE2_FIX>(eventId);130 SetFlag<HardEvent::MTE2_FIX>(eventId);
130 WaitFlag<HardEvent::MTE2_FIX>(eventId);131 WaitFlag<HardEvent::MTE2_FIX>(eventId);
@@ -146,6 +147,56 @@ static __aicore__ inline void LoadL0c2Gm(Intf* self, const GlobalTensor<typename
146 FreeTensorC1Buf(self, useC1Buf);147 FreeTensorC1Buf(self, useC1Buf);
147}148}
148 149 
150+template <class Intf>
151+static __aicore__ inline void LoadL0c2GmDual(Intf* self, const GlobalTensor<typename Intf::DstT>& output0,
152+ const GlobalTensor<typename Intf::Dst1T>& output1, uint8_t enAtomic = 0,
153+ bool enSequentialWrite = false)
154+{
155+ if constexpr (Intf::conv3dConfig.kernelSplitMode != TPL_SPLIT_KERNEL_HW) {
156+ if ASCEND_IS_AIV_SHOULD_RETURN {
157+ return;
158+ }
159+ }
160+ if (!self->ctx.needComputeFlag_) {
161+ return;
162+ }
163+ 
164+ LocalTensor<typename Intf::L0cT> useC1Buf;
165+ L0CDeQue<Intf>(self, useC1Buf);
166+ SetEnAtomic<Intf>(self, enAtomic);
167+ using Intf1 = Convolution3DBackprop::Output1Intf<Intf>;
168+ bool hasVectorScale = self->ctx.tiling_->quantMode0 ==
169+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT) ||
170+ self->ctx.tiling_->quantMode1 ==
171+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT);
172+ if (hasVectorScale) {
173+ event_t eventId = static_cast<event_t>(self->ctx.pipe_.FetchEventID(HardEvent::MTE2_FIX));
174+ SetFlag<HardEvent::MTE2_FIX>(eventId);
175+ WaitFlag<HardEvent::MTE2_FIX>(eventId);
176+ }
177+ if constexpr (Intf::Config::dType::format == Convolution3DBackprop::CubeFormat::NCDHW) {
178+ LoadL0c2OutForNz2Dn<Intf>(self, output0, useC1Buf);
179+ } else {
180+#if !__CUBE_VECTOR_FUSION_ONLY__
181+ LoadL0c2OutForNz2Nd<Intf>(self, output0, useC1Buf);
182+#endif
183+ }
184+ 
185+ auto* self1 = reinterpret_cast<Intf1*>(self);
186+ if constexpr (Intf1::Config::dType::format == Convolution3DBackprop::CubeFormat::NCDHW) {
187+ LoadL0c2OutForNz2Dn<Intf1>(self1, output1, useC1Buf);
188+ } else {
189+#if !__CUBE_VECTOR_FUSION_ONLY__
190+ LoadL0c2OutForNz2Nd<Intf1>(self1, output1, useC1Buf);
191+#endif
192+ }
193+ 
194+ if (enAtomic == 1) {
195+ SetAtomicNone();
196+ }
197+ FreeTensorC1Buf(self, useC1Buf);
198+}
199+ 
149} // namespace Convolution3DBackpropFunc200} // namespace Convolution3DBackpropFunc
150 201 
151#endif202#endif
@@ -25,6 +25,39 @@ using AscendC::LocalTensor;
25 25 
26namespace Convolution3DBackpropFunc {26namespace Convolution3DBackpropFunc {
27 27 
28+// 选当前输出对应的 scalar scale GM:第二路输出(y1)用 scale1Global_,第一路(y0)用 scale0Global_。
29+// scale1Global_ 仅在双输出编译(DTYPE_Y1)下存在,而 IsSecondOutput=true 的 Intf 也只在 DTYPE_Y1 下实例化,
30+// 故第二路分支由 if constexpr 编译期隔离,单输出编译不会引用到不存在的成员。
31+template <class Intf>
32+static __aicore__ inline auto& GetScaleGlobal(Intf* self)
33+{
34+ if constexpr (Intf::IsSecondOutput) {
35+#ifdef DTYPE_Y1
36+ return self->ctx.scale1Global_;
37+#else
38+ // 单输出编译不会实例化 IsSecondOutput=true 的 Intf,此分支不可达。
39+ return self->ctx.scale0Global_;
40+#endif
41+ } else {
42+ return self->ctx.scale0Global_;
43+ }
44+}
45+ 
46+// 选当前输出对应的 vector scale L1 buffer:第二路用 scale1L1Buf_,第一路用 scale0L1Buf_。
47+template <class Intf>
48+static __aicore__ inline auto& GetScaleL1Buf(Intf* self)
49+{
50+ if constexpr (Intf::IsSecondOutput) {
51+#ifdef DTYPE_Y1
52+ return self->ctx.scale1L1Buf_;
53+#else
54+ return self->ctx.scale0L1Buf_;
55+#endif
56+ } else {
57+ return self->ctx.scale0L1Buf_;
58+ }
59+}
60+ 
28template <class Intf>61template <class Intf>
29static __aicore__ inline void LoadL0c2GMFixPipe(Intf* self, const int64_t srcOffset, const int64_t dstOffset,62static __aicore__ inline void LoadL0c2GMFixPipe(Intf* self, const int64_t srcOffset, const int64_t dstOffset,
30 const GlobalTensor<typename Intf::DstT>& output,63 const GlobalTensor<typename Intf::DstT>& output,
@@ -32,10 +65,11 @@ static __aicore__ inline void LoadL0c2GMFixPipe(Intf* self, const int64_t srcOff
32 FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR>& fixPipeParams)65 FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR>& fixPipeParams)
33{66{
34 if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&67 if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&
35- self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {68+ Convolution3DBackprop::GetOutputQuantMode<Intf>(self) ==
69+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
36 uint64_t scaleAddr = self->ctx.curNIdx_ * self->ctx.tiling_->baseN;70 uint64_t scaleAddr = self->ctx.curNIdx_ * self->ctx.tiling_->baseN;
37 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR>(71 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR>(
38- output[dstOffset], useC1Buf[srcOffset], self->ctx.scaleL1Buf_[scaleAddr], fixPipeParams);72+ output[dstOffset], useC1Buf[srcOffset], GetScaleL1Buf<Intf>(self)[scaleAddr], fixPipeParams);
39 } else {73 } else {
40 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR>(output[dstOffset], useC1Buf[srcOffset],74 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR>(output[dstOffset], useC1Buf[srcOffset],
41 fixPipeParams);75 fixPipeParams);
@@ -49,10 +83,11 @@ static __aicore__ inline void LoadL0c2UbFixPipe(Intf* self, const int64_t srcOff
49 FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR>& fixPipeParams)83 FixpipeParamsArch3510<CO2Layout::COLUMN_MAJOR>& fixPipeParams)
50{84{
51 if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&85 if (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT &&
52- self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {86+ Convolution3DBackprop::GetOutputQuantMode<Intf>(self) ==
87+ static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
53 uint64_t scaleAddr = self->ctx.curNIdx_ * self->ctx.tiling_->baseN;88 uint64_t scaleAddr = self->ctx.curNIdx_ * self->ctx.tiling_->baseN;
54 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR_UB>(89 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR_UB>(
55- vecOutBuf[dstOffset], useC1Buf[srcOffset], self->ctx.scaleL1Buf_[scaleAddr], fixPipeParams);90+ vecOutBuf[dstOffset], useC1Buf[srcOffset], GetScaleL1Buf<Intf>(self)[scaleAddr], fixPipeParams);
56 } else {91 } else {
57 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR_UB>(vecOutBuf[dstOffset],92 Fixpipe<typename Intf::DstT, typename Intf::L0cT, CFG_COLUMN_MAJOR_UB>(vecOutBuf[dstOffset],
58 useC1Buf[srcOffset], fixPipeParams);93 useC1Buf[srcOffset], fixPipeParams);
@@ -63,11 +98,17 @@ template <class Intf, CO2Layout layout = CO2Layout::COLUMN_MAJOR>
63static __aicore__ inline void SetQuantInt32ToHalf(Intf* self, FixpipeParamsArch3510<layout>& fixPipeParams)98static __aicore__ inline void SetQuantInt32ToHalf(Intf* self, FixpipeParamsArch3510<layout>& fixPipeParams)
64{99{
65 if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {100 if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
66- if (self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {101+ const uint8_t quantMode = Convolution3DBackprop::GetOutputQuantMode<Intf>(self);
102+ if (quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
67 fixPipeParams.quantPre = QuantMode_t::VDEQF16; // int32 -> fp16 tensor quant103 fixPipeParams.quantPre = QuantMode_t::VDEQF16; // int32 -> fp16 tensor quant
68- } else {104+ } else if (quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::SCALAR_QUANT)) {
69 fixPipeParams.quantPre = QuantMode_t::DEQF16; // int32 -> fp16 scalar quant105 fixPipeParams.quantPre = QuantMode_t::DEQF16; // int32 -> fp16 scalar quant
70- fixPipeParams.deqScalar = self->ctx.scaleGlobal_.GetValue(0);106+ fixPipeParams.deqScalar = GetScaleGlobal<Intf>(self).GetValue(0);
107+ } else {
108+ // The formal scale slot can retain a supported compile-time format even when it is not connected.
109+ // NO_QUANT must not read that absent GM input; fixed-point fp16 writeback uses the unit coefficient.
110+ fixPipeParams.quantPre = QuantMode_t::DEQF16;
111+ fixPipeParams.deqScalar = DQ_SCALAR_QF_ONE;
71 }112 }
72 } else {113 } else {
73 fixPipeParams.quantPre = QuantMode_t::DEQF16; // int32 -> fp16 scalar quant114 fixPipeParams.quantPre = QuantMode_t::DEQF16; // int32 -> fp16 scalar quant
@@ -79,11 +120,15 @@ template <class Intf, CO2Layout layout = CO2Layout::COLUMN_MAJOR>
79static __aicore__ inline void SetQuantInt8(Intf* self, FixpipeParamsArch3510<layout>& fixPipeParams)120static __aicore__ inline void SetQuantInt8(Intf* self, FixpipeParamsArch3510<layout>& fixPipeParams)
80{121{
81 if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {122 if constexpr (Intf::Config::fType::format != Convolution3DBackprop::CubeFormat::UNSUPPORT) {
82- if (self->ctx.tiling_->quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {123+ const uint8_t quantMode = Convolution3DBackprop::GetOutputQuantMode<Intf>(self);
124+ if (quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::VECTOR_QUANT)) {
83 fixPipeParams.quantPre = QuantMode_t::VREQ8;125 fixPipeParams.quantPre = QuantMode_t::VREQ8;
126+ } else if (quantMode == static_cast<uint8_t>(Convolution3DBackprop::QuantMode::SCALAR_QUANT)) {
127+ fixPipeParams.quantPre = QuantMode_t::REQ8;
128+ fixPipeParams.deqScalar = GetScaleGlobal<Intf>(self).GetValue(0);
84 } else {129 } else {
85 fixPipeParams.quantPre = QuantMode_t::REQ8;130 fixPipeParams.quantPre = QuantMode_t::REQ8;
86- fixPipeParams.deqScalar = self->ctx.scaleGlobal_.GetValue(0);131+ fixPipeParams.deqScalar = DQ_SCALAR_QF_ONE;
87 }132 }
88 } else {133 } else {
89 fixPipeParams.quantPre = QuantMode_t::REQ8;134 fixPipeParams.quantPre = QuantMode_t::REQ8;