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

From: @zhangbuxue
Reviewed-by: @ginfung,@zh_qh
Signed-off-by: @zh_qh
This commit is contained in:
mindspore-ci-bot 2021-03-27 21:22:58 +08:00 committed by Gitee
commit 95f9f2c092
5 changed files with 159 additions and 27 deletions

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();

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

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

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

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)))