Browse Source

!1915 check dump option

Merge pull request !1915 from HW_KK/dump-option-check
tags/v1.5.1
i-robot Gitee 3 years ago
parent
commit
ab1b7623c6
5 changed files with 364 additions and 26 deletions
  1. +220
    -23
      ge/common/dump/dump_properties.cc
  2. +16
    -2
      ge/common/dump/dump_properties.h
  3. +1
    -1
      ge/session/inner_session.cc
  4. +1
    -0
      tests/ut/ge/CMakeLists.txt
  5. +126
    -0
      tests/ut/ge/common/dump_properties_unittest.cc

+ 220
- 23
ge/common/dump/dump_properties.cc View File

@@ -18,6 +18,7 @@

#include <cstdio>
#include <string>
#include <regex>

#include "common/ge/ge_util.h"
#include "framework/common/util.h"
@@ -37,6 +38,159 @@ const uint32_t kAtomicOverflow = (0x1 << 1);
const uint32_t kAllOverflow = (kAicoreOverflow | kAtomicOverflow);
} // namespace
namespace ge {
FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY void DumpProperties::Split(const std::string &s,
std::vector<std::string> &result,
const char *delchar) {
if (s.empty()) {
return;
}
result.clear();

char *buffer = new (std::nothrow)char[s.size() + 1];
if (buffer == nullptr) {
GELOGE(FAILED, "[Split][string] failed while malloc memory, string value is:%s", s.c_str());
REPORT_CALL_ERROR("E19999", "Memory malloc may fail when split string, get fatal exception, "
"string value is:%s", s.c_str());
return;
}
buffer[s.size()] = '\0';
errno_t e = strcpy_s(buffer, s.size() + 1, s.c_str());
if (e != EOK) {
delete[] buffer;
return;
}
char *context = nullptr;
char *p = strtok_s(buffer, delchar, &context);
while (p != nullptr) {
result.emplace_back(p);
p = strtok_s(nullptr, delchar, &context);
}
delete[] buffer;
}

FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY Status DumpProperties::CheckDumpStep(const std::string &dump_step) {
std::string modified_dum_step = dump_step + "|";
std::smatch result;
std::vector<string> match_vecs;
std::regex pattern(R"((\d{1,}-\d{1,}\||\d{1,}\|)+)");
if (regex_match(modified_dum_step, result, pattern)) {
Split(result.str(), match_vecs, "|");
if (match_vecs.empty()) {
REPORT_CALL_ERROR("E19999", "Split may get fatal exception, dump_step:%s.", dump_step.c_str());
GELOGE(FAILED, "[Check][Param] failed. Split may get fatal exception, ge.exec.dumpStep:%s.", dump_step.c_str());
return FAILED;
}
// 100 is the max sets of dump steps.
if (match_vecs.size() > 100) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpStep",
dump_step.c_str(),
" is not supported, only support dump <= 100 sets of data"}));
GELOGE(PARAM_INVALID, "[Check][Param] get dump_step value:%s, "
"dump_step only support dump <= 100 sets of data.", dump_step.c_str());
return PARAM_INVALID;
}
for (const auto &match_vec : match_vecs) {
std::vector<string> vec_after_split;
Split(match_vec, vec_after_split, "-");
if (match_vecs.empty()) {
REPORT_CALL_ERROR("E19999", "Split may get fatal exception.");
GELOGE(FAILED, "[Check][Param] failed, split may get fatal exception.");
return FAILED;
}
if (vec_after_split.size() > 1) {
if (std::atoi(vec_after_split[0].c_str()) >= std::atoi(vec_after_split[1].c_str())) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpStep",
dump_step.c_str(),
" is not supported."
"in range steps, the first step is >= second step, correct example:'0|5|10-20"}));
GELOGE(PARAM_INVALID, "[Check][Param] get dump_step value:%s, "
"in range steps, the first step is >= second step, correct example:'0|5|10-20'", dump_step.c_str());
return PARAM_INVALID;
}
}
}
} else {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpStep",
dump_step.c_str(),
" is not supported, correct example:'0|5|10|50-100."}));
GELOGE(PARAM_INVALID, "[Check][Param] get dump_step value:%s, "
"dump_step string style is error, correct example:'0|5|10|50-100.'", dump_step.c_str());
return PARAM_INVALID;
}
return SUCCESS;
}

FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY Status DumpProperties::CheckDumpMode(const std::string &dump_mode) {
const std::set<string> dump_mode_list = {"input", "output", "all"};
std::set<string>::iterator iter;

if ((iter = dump_mode_list.find(dump_mode)) == dump_mode_list.end()) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpMode",
dump_mode.c_str(),
" is not supported, should be one of the following:[input, output, all]"}));
GELOGE(PARAM_INVALID, "[Check][Param] the dump_debug_mode:%s, is is not supported,"
"should be one of the following:[input, output, all].", dump_mode.c_str());
return PARAM_INVALID;
}
return SUCCESS;
}

FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY Status DumpProperties::CheckDumpPath(const std::string &input) {
if (mmIsDir(input.c_str()) != EN_OK) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpPath",
input.c_str(),
" is not a directory."}));
GELOGE(PARAM_INVALID, "[Check][Param] the path:%s, is not directory.", input.c_str());
return PARAM_INVALID;
}
char trusted_path[MMPA_MAX_PATH] = { "\0" };
if (mmRealPath(input.c_str(), trusted_path, MMPA_MAX_PATH) != EN_OK) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpPath",
input.c_str(),
" dumpPath invalid."}));
GELOGE(PARAM_INVALID, "[Check][Param] the dumpPath:%s, is invalid.", input.c_str());
return PARAM_INVALID;
}
if (mmAccess2(trusted_path, M_R_OK | M_W_OK) != EN_OK) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpPath",
input.c_str(),
" does't have read, write permissions."}));
GELOGE(PARAM_INVALID, "[Check][Param] the path:%s, does't have read, write permissions.", input.c_str());
return PARAM_INVALID;
}
return SUCCESS;
}

FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY Status DumpProperties::CheckEnableDump(const std::string &input) {
std::set<string> enable_dump_option_list = {"1", "0"};
auto it = enable_dump_option_list.find(input);
if (it == enable_dump_option_list.end()) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.enableDump",
input.c_str(),
" only support 1 or 0."}));
GELOGE(PARAM_INVALID, "[Check][Param] Not support ge.exec.enableDump or ge.exec.enableDumpDebug format:%s, "
"only support 1 or 0.", input.c_str());
return PARAM_INVALID;
}
return SUCCESS;
}

FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY DumpProperties::DumpProperties(const DumpProperties &other) {
CopyFrom(other);
}
@@ -47,7 +201,26 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY DumpProperties &DumpProperties:
return *this;
}

FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY void DumpProperties::InitByOptions() {
FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY Status DumpProperties::SetDumpOptions() {
if (enable_dump_ == kEnableFlag) {
std::string dump_step;
if (GetContext().GetOption(OPTION_EXEC_DUMP_STEP, dump_step) == GRAPH_SUCCESS) {
GE_CHK_STATUS_RET(CheckDumpStep(dump_step), "[Check][dump_step] failed.");
GELOGI("Get dump step %s successfully", dump_step.c_str());
SetDumpStep(dump_step);
}
string dump_mode = "output";
if (GetContext().GetOption(OPTION_EXEC_DUMP_MODE, dump_mode) == GRAPH_SUCCESS) {
GELOGI("Get dump mode %s successfully", dump_mode.c_str());
GE_CHK_STATUS_RET(CheckDumpMode(dump_mode), "[Check][dump_mode] failed.");
SetDumpMode(dump_mode);
}
AddPropertyValue(DUMP_ALL_MODEL, {});
}
return SUCCESS;
}

FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY Status DumpProperties::InitByOptions() {
enable_dump_.clear();
enable_dump_debug_.clear();
dump_path_.clear();
@@ -57,17 +230,32 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY void DumpProperties::InitByOpti
is_infer_op_debug_ = false;
op_debug_mode_ = 0;

std::string enable_dump;
std::string enable_dump = std::to_string(false);
(void)GetContext().GetOption(OPTION_EXEC_ENABLE_DUMP, enable_dump);
enable_dump_ = enable_dump;
if (!enable_dump_.empty()) {
GE_CHK_STATUS_RET(CheckEnableDump(enable_dump_), "[Check][enable_dump] failed.");
}

std::string enable_dump_debug;
std::string enable_dump_debug = std::to_string(false);
(void)GetContext().GetOption(OPTION_EXEC_ENABLE_DUMP_DEBUG, enable_dump_debug);
enable_dump_debug_ = enable_dump_debug;

if (!enable_dump_debug_.empty()) {
GE_CHK_STATUS_RET(CheckEnableDump(enable_dump_debug_), "[Check][enable_dump_debug] failed.");
}
if ((enable_dump_ == kEnableFlag) && (enable_dump_debug_ == kEnableFlag)) {
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.enableDump and ge.exec.enableDumpDebug",
enable_dump_ + ", " + enable_dump_debug,
"ge.exec.enableDump and ge.exec.enableDumpDebug cannot be set to 1 at the same time."}));
GELOGE(FAILED, "ge.exec.enableDump and ge.exec.enableDumpDebug cannot be both set to 1 at the same time.");
return FAILED;
}
if ((enable_dump_ == kEnableFlag) || (enable_dump_debug_ == kEnableFlag)) {
std::string dump_path;
if (GetContext().GetOption(OPTION_EXEC_DUMP_PATH, dump_path) == GRAPH_SUCCESS) {
GE_CHK_STATUS_RET(CheckDumpPath(dump_path), "Check dump path failed.");
if (!dump_path.empty() && dump_path[dump_path.size() - 1] != '/') {
dump_path = dump_path + "/";
}
@@ -75,25 +263,21 @@ FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY void DumpProperties::InitByOpti
GELOGI("Get dump path %s successfully", dump_path.c_str());
SetDumpPath(dump_path);
} else {
GELOGW("Dump path is not set");
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpPath",
dump_path,
"ge.exec.dumpPath is not set."}));
GELOGE(FAILED, "[Check][dump_path] failed. Dump path is not set.");
return FAILED;
}
}

if (enable_dump_ == kEnableFlag) {
std::string dump_step;
if (GetContext().GetOption(OPTION_EXEC_DUMP_STEP, dump_step) == GRAPH_SUCCESS) {
GELOGI("Get dump step %s successfully", dump_step.c_str());
SetDumpStep(dump_step);
}
string dump_mode;
if (GetContext().GetOption(OPTION_EXEC_DUMP_MODE, dump_mode) == GRAPH_SUCCESS) {
GELOGI("Get dump mode %s successfully", dump_mode.c_str());
SetDumpMode(dump_mode);
}
AddPropertyValue(DUMP_ALL_MODEL, {});
}
GE_CHK_STATUS_RET(SetDumpOptions(), "SetDumpOptions failed.");

GE_CHK_STATUS_RET(SetDumpDebugOptions(), "SetDumpDebugOptions failed.");

SetDumpDebugOptions();
return SUCCESS;
}

// The following is the new dump scenario of the fusion operator
@@ -253,14 +437,20 @@ void DumpProperties::CopyFrom(const DumpProperties &other) {
}
}

void DumpProperties::SetDumpDebugOptions() {
Status DumpProperties::SetDumpDebugOptions() {
if (enable_dump_debug_ == kEnableFlag) {
std::string dump_debug_mode;
if (GetContext().GetOption(OPTION_EXEC_DUMP_DEBUG_MODE, dump_debug_mode) == GRAPH_SUCCESS) {
GELOGD("Get dump debug mode %s successfully", dump_debug_mode.c_str());
} else {
GELOGW("Dump debug mode is not set.");
return;
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpDebugMode",
dump_debug_mode,
"ge.exec.dumpDebugMode is not set."}));
GELOGE(PARAM_INVALID, "[Check][dump_debug_mode] failed. Dump debug mode is not set.");

return PARAM_INVALID;
}

if (dump_debug_mode == OP_DEBUG_AICORE) {
@@ -276,10 +466,17 @@ void DumpProperties::SetDumpDebugOptions() {
is_train_op_debug_ = true;
op_debug_mode_ = kAllOverflow;
} else {
GELOGW("ge.exec.dumpDebugMode is invalid.");
REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
std::vector<std::string>({
"ge.exec.dumpDebugMode",
dump_debug_mode,
"ge.exec.dumpDebugMode is invalid."}));
GELOGE(PARAM_INVALID, "[Set][DumpDebugOptions] failed, ge.exec.dumpDebugMode is invalid.");
return PARAM_INVALID;
}
} else {
GELOGI("ge.exec.enableDumpDebug is false or is not set.");
}
return SUCCESS;
}
} // namespace ge

+ 16
- 2
ge/common/dump/dump_properties.h View File

@@ -23,6 +23,7 @@
#include <vector>

namespace ge {
using Status = uint32_t;
class DumpProperties {
public:
DumpProperties() = default;
@@ -33,7 +34,7 @@ class DumpProperties {

DumpProperties &operator=(const DumpProperties &dump);

void InitByOptions();
Status InitByOptions();

void AddPropertyValue(const std::string &model, const std::set<std::string> &layers);

@@ -95,7 +96,20 @@ class DumpProperties {
private:
void CopyFrom(const DumpProperties &other);

void SetDumpDebugOptions();
Status SetDumpDebugOptions();

Status SetDumpOptions();

void Split(const std::string &s, std::vector<std::string> &result, const char *delchar);

Status CheckDumpStep(const std::string &dump_step);

Status CheckDumpMode(const std::string &dump_mode);

Status CheckDumpPath(const std::string &input);

Status CheckEnableDump(const std::string &input);

std::string enable_dump_;
std::string enable_dump_debug_;



+ 1
- 1
ge/session/inner_session.cc View File

@@ -121,7 +121,7 @@ Status InnerSession::Initialize() {
GE_CHK_RT_RET(rtSetDevice(GetContext().DeviceId()));

DumpProperties dump_properties;
dump_properties.InitByOptions();
GE_CHK_STATUS_RET(dump_properties.InitByOptions(), "Init dump properties failed.");
GE_CHK_STATUS_RET(AddDumpProperties(dump_properties), "[Add][DumpProperties] failed.");

ret = graph_manager_.Initialize(options_);


+ 1
- 0
tests/ut/ge/CMakeLists.txt View File

@@ -780,6 +780,7 @@ set(MULTI_PARTS_TEST_FILES
"common/util_unittest.cc"
"common/dump_manager_unittest.cc"
"common/dump_op_unittest.cc"
"common/dump_properties_unittest.cc"
"common/dump_exception_unittest.cc"
"common/opdebug_register_unittest.cc"
"common/format_transfer_unittest.cc"


+ 126
- 0
tests/ut/ge/common/dump_properties_unittest.cc View File

@@ -0,0 +1,126 @@
/**
* Copyright 2019-2020 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <gtest/gtest.h>

#define protected public
#define private public

#include "common/dump/dump_properties.h"
#include "ge_local_context.h"
#include "ge/ge_api_types.h"
#include "common/debug/log.h"
#include "common/ge_inner_error_codes.h"

namespace ge {
class UTEST_dump_properties : public testing::Test {
protected:
void SetUp() {}
void TearDown() {}
};

TEST_F(UTEST_dump_properties, check_dump_step) {
DumpProperties dp;
std::string dump_step{"0|3-5|10"};
std::string unsupport_input1{"0|5-3|10"};
std::string unsupport_input2{"one"};
std::string unsupport_input3;
for (int i = 0; i < 200; ++i) {
unsupport_input3 += std::to_string(i) + "|";
}
unsupport_input3.pop_back();
Status st = dp.CheckDumpStep(dump_step);
EXPECT_EQ(st, SUCCESS);
st = dp.CheckDumpStep(unsupport_input1);
EXPECT_NE(st, SUCCESS);
st = dp.CheckDumpStep(unsupport_input2);
EXPECT_NE(st, SUCCESS);
st = dp.CheckDumpStep(unsupport_input3);
EXPECT_NE(st, SUCCESS);
}

TEST_F(UTEST_dump_properties, check_dump_mode) {
DumpProperties dp;
std::string dump_mode_1{"input"};
std::string dump_mode_2{"output"};
std::string dump_mode_3{"all"};
std::string unsupport_input1{"mode1"};
Status st = dp.CheckDumpMode(dump_mode_1);
EXPECT_EQ(st, SUCCESS);
st = dp.CheckDumpMode(dump_mode_2);
EXPECT_EQ(st, SUCCESS);
st = dp.CheckDumpMode(dump_mode_3);
EXPECT_EQ(st, SUCCESS);
st = dp.CheckDumpMode(unsupport_input1);
EXPECT_NE(st, SUCCESS);
}

TEST_F(UTEST_dump_properties, check_dump_path) {
DumpProperties dp;
std::string dump_path{"/tmp/"};
std::string unsupport_input1{" \\unsupported"};
Status st = dp.CheckDumpPath(dump_path);
EXPECT_EQ(st, SUCCESS);
st = dp.CheckDumpPath(unsupport_input1);
EXPECT_NE(st, SUCCESS);
}

TEST_F(UTEST_dump_properties, check_enable_dump) {
DumpProperties dp;
std::string enable_dump_t{"1"};
std::string enable_dump_f{"0"};
std::string unsupport_input1{"true"};
std::string unsupport_input2{"false"};
Status st = dp.CheckEnableDump(enable_dump_t);
EXPECT_EQ(st, SUCCESS);
st = dp.CheckEnableDump(enable_dump_f);
EXPECT_EQ(st, SUCCESS);
st = dp.CheckEnableDump(unsupport_input1);
EXPECT_NE(st, SUCCESS);
st = dp.CheckEnableDump(unsupport_input2);
EXPECT_NE(st, SUCCESS);
}

TEST_F(UTEST_dump_properties, init_by_options_success_1) {
DumpProperties dp;
std::map<std::string, std::string> options {{OPTION_EXEC_ENABLE_DUMP, "1"},
{OPTION_EXEC_DUMP_PATH, "/tmp/"},
{OPTION_EXEC_DUMP_STEP, "0|1-3|10"},
{OPTION_EXEC_DUMP_MODE, "all"}};
GetThreadLocalContext().SetGlobalOption(options);
Status st = dp.InitByOptions();
EXPECT_EQ(st, SUCCESS);
}

TEST_F(UTEST_dump_properties, init_by_options_success_2) {
DumpProperties dp;
std::map<std::string, std::string> options {{OPTION_EXEC_ENABLE_DUMP_DEBUG, "1"},
{OPTION_EXEC_DUMP_PATH, "/tmp/"},
{OPTION_EXEC_DUMP_DEBUG_MODE, "aicore_overflow"}};
GetThreadLocalContext().SetGlobalOption(options);
Status st = dp.InitByOptions();
EXPECT_EQ(st, SUCCESS);
}

TEST_F(UTEST_dump_properties, init_by_options_failed) {
DumpProperties dp;
std::map<std::string, std::string> options {{OPTION_EXEC_ENABLE_DUMP_DEBUG, "1"},
{OPTION_EXEC_DUMP_PATH, "/tmp/"}};
GetThreadLocalContext().SetGlobalOption(options);
Status st = dp.InitByOptions();
EXPECT_NE(st, SUCCESS);
}
} // namespace ge

Loading…
Cancel
Save