Browse Source

optimize exception mode when use undefined name in if for and while

pull/14244/head
buxue 4 years ago
parent
commit
d830a2b55a
5 changed files with 159 additions and 27 deletions
  1. +5
    -3
      mindspore/ccsrc/pipeline/jit/parse/function_block.cc
  2. +7
    -0
      tests/ut/cpp/pipeline/parse/parser_test.cc
  3. +0
    -13
      tests/ut/cpp/pipeline/parse/resolve_test.cc
  4. +1
    -1
      tests/ut/cpp/python_input/gtest_input/pipeline/parse/parser_test.py
  5. +146
    -10
      tests/ut/python/pipeline/parse/test_use_undefined_var.py

+ 5
- 3
mindspore/ccsrc/pipeline/jit/parse/function_block.cc View File

@@ -169,6 +169,9 @@ AnfNodePtr FunctionBlock::MakeResolveSymbol(const std::string &value) {
return MakeResolveClassMember(bits_str);
}
py::tuple namespace_var = parser_.ast()->CallParserObjMethod(PYTHON_PARSE_GET_NAMESPACE_SYMBOL, value);
if (namespace_var[0].is_none()) {
MS_EXCEPTION(NameError) << "The name \'" << value << "\' is not defined.";
}

NameSpacePtr name_space = std::make_shared<NameSpace>(RESOLVE_NAMESPACE_NAME_SYMBOL_STR, namespace_var[0]);
SymbolPtr symbol = std::make_shared<Symbol>(namespace_var[1].cast<std::string>());
@@ -193,6 +196,7 @@ AnfNodePtr FunctionBlock::MakeResolve(const NameSpacePtr &name_space, const Symb

// Add input for the block's phi parameter
void FunctionBlock::SetPhiArgument(const ParameterPtr &phi) {
TraceGuard trace_guard(std::make_shared<TraceResolve>(phi->debug_info()));
std::string var = phi_nodes_[phi];
MS_LOG(DEBUG) << "graph " << func_graph_->ToString() << " set phi " << phi->ToString() << " for var " << var;
auto removable = CollectRemovablePhi(phi);
@@ -205,7 +209,6 @@ void FunctionBlock::SetPhiArgument(const ParameterPtr &phi) {
MS_EXCEPTION_IF_NULL(pred);
MS_LOG(DEBUG) << "graph " << func_graph_->ToString() << " pred_blocks_ " << pred->func_graph_->ToString();
AnfNodePtr arg_node = pred->ReadVariable(var);
arg_node->set_debug_info(phi->debug_info());
CNodePtr jump = pred->jumps_[this];
jump->add_input(arg_node);
}
@@ -264,7 +267,6 @@ bool FunctionBlock::CollectRemovablePhi(const ParameterPtr &phi) {
}
AnfNodePtr arg_node = SearchReplaceNode(var, phi);
if (arg_node != nullptr) {
arg_node->set_debug_info(phi->debug_info());
MS_LOG(DEBUG) << "graph " << func_graph_->ToString() << " phi " << phi->ToString() << " can be replaced with "
<< arg_node->DebugString();
// Replace var with new one. This equal to statement in TR "v0 is immediately replaced by v1."
@@ -417,7 +419,7 @@ void FunctionBlock::AttachIsolatedNodesBeforeReturn() {
states.emplace_back(NewValueNode(prim::kPrimMakeTuple));
for (auto &node : isolated_nodes_) {
MS_LOG(DEBUG) << "Adding dependency, node: " << node->DebugString(2) << " in " << func_graph()->ToString();
if (node->func_graph() == func_graph() || node->isa<Parameter>()) {
if (node->func_graph() == func_graph()) {
states.emplace_back(node);
} else {
MS_LOG(INFO) << "Ignored FV dependency, node: " << node->DebugString(2) << " in " << func_graph()->ToString();


+ 7
- 0
tests/ut/cpp/pipeline/parse/parser_test.cc View File

@@ -380,5 +380,12 @@ TEST_F(TestParser, TestParseGraphCallVargs) {
bool ret_ = ResolveAll(manager);
ASSERT_TRUE(ret_);
}

TEST_F(TestParser, TestParserUndefinedVar) {
py::function fn_ = python_adapter::GetPyFn("gtest_input.pipeline.parse.parser_test", "test_parse_undefined_var");

// parse undefined var
EXPECT_THROW({ ParsePythonCode(fn_); }, std::runtime_error);
}
} // namespace parse
} // namespace mindspore

+ 0
- 13
tests/ut/cpp/pipeline/parse/resolve_test.cc View File

@@ -86,18 +86,5 @@ TEST_F(TestResolve, TestParseGraphTestClosureResolve) {
i++;
}
}
TEST_F(TestResolve, TestResolveFail) {
py::function fn_ = python_adapter::GetPyFn("gtest_input.pipeline.parse.parser_test", "test_resolvefail");

// parse graph
FuncGraphPtr func_graph = ParsePythonCode(fn_);
ASSERT_FALSE(nullptr == func_graph);

// save the func_graph to manager
std::shared_ptr<FuncGraphManager> manager = Manage(func_graph);

// call resolve
EXPECT_THROW({ ResolveAll(manager); }, std::runtime_error);
}
} // namespace parse
} // namespace mindspore

+ 1
- 1
tests/ut/cpp/python_input/gtest_input/pipeline/parse/parser_test.py View File

@@ -298,7 +298,7 @@ def test_augassign(x, y):
return y


def test_resolvefail(x, y):
def test_parse_undefined_var(x, y):
a = x + y + Undef
return a



+ 146
- 10
tests/ut/python/pipeline/parse/test_use_undefined_var.py View File

@@ -32,6 +32,7 @@ def test_use_undefined_var():
def construct(self, x):
ret = x + a
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
@@ -50,12 +51,12 @@ def test_insert_undefined_var():
b
ret = x + x
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'b' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(50)" in str(err.value)
assert "b" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(51)" in str(err.value)


def test_insert_undefined_var_compute():
@@ -68,13 +69,120 @@ def test_insert_undefined_var_compute():
c + x
ret = x + x
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'c' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(68)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(69)" in str(err.value)
assert "c + x" in str(err.value)


def test_insert_undefined_var_in_if():
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.value = [11, 22, 33, 44]

def construct(self, x):
if x > 0:
i
ret = x + x
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'i' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(89)" in str(err.value)


def test_insert_undefined_var_in_while_inner_if():
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.value = [11, 22, 33, 44]

def construct(self, x):
while x > 0:
if x > 1:
j
x = x - 1
ret = x + x
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'j' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(109)" in str(err.value)


def test_insert_undefined_var_compute__in_while_inner_if():
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.value = [11, 22, 33, 44]

def construct(self, x):
while x > 0:
if x > 1:
p + x
x = x - 1
ret = x + x
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'p' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(130)" in str(err.value)
assert "p + x" in str(err.value)


def test_insert_undefined_var_compute__in_for_inner_if():
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.value = [11, 22, 33, 44]

def construct(self, x):
for i in self.value:
if x > 1:
w
x = x - i
ret = x + x
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'w' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(152)" in str(err.value)
assert "w" in str(err.value)


def test_use_undefined_var_for_inner_if():
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.value = [11, 22, 33, 44]

def construct(self, x):
for i in self.value:
if x > 1:
x = x - i + y
ret = x + x
return ret

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'y' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(174)" in str(err.value)
assert "y" in str(err.value)


def test_use_undefined_var_in_for():
class Net(nn.Cell):
def __init__(self):
@@ -85,11 +193,12 @@ def test_use_undefined_var_in_for():
for i in self.value:
x = x + d + i
return x

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'd' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(86)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(194)" in str(err.value)
assert "x = x + d + i" in str(err.value)


@@ -104,15 +213,16 @@ def test_insert_undefined_var_in_for():
e
x = x + i
return x

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'e' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(104)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(213)" in str(err.value)
assert "e" in str(err.value)


def test_insert_undefined_var_compute_for():
def test_insert_undefined_var_compute_in_for():
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
@@ -123,11 +233,12 @@ def test_insert_undefined_var_compute_for():
f + i
x = x + i
return x

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'f' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(123)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(233)" in str(err.value)
assert "f + i" in str(err.value)


@@ -140,11 +251,12 @@ def test_use_undefined_var_in_while():
while x < 0:
x = x - g
return x

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'g' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(141)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(252)" in str(err.value)
assert "x = x - g" in str(err.value)


@@ -159,11 +271,12 @@ def test_insert_undefined_var_in_while():
h
x = x - 1
return x

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'h' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(159)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(271)" in str(err.value)
assert "h" in str(err.value)


@@ -178,14 +291,35 @@ def test_insert_undefined_var_compute_while():
x + i
x = x - 1
return x

net = Net()
with pytest.raises(NameError) as err:
net(Tensor(np.arange(4)))
assert "The name 'i' is not defined" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(178)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(291)" in str(err.value)
assert "x + i" in str(err.value)


def test_call_none_in_if():
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.value = [11, 22, 33, 44]

def construct(self, x):
ret = 0
if self.value:
ret = self.func(x)
return ret

net = Net()
with pytest.raises(RuntimeError) as err:
net(Tensor(np.arange(4)))
assert "Not AbstractFunction: AbstractNone(Value: None)" in str(err.value)
assert "tests/ut/python/pipeline/parse/test_use_undefined_var.py(312)" in str(err.value)
assert "ret = self.func(x)" in str(err.value)


def test_insert_defined_var():
class Net(nn.Cell):
def __init__(self):
@@ -196,6 +330,7 @@ def test_insert_defined_var():
x
ret = x + x
return ret

net = Net()
net(Tensor(np.arange(4)))

@@ -210,5 +345,6 @@ def test_insert_defined_var_compute():
x - x
ret = x + x
return ret

net = Net()
net(Tensor(np.arange(4)))

Loading…
Cancel
Save