已合并
【PR】: sync develop to master 0829 #455
张德鹏创建于 8月29日
【PR】: sync develop to master 0829 #455
已合并
共 15 个文件变更+132-16
| @@ -35,3 +35,6 @@ cmake-build-* | |||
| 35 | 35 | ||
| 36 | # Log files | 36 | # Log files |
| 37 | *.log | 37 | *.log |
| 38 | + | ||
| 39 | +# OAT scan artifacts (generated by pre-commit oat_check.sh) | ||
| 40 | +oat_reports/ | ||
| @@ -110,6 +110,11 @@ OpAICoreDef &OpAICoreDef::SetTiling(gert::OpImplRegisterV2::TilingKernelFunc fun | |||
| 110 | return *this; | 110 | return *this; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | +OpAICoreDef &OpAICoreDef::SetGenSimplifiedKey(gert::OpImplRegisterV2::GenSimplifiedKeyKernelFunc func) { | ||
| 114 | + this->impl_->gen_simplified_key_func = func; | ||
| 115 | + return *this; | ||
| 116 | +} | ||
| 117 | + | ||
| 113 | OpAICoreDef &OpAICoreDef::SetCheckSupport(optiling::OP_CHECK_FUNC func) { | 118 | OpAICoreDef &OpAICoreDef::SetCheckSupport(optiling::OP_CHECK_FUNC func) { |
| 114 | return this->impl_->SetCheckSupport(this, func); | 119 | return this->impl_->SetCheckSupport(this, func); |
| 115 | } | 120 | } |
| @@ -154,6 +159,10 @@ gert::OpImplRegisterV2::TilingKernelFunc &OpAICoreDef::GetTiling(void) { | |||
| 154 | return this->impl_->tiling_func; | 159 | return this->impl_->tiling_func; |
| 155 | } | 160 | } |
| 156 | 161 | ||
| 162 | +gert::OpImplRegisterV2::GenSimplifiedKeyKernelFunc &OpAICoreDef::GetGenSimplifiedKey(void) { | ||
| 163 | + return this->impl_->gen_simplified_key_func; | ||
| 164 | +} | ||
| 165 | + | ||
| 157 | optiling::OP_CHECK_FUNC &OpAICoreDef::GetCheckSupport(void) { | 166 | optiling::OP_CHECK_FUNC &OpAICoreDef::GetCheckSupport(void) { |
| 158 | return this->impl_->op_chk_support; | 167 | return this->impl_->op_chk_support; |
| 159 | } | 168 | } |
| @@ -1396,6 +1396,7 @@ void OpAICoreConfigImpl::AddCfgItem(OpAICoreConfig *parent_this, const char *key | |||
| 1396 | 1396 | ||
| 1397 | void OpAICoreDefImpl::Construct(OpAICoreDef *parent_this, const OpAICoreDef &aicore_def) { | 1397 | void OpAICoreDefImpl::Construct(OpAICoreDef *parent_this, const OpAICoreDef &aicore_def) { |
| 1398 | parent_this->impl_->tiling_func = aicore_def.impl_->tiling_func; | 1398 | parent_this->impl_->tiling_func = aicore_def.impl_->tiling_func; |
| 1399 | + parent_this->impl_->gen_simplified_key_func = aicore_def.impl_->gen_simplified_key_func; | ||
| 1399 | parent_this->impl_->tiling_parse = aicore_def.impl_->tiling_parse; | 1400 | parent_this->impl_->tiling_parse = aicore_def.impl_->tiling_parse; |
| 1400 | parent_this->impl_->ci_creator = aicore_def.impl_->ci_creator; | 1401 | parent_this->impl_->ci_creator = aicore_def.impl_->ci_creator; |
| 1401 | parent_this->impl_->ci_deleter = aicore_def.impl_->ci_deleter; | 1402 | parent_this->impl_->ci_deleter = aicore_def.impl_->ci_deleter; |
| @@ -1112,7 +1112,7 @@ void PluginManager::GetFileListWithSuffix(const std::string &path, const std::st | |||
| 1112 | 1112 | ||
| 1113 | const INT32 is_dir = mmIsDir(&(resolved_path[0U])); | 1113 | const INT32 is_dir = mmIsDir(&(resolved_path[0U])); |
| 1114 | if (is_dir != EN_OK) { | 1114 | if (is_dir != EN_OK) { |
| 1115 | - GELOGW("[FindSo][Check] Open directory %s failed, maybe it is not exit or not a dir, errmsg:%s", | 1115 | + GELOGW("[FindSo][Check] Open directory %s failed, maybe it does not exist or is not a dir, errmsg:%s", |
| 1116 | &(resolved_path[0U]), strerror(errno)); | 1116 | &(resolved_path[0U]), strerror(errno)); |
| 1117 | return; | 1117 | return; |
| 1118 | } | 1118 | } |
| @@ -125,7 +125,7 @@ bool GetBasePath(std::string &basePath, const std::string &opType) { | |||
| 125 | bool CreateDirectory(const std::string &path) { | 125 | bool CreateDirectory(const std::string &path) { |
| 126 | GELOGD("Running CreateDirectory."); | 126 | GELOGD("Running CreateDirectory."); |
| 127 | if (DirectoryExists(path)) { | 127 | if (DirectoryExists(path)) { |
| 128 | - GELOGD("Directory is existed."); | 128 | + GELOGD("Directory already exists."); |
| 129 | return true; | 129 | return true; |
| 130 | } else { | 130 | } else { |
| 131 | std::string currentPath = path; | 131 | std::string currentPath = path; |
| @@ -178,7 +178,7 @@ bool CreateSymlink(const std::string &targetPath, const std::string &linkPath) { | |||
| 178 | std::string parentDir = GetParentPath(linkPath); | 178 | std::string parentDir = GetParentPath(linkPath); |
| 179 | if (!DirectoryExists(parentDir)) { | 179 | if (!DirectoryExists(parentDir)) { |
| 180 | if (!CreateDirectory(parentDir)) { | 180 | if (!CreateDirectory(parentDir)) { |
| 181 | - GELOGE(ge::FAILED, "Failed create directory: %s", parentDir.c_str()); | 181 | + GELOGE(ge::FAILED, "Failed to create directory: %s", parentDir.c_str()); |
| 182 | return false; | 182 | return false; |
| 183 | } | 183 | } |
| 184 | } | 184 | } |
| @@ -29,7 +29,7 @@ | |||
| 29 | } else if (((merged_funcs).func_name) != nullptr and ((src_funcs).func_name != nullptr)) { \ | 29 | } else if (((merged_funcs).func_name) != nullptr and ((src_funcs).func_name != nullptr)) { \ |
| 30 | GELOGW("op type %s %s func has been registered.", (op_type), #func_name); \ | 30 | GELOGW("op type %s %s func has been registered.", (op_type), #func_name); \ |
| 31 | } else { \ | 31 | } else { \ |
| 32 | - /* 空分支,无需操作 */ \ | 32 | + /* 空分支,无需操作 */ \ |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | #define MERGE_SCALAR(merged, src, member) \ | 35 | #define MERGE_SCALAR(merged, src, member) \ |
| @@ -39,7 +39,7 @@ | |||
| 39 | } else if ((merged).member != 0 && (src).member != 0) { \ | 39 | } else if ((merged).member != 0 && (src).member != 0) { \ |
| 40 | GELOGW("op type %s " #member " has been registered", op_type.c_str()); \ | 40 | GELOGW("op type %s " #member " has been registered", op_type.c_str()); \ |
| 41 | } else { \ | 41 | } else { \ |
| 42 | - /* 已经注册且没有重复注册 */ \ | 42 | + /* 已经注册且没有重复注册 */ \ |
| 43 | } \ | 43 | } \ |
| 44 | } while (0) | 44 | } while (0) |
| 45 | 45 | ||
| @@ -114,7 +114,6 @@ ge::graphStatus OpImplSpaceRegistryImpl::AddSoToRegistry(const OppSoDesc &so_des | |||
| 114 | << std::endl; | 114 | << std::endl; |
| 115 | ss << "Error detail: " << mmDlerror() << std::endl; | 115 | ss << "Error detail: " << mmDlerror() << std::endl; |
| 116 | GELOGE(ge::GRAPH_FAILED, "%s", ss.str().c_str()); | 116 | GELOGE(ge::GRAPH_FAILED, "%s", ss.str().c_str()); |
| 117 | - std::cout << "[ERROR] " << ss.str() << std::endl; | ||
| 118 | return nullptr; | 117 | return nullptr; |
| 119 | } | 118 | } |
| 120 | const std::function<void()> callback = [&handle]() { CloseHandle(handle); }; | 119 | const std::function<void()> callback = [&handle]() { CloseHandle(handle); }; |
| @@ -88,7 +88,7 @@ ge::graphStatus AppendConvertedAttr(TilingData *tiling_data, const RuntimeAttrs | |||
| 88 | const T1 *attr = attrs->GetAttrPointer<T1>(attr_index); | 88 | const T1 *attr = attrs->GetAttrPointer<T1>(attr_index); |
| 89 | GE_CHECK_NOTNULL(attr); | 89 | GE_CHECK_NOTNULL(attr); |
| 90 | if (!ge::IntegerChecker<T2>::Compat(*attr)) { | 90 | if (!ge::IntegerChecker<T2>::Compat(*attr)) { |
| 91 | - GELOGW("[Check][Param] attr[%zu] overflow, large than max dst type", attr_index); | 91 | + GELOGW("[Check][Param] attr[%zu] overflow, larger than max dst type", attr_index); |
| 92 | } | 92 | } |
| 93 | const T2 attr_data = GetValue<T1, T2>(*attr); | 93 | const T2 attr_data = GetValue<T1, T2>(*attr); |
| 94 | return tiling_data->Append<T2>(attr_data); | 94 | return tiling_data->Append<T2>(attr_data); |
| @@ -33,3 +33,22 @@ OpImplRegisterV2 &GenSimplifiedKey(GenSimplifiedKeyKernelFunc gen_simplifiedkey_ | |||
| 33 | ## 约束说明 | 33 | ## 约束说明 |
| 34 | 34 | ||
| 35 | 无。 | 35 | 无。 |
| 36 | + | ||
| 37 | +## 通过OpDef注册 | ||
| 38 | + | ||
| 39 | +使用`OpDef`定义AscendC算子时,可通过`OpAICoreDef::SetGenSimplifiedKey`注册回调,`OP_ADD`会在生成Tiling注册库时将该回调转交给`OpImplRegisterV2`。 | ||
| 40 | + | ||
| 41 | +```cpp | ||
| 42 | +class AddCustom : public OpDef { | ||
| 43 | + public: | ||
| 44 | + explicit AddCustom(const char *name) : OpDef(name) { | ||
| 45 | + this->AICore() | ||
| 46 | + .SetTiling(TilingFunc) | ||
| 47 | + .SetGenSimplifiedKey(GenSimplifiedKeyFunc) | ||
| 48 | + .AddConfig("ascend910b"); | ||
| 49 | + } | ||
| 50 | +}; | ||
| 51 | +OP_ADD(AddCustom); | ||
| 52 | +``` | ||
| 53 | + | ||
| 54 | +该接口仅注册用户自定义key片段生成函数。完整Simplified Key中的算子类型、确定性模式和实现模式仍由运行时框架组装。 | ||
| @@ -189,13 +189,13 @@ inline bool AppendVectorStrAttr(const ge::AnyValue &attr, std::vector<std::vecto | |||
| 189 | for (size_t i = 0U; i < (*val).size(); ++i) { | 189 | for (size_t i = 0U; i < (*val).size(); ++i) { |
| 190 | const size_t ele_str_size = (*val)[i].size() + 1; | 190 | const size_t ele_str_size = (*val)[i].size() + 1; |
| 191 | if (ge::AddOverflow(total_str_size, ele_str_size, total_str_size)) { | 191 | if (ge::AddOverflow(total_str_size, ele_str_size, total_str_size)) { |
| 192 | - GELOGW("Add over flow ele str size %zu, total_str_size %zu.", ele_str_size, total_str_size); | 192 | + GELOGW("Add overflow ele str size %zu, total_str_size %zu.", ele_str_size, total_str_size); |
| 193 | return false; | 193 | return false; |
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | size_t total_size = 0U; | 196 | size_t total_size = 0U; |
| 197 | if (ge::AddOverflow(total_str_size, sizeof(ContinuousVector), total_size)) { | 197 | if (ge::AddOverflow(total_str_size, sizeof(ContinuousVector), total_size)) { |
| 198 | - GELOGW("Add over flow ContinuousVector size %zu, total_str_size %zu.", sizeof(ContinuousVector), total_str_size); | 198 | + GELOGW("Add overflow ContinuousVector size %zu, total_str_size %zu.", sizeof(ContinuousVector), total_str_size); |
| 199 | return false; | 199 | return false; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| @@ -293,4 +293,4 @@ inline std::unique_ptr<uint8_t[]> CreateAttrBufferWithAttrs(const std::vector<ge | |||
| 293 | } | 293 | } |
| 294 | } // namespace bg | 294 | } // namespace bg |
| 295 | } // namespace gert | 295 | } // namespace gert |
| 296 | -#endif | 296 | +#endif |
| @@ -420,6 +420,7 @@ class OpAICoreDef { | |||
| 420 | ~OpAICoreDef(); | 420 | ~OpAICoreDef(); |
| 421 | OpAICoreDef &operator=(const OpAICoreDef &aicore_def); | 421 | OpAICoreDef &operator=(const OpAICoreDef &aicore_def); |
| 422 | OpAICoreDef &SetTiling(gert::OpImplRegisterV2::TilingKernelFunc func); | 422 | OpAICoreDef &SetTiling(gert::OpImplRegisterV2::TilingKernelFunc func); |
| 423 | + OpAICoreDef &SetGenSimplifiedKey(gert::OpImplRegisterV2::GenSimplifiedKeyKernelFunc func); | ||
| 423 | OpAICoreDef &SetCheckSupport(optiling::OP_CHECK_FUNC func); | 424 | OpAICoreDef &SetCheckSupport(optiling::OP_CHECK_FUNC func); |
| 424 | OpAICoreDef &SetOpSelectFormat(optiling::OP_CHECK_FUNC func); | 425 | OpAICoreDef &SetOpSelectFormat(optiling::OP_CHECK_FUNC func); |
| 425 | OpAICoreDef &SetOpSupportInfo(optiling::OP_CHECK_FUNC func); | 426 | OpAICoreDef &SetOpSupportInfo(optiling::OP_CHECK_FUNC func); |
| @@ -427,6 +428,7 @@ class OpAICoreDef { | |||
| 427 | OpAICoreDef &SetParamGeneralize(optiling::PARAM_GENERALIZE_FUNC func); | 428 | OpAICoreDef &SetParamGeneralize(optiling::PARAM_GENERALIZE_FUNC func); |
| 428 | OpAICoreDef &LaunchWithZeroEleOutputTensors(bool launchFlag); | 429 | OpAICoreDef &LaunchWithZeroEleOutputTensors(bool launchFlag); |
| 429 | gert::OpImplRegisterV2::TilingKernelFunc &GetTiling(void); | 430 | gert::OpImplRegisterV2::TilingKernelFunc &GetTiling(void); |
| 431 | + gert::OpImplRegisterV2::GenSimplifiedKeyKernelFunc &GetGenSimplifiedKey(void); | ||
| 430 | optiling::OP_CHECK_FUNC &GetCheckSupport(void); | 432 | optiling::OP_CHECK_FUNC &GetCheckSupport(void); |
| 431 | optiling::OP_CHECK_FUNC &GetOpSelectFormat(void); | 433 | optiling::OP_CHECK_FUNC &GetOpSelectFormat(void); |
| 432 | optiling::OP_CHECK_FUNC &GetOpSupportInfo(void); | 434 | optiling::OP_CHECK_FUNC &GetOpSupportInfo(void); |
| @@ -36,6 +36,7 @@ | |||
| 36 | opType op(#opType); \ | 36 | opType op(#opType); \ |
| 37 | gert::OpImplRegisterV2 impl(#opType); \ | 37 | gert::OpImplRegisterV2 impl(#opType); \ |
| 38 | impl.Tiling(op.AICore().GetTiling()); \ | 38 | impl.Tiling(op.AICore().GetTiling()); \ |
| 39 | + impl.GenSimplifiedKey(op.AICore().GetGenSimplifiedKey()); \ | ||
| 39 | impl.TilingParse<OpAddCompilerInfoPlaceholder##opType>(TilingPrepare##opType); \ | 40 | impl.TilingParse<OpAddCompilerInfoPlaceholder##opType>(TilingPrepare##opType); \ |
| 40 | optiling::OpCheckFuncHelper(FUNC_CHECK_SUPPORTED, #opType, op.AICore().GetCheckSupport()); \ | 41 | optiling::OpCheckFuncHelper(FUNC_CHECK_SUPPORTED, #opType, op.AICore().GetCheckSupport()); \ |
| 41 | optiling::OpCheckFuncHelper(FUNC_OP_SELECT_FORMAT, #opType, op.AICore().GetOpSelectFormat()); \ | 42 | optiling::OpCheckFuncHelper(FUNC_OP_SELECT_FORMAT, #opType, op.AICore().GetOpSelectFormat()); \ |
| @@ -201,6 +201,7 @@ class OpAICoreDefImpl { | |||
| 201 | optiling::PARAM_GENERALIZE_FUNC op_generlize_func = nullptr; | 201 | optiling::PARAM_GENERALIZE_FUNC op_generlize_func = nullptr; |
| 202 | bool zero_ele_output_launch_flag = false; | 202 | bool zero_ele_output_launch_flag = false; |
| 203 | std::map<ge::AscendString, OpAICoreConfig> aicore_configs = {}; | 203 | std::map<ge::AscendString, OpAICoreConfig> aicore_configs = {}; |
| 204 | + gert::OpImplRegisterV2::GenSimplifiedKeyKernelFunc gen_simplified_key_func = nullptr; | ||
| 204 | 205 | ||
| 205 | static void Construct(OpAICoreDef *parent_this, const OpAICoreDef &aicore_def); | 206 | static void Construct(OpAICoreDef *parent_this, const OpAICoreDef &aicore_def); |
| 206 | OpAICoreDef &Eq(OpAICoreDef *parent_this, const OpAICoreDef &aicore_def); | 207 | OpAICoreDef &Eq(OpAICoreDef *parent_this, const OpAICoreDef &aicore_def); |
| @@ -23,6 +23,26 @@ class OpDefAICoreUT : public testing::Test { | |||
| 23 | void TearDown() {} | 23 | void TearDown() {} |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | +ge::graphStatus TestGenSimplifiedKey(gert::TilingContext *context, ge::char_t *simplified_key) { | ||
| 27 | + (void)context; | ||
| 28 | + (void)simplified_key; | ||
| 29 | + return ge::GRAPH_SUCCESS; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +TEST_F(OpDefAICoreUT, GenSimplifiedKeyTest) { | ||
| 33 | + OpAICoreDef aicore_def; | ||
| 34 | + EXPECT_EQ(aicore_def.GetGenSimplifiedKey(), nullptr); | ||
| 35 | + EXPECT_EQ(&aicore_def.SetGenSimplifiedKey(TestGenSimplifiedKey), &aicore_def); | ||
| 36 | + EXPECT_EQ(aicore_def.GetGenSimplifiedKey(), &TestGenSimplifiedKey); | ||
| 37 | + | ||
| 38 | + OpAICoreDef copied(aicore_def); | ||
| 39 | + EXPECT_EQ(copied.GetGenSimplifiedKey(), &TestGenSimplifiedKey); | ||
| 40 | + | ||
| 41 | + OpAICoreDef assigned; | ||
| 42 | + assigned = aicore_def; | ||
| 43 | + EXPECT_EQ(assigned.GetGenSimplifiedKey(), &TestGenSimplifiedKey); | ||
| 44 | +} | ||
| 45 | + | ||
| 26 | TEST_F(OpDefAICoreUT, AICoreTest) { | 46 | TEST_F(OpDefAICoreUT, AICoreTest) { |
| 27 | OpAICoreDef aicoreDef; | 47 | OpAICoreDef aicoreDef; |
| 28 | OpAICoreConfig config; | 48 | OpAICoreConfig config; |
| @@ -0,0 +1,63 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +#define OP_TILING_LIB | ||
| 12 | +#include <gtest/gtest.h> | ||
| 13 | +#include "register/op_def_registry.h" | ||
| 14 | +#include "register/op_impl_registry_base.h" | ||
| 15 | + | ||
| 16 | +namespace ops { | ||
| 17 | +namespace { | ||
| 18 | + | ||
| 19 | +ge::graphStatus TestTiling(gert::TilingContext *context) { | ||
| 20 | + (void)context; | ||
| 21 | + return ge::GRAPH_SUCCESS; | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +ge::graphStatus TestGenSimplifiedKey(gert::TilingContext *context, ge::char_t *simplified_key) { | ||
| 25 | + (void)context; | ||
| 26 | + (void)simplified_key; | ||
| 27 | + return ge::GRAPH_SUCCESS; | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +class OpDefWithGenSimplifiedKey : public OpDef { | ||
| 31 | + public: | ||
| 32 | + explicit OpDefWithGenSimplifiedKey(const char *name) : OpDef(name) { | ||
| 33 | + this->AICore().SetTiling(TestTiling).SetGenSimplifiedKey(TestGenSimplifiedKey); | ||
| 34 | + } | ||
| 35 | +}; | ||
| 36 | +OP_ADD(OpDefWithGenSimplifiedKey); | ||
| 37 | + | ||
| 38 | +class OpDefWithoutGenSimplifiedKey : public OpDef { | ||
| 39 | + public: | ||
| 40 | + explicit OpDefWithoutGenSimplifiedKey(const char *name) : OpDef(name) { | ||
| 41 | + this->AICore().SetTiling(TestTiling); | ||
| 42 | + } | ||
| 43 | +}; | ||
| 44 | +OP_ADD(OpDefWithoutGenSimplifiedKey); | ||
| 45 | + | ||
| 46 | +class OpDefRegistryTilingUT : public testing::Test {}; | ||
| 47 | + | ||
| 48 | +TEST_F(OpDefRegistryTilingUT, RegisterGenSimplifiedKey) { | ||
| 49 | + const auto *funcs = gert::OpImplRegistry::GetInstance().GetOpImpl("OpDefWithGenSimplifiedKey"); | ||
| 50 | + ASSERT_NE(funcs, nullptr); | ||
| 51 | + EXPECT_EQ(funcs->tiling, &TestTiling); | ||
| 52 | + EXPECT_EQ(funcs->gen_simplifiedkey, &TestGenSimplifiedKey); | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +TEST_F(OpDefRegistryTilingUT, KeepNullWhenCallbackIsNotSet) { | ||
| 56 | + const auto *funcs = gert::OpImplRegistry::GetInstance().GetOpImpl("OpDefWithoutGenSimplifiedKey"); | ||
| 57 | + ASSERT_NE(funcs, nullptr); | ||
| 58 | + EXPECT_EQ(funcs->tiling, &TestTiling); | ||
| 59 | + EXPECT_EQ(funcs->gen_simplifiedkey, nullptr); | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +} // namespace | ||
| 63 | +} // namespace ops | ||
| @@ -371,15 +371,13 @@ TEST_F(OppSoManagerUT, LoadAllOppPackage_dlopen_fail) { | |||
| 371 | std::set<std::string> opp_path; | 371 | std::set<std::string> opp_path; |
| 372 | SetOpHostAndGraphSo(opp_path); | 372 | SetOpHostAndGraphSo(opp_path); |
| 373 | 373 | ||
| 374 | - std::stringstream capture_cout; | 374 | + testing::internal::CaptureStdout(); |
| 375 | - auto origin_cout_buffer = std::cout.rdbuf(); | ||
| 376 | - std::cout.rdbuf(capture_cout.rdbuf()); | ||
| 377 | 375 | ||
| 378 | gert::OppPackageUtils::LoadAllOppPackage(); | 376 | gert::OppPackageUtils::LoadAllOppPackage(); |
| 379 | 377 | ||
| 380 | - std::cout.rdbuf(origin_cout_buffer); | 378 | + const std::string captured_stdout = testing::internal::GetCapturedStdout(); |
| 381 | - const std::string expect_log = "[ERROR] Failed to load"; | 379 | + const std::string expect_log = "Failed to load"; |
| 382 | - EXPECT_EQ(capture_cout.str().find(expect_log) != std::string::npos, true); | 380 | + EXPECT_NE(captured_stdout.find(expect_log), std::string::npos); |
| 383 | 381 | ||
| 384 | RemoveTempPaths({opp_path}); | 382 | RemoveTempPaths({opp_path}); |
| 385 | } | 383 | } |