!31654 [ME]Support raise in constant scenarios.

Merge pull request !31654 from Margaret_wangrui/raise
This commit is contained in:
i-robot 2022-03-23 02:28:37 +00:00 committed by Gitee
commit f59de99ed6
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
11 changed files with 520 additions and 54 deletions

View File

@ -32,6 +32,7 @@
#include "frontend/operator/ops.h"
#include "frontend/operator/composite/composite.h"
#include "utils/ms_context.h"
#include "utils/log_adapter.h"
#include "utils/interpret_node_recorder.h"
#include "pipeline/jit/debug/trace.h"
#include "mindspore/core/ir/cell.h"
@ -86,6 +87,7 @@ void Parser::BuildMethodMap() {
stmt_method_map_["Break"] = &Parser::ParseBreak;
stmt_method_map_["Continue"] = &Parser::ParseContinue;
stmt_method_map_["Pass"] = &Parser::ParsePass;
stmt_method_map_["Raise"] = &Parser::ParseRaise;
expr_method_map_["NoneType"] = &Parser::ParseNone;
expr_method_map_["BinOp"] = &Parser::ParseBinOp;
expr_method_map_["Name"] = &Parser::ParseName;
@ -110,6 +112,8 @@ void Parser::BuildMethodMap() {
expr_method_map_["Ellipsis"] = &Parser::ParseEllipsis;
expr_method_map_["ListComp"] = &Parser::ParseListComp;
expr_method_map_["GeneratorExp"] = &Parser::ParseListComp; // We treat 'GeneratorExp' the same as 'ListComp'.
expr_method_map_["JoinedStr"] = &Parser::ParseJoinedStr;
expr_method_map_["FormattedValue"] = &Parser::ParseFormattedValue;
}
void Parser::UpdateTopFuncGraph(const FuncGraphPtr &func_graph) { top_func_graph_ = FuncGraphWeakPtr(func_graph); }
@ -884,6 +888,47 @@ AnfNodePtr Parser::ParseSuper(const FunctionBlockPtr &block, const py::list &arg
return block->MakeResolve(name_space, symbol);
}
void Parser::ParseStrInError(const FunctionBlockPtr &block, const py::list &args, std::vector<AnfNodePtr> *str_nodes) {
for (size_t i = 0; i < args.size(); ++i) {
AnfNodePtr node = ParseExprNode(block, args[i]);
(void)str_nodes->emplace_back(node);
}
}
std::vector<AnfNodePtr> Parser::ParseException(const FunctionBlockPtr &block, const py::list &args,
const std::string &name) {
auto exception_type_node = NewValueNode(name);
std::vector<AnfNodePtr> node_inputs = {exception_type_node};
ParseStrInError(block, args, &node_inputs);
return node_inputs;
}
std::vector<AnfNodePtr> Parser::ParseRaiseCall(const FunctionBlockPtr &block, const py::object &node) {
MS_LOG(DEBUG) << "Process ast Call, the current node is raise.";
// Process function call
py::object function_ast_node = python_adapter::GetPyObjAttr(node, "func");
// Process raise ValueError
if (py::isinstance<py::none>(function_ast_node)) {
auto name_id = py::cast<std::string>(python_adapter::GetPyObjAttr(node, "id"));
if (std::find(exception_types.begin(), exception_types.end(), name_id) != exception_types.end()) {
return {NewValueNode(name_id)};
}
}
py::list args = python_adapter::GetPyObjAttr(node, "args");
auto arg_type =
AstSubType(py::cast<int32_t>(ast_->CallParseModFunction(PYTHON_PARSE_GET_AST_TYPE, function_ast_node)));
if (arg_type == AST_SUB_TYPE_NAME) {
auto name_id = py::cast<std::string>(python_adapter::GetPyObjAttr(function_ast_node, "id"));
MS_LOG(DEBUG) << "The name of call node is: " << name_id;
if (std::find(exception_types.begin(), exception_types.end(), name_id) != exception_types.end()) {
return ParseException(block, args, name_id);
}
}
return {};
}
// Process function call, eg : f1(x, y) ...
AnfNodePtr Parser::ParseCall(const FunctionBlockPtr &block, const py::object &node) {
MS_LOG(DEBUG) << "Process ast Call";
@ -895,6 +940,7 @@ AnfNodePtr Parser::ParseCall(const FunctionBlockPtr &block, const py::object &no
AstSubType(py::cast<int32_t>(ast_->CallParseModFunction(PYTHON_PARSE_GET_AST_TYPE, function_ast_node)));
if (arg_type == AST_SUB_TYPE_NAME) {
auto name_id = py::cast<std::string>(python_adapter::GetPyObjAttr(function_ast_node, "id"));
MS_LOG(DEBUG) << "The name of call node is: " << name_id;
if (name_id == "super") {
return ParseSuper(block, args);
}
@ -2012,6 +2058,29 @@ AnfNodePtr Parser::ParseListComp(const FunctionBlockPtr &block, const py::object
return output;
}
AnfNodePtr Parser::ParseJoinedStr(const FunctionBlockPtr &block, const py::object &node) {
MS_LOG(DEBUG) << "Process ast JoinedStr.";
MS_EXCEPTION_IF_NULL(block);
py::list py_values = python_adapter::GetPyObjAttr(node, "values");
std::vector<AnfNodePtr> value_nodes{NewValueNode(prim::kPrimMakeTuple)};
for (size_t i = 0; i < py_values.size(); ++i) {
AnfNodePtr str_value = ParseExprNode(block, py_values[i]);
(void)value_nodes.emplace_back(str_value);
}
auto func_graph = block->func_graph();
MS_EXCEPTION_IF_NULL(func_graph);
AnfNodePtr output = func_graph->NewCNodeInOrder(std::move(value_nodes));
return output;
}
AnfNodePtr Parser::ParseFormattedValue(const FunctionBlockPtr &block, const py::object &node) {
MS_LOG(DEBUG) << "Process ast FormattedValue.";
MS_EXCEPTION_IF_NULL(block);
py::object value_object = python_adapter::GetPyObjAttr(node, "value");
AnfNodePtr value_node = ParseExprNode(block, value_object);
return value_node;
}
void Parser::HandleAssignName(const FunctionBlockPtr &block, const py::object &target_object,
const AnfNodePtr &assigned_node) {
MS_EXCEPTION_IF_NULL(block);
@ -2336,6 +2405,28 @@ FunctionBlockPtr Parser::ParsePass(const FunctionBlockPtr &block, const py::obje
return block;
}
FunctionBlockPtr Parser::ParseRaise(const FunctionBlockPtr &block, const py::object &node) {
MS_LOG(DEBUG) << "Process raise statement";
MS_EXCEPTION_IF_NULL(block);
auto func_graph = block->func_graph();
MS_EXCEPTION_IF_NULL(func_graph);
py::object exc_ast_node = python_adapter::GetPyObjAttr(node, "exc");
// raise
if (py::isinstance<py::none>(exc_ast_node)) {
CNodePtr raise_node = func_graph->NewCNodeInOrder({NewValueNode(prim::kPrimRaise)});
func_graph->set_return(raise_node);
return block;
}
auto exc_node_inputs = ParseRaiseCall(block, exc_ast_node);
// raise ExceptionType or raise ExceptionType(ExceptionString)
std::vector<AnfNodePtr> inputs{NewValueNode(prim::kPrimRaise)};
(void)inputs.insert(inputs.end(), exc_node_inputs.begin(), exc_node_inputs.end());
CNodePtr raise_node = func_graph->NewCNodeInOrder(inputs);
CNodePtr return_node = func_graph->NewCNodeInOrder({NewValueNode(prim::kPrimReturn), raise_node});
func_graph->set_return(return_node);
return block;
}
AnfNodePtr FindPhis(const mindspore::HashMap<ParameterPtr, AnfNodePtr> &removable_phis, const AnfNodePtr &node) {
MS_EXCEPTION_IF_NULL(node);
const auto &inp = node->cast<ParameterPtr>();

View File

@ -142,6 +142,8 @@ class Parser {
FunctionBlockPtr ParseContinue(const FunctionBlockPtr &block, const py::object &node);
// Process pass statement
FunctionBlockPtr ParsePass(const FunctionBlockPtr &block, const py::object &node);
// Process raise statement
FunctionBlockPtr ParseRaise(const FunctionBlockPtr &block, const py::object &node);
// Process the expr and slice node method list
AnfNodePtr ParseBinOp(const FunctionBlockPtr &block, const py::object &node);
@ -197,6 +199,11 @@ class Parser {
const py::object &generator_node);
AnfNodePtr ParseListCompIfs(const FunctionBlockPtr &list_body_block, const ParameterPtr &list_param,
const py::object &node, const py::object &generator_node);
AnfNodePtr ParseJoinedStr(const FunctionBlockPtr &block, const py::object &node);
AnfNodePtr ParseFormattedValue(const FunctionBlockPtr &block, const py::object &node);
std::vector<AnfNodePtr> ParseException(const FunctionBlockPtr &block, const py::list &args, const std::string &name);
std::vector<AnfNodePtr> ParseRaiseCall(const FunctionBlockPtr &block, const py::object &node);
void ParseStrInError(const FunctionBlockPtr &block, const py::list &args, std::vector<AnfNodePtr> *str_nodes);
// Transform tail call to parallel call.
void TransformParallelCall();

View File

@ -467,7 +467,8 @@ EvalResultPtr TrivialPrimEvaluator::Run(AnalysisEnginePtr engine, const ConfigPt
EvalResultPtr TransitionPrimEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &out_conf) {
if (args_conf_list.empty() && identifier_ != "MakeTupleEvaluator" && identifier_ != "MakeListEvaluator") {
if (args_conf_list.empty() && identifier_ != "MakeTupleEvaluator" && identifier_ != "MakeListEvaluator" &&
identifier_ != "RaiseEvaluator") {
MS_LOG(EXCEPTION) << "Size should be greater than 0, during running " << identifier_;
}
AbstractBasePtrList args_spec_list;

View File

@ -37,6 +37,7 @@
#include "pipeline/jit/parse/resolve.h"
#include "pipeline/jit/pipeline.h"
#include "pipeline/jit/static_analysis/static_analysis.h"
#include "pipeline/jit/debug/trace.h"
#include "include/common/utils/convert_utils.h"
#include "include/common/utils/convert_utils_py.h"
#include "utils/ms_context.h"
@ -1918,6 +1919,82 @@ class PartialEvaluator : public Evaluator {
}
};
class RaiseEvaluator : public TransitionPrimEvaluator {
public:
RaiseEvaluator() : TransitionPrimEvaluator("RaiseEvaluator") {}
~RaiseEvaluator() override = default;
MS_DECLARE_PARENT(RaiseEvaluator, TransitionPrimEvaluator);
EvalResultPtr EvalPrim(const AnalysisEnginePtr &engine, const AbstractBasePtrList &args_spec_list,
const ConfigPtr &in_conf0, const AnfNodeConfigPtr &out_conf) override {
auto node = out_conf->node();
MS_EXCEPTION_IF_NULL(node);
auto cur_graph = node->func_graph();
MS_EXCEPTION_IF_NULL(cur_graph);
if (cur_graph->is_tensor_condition_branch()) {
MS_LOG(EXCEPTION) << "Currently only supports raise in constant scenarios."
<< "Tensor type data cannot exist in the conditional statement."
<< "Please check your conditions which raise node is located at:"
<< trace::GetDebugInfo(node->debug_info()) << ".";
}
if (args_spec_list.empty()) {
// process raise
MS_LOG(EXCEPTION) << "No active exception to reraise.";
}
std::string exception_type = GetScalarStringValue(args_spec_list[0]);
auto iter = exception_types_map.find(exception_type);
if (iter == exception_types_map.end()) {
MS_LOG(EXCEPTION) << "Unsupported exception type: " << exception_type << ".";
}
ExceptionType type = iter->second;
if (args_spec_list.size() == 1) {
// Process raise ValueError()
MS_EXCEPTION(type);
}
std::string exception_string = "";
for (size_t index = 1; index < args_spec_list.size(); ++index) {
exception_string += GetExceptionString(args_spec_list[index]);
}
MS_EXCEPTION(type) << exception_string;
return nullptr;
}
private:
std::string GetExceptionString(const AbstractBasePtr &arg) {
std::string exception_str = "";
if (arg->isa<abstract::AbstractTuple>()) {
// Process raise ValueError("str")
auto arg_tuple = arg->cast<abstract::AbstractTuplePtr>();
const auto &arg_tuple_elements = arg_tuple->elements();
if (arg_tuple_elements.size() == 0) {
MS_LOG(EXCEPTION) << "The arg_tuple_elements can't be empty.";
}
for (size_t index = 0; index < arg_tuple_elements.size(); ++index) {
auto &element = arg_tuple_elements[index];
exception_str += GetScalarStringValue(element);
}
} else {
// Process raise ValueError
exception_str += GetScalarStringValue(arg);
}
return exception_str;
}
std::string GetScalarStringValue(const AbstractBasePtr &abs) {
std::string str = "";
if (abs->isa<abstract::AbstractScalar>()) {
auto scalar = abs->cast<abstract::AbstractScalarPtr>();
auto scalar_value = scalar->BuildValue();
if (scalar_value->isa<Int64Imm>()) {
str = std::to_string(GetValue<int64_t>(scalar_value));
} else if (scalar_value->isa<StringImm>()) {
str = GetValue<std::string>(scalar_value);
}
}
return str;
}
};
struct PrimitiveImplInferValue {
PrimitiveImpl impl_; // implement function of primitive
bool eval_value_; // whether evaluate value
@ -1976,6 +2053,7 @@ void InitPrimEvaluatorConstructors() {
constructor[prim::kPrimPyInterpret] = std::make_shared<PyInterpretEvaluator>();
constructor[prim::kPrimMakeTuple] = std::make_shared<MakeTupleEvaluator>();
constructor[prim::kPrimMakeList] = std::make_shared<MakeListEvaluator>();
constructor[prim::kPrimRaise] = std::make_shared<RaiseEvaluator>();
}
} // namespace

View File

@ -34,6 +34,20 @@ AbstractBasePtr InferImplReturn(const AnalysisEnginePtr &, const PrimitivePtr &,
return abs_base;
}
void SetTensorFlag(const AbstractBasePtr abs) {
if (abs->isa<abstract::AbstractFunction>()) {
const auto &func_abs = abs->cast<abstract::AbstractFunctionPtr>();
MS_EXCEPTION_IF_NULL(func_abs);
auto closure_abs = func_abs->cast<abstract::FuncGraphAbstractClosurePtr>();
if (closure_abs) {
auto func = closure_abs->func_graph();
MS_EXCEPTION_IF_NULL(func);
func->set_is_tensor_condition_branch(true);
MS_LOG(DEBUG) << "Set is_tensor_condition_branch for func_graph:" << func->ToString();
}
}
}
AbstractBasePtr InferImplSwitch(const AnalysisEnginePtr &, const PrimitivePtr &,
const AbstractBasePtrList &args_spec_list) {
// Inputs: condition, true branch, false branch
@ -51,6 +65,11 @@ AbstractBasePtr InferImplSwitch(const AnalysisEnginePtr &, const PrimitivePtr &,
MS_EXCEPTION_IF_NULL(v);
// For tensor as condition, keeps both true and false branch.
if (v->isa<AnyValue>() || cond->isa<AbstractTensor>()) {
// Need record two func_graph
if (cond->isa<AbstractTensor>()) {
SetTensorFlag(tb);
SetTensorFlag(fb);
}
MS_EXCEPTION_IF_NULL(tb);
return tb->Join(fb);
}

View File

@ -742,6 +742,7 @@ GVAR_DEF(PrimitivePtr, kPrimAssignAdd, std::make_shared<Primitive>(kAssignAdd));
GVAR_DEF(PrimitivePtr, kPrimAssignSub, std::make_shared<Primitive>(kAssignSub));
GVAR_DEF(PrimitivePtr, kPrimSelect, std::make_shared<Primitive>(kSelect));
GVAR_DEF(PrimitivePtr, kPrimCall, std::make_shared<Primitive>("call"));
GVAR_DEF(PrimitivePtr, kPrimRaise, std::make_shared<Primitive>("raise"));
GVAR_DEF(PrimitivePtr, kPrimMakeTuple, std::make_shared<Primitive>(kMakeTuple));
GVAR_DEF(PrimitivePtr, kPrimMakeSlice, std::make_shared<Primitive>("make_slice"));

View File

@ -366,6 +366,11 @@ class MS_CORE_API FuncGraph : public deprecated::api::FuncGraph, public FuncGrap
void set_used_forward_nodes(const std::vector<AnfNodePtr> &used_forward_nodes);
void ClearUsedForwardNodes() { used_forward_nodes_.clear(); }
bool is_tensor_condition_branch() const { return is_tensor_condition_branch_; }
void set_is_tensor_condition_branch(bool is_tensor_condition_branch) {
is_tensor_condition_branch_ = is_tensor_condition_branch;
}
private:
// Only used for func_graph manager to control resource free.
int attached_mng_cnt() const { return attached_mng_cnt_; }
@ -455,6 +460,8 @@ class MS_CORE_API FuncGraph : public deprecated::api::FuncGraph, public FuncGrap
// forward nodes used in grad graph will be added to output for holding output values.
bool modify_output_ = false;
mindspore::HashSet<AnfNodePtr> used_forward_nodes_;
// If the func_graph is input of switch node, and the condition of switch is AbstractTensor, need set true.
bool is_tensor_condition_branch_ = false;
};
inline CNodePtr NewCNode(const std::vector<AnfNodePtr> &inputs, const FuncGraphPtr &fg) {

View File

@ -23,6 +23,7 @@
#include <sstream>
#include <memory>
#include <map>
#include <vector>
#include <thread>
#include <functional>
#include "utils/visible.h"
@ -71,6 +72,33 @@ enum ExceptionType {
NameError
};
// exception types
const std::vector<std::string> exception_types = {"NoExceptionType", "UnknownError", "ArgumentError",
"NotSupportError", "NotExistsError", "AlreadyExistsError",
"UnavailableError", "DeviceProcessError", "AbortedError",
"TimeOutError", "ResourceUnavailable", "NoPermissionError",
"IndexError", "ValueError", "TypeError",
"KeyError", "AttributeError", "NameError"};
static inline std::map<std::string, ExceptionType> exception_types_map = {{"NoExceptionType", NoExceptionType},
{"UnknownError", UnknownError},
{"ArgumentError", ArgumentError},
{"NotSupportError", NotSupportError},
{"NotExistsError", NotExistsError},
{"AlreadyExistsError", AlreadyExistsError},
{"UnavailableError", UnavailableError},
{"DeviceProcessError", DeviceProcessError},
{"AbortedError", AbortedError},
{"TimeOutError", TimeOutError},
{"ResourceUnavailable", ResourceUnavailable},
{"NoPermissionError", NoPermissionError},
{"IndexError", IndexError},
{"ValueError", ValueError},
{"TypeError", TypeError},
{"KeyError", KeyError},
{"AttributeError", AttributeError},
{"NameError", NameError}};
struct LocationInfo {
LocationInfo(const char *file, int line, const char *func) : file_(file), line_(line), func_(func) {}
~LocationInfo() = default;

View File

@ -0,0 +1,277 @@
# Copyright 2022 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.
# ============================================================================
""" test graph raise """
import pytest
import numpy as np
import mindspore.nn as nn
from mindspore import Tensor, context
import mindspore.common.dtype as mstype
from mindspore.common.api import _cell_graph_executor
context.set_context(mode=context.GRAPH_MODE)
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_1():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self, x):
if x == 1:
raise ValueError()
return x
with pytest.raises(ValueError, match=""):
net = RaiseNet()
res = net(1)
print("res:", res)
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_2():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self, x):
if x == 1:
raise ValueError(1)
return x
with pytest.raises(ValueError, match="1"):
net = RaiseNet()
res = net(1)
print("res:", res)
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_3():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self, x):
if x == 1:
raise ValueError(f"The input should not be 1.")
return x
with pytest.raises(ValueError, match="The input should not be 1."):
net = RaiseNet()
res = net(1)
print("res:", res)
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_4():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self, x):
if x == 1:
raise ValueError(f"The input should not be 1.")
return x
with pytest.raises(RuntimeError, match="Currently only supports raise in constant scenarios."):
net = RaiseNet()
x = Tensor(9, mstype.int32)
res = net(x)
assert res == 9
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_5():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class NetWithRaise(nn.Cell):
def construct(self, x):
raise ValueError(f"exception in construct.")
with pytest.raises(ValueError, match="exception in construct."):
net = NetWithRaise()
inp = Tensor(np.ones([1, 1, 32, 32]).astype(np.float32))
_cell_graph_executor.compile(net, inp)
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_6():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class NetWithRaise(nn.Cell):
def subfunc(self):
raise ValueError(f"exception in subfunc.")
def construct(self, x):
y = Tensor(0)
if x > 0:
y = Tensor(1)
elif x == 1:
y = Tensor(2)
else:
self.subfunc()
return y
with pytest.raises(ValueError, match="exception in subfunc."):
net = NetWithRaise()
x = -1
res = net(x)
print("res:", res)
@pytest.mark.skip(reason='Not support graph raise feature yet')
def test_raise_7():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self):
x = [1, 3, 5, 7, 9]
raise ValueError("Not expected value, x is {}".format(x))
with pytest.raises(ValueError) as info:
net = RaiseNet()
res = net()
print("res:", res)
assert "Not expected value, x is [1, 3, 5, 7, 9]" in str(info.value)
@pytest.mark.skip(reason='Not support graph raise feature yet')
def test_raise_8():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def __init__(self):
super(RaiseNet, self).__init__()
self.x = [1, 3, 5, 7]
def construct(self):
if self.x == [1, 3, 5, 7, 9]:
return 5
if self.x == [1, 3, 5]:
return 3
raise ValueError("Not expected value, x is {}".format(self.x))
with pytest.raises(ValueError) as info:
net = RaiseNet()
res = net()
print("res:", res)
assert "Not expected value, x is [1, 3, 5, 7]" in str(info.value)
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_9():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self):
x = 11
raise ValueError(f"The input can not be {x}.")
with pytest.raises(ValueError) as info:
net = RaiseNet()
res = net()
print("res:", res)
assert "The input can not be 11." in str(info.value)
@pytest.mark.skip(reason='Not support graph raise feature yet')
def test_raise_10():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self, x):
raise ValueError(f"The input can not be %s." % x)
with pytest.raises(ValueError) as info:
net = RaiseNet()
res = net(11)
print("res:", res)
assert "The input can not be 11." in str(info.value)
@pytest.mark.level0
@pytest.mark.platform_x86_gpu_training
@pytest.mark.platform_arm_ascend_training
@pytest.mark.platform_x86_ascend_training
@pytest.mark.env_onecard
def test_raise_11():
"""
Feature: graph raise.
Description: Test raise.
Expectation: No exception.
"""
class RaiseNet(nn.Cell):
def construct(self, x):
raise ValueError(f"The input can not be ", x, ".")
with pytest.raises(ValueError) as info:
net = RaiseNet()
res = net(11)
print("res:", res)
assert "The input can not be 11." in str(info.value)

View File

@ -16,8 +16,6 @@
import functools
import logging
import numpy as np
import pytest
import mindspore.context as context
from mindspore import Tensor
from mindspore import nn
@ -66,27 +64,6 @@ def test_net_without_construct():
_cell_graph_executor.compile(net, inp)
class NetWithRaise(nn.Cell):
""" NetWithRaise definition """
def __init__(self):
super(NetWithRaise, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5, pad_mode='valid')
# raise exception in method 'construct'
def construct(self, x):
raise 'exception in construct'
def test_net_with_raise():
""" test_net_with_raise """
net = NetWithRaise()
inp = Tensor(np.ones([1, 1, 32, 32]).astype(np.float32))
with pytest.raises(RuntimeError) as err:
_cell_graph_executor.compile(net, inp)
assert "Unsupported statement 'Raise'." in str(err.value)
class NetAddN(nn.Cell):
"""net for test AddN"""

View File

@ -30,9 +30,6 @@ context.set_context(mode=context.GRAPH_MODE)
def test_missing_return():
class NetMissReturn(nn.Cell):
def __init__(self):
super(NetMissReturn, self).__init__()
def construct(self, x, y, z):
if x == 1:
return 10
@ -65,9 +62,6 @@ def test_missing_return():
def test_nest_function_missing_return():
class NetNestFuncMissReturn(nn.Cell):
def __init__(self):
super(NetNestFuncMissReturn, self).__init__()
def construct(self, x, y, z):
if x == 1:
return 10
@ -100,12 +94,9 @@ def test_nest_function_missing_return():
def test_raise_in_method():
class NetRaiseInMethod(nn.Cell):
def __init__(self):
super(NetRaiseInMethod, self).__init__()
def construct(self, x, y, z):
if x == 1:
return 10
return Tensor(10, mstype.int32)
elif x == 20:
# add not support grammar 'raise' here
raise ValueError('Illegal case')
@ -118,24 +109,22 @@ def test_raise_in_method():
z = Tensor(2, mstype.int32)
with pytest.raises(RuntimeError) as er:
net(x, y, z)
assert "Unsupported statement 'Raise'." in str(er.value)
assert "Currently only supports raise in constant scenarios." in str(er.value)
def test_raise_in_nested_function():
class NetNestRaise(nn.Cell):
def __init__(self):
super(NetNestRaise, self).__init__()
def nest_fn(self, u):
if u > 0:
# add not support grammar 'raise' here
raise ValueError('Illegal case')
return u + z + 1
def construct(self, x, y, z):
if x == 1:
return 10
return Tensor(10, mstype.int32)
elif x == 20:
def nest_fn(u):
if u > 0:
# add not support grammar 'raise' here
raise ValueError('Illegal case')
return u + z + 1
return nest_fn(y)
return self.nest_fn(y)
else:
return y + z
@ -145,14 +134,11 @@ def test_raise_in_nested_function():
z = Tensor(2, mstype.int32)
with pytest.raises(RuntimeError) as er:
net(x, y, z)
assert "Unsupported statement 'Raise'." in str(er.value)
assert "Currently only supports raise in constant scenarios." in str(er.value)
def test_nest_branch_with_return():
class NetBranchWithReturn(nn.Cell):
def __init__(self):
super(NetBranchWithReturn, self).__init__()
def construct(self, x, y, z):
if x == 1:
return 10
@ -168,9 +154,6 @@ def test_nest_branch_with_return():
def test_any_with_no_return():
class NetAnyNoReturn(nn.Cell):
def __init__(self):
super(NetAnyNoReturn, self).__init__()
def construct(self, inp):
result = inp.any()
if result:
@ -186,9 +169,6 @@ def test_any_with_no_return():
def test_missing_construct():
class NetMissConstruct(nn.Cell):
def __init__(self):
super(NetMissConstruct, self).__init__()
def construct1(self, inp):
return 5