forked from huawei/mindspore2022
!31654 [ME]Support raise in constant scenarios.
Merge pull request !31654 from Margaret_wangrui/raise
This commit is contained in:
commit
f59de99ed6
|
|
@ -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>();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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"""
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue