已合并
perf: 限制V2 stride计算上限 #1955
gaoxin创建于 21 天前
perf: 限制V2 stride计算上限 #1955
已合并
共 3 个文件变更+61-6
| @@ -261,6 +261,7 @@ af::Status LoadStoreStrideV2Func(const std::map<std::string, float> ¶m_map, | |||
| 261 | // Stride惩罚项:k * block_count * stride * data_type_size | 261 | // Stride惩罚项:k * block_count * stride * data_type_size |
| 262 | Expr block_count = CalculateBlockCountByIndex(dims, block_count_idx); | 262 | Expr block_count = CalculateBlockCountByIndex(dims, block_count_idx); |
| 263 | Expr stride_used = LimitedStrideUpperBound(stride * GetDataTypeSizeExpr(param_map), upper_val); | 263 | Expr stride_used = LimitedStrideUpperBound(stride * GetDataTypeSizeExpr(param_map), upper_val); |
| 264 | + stride_used = af::sym::Min(stride_used, upper_val); | ||
| 264 | res = af::sym::Mul(k, af::sym::Mul(block_count, stride_used)); | 265 | res = af::sym::Mul(k, af::sym::Mul(block_count, stride_used)); |
| 265 | GELOGD( | 266 | GELOGD( |
| 266 | "LoadStoreStrideV2: dims[%s], k=%s, block_count=%s, block_count_idx=%d, " | 267 | "LoadStoreStrideV2: dims[%s], k=%s, block_count=%s, block_count_idx=%d, " |
| @@ -33,6 +33,11 @@ using namespace att; | |||
| 33 | using namespace af::sym; | 33 | using namespace af::sym; |
| 34 | using namespace af::ascir; | 34 | using namespace af::ascir; |
| 35 | 35 | ||
| 36 | +namespace att { | ||
| 37 | +af::Status LoadStoreStrideV2Func(const std::map<std::string, float> ¶m_map, const std::vector<Expr> &dims, | ||
| 38 | + const Expr &stride, Expr &res); | ||
| 39 | +} | ||
| 40 | + | ||
| 36 | class UTestAscirPerfV2 : public ::testing::Test { | 41 | class UTestAscirPerfV2 : public ::testing::Test { |
| 37 | public: | 42 | public: |
| 38 | static ge::RuntimeStubV2 stub_v_2; | 43 | static ge::RuntimeStubV2 stub_v_2; |
| @@ -741,14 +746,14 @@ TEST_F(UTestAscirPerfV2, TestNddmaApiSmallBlockLen) { | |||
| 741 | const std::string kLastAxisLen = "TernaryOp(" + kIsSmallBlockLen + ", z6t_size, 16)"; | 746 | const std::string kLastAxisLen = "TernaryOp(" + kIsSmallBlockLen + ", z6t_size, 16)"; |
| 742 | // NddmaStride with penalty: penalty + stride calculation | 747 | // NddmaStride with penalty: penalty + stride calculation |
| 743 | // penalty = block_count_idx * stride_used * penalty_coeff = 2 * Abs((32-z6t_size))*8) * 4 = 64.0 * Abs((32-z6t_size)) | 748 | // penalty = block_count_idx * stride_used * penalty_coeff = 2 * Abs((32-z6t_size))*8) * 4 = 64.0 * Abs((32-z6t_size)) |
| 744 | - // stride = k * block_count * stride_used = 0.005 * (238*z0z1t_size) * Abs((32-z6t_size))*8) = 9.52... * | 749 | + // stride = k * block_count * stride_used |
| 745 | - // Abs((32-z6t_size)) * z0z1t_size | 750 | + // = 0.005 * (238*z0z1t_size) * Min(4096, Abs((32-z6t_size))*8) |
| 746 | const std::string kPenalty = "(64.0 * Abs((32 - z6t_size)))"; | 751 | const std::string kPenalty = "(64.0 * Abs((32 - z6t_size)))"; |
| 747 | - const std::string kStride = "(9.51999978721142 * Abs((32 - z6t_size)) * z0z1t_size)"; | 752 | + const std::string kStride = "(1.18999997340143 * Min(4096.0, (8 * Abs((32 - z6t_size)))) * z0z1t_size)"; |
| 748 | - // Note: SymEngine may reorder additive terms; nddma_perf comes before penalty and stride | 753 | + // Note: SymEngine may reorder additive terms; the stride term comes before nddma_perf and penalty. |
| 749 | - EXPECT_EQ(Str(res.Replace(ret)), "((1904 * " + kLastAxisLen + | 754 | + EXPECT_EQ(Str(res.Replace(ret)), "(" + kStride + " + (1904 * " + kLastAxisLen + |
| 750 | " * z0z1t_size / (((6.3899998664856 / (block_dim)) + 7.6100001335144))) + " + | 755 | " * z0z1t_size / (((6.3899998664856 / (block_dim)) + 7.6100001335144))) + " + |
| 751 | - kPenalty + " + " + kStride + " + 418.978912353516)"); | 756 | + kPenalty + " + 418.978912353516)"); |
| 752 | } | 757 | } |
| 753 | 758 | ||
| 754 | TEST_F(UTestAscirPerfV2, TestNddmaApiGmStrideTranspose) { | 759 | TEST_F(UTestAscirPerfV2, TestNddmaApiGmStrideTranspose) { |
| @@ -1150,6 +1155,41 @@ TEST_F(UTestAscirPerfV2, TestGetMicroApiPerfTableInvalid) { | |||
| 1150 | EXPECT_EQ(perf_param_table_v2.GetVfInstructPerfTable("invalid").size(), 0); | 1155 | EXPECT_EQ(perf_param_table_v2.GetVfInstructPerfTable("invalid").size(), 0); |
| 1151 | } | 1156 | } |
| 1152 | 1157 | ||
| 1158 | +TEST_F(UTestAscirPerfV2, TestLoadStoreStrideModelParamsCoverSupportedTypes) { | ||
| 1159 | + const auto table = Json::parse(kParamV2Info); | ||
| 1160 | + const std::vector<std::string> dtypes = {"int8", "uint8", "int16", "uint16", "int32", "uint32", | ||
| 1161 | + "int64", "uint64", "float16", "bfloat16", "float32", "bool"}; | ||
| 1162 | + for (const auto &op : {"LoadStride", "StoreStride"}) { | ||
| 1163 | + const auto ¶ms = table.at(op).at("model_params"); | ||
| 1164 | + EXPECT_EQ(params.size(), dtypes.size()); | ||
| 1165 | + for (const auto &dtype : dtypes) { | ||
| 1166 | + SCOPED_TRACE(std::string(op) + ":" + dtype); | ||
| 1167 | + const auto key = dtype + "to" + dtype; | ||
| 1168 | + ASSERT_TRUE(params.contains(key)); | ||
| 1169 | + EXPECT_FLOAT_EQ(params.at(key).at("k").get<float>(), std::string(op) == "LoadStride" ? 0.005f : 0.0385f); | ||
| 1170 | + EXPECT_FLOAT_EQ(params.at(key).at("u").get<float>(), 4096.0f); | ||
| 1171 | + EXPECT_FLOAT_EQ(params.at(key).at("penalty_coeff").get<float>(), 0.0f); | ||
| 1172 | + } | ||
| 1173 | + EXPECT_FALSE(params.contains("int4toint4")); | ||
| 1174 | + } | ||
| 1175 | +} | ||
| 1176 | + | ||
| 1177 | +TEST_F(UTestAscirPerfV2, TestLoadStoreStrideUsesConfiguredUpperBound) { | ||
| 1178 | + const Expr dynamic_stride = CreateExpr("stride"); | ||
| 1179 | + for (const float upper_bound : {2048.0f, 8192.0f}) { | ||
| 1180 | + const std::map<std::string, float> params = {{"k", 1.0f}, {"u", upper_bound}, {"data_type_size", 2.0f}}; | ||
| 1181 | + for (const Expr &stride : {CreateExpr(100), CreateExpr(5000), dynamic_stride}) { | ||
| 1182 | + SCOPED_TRACE(std::to_string(upper_bound) + ":" + Str(stride)); | ||
| 1183 | + Expr result; | ||
| 1184 | + ASSERT_EQ(LoadStoreStrideV2Func(params, {CreateExpr(1)}, stride, result), af::SUCCESS); | ||
| 1185 | + Expr expected = CreateExpr(1.0f) * af::sym::Min(stride * CreateExpr(2), CreateExpr(upper_bound)); | ||
| 1186 | + result.Simplify(); | ||
| 1187 | + expected.Simplify(); | ||
| 1188 | + EXPECT_EQ(Str(result), Str(expected)); | ||
| 1189 | + } | ||
| 1190 | + } | ||
| 1191 | +} | ||
| 1192 | + | ||
| 1153 | TEST_F(UTestAscirPerfV2, TestApiNameNotRegistered) { | 1193 | TEST_F(UTestAscirPerfV2, TestApiNameNotRegistered) { |
| 1154 | const auto api_perf = GetApiPerf("invalid"); | 1194 | const auto api_perf = GetApiPerf("invalid"); |
| 1155 | EXPECT_EQ(api_perf, nullptr); | 1195 | EXPECT_EQ(api_perf, nullptr); |
| @@ -926,6 +926,13 @@ const std::string kParamV2Info = R"( | |||
| 926 | "LoadStride": { | 926 | "LoadStride": { |
| 927 | "model_type": "LoadStoreStrideV2Func", | 927 | "model_type": "LoadStoreStrideV2Func", |
| 928 | "model_params": { | 928 | "model_params": { |
| 929 | + "int8toint8": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 930 | + "int16toint16": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 931 | + "uint16touint16": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 932 | + "int32toint32": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 933 | + "uint32touint32": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 934 | + "uint64touint64": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 935 | + "booltobool": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 929 | "int64toint64": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | 936 | "int64toint64": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, |
| 930 | "float16tofloat16": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | 937 | "float16tofloat16": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, |
| 931 | "float32tofloat32": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, | 938 | "float32tofloat32": {"k": 0.005, "u": 4096.0, "penalty_coeff": 0.0}, |
| @@ -956,6 +963,13 @@ const std::string kParamV2Info = R"( | |||
| 956 | "StoreStride": { | 963 | "StoreStride": { |
| 957 | "model_type": "LoadStoreStrideV2Func", | 964 | "model_type": "LoadStoreStrideV2Func", |
| 958 | "model_params": { | 965 | "model_params": { |
| 966 | + "int8toint8": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 967 | + "int16toint16": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 968 | + "uint16touint16": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 969 | + "int32toint32": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 970 | + "uint32touint32": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 971 | + "uint64touint64": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 972 | + "booltobool": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | ||
| 959 | "int64toint64": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | 973 | "int64toint64": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, |
| 960 | "float16tofloat16": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | 974 | "float16tofloat16": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, |
| 961 | "float32tofloat32": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, | 975 | "float32tofloat32": {"k": 0.0385, "u": 4096.0, "penalty_coeff": 0.0}, |