已合并
fix(aclnn): RT2执行前设置确定性配置 #4456
ClarkXie创建于 20 天前
fix(aclnn): RT2执行前设置确定性配置 #4456
已合并
ClarkXie创建于 20 天前
12 个文件变更+78-42
@@ -1061,24 +1061,10 @@ ge::graphStatus GetDeterministicLevel(int32_t &deterministic_level, bool &has_de
1061 return ge::GRAPH_SUCCESS;1061 return ge::GRAPH_SUCCESS;
1062}1062}
1063 1063 
1064-ge::graphStatus CheckDeterministicConfig(const int32_t deterministic, const int32_t deterministic_level) {
1065- if ((deterministic == 0) != (deterministic_level == 0)) {
1066- const std::string value = std::to_string(deterministic) + " / " + std::to_string(deterministic_level);
1067- const char *reason = "must both be 0 or both non-zero.";
1068- REPORT_PREDEFINED_ERR_MSG(
1069- "E10001", std::vector<const char *>({"parameter", "value", "reason"}),
1070- std::vector<const char *>({"deterministic / deterministic_level", value.c_str(), reason}));
1071- GELOGE(ge::PARAM_INVALID, "Deterministic[%d] and deterministic level[%d] are inconsistent.", deterministic,
1072- deterministic_level);
1073- return ge::PARAM_INVALID;
1074- }
1075- return ge::GRAPH_SUCCESS;
1076-}
1077- 
1078ge::graphStatus SetDeterministicConfig(const int32_t deterministic, const int32_t deterministic_level) {1064ge::graphStatus SetDeterministicConfig(const int32_t deterministic, const int32_t deterministic_level) {
1079- GE_ASSERT_SUCCESS(CheckDeterministicConfig(deterministic, deterministic_level));1065+ const int32_t effective_level = (deterministic != 0 && deterministic_level == 0) ? 1 : deterministic_level;
1080- GE_CHK_ACL_RET(aclrtSetSysParamOpt(ACL_OPT_DETERMINISTIC, deterministic_level));1066+ GE_CHK_ACL_RET(aclrtSetSysParamOpt(ACL_OPT_DETERMINISTIC, effective_level));
1081- GE_CHK_ACL_RET(aclrtCtxSetSysParamOpt(ACL_OPT_DETERMINISTIC, deterministic_level));1067+ GE_CHK_ACL_RET(aclrtCtxSetSysParamOpt(ACL_OPT_DETERMINISTIC, effective_level));
1082 return ge::GRAPH_SUCCESS;1068 return ge::GRAPH_SUCCESS;
1083}1069}
1084 1070 
@@ -109,6 +109,10 @@ cluster\_config.json配置示例如下:
109{ge::ir_option::DETERMINISTIC, "1"}109{ge::ir_option::DETERMINISTIC, "1"}
110```110```
111 111 
112+**使用约束:**
113+ 
114+通过GE图引擎接口构建离线模型时,建议在模型构建阶段通过`ge::ir_option::DETERMINISTIC``ge::ir_option::DETERMINISTIC_LEVEL`设置确定性及一致性配置。通过`aclmdl`接口加载、执行离线模型时,不建议调用`aclrtSetSysParamOpt``aclrtCtxSetSysParamOpt`,通过`ACL_OPT_DETERMINISTIC`修改该配置,否则可能导致运行时配置与模型构建时的配置不一致,无法保证预期的确定性及一致性效果。如需调整该配置,建议重新构建离线模型。
115+ 
112**产品支持情况:**116**产品支持情况:**
113 117 
114<!-- npu="950" id8 -->118<!-- npu="950" id8 -->
@@ -90,6 +90,10 @@ HF32是昇腾推出的专门用于算子内部计算的单精度浮点类型,
90{ge::ir_option::DETERMINISTIC_LEVEL, "2"}90{ge::ir_option::DETERMINISTIC_LEVEL, "2"}
91```91```
92 92 
93+**使用约束:**
94+ 
95+通过GE图引擎接口构建离线模型时,建议在模型构建阶段通过`ge::ir_option::DETERMINISTIC``ge::ir_option::DETERMINISTIC_LEVEL`设置确定性及一致性配置。通过`aclmdl`接口加载、执行离线模型时,不建议调用`aclrtSetSysParamOpt``aclrtCtxSetSysParamOpt`,通过`ACL_OPT_DETERMINISTIC`修改该配置,否则可能导致运行时配置与模型构建时的配置不一致,无法保证预期的确定性及一致性效果。如需调整该配置,建议重新构建离线模型。
96+ 
93**产品支持情况:**97**产品支持情况:**
94 98 
95<!-- npu="950" id15 -->99<!-- npu="950" id15 -->
@@ -50,4 +50,4 @@ atc --deterministic=0 ...
50 50 
51## 依赖约束51## 依赖约束
52 52 
53-53+离线推理场景下,建议在模型转换阶段通过`--deterministic`和`--deterministic_level`设置确定性及一致性配置。通过`aclmdl`接口加载、执行离线模型时,不建议调用`aclrtSetSysParamOpt`或`aclrtCtxSetSysParamOpt`,通过`ACL_OPT_DETERMINISTIC`修改该配置,否则可能导致运行时配置与模型转换时的配置不一致,法保证预期的确定性及一致性效果。如需调整该配置,建议使用目标配置重新转换模型。
@@ -64,4 +64,4 @@ atc --deterministic=0 --deterministic_level=0 ...
64 64 
65## 依赖约束65## 依赖约束
66 66 
67-67+离线推理场景下,建议在模型转换阶段通过`--deterministic`和`--deterministic_level`设置确定性及一致性配置。通过`aclmdl`接口加载、执行离线模型时,不建议调用`aclrtSetSysParamOpt`或`aclrtCtxSetSysParamOpt`,通过`ACL_OPT_DETERMINISTIC`修改该配置,否则可能导致运行时配置与模型转换时的配置不一致,法保证预期的确定性及一致性效果。如需调整该配置,建议使用目标配置重新转换模型。
@@ -243,6 +243,9 @@ class VISIBILITY_EXPORT ModelV2Executor {
243 rtStream_t default_stream_ = nullptr;243 rtStream_t default_stream_ = nullptr;
244 ExecutorSubscribersScheduler subscribers_;244 ExecutorSubscribersScheduler subscribers_;
245 ExecutorState state_ = ExecutorState::kInit;245 ExecutorState state_ = ExecutorState::kInit;
246+ bool need_set_deterministic_config_ = false;
247+ int32_t deterministic_ = 0;
248+ int32_t deterministic_level_ = 0;
246 std::string file_constant_weight_dir_;249 std::string file_constant_weight_dir_;
247 // 自动多流寻优标识,空表示不打点;本执行器无 model_id,由打点模块分配250 // 自动多流寻优标识,空表示不打点;本执行器无 model_id,由打点模块分配
248 std::string auto_multistream_tuning_mode_;251 std::string auto_multistream_tuning_mode_;
@@ -149,6 +149,10 @@ std::unique_ptr<ModelV2Executor> ModelV2ExecutorBuilder::Build(const ExecutorOpt
149 149 
150 ge::ComputeGraphPtr root_graph = root_model_->GetRootGraph();150 ge::ComputeGraphPtr root_graph = root_model_->GetRootGraph();
151 GE_ASSERT_NOTNULL(root_graph);151 GE_ASSERT_NOTNULL(root_graph);
152+ (void)ge::AttrUtils::GetInt(root_graph, ge::DETERMINISTIC, executor->deterministic_);
153+ (void)ge::AttrUtils::GetInt(root_graph, ge::DETERMINISTIC_LEVEL, executor->deterministic_level_);
154+ executor->need_set_deterministic_config_ =
155+ (executor->deterministic_ != 0) || ge::AttrUtils::HasAttr(root_graph, ge::DETERMINISTIC_LEVEL);
152 GE_ASSERT_GRAPH_SUCCESS(RestoreDeviceVarMem(*executor));156 GE_ASSERT_GRAPH_SUCCESS(RestoreDeviceVarMem(*executor));
153 uint32_t cur_model_id = root_model_->GetCurModelId();157 uint32_t cur_model_id = root_model_->GetCurModelId();
154 std::string model_name = root_model_->GetModelName();158 std::string model_name = root_model_->GetModelName();
@@ -31,6 +31,7 @@
31#include "graph/manager/session_id_manager.h"31#include "graph/manager/session_id_manager.h"
32#include "acl/acl_rt.h"32#include "acl/acl_rt.h"
33#include "common/ge_rts_decl.h"33#include "common/ge_rts_decl.h"
34+#include "common/op_tiling/op_tiling_rt2.h"
34 35 
35namespace gert {36namespace gert {
36namespace {37namespace {
@@ -244,6 +245,10 @@ ge::graphStatus ModelV2Executor::Execute(const ModelExecuteArg &arg, Tensor **in
244 245 
245 GE_RETURN_IF_ERROR(CheckIoReuseAddrs(inputs, input_num, outputs, output_num));246 GE_RETURN_IF_ERROR(CheckIoReuseAddrs(inputs, input_num, outputs, output_num));
246 247 
248+ if (need_set_deterministic_config_) {
249+ GE_RETURN_IF_ERROR(optiling::SetGlobalDeterministicConfig(deterministic_, deterministic_level_));
250+ }
251+ 
247 ge::multistream_tune::StepScope step(ge::multistream_tune::kSiteModelV2Executor, auto_multistream_tuning_mode_,252 ge::multistream_tune::StepScope step(ge::multistream_tune::kSiteModelV2Executor, auto_multistream_tuning_mode_,
248 auto_multistream_tuning_id_, arg.stream);253 auto_multistream_tuning_id_, arg.stream);
249 ge::graphStatus ret = ge::GRAPH_FAILED;254 ge::graphStatus ret = ge::GRAPH_FAILED;
@@ -158,8 +158,15 @@ ge::graphStatus CreateAclnnDeterministicConfig(const ge::NodePtr &node, const Lo
158 std::to_string(config.op_deterministic) + "_" +158 std::to_string(config.op_deterministic) + "_" +
159 std::to_string(static_cast<int32_t>(config.has_op_deterministic_level)) + "_" +159 std::to_string(static_cast<int32_t>(config.has_op_deterministic_level)) + "_" +
160 std::to_string(config.op_deterministic_level);160 std::to_string(config.op_deterministic_level);
161- config_holder = lower_input.global_data->GetOrCreateUniqueValueHolder(161+ const auto holders =
162- key, [&config]() { return bg::ValueHolder::CreateConst(&config, sizeof(config)); });162+ lower_input.global_data->GetOrCreateUniqueValueHolder(key, [&config]() -> std::vector<bg::ValueHolderPtr> {
163+ return bg::FrameSelector::OnInitRoot([&config]() -> std::vector<bg::ValueHolderPtr> {
164+ return {bg::ValueHolder::CreateConst(&config, sizeof(config))};
165+ });
166+ });
167+ GE_ASSERT_TRUE(!holders.empty());
168+ GE_ASSERT_NOTNULL(holders[0]);
169+ config_holder = holders[0];
163 return ge::GRAPH_SUCCESS;170 return ge::GRAPH_SUCCESS;
164}171}
165 172 
@@ -172,8 +179,7 @@ ge::graphStatus BuildAclnnOriginalDeterministicConfig(const ge::NodePtr &node,
172 179 
173 GE_ASSERT_SUCCESS(180 GE_ASSERT_SUCCESS(
174 optiling::GetGraphDeterministicConfig(root_compute_graph, config.deterministic, config.deterministic_level));181 optiling::GetGraphDeterministicConfig(root_compute_graph, config.deterministic, config.deterministic_level));
175- 182+ return ge::GRAPH_SUCCESS;
176- return optiling::SetGlobalDeterministicConfig(config.deterministic, config.deterministic_level);
177}183}
178 184 
179ge::graphStatus CreateAclnnOriginalDeterministicConfig(const ge::NodePtr &node, const LowerInput &lower_input,185ge::graphStatus CreateAclnnOriginalDeterministicConfig(const ge::NodePtr &node, const LowerInput &lower_input,
@@ -110,6 +110,13 @@ TEST_F(AclnnNodeConverterST, TestHgl) {
110 global_data.SetSpaceRegistriesV2(*space_registry_array);110 global_data.SetSpaceRegistriesV2(*space_registry_array);
111 auto add_ret = LoweringAclnnNode(add_node, add_input);111 auto add_ret = LoweringAclnnNode(add_node, add_input);
112 ASSERT_TRUE(add_ret.result.IsSuccess());112 ASSERT_TRUE(add_ret.result.IsSuccess());
113+ size_t set_config_count = 0U;
114+ for (const auto &node : init_frame_->GetExecuteGraph()->GetAllNodes()) {
115+ if (node->GetType() == "SetAclnnGlobalDeterministicConfig") {
116+ ++set_config_count;
117+ }
118+ }
119+ EXPECT_EQ(set_config_count, 0U);
113}120}
114 121 
115TEST_F(AclnnNodeConverterST, LoweringTwoStagesWithCombinedDeterministicAttrs) {122TEST_F(AclnnNodeConverterST, LoweringTwoStagesWithCombinedDeterministicAttrs) {
@@ -157,6 +164,13 @@ TEST_F(AclnnNodeConverterST, LoweringTwoStagesWithCombinedDeterministicAttrs) {
157 global_data.SetSpaceRegistriesV2(*space_registry_array);164 global_data.SetSpaceRegistriesV2(*space_registry_array);
158 auto add_ret = LoweringAclnnNode(add_node, add_input);165 auto add_ret = LoweringAclnnNode(add_node, add_input);
159 ASSERT_TRUE(add_ret.result.IsSuccess());166 ASSERT_TRUE(add_ret.result.IsSuccess());
167+ size_t set_config_count = 0U;
168+ for (const auto &node : init_frame_->GetExecuteGraph()->GetAllNodes()) {
169+ if (node->GetType() == "SetAclnnGlobalDeterministicConfig") {
170+ ++set_config_count;
171+ }
172+ }
173+ EXPECT_EQ(set_config_count, 0U);
160}174}
161 175 
162TEST_F(AclnnNodeConverterST, LoweringWithDeterministicAttr) {176TEST_F(AclnnNodeConverterST, LoweringWithDeterministicAttr) {
@@ -1346,12 +1346,15 @@ TEST_F(RegisterOpTilingRT2UT, SetDeterministicConfigPassesThroughLevel) {
1346 }1346 }
1347}1347}
1348 1348 
1349-TEST_F(RegisterOpTilingRT2UT, SetDeterministicConfigRejectsInconsistentConfig) {1349+TEST_F(RegisterOpTilingRT2UT, SetDeterministicConfigAcceptsIndependentValues) {
1350- EXPECT_NE(SetDeterministicConfig(1, 0), GRAPH_SUCCESS);1350+ EXPECT_EQ(SetDeterministicConfig(1, 0), GRAPH_SUCCESS);
1351- EXPECT_TRUE(acl_runtime_stub_->GetSysParamSetRecords().empty());1351+ EXPECT_EQ(SetDeterministicConfig(0, 1), GRAPH_SUCCESS);
1352- 1352+ const auto &records = acl_runtime_stub_->GetSysParamSetRecords();
1353- EXPECT_NE(SetDeterministicConfig(0, 1), GRAPH_SUCCESS);1353+ ASSERT_EQ(records.size(), 4U);
1354- EXPECT_TRUE(acl_runtime_stub_->GetSysParamSetRecords().empty());1354+ EXPECT_EQ(records[0].value, 1);
1355+ EXPECT_EQ(records[1].value, 1);
1356+ EXPECT_EQ(records[2].value, 1);
1357+ EXPECT_EQ(records[3].value, 1);
1355}1358}
1356 1359 
1357TEST_F(RegisterOpTilingRT2UT, SetDeterministicConfigPropagatesAclFailures) {1360TEST_F(RegisterOpTilingRT2UT, SetDeterministicConfigPropagatesAclFailures) {
@@ -113,6 +113,13 @@ TEST_F(AclnnNodeConverterUT, TestHgl) {
113 global_data.SetSpaceRegistriesV2(*space_registry_array);113 global_data.SetSpaceRegistriesV2(*space_registry_array);
114 auto add_ret = LoweringAclnnNode(add_node, add_input);114 auto add_ret = LoweringAclnnNode(add_node, add_input);
115 ASSERT_TRUE(add_ret.result.IsSuccess());115 ASSERT_TRUE(add_ret.result.IsSuccess());
116+ size_t set_config_count = 0U;
117+ for (const auto &node : init_frame_->GetExecuteGraph()->GetAllNodes()) {
118+ if (node->GetType() == "SetAclnnGlobalDeterministicConfig") {
119+ ++set_config_count;
120+ }
121+ }
122+ EXPECT_EQ(set_config_count, 0U);
116}123}
117 124 
118TEST_F(AclnnNodeConverterUT, TestHgl_Twostages) {125TEST_F(AclnnNodeConverterUT, TestHgl_Twostages) {
@@ -162,9 +169,9 @@ TEST_F(AclnnNodeConverterUT, TestHgl_Twostages) {
162 ge::DumpGraph(exe_graph, "AclnnNodeConverterUT");169 ge::DumpGraph(exe_graph, "AclnnNodeConverterUT");
163 170 
164 // check main 图中节点数量, 由于没走CEM, main图上有俩InnerData连给PrepareCacheableTilingFwkData171 // check main 图中节点数量, 由于没走CEM, main图上有俩InnerData连给PrepareCacheableTilingFwkData
165- // 确定性配置新增一个Const和一个InnerData输入172+ // 确定性配置的Const在Init图中,main图新增一个InnerData输入
166 ASSERT_EQ(ExeGraphSummaryChecker(exe_graph).StrictAllNodeTypes({{"Data", 4},173 ASSERT_EQ(ExeGraphSummaryChecker(exe_graph).StrictAllNodeTypes({{"Data", 4},
167- {"Const", 10},174+ {"Const", 9},
168 {"AllocBatchHbm", 1},175 {"AllocBatchHbm", 1},
169 {"AllocMemHbm", 1},176 {"AllocMemHbm", 1},
170 {"BuildDualStageAclnnOpFwkData", 1},177 {"BuildDualStageAclnnOpFwkData", 1},
@@ -177,13 +184,20 @@ TEST_F(AclnnNodeConverterUT, TestHgl_Twostages) {
177 {"FreeBatchHbm", 1},184 {"FreeBatchHbm", 1},
178 {"FreeMemory", 3},185 {"FreeMemory", 3},
179 {"InferShape", 1},186 {"InferShape", 1},
180- {"InnerData", 10},187+ {"InnerData", 11},
181 {"MakeSureTensorAtDevice", 2},188 {"MakeSureTensorAtDevice", 2},
182 {"SelectL1Allocator", 1},189 {"SelectL1Allocator", 1},
183 {"SelectL2Allocator", 1},190 {"SelectL2Allocator", 1},
184 {"SplitDataTensor", 2},191 {"SplitDataTensor", 2},
185 {"SplitRtStreams", 1}}),192 {"SplitRtStreams", 1}}),
186 "success");193 "success");
194+ size_t set_config_count = 0U;
195+ for (const auto &node : init_frame_->GetExecuteGraph()->GetAllNodes()) {
196+ if (node->GetType() == "SetAclnnGlobalDeterministicConfig") {
197+ ++set_config_count;
198+ }
199+ }
200+ EXPECT_EQ(set_config_count, 0U);
187}201}
188 202 
189TEST_F(AclnnNodeConverterUT, TestHgl_Twostages_Failed) {203TEST_F(AclnnNodeConverterUT, TestHgl_Twostages_Failed) {
@@ -263,10 +277,10 @@ TEST_F(AclnnNodeConverterUT, LoweringWithDeterministicAttr) {
263 277 
264 auto add_ret = LoweringAclnnNode(add_node, add_input);278 auto add_ret = LoweringAclnnNode(add_node, add_input);
265 ASSERT_TRUE(add_ret.result.IsSuccess());279 ASSERT_TRUE(add_ret.result.IsSuccess());
266- EXPECT_EQ(acl_runtime_stub_->GetSysParamSetRecords().size(), 2U);280+ EXPECT_TRUE(acl_runtime_stub_->GetSysParamSetRecords().empty());
267}281}
268 282 
269-TEST_F(AclnnNodeConverterUT, LoweringUsesLatestDeterministicConfig) {283+TEST_F(AclnnNodeConverterUT, LoweringDoesNotSetGlobalDeterministicConfig) {
270 auto graph = ShareGraph::AicoreGraph();284 auto graph = ShareGraph::AicoreGraph();
271 auto add_node = graph->FindNode("add1");285 auto add_node = graph->FindNode("add1");
272 (void)ge::AttrUtils::SetStr(add_node->GetOpDesc(), "_deterministic", "1");286 (void)ge::AttrUtils::SetStr(add_node->GetOpDesc(), "_deterministic", "1");
@@ -301,14 +315,7 @@ TEST_F(AclnnNodeConverterUT, LoweringUsesLatestDeterministicConfig) {
301 315 
302 auto add_ret = LoweringAclnnNode(add_node, add_input);316 auto add_ret = LoweringAclnnNode(add_node, add_input);
303 ASSERT_TRUE(add_ret.result.IsSuccess());317 ASSERT_TRUE(add_ret.result.IsSuccess());
304- const auto &records = acl_runtime_stub_->GetSysParamSetRecords();318+ EXPECT_TRUE(acl_runtime_stub_->GetSysParamSetRecords().empty());
305- ASSERT_EQ(records.size(), 2U);
306- EXPECT_FALSE(records[0].is_context);
307- EXPECT_EQ(records[0].opt, ACL_OPT_DETERMINISTIC);
308- EXPECT_EQ(records[0].value, 0);
309- EXPECT_TRUE(records[1].is_context);
310- EXPECT_EQ(records[1].opt, ACL_OPT_DETERMINISTIC);
311- EXPECT_EQ(records[1].value, 0);
312}319}
313 320 
314TEST_F(AclnnNodeConverterUT, LoweringWithDeterministicLevelAttr) {321TEST_F(AclnnNodeConverterUT, LoweringWithDeterministicLevelAttr) {