forked from mindspore-Ecosystem/mindspore
Add global Py param when processing global namespace info.
This commit is contained in:
parent
fa73749208
commit
d0ca18b921
|
@ -605,11 +605,11 @@ class Parser:
|
|||
value = self.global_namespace[var]
|
||||
if self.is_unsupported_namespace(value):
|
||||
error_info = f"The builtin function '{var}' of python is not supported in graph mode."
|
||||
return None, var, error_info
|
||||
return None, error_info
|
||||
return self.global_namespace, var
|
||||
|
||||
error_info = f"The name '{var}' is not defined in function '{self.function_name}'."
|
||||
return None, var, error_info
|
||||
return None, error_info
|
||||
|
||||
def is_unsupported_builtin_type(self, value_type):
|
||||
"""To check if not supported builtin type"""
|
||||
|
@ -675,13 +675,13 @@ class Parser:
|
|||
return True
|
||||
# Support nn.layer. To check if exclude other module.
|
||||
if rightmost_name in self.ms_nn_ns:
|
||||
logger.info(f"Found '{name}'({rightmost_name}) in nn namespace: {str(self.ms_nn_ns)}.")
|
||||
logger.debug(f"Found '{name}'({rightmost_name}) in nn namespace: {str(self.ms_nn_ns)}.")
|
||||
return True
|
||||
if rightmost_name in trope_ns:
|
||||
logger.debug(f"Found '{name}'({rightmost_name}) in trope namespace: {str(trope_ns)}.")
|
||||
return True
|
||||
|
||||
logger.error(f"Not found '{name}' in mindspore supported namespace.")
|
||||
logger.info(f"Not found '{name}' in mindspore supported namespace.")
|
||||
return False
|
||||
|
||||
def get_builtin_namespace_symbol(self, var: str):
|
||||
|
@ -701,11 +701,12 @@ class Parser:
|
|||
return self.global_namespace, var, value
|
||||
if not self.is_supported_namespace_module(value): # Check if support including instance of types.ModuleType
|
||||
return self.global_namespace, var, value
|
||||
return self.global_namespace, var
|
||||
supported = True
|
||||
return self.global_namespace, var, value, supported
|
||||
|
||||
error_info = f"The name '{var}' is not defined, or not supported in graph mode."
|
||||
logger.debug(f"error_info: {error_info}")
|
||||
return None, var, error_info
|
||||
return None, error_info
|
||||
|
||||
def analyze_super(self, class_type_node, subclass_instance):
|
||||
"""Analyze super and return a class instance."""
|
||||
|
|
|
@ -195,33 +195,59 @@ AnfNodePtr FunctionBlock::MakeResolveClassMember(const std::string &attr) {
|
|||
return MakeResolve(name_space, symbol);
|
||||
}
|
||||
|
||||
AnfNodePtr FunctionBlock::HandleNamespaceInfo(const py::tuple &namespace_info) {
|
||||
const size_t namespace_info_size = 2;
|
||||
const size_t namespace_more_info_size = 3;
|
||||
if (namespace_info.size() != namespace_info_size && namespace_info.size() != namespace_more_info_size) {
|
||||
MS_EXCEPTION(NameError) << "namespace info size should be 2 or 3, but got " << namespace_info.size();
|
||||
AnfNodePtr FunctionBlock::GetResolveNode(const py::tuple &info) {
|
||||
constexpr size_t namespace_index = 0;
|
||||
constexpr size_t symbol_index = 1;
|
||||
NameSpacePtr name_space = std::make_shared<NameSpace>(RESOLVE_NAMESPACE_NAME_SYMBOL_STR, info[namespace_index]);
|
||||
SymbolPtr symbol = std::make_shared<Symbol>(info[symbol_index].cast<std::string>());
|
||||
return MakeResolve(name_space, symbol);
|
||||
}
|
||||
|
||||
AnfNodePtr FunctionBlock::HandleNamespaceInfo(const py::tuple &info) {
|
||||
constexpr size_t namespace_index = 0;
|
||||
constexpr size_t symbol_index = 1;
|
||||
constexpr size_t namespace_info_size = 2;
|
||||
if (info.size() != namespace_info_size) {
|
||||
MS_EXCEPTION(NameError) << "namespace info size should be 2, but got " << info.size();
|
||||
}
|
||||
bool unsupported = false;
|
||||
py::object py_obj;
|
||||
if (namespace_info.size() == namespace_more_info_size) {
|
||||
if (namespace_info[0].is_none()) { // If namespace is None, the symbol is an undefined name.
|
||||
MS_EXCEPTION(NameError) << namespace_info[namespace_more_info_size - 1].cast<std::string>();
|
||||
} else { // Or, the symbol is an unsupported builtin symbol in Graph mode.
|
||||
unsupported = true;
|
||||
py_obj = namespace_info[namespace_more_info_size - 1];
|
||||
|
||||
// If namespace is None, the symbol is an undefined name.
|
||||
if (info[namespace_index].is_none()) {
|
||||
MS_EXCEPTION(NameError) << info[symbol_index].cast<std::string>();
|
||||
}
|
||||
return GetResolveNode(info);
|
||||
}
|
||||
|
||||
AnfNodePtr FunctionBlock::HandleBuiltinNamespaceInfo(const py::tuple &info) {
|
||||
constexpr size_t closure_info_size = 2;
|
||||
constexpr size_t unsupported_info_size = 3;
|
||||
constexpr size_t supported_info_size = 4;
|
||||
constexpr size_t namespace_index = 0;
|
||||
constexpr size_t symbol_index = 1;
|
||||
constexpr size_t value_index = 2;
|
||||
if (info.size() < closure_info_size || info.size() > supported_info_size) {
|
||||
MS_EXCEPTION(NameError) << "namespace info size should be 2, 3 or 4, but got " << info.size();
|
||||
}
|
||||
|
||||
// Handle closure namespace info.
|
||||
if (info.size() == closure_info_size) {
|
||||
// If namespace is None, the symbol is an undefined name.
|
||||
if (info[namespace_index].is_none()) {
|
||||
MS_EXCEPTION(NameError) << info[symbol_index].cast<std::string>();
|
||||
}
|
||||
return GetResolveNode(info);
|
||||
}
|
||||
NameSpacePtr name_space = std::make_shared<NameSpace>(RESOLVE_NAMESPACE_NAME_SYMBOL_STR, namespace_info[0]);
|
||||
SymbolPtr symbol = std::make_shared<Symbol>(namespace_info[1].cast<std::string>());
|
||||
MS_LOG(DEBUG) << "[" << func_graph()->ToString() << "] name_space: " << name_space->ToString()
|
||||
<< ", symbol: " << symbol->ToString() << ", unsupported: " << unsupported;
|
||||
auto resolved_node = MakeResolve(name_space, symbol);
|
||||
if (unsupported) {
|
||||
|
||||
// Handle global namespace info.
|
||||
auto resolved_node = GetResolveNode(info);
|
||||
if (info.size() == unsupported_info_size) {
|
||||
resolved_node->set_interpret(true);
|
||||
AddGlobalPyParam(symbol->name(), py_obj);
|
||||
MS_LOG(INFO) << "[" << func_graph()->ToString() << "] Added global python symbol: {" << symbol->name() << " : "
|
||||
<< py::str(py_obj) << "}";
|
||||
}
|
||||
SymbolPtr symbol = std::make_shared<Symbol>(info[symbol_index].cast<std::string>());
|
||||
py::object py_obj = info[value_index];
|
||||
AddGlobalPyParam(symbol->name(), py_obj);
|
||||
MS_LOG(INFO) << "[" << func_graph()->ToString() << "] Added global python symbol: {" << symbol->name() << " : "
|
||||
<< py::str(py_obj) << "}";
|
||||
return resolved_node;
|
||||
}
|
||||
|
||||
|
@ -248,7 +274,7 @@ AnfNodePtr FunctionBlock::MakeResolveSymbol(const std::string &value) {
|
|||
return HandleNamespaceInfo(namespace_info);
|
||||
} else {
|
||||
py::tuple namespace_info = ast->CallParserObjMethod(PYTHON_PARSE_GET_BUILTIN_NAMESPACE_SYMBOL, value);
|
||||
return HandleNamespaceInfo(namespace_info);
|
||||
return HandleBuiltinNamespaceInfo(namespace_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,10 +563,12 @@ void FunctionBlock::AttachIsolatedNodesBeforeReturn() {
|
|||
isolated_nodes_.clear();
|
||||
|
||||
AnfNodePtr state = nullptr;
|
||||
if (states.size() == 1) {
|
||||
constexpr size_t no_state_size = 1;
|
||||
constexpr size_t only_one_state_size = 2;
|
||||
if (states.size() == no_state_size) {
|
||||
// Only MakeTuple, no state left.
|
||||
return;
|
||||
} else if (states.size() == 2) {
|
||||
} else if (states.size() == only_one_state_size) {
|
||||
// If there are only MakeTuple and another node in states(the states size is 2),
|
||||
// do not need to MakeTuple, just use the node.
|
||||
state = states[1];
|
||||
|
|
|
@ -74,7 +74,9 @@ class FunctionBlock : public std::enable_shared_from_this<FunctionBlock> {
|
|||
AnfNodePtr MakeResolveSymbol(const std::string &value);
|
||||
AnfNodePtr MakeResolveOperation(const std::string &value);
|
||||
AnfNodePtr MakeResolve(const std::shared_ptr<NameSpace> &name_space, const std::shared_ptr<Symbol> &resolve_symbol);
|
||||
AnfNodePtr GetResolveNode(const py::tuple &namespace_info);
|
||||
AnfNodePtr HandleNamespaceInfo(const py::tuple &namespace_info);
|
||||
AnfNodePtr HandleBuiltinNamespaceInfo(const py::tuple &namespace_info);
|
||||
AnfNodePtr MakeInterpret(const std::string &script_text, const AnfNodePtr &global_dict_node,
|
||||
const AnfNodePtr &local_dict_node, const AnfNodePtr &orig_node);
|
||||
const std::unordered_map<ParameterPtr, AnfNodePtr> &removable_phis() const { return removable_phis_; }
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# Copyright 2021 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 fallback """
|
||||
import pytest
|
||||
import numpy as np
|
||||
|
||||
import mindspore.nn as nn
|
||||
from mindspore import Tensor, ms_function, context
|
||||
import mindspore.common.dtype as mstype
|
||||
|
||||
context.set_context(mode=context.GRAPH_MODE)
|
||||
|
||||
|
||||
class ControlNet(nn.Cell):
|
||||
def inner_function_1(self, a, b):
|
||||
return a + b
|
||||
|
||||
def inner_function_2(self, a, b):
|
||||
return a - b
|
||||
|
||||
def construct(self, x):
|
||||
a = Tensor(np.array(4), mstype.int32)
|
||||
b = Tensor(np.array(5), mstype.int32)
|
||||
if a + b > x:
|
||||
return self.inner_function_1(a, b)
|
||||
return self.inner_function_2(a, b)
|
||||
|
||||
|
||||
@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_fallback_control_sink_tensor():
|
||||
"""
|
||||
Feature: Fallback feature: support define Tensor in Class construct.
|
||||
Description: Fallback feature: support define Tensor in Class construct.
|
||||
Expectation: Fallback feature: support define Tensor in Class construct.
|
||||
"""
|
||||
x = Tensor(np.array(1), mstype.int32)
|
||||
net = ControlNet()
|
||||
output = net(x)
|
||||
output_expect = Tensor(9, mstype.int32)
|
||||
assert output == output_expect
|
||||
|
||||
|
||||
@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_np_tensor_list():
|
||||
"""
|
||||
Feature: Fallback feature
|
||||
Description: support Basic method of Tensor list.
|
||||
Expectation: No exception.
|
||||
"""
|
||||
@ms_function
|
||||
def np_tensor_list():
|
||||
a = Tensor(np.array(4), mstype.int32)
|
||||
b = Tensor(np.array(5), mstype.int32)
|
||||
c = Tensor(np.array(6), mstype.int32)
|
||||
tensor_list = [a, b]
|
||||
for tensor in tensor_list:
|
||||
print(tensor)
|
||||
tensor_list.append(tensor_list[-1] + c)
|
||||
return tensor_list
|
||||
|
||||
tensor_list = np_tensor_list()
|
||||
print("tensor_list:", tensor_list)
|
||||
assert len(tensor_list) == 3
|
|
@ -60,7 +60,6 @@ def use_tensor_with_mstype():
|
|||
return me_x
|
||||
|
||||
|
||||
@pytest.mark.skip(reason='Not support graph fallback feature yet')
|
||||
def test_tensor_with_mstype():
|
||||
"""
|
||||
Feature: JIT Fallback
|
||||
|
@ -70,6 +69,22 @@ def test_tensor_with_mstype():
|
|||
print(use_tensor_with_mstype())
|
||||
|
||||
|
||||
@ms_function
|
||||
def use_tuple_of_tensor():
|
||||
me_x = (Tensor(1), Tensor(1))
|
||||
return me_x
|
||||
|
||||
|
||||
@pytest.mark.skip(reason='Not support graph fallback feature yet')
|
||||
def test_tuple_of_tensor():
|
||||
"""
|
||||
Feature: JIT Fallback
|
||||
Description: Test tuple of tensor in graph mode.
|
||||
Expectation: No exception.
|
||||
"""
|
||||
print(use_tuple_of_tensor())
|
||||
|
||||
|
||||
class Net(nn.Cell):
|
||||
def __init__(self):
|
||||
super(Net, self).__init__()
|
||||
|
@ -215,63 +230,6 @@ def test_np_fallback_func_tensor_index():
|
|||
assert output == output_expect
|
||||
|
||||
|
||||
class ControlNet(nn.Cell):
|
||||
def __init__(self):
|
||||
super(ControlNet, self).__init__()
|
||||
|
||||
def inner_function_1(self, a, b):
|
||||
return a + b
|
||||
|
||||
def inner_function_2(self, a, b):
|
||||
return a - b
|
||||
|
||||
def construct(self, x):
|
||||
a = Tensor(np.array(4), mstype.int32)
|
||||
b = Tensor(np.array(5), mstype.int32)
|
||||
if a + b > x:
|
||||
return self.inner_function_1(a, b)
|
||||
return self.inner_function_2(a, b)
|
||||
|
||||
|
||||
# NameError: name 'mstype' is not defined.
|
||||
@pytest.mark.skip(reason='Not support graph fallback feature yet')
|
||||
def test_fallback_control_sink_tensor():
|
||||
"""
|
||||
Feature: Fallback feature: support define Tensor in Class construct.
|
||||
Description: Fallback feature: support define Tensor in Class construct.
|
||||
Expectation: Fallback feature: support define Tensor in Class construct.
|
||||
"""
|
||||
x = Tensor(np.array(1), mstype.int32)
|
||||
net = ControlNet()
|
||||
output = net(x)
|
||||
output_expect = Tensor(9, mstype.int32)
|
||||
assert output == output_expect
|
||||
|
||||
|
||||
# NameError: name 'mytype' is not defined
|
||||
@pytest.mark.skip(reason='Not support graph fallback feature yet')
|
||||
def test_np_tensor_list():
|
||||
"""
|
||||
Feature: Fallback feature
|
||||
Description: support Basic method of Tensor list.
|
||||
Expectation: No exception.
|
||||
"""
|
||||
@ms_function
|
||||
def np_tensor_list():
|
||||
a = Tensor(np.array(4), mstype.int32)
|
||||
b = Tensor(np.array(5), mstype.int32)
|
||||
c = Tensor(np.array(6), mstype.int32)
|
||||
tensor_list = [a, b]
|
||||
for tensor in tensor_list:
|
||||
print(tensor)
|
||||
tensor_list.append(tensor_list[-1] + c)
|
||||
return tensor_list
|
||||
|
||||
tensor_list = np_tensor_list()
|
||||
print("tensor_list:", tensor_list)
|
||||
assert len(tensor_list) == 3
|
||||
|
||||
|
||||
# EvalCNode: This may be not defined, or it can't be a operator.
|
||||
@pytest.mark.skip(reason='Not support graph fallback feature yet')
|
||||
def test_np_tensor_add():
|
||||
|
|
Loading…
Reference in New Issue