已合并
[dx]aclnn通路新增前置transpose,优化超大Cin轴场景性能 #1462
Zehai创建于 2月3日
[dx]aclnn通路新增前置transpose,优化超大Cin轴场景性能 #1462
已合并
从已删除 :wzh_feature02合入到cann/ops-nnmaster
共 3 个文件变更+58-5
| @@ -116,8 +116,8 @@ int aclnnConvolutionBackwardTest(int32_t deviceId, aclrtStream &stream) | |||
| 116 | CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | 116 | CHECK_FREE_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); |
| 117 | // 2. 构造输入与输出,需要根据API的接口自定义构造 | 117 | // 2. 构造输入与输出,需要根据API的接口自定义构造 |
| 118 | std::vector<int64_t> gradOutputShape = {4, 320, 80, 80}; | 118 | std::vector<int64_t> gradOutputShape = {4, 320, 80, 80}; |
| 119 | - std::vector<int64_t> inputShape = {4, 320, 80, 80}; | 119 | + std::vector<int64_t> inputShape = {4, 30, 80, 80}; |
| 120 | - std::vector<int64_t> weightShape = {320, 320, 3, 3}; | 120 | + std::vector<int64_t> weightShape = {320, 30, 3, 3}; |
| 121 | std::vector<int64_t> biasSize = {320}; | 121 | std::vector<int64_t> biasSize = {320}; |
| 122 | std::vector<int64_t> stride = {1, 1}; | 122 | std::vector<int64_t> stride = {1, 1}; |
| 123 | std::vector<int64_t> padding = {1,1}; | 123 | std::vector<int64_t> padding = {1,1}; |
| @@ -128,8 +128,8 @@ int aclnnConvolutionBackwardTest(int32_t deviceId, aclrtStream &stream) | |||
| 128 | bool outputMask[3] = {true, true, true}; | 128 | bool outputMask[3] = {true, true, true}; |
| 129 | int8_t cubeMathType = 1; | 129 | int8_t cubeMathType = 1; |
| 130 | 130 | ||
| 131 | - std::vector<int64_t> gradInputShape = {4, 320, 80, 80}; | 131 | + std::vector<int64_t> gradInputShape = {4, 30, 80, 80}; |
| 132 | - std::vector<int64_t> gradWeightShape = {320, 320, 3, 3}; | 132 | + std::vector<int64_t> gradWeightShape = {320, 30, 3, 3}; |
| 133 | std::vector<int64_t> gradBiasShape = {320}; | 133 | std::vector<int64_t> gradBiasShape = {320}; |
| 134 | 134 | ||
| 135 | // 创建gradOutput aclTensor | 135 | // 创建gradOutput aclTensor |
| @@ -38,6 +38,7 @@ const int64_t H_DIM_NCDHW_INDEX = 3; | |||
| 38 | const int64_t W_DIM_NCDHW_INDEX = 4; | 38 | const int64_t W_DIM_NCDHW_INDEX = 4; |
| 39 | const FVector<int64_t> OUTPUT_BACKPROP_N2H_SHAPE_DIMS = {3, 2, 0, 4, 1}; | 39 | const FVector<int64_t> OUTPUT_BACKPROP_N2H_SHAPE_DIMS = {3, 2, 0, 4, 1}; |
| 40 | const FVector<int64_t> WEIGHT_N2H_SHAPE_DIMS = {0, 2, 3, 4, 1}; | 40 | const FVector<int64_t> WEIGHT_N2H_SHAPE_DIMS = {0, 2, 3, 4, 1}; |
| 41 | +const FVector<int64_t> WEIGHT_TRANSPOSE_SHAPE_DIMS = {0, 2, 3, 4, 1}; | ||
| 41 | constexpr int64_t C1_DIM_NDC1HWC0_INDEX = 2; | 42 | constexpr int64_t C1_DIM_NDC1HWC0_INDEX = 2; |
| 42 | constexpr int64_t C0_DIM_NDC1HWC0_INDEX = 5; | 43 | constexpr int64_t C0_DIM_NDC1HWC0_INDEX = 5; |
| 43 | constexpr uint32_t BASIC_BLOCK_SIZE_128 = 128; | 44 | constexpr uint32_t BASIC_BLOCK_SIZE_128 = 128; |
| @@ -57,6 +58,9 @@ constexpr int64_t W_IN_TRANSPOSE_N2H_RULE_MAX = 64; | |||
| 57 | constexpr int64_t W_K_TRANSPOSE_N2H_RULE_MAX = 10; | 58 | constexpr int64_t W_K_TRANSPOSE_N2H_RULE_MAX = 10; |
| 58 | constexpr int64_t N2H_W_IN_SIXTY = 60; | 59 | constexpr int64_t N2H_W_IN_SIXTY = 60; |
| 59 | constexpr int64_t N2H_W_IN_FORTY = 40; | 60 | constexpr int64_t N2H_W_IN_FORTY = 40; |
| 61 | +constexpr int64_t C_IN_TRANSPOSE_LIMIT_MIN = 16; | ||
| 62 | +constexpr int64_t C_IN_TRANSPOSE_LIMIT_MAX = 32; | ||
| 63 | +constexpr float MAX_CIN_MULTIPLIER = 1.5f; | ||
| 60 | 64 | ||
| 61 | const vector<vector<int64_t>> CONV2D_BACKPROP_INPUT_CAST_WHITE_LIST = | 65 | const vector<vector<int64_t>> CONV2D_BACKPROP_INPUT_CAST_WHITE_LIST = |
| 62 | { | 66 | { |
| @@ -2063,6 +2067,40 @@ static bool CheckN2HEnable(const aclTensor *weight, aclTensor *&output, | |||
| 2063 | return CheckN2HNativeAttrAvailable(weight, output); | 2067 | return CheckN2HNativeAttrAvailable(weight, output); |
| 2064 | } | 2068 | } |
| 2065 | 2069 | ||
| 2070 | +static bool CheckWeightPreTransposeEnable(const aclTensor *weight, int groups) { | ||
| 2071 | + OP_LOGD("Enter CheckWeightPreTransposeEnable."); | ||
| 2072 | + | ||
| 2073 | + if (groups > 1 || weight->GetOriginalFormat() != op::Format::FORMAT_NCDHW) { | ||
| 2074 | + return false; | ||
| 2075 | + } | ||
| 2076 | + | ||
| 2077 | + auto dataType = weight->GetDataType(); | ||
| 2078 | + if (dataType != op::DataType::DT_FLOAT && dataType != op::DataType::DT_FLOAT16 && dataType != op::DataType::DT_BF16) { | ||
| 2079 | + return false; | ||
| 2080 | + } | ||
| 2081 | + | ||
| 2082 | + auto weightShape = weight->GetOriginalShape(); | ||
| 2083 | + for (size_t i = 0; i < weightShape.GetDimNum(); i++) { | ||
| 2084 | + if (weightShape[i] <= 0) { | ||
| 2085 | + return false; | ||
| 2086 | + } | ||
| 2087 | + } | ||
| 2088 | + | ||
| 2089 | + uint64_t cout = weightShape[N_DIM_NCDHW_INDEX]; | ||
| 2090 | + uint64_t cin = weightShape[C_DIM_NCDHW_INDEX]; | ||
| 2091 | + uint64_t dk = weightShape[D_DIM_NCDHW_INDEX]; | ||
| 2092 | + uint64_t hk = weightShape[H_DIM_NCDHW_INDEX]; | ||
| 2093 | + uint64_t wk = weightShape[W_DIM_NCDHW_INDEX]; | ||
| 2094 | + if (dk * hk * wk <= 1) { | ||
| 2095 | + return false; | ||
| 2096 | + } | ||
| 2097 | + | ||
| 2098 | + if ((cin != C_IN_TRANSPOSE_LIMIT_MIN && cin < C_IN_TRANSPOSE_LIMIT_MAX) || cin <= dk * hk * wk) { | ||
| 2099 | + return false; | ||
| 2100 | + } | ||
| 2101 | + return (cout > cin) ? (cout < MAX_CIN_MULTIPLIER * cin) : (cin < MAX_CIN_MULTIPLIER * cout); | ||
| 2102 | +} | ||
| 2103 | + | ||
| 2066 | static aclnnStatus N2HOptimize(const aclTensor *&weight, const aclTensor *&outBackprop, | 2104 | static aclnnStatus N2HOptimize(const aclTensor *&weight, const aclTensor *&outBackprop, |
| 2067 | aclTensor *&output, aclIntArray *&stride5, aclOpExecutor *executor) { | 2105 | aclTensor *&output, aclIntArray *&stride5, aclOpExecutor *executor) { |
| 2068 | OP_LOGD("Enable N2H optimize."); | 2106 | OP_LOGD("Enable N2H optimize."); |
| @@ -2147,6 +2185,21 @@ static aclnnStatus Conv3DBackpropInputWithFlag(const aclTensor *input, const acl | |||
| 2147 | return ACLNN_ERR_INNER_NULLPTR; | 2185 | return ACLNN_ERR_INNER_NULLPTR; |
| 2148 | } | 2186 | } |
| 2149 | } | 2187 | } |
| 2188 | + | ||
| 2189 | + if (CheckWeightPreTransposeEnable(weight, groups)) { | ||
Y | |||
| 2190 | + OP_LOGD("Conv3d backpropInput v2 support weight pre transpose."); | ||
| 2191 | + // transpose weight NCDHW -> NDHWC | ||
| 2192 | + auto permAfter = executor->AllocIntArray(WEIGHT_TRANSPOSE_SHAPE_DIMS.data(), WEIGHT_TRANSPOSE_SHAPE_DIMS.size()); | ||
| 2193 | + CHECK_RET(permAfter != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 2194 | + weight = l0op::Transpose(weight, permAfter, executor); | ||
| 2195 | + | ||
| 2196 | + // change weight format | ||
| 2197 | + CHECK_RET(weight != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 2198 | + const_cast<aclTensor*>(weight)->SetOriginalFormat(Format::FORMAT_NDHWC); | ||
| 2199 | + const_cast<aclTensor*>(weight)->SetStorageFormat(Format::FORMAT_NDHWC); | ||
| 2200 | + const_cast<aclTensor*>(weight)->SetViewFormat(Format::FORMAT_NDHWC); | ||
| 2201 | + } | ||
| 2202 | + | ||
| 2150 | L0_DFX(Conv3DBackpropInputWithFlag, input, weight, outBackprop, stride, padding, dilation, groups, useHf32Flag, output); | 2203 | L0_DFX(Conv3DBackpropInputWithFlag, input, weight, outBackprop, stride, padding, dilation, groups, useHf32Flag, output); |
| 2151 | if (useV2Flag) { | 2204 | if (useV2Flag) { |
| 2152 | bool enableHf32 = (outBackprop->GetDataType() == DataType::DT_FLOAT) && (useHf32Flag == 0x40); | 2205 | bool enableHf32 = (outBackprop->GetDataType() == DataType::DT_FLOAT) && (useHf32Flag == 0x40); |
| @@ -1117,7 +1117,7 @@ static bool CheckPreTransposeEnable(const aclTensor *weight, int groups) { | |||
| 1117 | } | 1117 | } |
| 1118 | 1118 | ||
| 1119 | auto dataType = weight->GetDataType(); | 1119 | auto dataType = weight->GetDataType(); |
| 1120 | - if (dataType != op::DataType::DT_FLOAT && dataType != op::DataType::DT_FLOAT16) { | 1120 | + if (dataType != op::DataType::DT_FLOAT && dataType != op::DataType::DT_FLOAT16 && dataType != op::DataType::DT_BF16) { |
| 1121 | return false; | 1121 | return false; |
| 1122 | } | 1122 | } |
| 1123 | 1123 | ||
加一下Ops::NN::AclnnUtil::IsRegbase()芯片代际隔离判断