已合并
修正Conv3D Transpose N2H方案准入规则 #9726
hexinhui创建于 9月2日
修正Conv3D Transpose N2H方案准入规则 #9726
已合并
共 3 个文件变更+90-7
| @@ -5007,7 +5007,8 @@ private: | |||
| 5007 | static aclnnStatus CheckN2HAndTranspose(const aclTensor*& input, const aclTensor*& weight, int groups, | 5007 | static aclnnStatus CheckN2HAndTranspose(const aclTensor*& input, const aclTensor*& weight, int groups, |
| 5008 | aclOpExecutor* executor, TransposeAdaptParam* params) | 5008 | aclOpExecutor* executor, TransposeAdaptParam* params) |
| 5009 | { | 5009 | { |
| 5010 | - if (CheckTransposeN2HEnable(input, weight, params->adaptStride, params->adaptDilation, params->adaptPad, groups)) { | 5010 | + if (CheckTransposeN2HEnable(input, weight, params->adaptStride, params->adaptDilation, params->adaptPad, |
L | |||
| 5011 | + params->adaptoutputPad, groups)) { | ||
| 5011 | auto ret = N2HChangeInput(input, executor); | 5012 | auto ret = N2HChangeInput(input, executor); |
| 5012 | if (ret != ACLNN_SUCCESS) { | 5013 | if (ret != ACLNN_SUCCESS) { |
| 5013 | OP_LOGE(ACLNN_ERR_INNER_INFERSHAPE_ERROR, "N2H failed."); | 5014 | OP_LOGE(ACLNN_ERR_INNER_INFERSHAPE_ERROR, "N2H failed."); |
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "opdev/op_log.h" | 23 | #include "opdev/op_log.h" |
| 24 | #include "opdev/shape_utils.h" | 24 | #include "opdev/shape_utils.h" |
| 25 | #include "aclnn_kernels/transpose.h" | 25 | #include "aclnn_kernels/transpose.h" |
| 26 | +#include "op_api/aclnn_util.h" | ||
| 26 | 27 | ||
| 27 | using namespace op; | 28 | using namespace op; |
| 28 | 29 | ||
| @@ -76,6 +77,9 @@ constexpr int64_t W_IN_TRANSPOSE_N2H_RULE_MAX = 64; | |||
| 76 | constexpr int64_t W_K_TRANSPOSE_N2H_RULE_MAX = 10; | 77 | constexpr int64_t W_K_TRANSPOSE_N2H_RULE_MAX = 10; |
| 77 | constexpr int64_t N2H_W_IN_SIXTY = 60; | 78 | constexpr int64_t N2H_W_IN_SIXTY = 60; |
| 78 | constexpr int64_t N2H_W_IN_FORTY = 40; | 79 | constexpr int64_t N2H_W_IN_FORTY = 40; |
| 80 | +constexpr uint64_t N2H_NO_HKWK_BASE_M = 1024; | ||
| 81 | +constexpr uint64_t N2H_NO_HKWK_BASE_N = 16; | ||
| 82 | +constexpr uint64_t N2H_CUBE_BLOCK_BYTES = 32; | ||
| 79 | constexpr int64_t C_IN_TRANSPOSE_LIMIT_MIN = 16; | 83 | constexpr int64_t C_IN_TRANSPOSE_LIMIT_MIN = 16; |
| 80 | constexpr int64_t C_IN_TRANSPOSE_LIMIT_MAX = 32; | 84 | constexpr int64_t C_IN_TRANSPOSE_LIMIT_MAX = 32; |
| 81 | constexpr float MAX_CIN_MULTIPLIER = 1.5f; | 85 | constexpr float MAX_CIN_MULTIPLIER = 1.5f; |
| @@ -1138,6 +1142,23 @@ static bool CheckN2HTransposeAttrCriteria(int64_t wi, int64_t cin) | |||
| 1138 | return true; | 1142 | return true; |
| 1139 | } | 1143 | } |
| 1140 | 1144 | ||
| 1145 | +static bool IsN2HTransposeDtype(DataType dataType) | ||
| 1146 | +{ | ||
| 1147 | + return dataType == DataType::DT_FLOAT16 || dataType == DataType::DT_BF16 || dataType == DataType::DT_FLOAT; | ||
| 1148 | +} | ||
| 1149 | + | ||
| 1150 | +static bool CheckN2HTransposeDtypeAvailable(const aclTensor* input, const aclTensor* weight) | ||
| 1151 | +{ | ||
| 1152 | + const auto inputDtype = input->GetDataType(); | ||
| 1153 | + const auto weightDtype = weight->GetDataType(); | ||
| 1154 | + if (inputDtype != weightDtype || !IsN2HTransposeDtype(inputDtype) || !IsN2HTransposeDtype(weightDtype)) { | ||
| 1155 | + OP_LOGD("[N2H] only FP16, BF16 and FP32 are supported, but inputDtype=%d, weightDtype=%d.", | ||
| 1156 | + static_cast<int>(inputDtype), static_cast<int>(weightDtype)); | ||
| 1157 | + return false; | ||
| 1158 | + } | ||
| 1159 | + return true; | ||
| 1160 | +} | ||
| 1161 | + | ||
| 1141 | static bool CheckN2HTransposeNativeAttrAvailable(const aclTensor* input, const aclTensor* weight) | 1162 | static bool CheckN2HTransposeNativeAttrAvailable(const aclTensor* input, const aclTensor* weight) |
| 1142 | { | 1163 | { |
| 1143 | auto inputShape = input->GetStorageShape(); | 1164 | auto inputShape = input->GetStorageShape(); |
| @@ -1168,15 +1189,66 @@ static bool CheckN2HTransposeNativeAttrAvailable(const aclTensor* input, const a | |||
| 1168 | return false; | 1189 | return false; |
| 1169 | } | 1190 | } |
| 1170 | if (cout < 1 || cout > C_TRANSPOSE_N2H_RULE_MAX || cin < 1 || cin > C_TRANSPOSE_N2H_RULE_MAX) { | 1191 | if (cout < 1 || cout > C_TRANSPOSE_N2H_RULE_MAX || cin < 1 || cin > C_TRANSPOSE_N2H_RULE_MAX) { |
| 1171 | - OP_LOGD("[N2H] the valid range for cout is [1, 128], and for cin is [1, 128], but cout=%lld, cin=%lld.", cout, | 1192 | + OP_LOGD("[N2H] the valid range for cout and cin is [1, 128], but " |
| 1172 | - cin); | 1193 | + "cout=%lld, cin=%lld.", |
| 1194 | + cout, cin); | ||
| 1173 | return false; | 1195 | return false; |
| 1174 | } | 1196 | } |
| 1175 | return CheckN2HTransposeAttrCriteria(wi, cin); | 1197 | return CheckN2HTransposeAttrCriteria(wi, cin); |
| 1176 | } | 1198 | } |
| 1177 | 1199 | ||
| 1200 | +static bool CheckN2HNoHkWkL1Probe(const aclTensor* input, const aclTensor* weight, const aclIntArray* stride5, | ||
| 1201 | + const aclIntArray* outputPadding5) | ||
| 1202 | +{ | ||
| 1203 | + if (stride5 == nullptr || outputPadding5 == nullptr || stride5->Size() != conv3dDimNum || | ||
| 1204 | + outputPadding5->Size() != conv3dDimNum) { | ||
| 1205 | + return false; | ||
| 1206 | + } | ||
| 1207 | + | ||
| 1208 | + const auto inputShape = input->GetStorageShape(); | ||
| 1209 | + const auto weightShape = weight->GetStorageShape(); | ||
| 1210 | + const int64_t batch = inputShape[N_DIM_NCDHW_INDEX]; | ||
| 1211 | + const int64_t wi = inputShape[W_DIM_NCDHW_INDEX]; | ||
| 1212 | + const int64_t wk = weightShape[W_DIM_NCDHW_INDEX]; | ||
| 1213 | + const int64_t strideW = stride5->GetData()[W_DIM_NCDHW_INDEX]; | ||
| 1214 | + const int64_t outputPaddingW = outputPadding5->GetData()[W_DIM_NCDHW_INDEX]; | ||
| 1215 | + if (batch <= 0 || wi <= 0 || wk <= 0 || strideW <= 0 || outputPaddingW < 0) { | ||
| 1216 | + return false; | ||
| 1217 | + } | ||
| 1218 | + | ||
| 1219 | + const uint64_t wo = (wi - 1) * strideW + wk + outputPaddingW; | ||
| 1220 | + uint64_t calHo = 0; | ||
| 1221 | + if (N2H_NO_HKWK_BASE_M % wo == 0 || wo % N2H_NO_HKWK_BASE_M == 0) { | ||
| 1222 | + calHo = N2H_NO_HKWK_BASE_M / wo + static_cast<uint64_t>(N2H_NO_HKWK_BASE_M % wo != 0); | ||
| 1223 | + } else if (N2H_NO_HKWK_BASE_M > wo) { | ||
| 1224 | + calHo = N2H_NO_HKWK_BASE_M / wo + 2; | ||
| 1225 | + } else { | ||
| 1226 | + calHo = 2; | ||
| 1227 | + } | ||
| 1228 | + const uint64_t curHo = std::min(static_cast<uint64_t>(batch), calHo); | ||
| 1229 | + const uint64_t aProbe = curHo * static_cast<uint64_t>(wi) * static_cast<uint64_t>(strideW) * N2H_CUBE_BLOCK_BYTES; | ||
| 1230 | + const uint64_t bProbe = static_cast<uint64_t>(wk) * N2H_CUBE_BLOCK_BYTES * N2H_NO_HKWK_BASE_N; | ||
| 1231 | + uint64_t requiredL1 = aProbe + bProbe; | ||
| 1232 | + | ||
| 1233 | + auto platformInfo = GetCurrentPlatformInfo().GetPlatformInfos(); | ||
| 1234 | + if (platformInfo == nullptr) { | ||
| 1235 | + return false; | ||
| 1236 | + } | ||
| 1237 | + uint64_t availableL1 = 0; | ||
| 1238 | + platformInfo->GetLocalMemSize(fe::LocalMemType::L1, availableL1); | ||
| 1239 | + if (availableL1 == 0) { | ||
| 1240 | + return false; | ||
| 1241 | + } | ||
| 1242 | + | ||
| 1243 | + const bool enabled = requiredL1 <= availableL1; | ||
| 1244 | + OP_LOGD("[N2H] no-HkWk L1 probe %s: required=%lu, available=%lu, N=%lld, Wi=%lld, " | ||
| 1245 | + "Wk=%lld, strideW=%lld, outputPaddingW=%lld", | ||
| 1246 | + enabled ? "passed" : "rejected", requiredL1, availableL1, batch, wi, wk, strideW, outputPaddingW); | ||
| 1247 | + return enabled; | ||
| 1248 | +} | ||
| 1249 | + | ||
| 1178 | bool CheckTransposeN2HEnable(const aclTensor* input, const aclTensor* weight, aclIntArray* stride5, | 1250 | bool CheckTransposeN2HEnable(const aclTensor* input, const aclTensor* weight, aclIntArray* stride5, |
| 1179 | - aclIntArray* dilation5, aclIntArray* pad5, int groups) | 1251 | + aclIntArray* dilation5, aclIntArray* pad5, aclIntArray* outputPadding5, int groups) |
| 1180 | { | 1252 | { |
| 1181 | OP_LOGD("Conv3d Transpose Check N2H attribute."); | 1253 | OP_LOGD("Conv3d Transpose Check N2H attribute."); |
| 1182 | if (groups != 1) { | 1254 | if (groups != 1) { |
| @@ -1186,8 +1258,18 @@ bool CheckTransposeN2HEnable(const aclTensor* input, const aclTensor* weight, ac | |||
| 1186 | if (!CheckN2HTransposeAttrAvailable(stride5, dilation5, pad5)) { | 1258 | if (!CheckN2HTransposeAttrAvailable(stride5, dilation5, pad5)) { |
| 1187 | return false; | 1259 | return false; |
| 1188 | } | 1260 | } |
| 1189 | - // check N, D, H, W, C and access criteria | 1261 | + if (!CheckN2HTransposeNativeAttrAvailable(input, weight)) { |
| 1190 | - return CheckN2HTransposeNativeAttrAvailable(input, weight); | 1262 | + return false; |
| 1263 | + } | ||
| 1264 | + // 非950分支保持原有方案 | ||
| 1265 | + if (!Ops::NN::AclnnUtil::IsRegbase()) { | ||
| 1266 | + return true; | ||
| 1267 | + } | ||
| 1268 | + if (!CheckN2HTransposeDtypeAvailable(input, weight)) { | ||
| 1269 | + return false; | ||
| 1270 | + } | ||
| 1271 | + // 提前计算HkWk模板准入条件,防止性能劣化 | ||
| 1272 | + return CheckN2HNoHkWkL1Probe(input, weight, stride5, outputPadding5); | ||
| 1191 | } | 1273 | } |
| 1192 | 1274 | ||
| 1193 | bool CheckPreTransposeEnable(const aclTensor* weight, int groups) | 1275 | bool CheckPreTransposeEnable(const aclTensor* weight, int groups) |
| @@ -154,7 +154,7 @@ bool IsSupportConv2DTransposeTo3D(const aclTensor* input, const aclTensor* weigh | |||
| 154 | const aclIntArray* stride, const aclIntArray* padding, const aclIntArray* dilation, | 154 | const aclIntArray* stride, const aclIntArray* padding, const aclIntArray* dilation, |
| 155 | const aclIntArray* outputPadding, const int64_t groups, aclTensor* output); | 155 | const aclIntArray* outputPadding, const int64_t groups, aclTensor* output); |
| 156 | bool CheckTransposeN2HEnable(const aclTensor* input, const aclTensor* weight, aclIntArray* stride5, | 156 | bool CheckTransposeN2HEnable(const aclTensor* input, const aclTensor* weight, aclIntArray* stride5, |
| 157 | - aclIntArray* dilation5, aclIntArray* pad5, int groups); | 157 | + aclIntArray* dilation5, aclIntArray* pad5, aclIntArray* outputPadding5, int groups); |
| 158 | bool CheckPreTransposeEnable(const aclTensor* weight, int groups); | 158 | bool CheckPreTransposeEnable(const aclTensor* weight, int groups); |
| 159 | aclnnStatus N2HChangeInput(const aclTensor*& input, aclOpExecutor* executor); | 159 | aclnnStatus N2HChangeInput(const aclTensor*& input, aclOpExecutor* executor); |
| 160 | void GetConv3DTransposeAdapterParam(const aclTensor* input, const aclIntArray* stride, const aclIntArray* padding, | 160 | void GetConv3DTransposeAdapterParam(const aclTensor* input, const aclIntArray* stride, const aclIntArray* padding, |


使用gitcode-pr-issue添加一下ISSUE吧