from mindspore import Tensor, jit
a = 1
b = [Tensor([1]), Tensor([2])]
c = ["a", "b", "c"]
def foo(a, b, c):
return a, b, c
上述代码中,输入a
,b
,c
均为常量。
图模式内生成的标量或者Tensor为常量。例如:
from mindspore import jit, Tensor
def foo():
a = 1
b = "2"
c = Tensor([1, 2, 3])
return a, b, c
上述代码中, a
,b
,c
均为常量。
常量运算得到的结果为常量。例如:
from mindspore import jit, Tensor
def foo():
a = Tensor([1, 2, 3])
b = Tensor([1, 1, 1])
c = a + b
return c
上述代码中,a
、b
均为图模式内产生的Tensor为常量,因此其计算得到的结果也是常量。但如果其中之一为变量时,其返回值也会为变量。
所有mutable接口的返回值均为变量(无论是在图外使用mutable还是在图内使用)。例如:
from mindspore import Tensor, jit
from mindspore.common import mutable
a = mutable([Tensor([1]), Tensor([2])])
def foo(a):
b = mutable(Tensor([3]))
c = mutable((Tensor([1]), Tensor([2])))
return a, b, c
上述代码中,a
是在图外调用mutable接口的,b
和c
是在图内调用mutable接口生成的,a
、b
、c
均为变量。
作为静态图的输入的Tensor都是变量。例如:
from mindspore import Tensor, jit
a = Tensor([1])
b = (Tensor([1]), Tensor([2]))
def foo(a, b):
return a, b
上述代码中,a
是作为图模式输入的Tensor,因此其为变量。但b
是作为图模式输入的元组,非Tensor类型,即使其内部的元素均为Tensor,b
也是常量。
通过变量计算得到的是变量。
如果一个量是算子的输出,那么其多数情况下为常量。例如:
from mindspore import Tensor, jit, ops
a = Tensor([1])
b = Tensor([2])
def foo(a, b):
c = a + b
return c
在这种情况下,c
是a
和b
计算来的结果,且用来计算的输入a
、b
均为变量,因此c
也是变量。
Number
支持int
(整型)、float
(浮点型)、bool
(布尔类型),不支持complex
(复数)。
支持在网络里定义Number
,即支持语法:y = 1
、y = 1.2
、y = True
。
当数据为常量时,编译时期可以获取到数值,在网络中可以支持强转Number
的语法:y = int(x)
、y = float(x)
、y = bool(x)
。
当数据为变量时,即需要在运行时期才可以获取到数值,也支持使用int(),float(),bool()等内置函数Python内置函数进行数据类型的转换。例如:
from mindspore import Tensor, jit
def foo(x):
out1 = int(11.1)
out2 = int(Tensor([10]))
out3 = int(x.asnumpy())
return out1, out2, out3
res = foo(Tensor(2))
print("res[0]:", res[0])
print("res[1]:", res[1])
print("res[2]:", res[2])
结果如下:
res[0]: 11
res[1]: 10
res[2]: 2
支持返回Number类型。例如:
import mindspore as ms
@ms.jit
def test_return_scalar(x, y):
return x + y
res = test_return_scalar(ms.mutable(1), ms.mutable(2))
print(res)
String
支持在网络里构造String
,即支持使用引号('
或"
)来创建字符串,如x = 'abcd'
或y = "efgh"
。可以通过str()
的方式进行将常量转换成字符串。支持对字符串连接,截取,以及使用成员运算符(in
或not in
)判断字符串是否包含指定的字符。支持格式化字符串的输出,将一个值插入到一个有字符串格式符%s
的字符串中。支持在常量场景下使用格式化字符串函数str.format()
。
from mindspore import jit
def foo():
var1 = 'Hello!'
var2 = "MindSpore"
var3 = str(123)
var4 = "{} is {}".format("string", var3)
return var1[0], var2[4:9], var1 + var2, var2 * 2, "H" in var1, "My name is %s!" % var2, var4
res = foo()
print("res:", res)
结果如下:
res: ('H', 'Spore', 'Hello!MindSpore', 'MindSporeMindSpore', True, 'My name is MindSpore!', 'string is 123')
List
在JIT_SYNTAX_LEVEL
设置为LAX
的情况下,静态图模式可以支持部分List
对象的inplace操作,具体介绍详见支持列表就地修改操作章节。
List
的基础使用场景如下:
图模式支持图内创建List
。
支持在图模式内创建List
对象,且List
内对象的元素可以包含任意图模式支持的类型,也支持多层嵌套。例如:
import numpy as np
import mindspore as ms
@ms.jit
def generate_list():
a = [1, 2, 3, 4]
b = ["1", "2", "a"]
c = [ms.Tensor([1]), ms.Tensor([2])]
d = [a, b, c, (4, 5)]
return d
上述示例代码中,所有的List
对象都可以被正常的创建。
图模式支持返回List
。
在MindSpore2.0版本之前,当图模式返回List
对象时,List
会被转换为Tuple
。MindSpore2.0版本已经可以支持返回List
对象。例如:
import mindspore as ms
@ms.jit
def list_func():
a = [1, 2, 3, 4]
return a
output = list_func() # output: [1, 2, 3, 4]
与图模式内创建List
相同,图模式返回List
对象可以包括任意图模式支持的类型,也支持多层嵌套。
图模式支持从全局变量中获取List
对象。
import mindspore as ms
global_list = [1, 2, 3, 4]
@ms.jit
def list_func():
global_list.reverse()
return global_list
output = list_func() # output: [4, 3, 2, 1]
需要注意的是,在基础场景下图模式返回的列表与全局变量的列表不是同一个对象,当JIT_SYNTAX_LEVEL
设置为LAX
时,返回的对象与全局对象为统一对象。
图模式支持以List
作为输入。
图模式支持List
作为静态图的输入,作为输入的List
对象的元素必须为图模式支持的输入类型,也支持多层嵌套。
import mindspore as ms
list_input = [1, 2, 3, 4]
@ms.jit
def list_func(x):
return x
output = list_func(list_input) # output: [1, 2, 3, 4]
需要注意的是,List
作为静态图输入时,无论其内部的元素是什么类型,一律被视为常量。
图模式支持List的内置方法。
List
内置方法的详细介绍如下:
List索引取值
基础语法:element = list_object[index]
。
基础语义:将List
对象中位于第index
位的元素提取出来(index
从0开始)。支持多层索引取值。
索引值index
支持类型包括int
,Tensor
和slice
。其中,int
以及Tensor
类型的输入可以支持常量以及变量,slice
内部数据必须为编译时能够确定的常量。
示例如下:
import mindspore as ms
@ms.jit()
def list_getitem_func():
x = [[1, 2], 3, 4]
a = x[0]
b = x[0][ms.Tensor([1])]
c = x[1:3:1]
return a, b, c
a, b, c = list_getitem_func()
print('a:{}'.format(a))
print('b:{}'.format(b))
print('c:{}'.format(c))
结果如下:
a:[1, 2]
c:[3, 4]
List索引赋值
基础语法:list_object[index] = target_element
。
基础语义:将List
对象中位于第index
位的元素赋值为 target_element
(index
从0开始)。支持多层索引赋值。
索引值index
支持类型包括int
,Tensor
和slice
。其中,int
以及Tensor
类型的输入可以支持常量以及变量,slice
内部数据必须为编译时能够确定的常量。
索引赋值对象target_element
支持所有图模式支持的数据类型。
目前,List
索引赋值不支持inplace操作, 索引赋值后将会生成一个新的对象。该操作后续将会支持inplace操作。
示例如下:
import mindspore as ms
@ms.jit()
def test_setitem_func():
x = [[0, 1], 2, 3, 4]
x[1] = 10
x[2] = "ok"
x[3] = (1, 2, 3)
x[0][1] = 88
return x
output = test_setitem_func()
print('output:{}'.format(output))
结果如下:
output:[[0, 88], 10, 'ok', (1, 2, 3)]
List.append
基础语法:list_object.append(target_element)
。
基础语义:向List
对象list_object
的最后追加元素target_element
。
目前,List.append
不支持inplace操作, 索引赋值后将会生成一个新的对象。该操作后续将会支持inplace操作。
示例如下:
import mindspore as ms
@ms.jit()
def test_list():
x = [1, 2, 3]
x.append(4)
return x
x = test_list()
print('x:{}'.format(x))
结果如下:
x:[1, 2, 3, 4]
List.clear
基础语法:list_object.clear()
。
基础语义:清空List
对象 list_object
中包含的元素。
目前,List.clear
不支持inplace, 索引赋值后将会生成一个新的对象。该操作后续将会支持inplace。
示例如下:
import mindspore as ms
@ms.jit()
def test_list_clear():
x = [1, 3, 4]
x.clear()
return x
x = test_list_clear()
print('x:{}'.format(x))
结果如下:
List.extend
基础语法:list_object.extend(target)
。
基础语义:向List
对象list_object
的最后依次插入target
内的所有元素。
target
支持的类型为Tuple
,List
以及Tensor
。其中,如果target
类型为Tensor
的情况下,会先将该Tensor
转换为List
,再进行插入操作。
示例如下:
import mindspore as ms
@ms.jit()
def test_list_extend():
x1 = [1, 2, 3]
x1.extend((4, "a"))
x2 = [1, 2, 3]
x2.extend(ms.Tensor([4, 5]))
return x1, x2
output1, output2 = test_list_extend()
print('output1:{}'.format(output1))
print('output2:{}'.format(output2))
结果如下:
output1:[1, 2, 3, 4, 'a']
output2:[1, 2, 3, Tensor(shape=[1], dtype=Int64, value= [4]), Tensor(shape=[1], dtype=Int64, value= [5])]
List.pop
基础语法:pop_element = list_object.pop(index=-1)
。
基础语义:将List
对象list_object
的第index
个元素从list_object
中删除,并返回该元素。
index
要求必须为常量int
, 当list_object
的长度为list_obj_size
时,index
的取值范围为:[-list_obj_size,list_obj_size-1]
。index
为负数,代表从后往前的位数。当没有输入index
时,默认值为-1,即删除最后一个元素。
import mindspore as ms
@ms.jit()
def test_list_pop():
x = [1, 2, 3]
b = x.pop()
return b, x
pop_element, res_list = test_list_pop()
print('pop_element:{}'.format(pop_element))
print('res_list:{}'.format(res_list))
结果如下:
pop_element:3
res_list:[1, 2]
List.reverse
基础语法:list_object.reverse()
。
基础语义:将List
对象list_object
的元素顺序倒转。
示例如下:
import mindspore as ms
@ms.jit()
def test_list_reverse():
x = [1, 2, 3]
x.reverse()
return x
output = test_list_reverse()
print('output:{}'.format(output))
结果如下:
output1:[3, 2, 1]
List.insert
基础语法:list_object.insert(index, target_obj)
。
基础语义:将target_obj
插入到list_object
的第index
位。
index
要求必须为常量int
。如果list_object
的长度为list_obj_size
。当index < -list_obj_size
时,插入到List
的第一位。当index >= list_obj_size
时,插入到List
的最后。index
为负数代表从后往前的位数。
示例如下:
import mindspore as ms
@ms.jit()
def test_list_insert():
x = [1, 2, 3]
x.insert(3, 4)
return x
output = test_list_insert()
print('output:{}'.format(output))
结果如下:
output:[1, 2, 3, 4]
Tuple
支持在网络里构造元组Tuple
,使用小括号包含元素,即支持语法y = (1, 2, 3)
。元组Tuple
的元素不能修改,但支持索引访问元组Tuple
中的元素,支持对元组进行连接组合。
支持索引取值。
支持使用方括号加下标索引的形式来访问元组Tuple
中的元素,索引值支持int
、slice
、Tensor
,也支持多层索引取值,即支持语法data = tuple_x[index0][index1]...
。
索引值为Tensor
有如下限制:
Tuple
里存放的都是Cell
,每个Cell
要在Tuple
定义之前完成定义,每个Cell
的入参个数、入参类型和入参shape
要求一致,每个Cell
的输出个数、输出类型和输出shape
也要求一致。
索引Tensor
是一个dtype
为int32
的标量Tensor
,取值范围在[-tuple_len, tuple_len)
,Ascend
后端不支持负数索引。
支持CPU
、GPU
和Ascend
后端。
int
、slice
索引示例如下:
import numpy as np
import mindspore as ms
t = ms.Tensor(np.array([1, 2, 3]))
@ms.jit()
def test_index():
x = (1, (2, 3, 4), 3, 4, t)
y = x[1][1]
z = x[4]
m = x[1:4]
n = x[-4]
return y, z, m, n
y, z, m, n = test_index()
print('y:{}'.format(y))
print('z:{}'.format(z))
print('m:{}'.format(m))
print('n:{}'.format(n))
结果如下:
z:[1 2 3]
m:((2, 3, 4), 3, 4)
n:(2, 3, 4)
Tensor
索引示例如下:
import mindspore as ms
from mindspore import nn, set_context
set_context(mode=ms.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.relu = nn.ReLU()
self.softmax = nn.Softmax()
self.layers = (self.relu, self.softmax)
def construct(self, x, index):
ret = self.layers[index](x)
return ret
x = ms.Tensor([-1.0], ms.float32)
net = Net()
ret = net(x, 0)
print('ret:{}'.format(ret))
结果如下:
ret:[0.]
支持连接组合。
与字符串String
类似,元组支持使用+
和*
进行组合,得到一个新的元组Tuple
,例如:
import mindspore as ms
@ms.jit()
def test_index():
x = (1, 2, 3)
y = (4, 5, 6)
return x + y, x * 2
out1, out2 = test_index()
print('out1:{}'.format(out1))
print('out2:{}'.format(out2))
结果如下:
out1:(1, 2, 3, 4, 5, 6)
out2:(1, 2, 3, 1, 2, 3)
Dictionary
支持在网络里构造字典Dictionary
,每个键值key:value
用冒号:
分割,每个键值对之间用逗号,
分割,整个字典使用大括号{}
包含键值对,即支持语法y = {"a": 1, "b": 2}
。
键key
是唯一的,如果字典中存在多个相同的key
,则重复的key
以最后一个作为最终结果;而值value
可以不是唯一的。键key
需要保证是不可变的。当前键key
支持String
、Number
、常量Tensor
以及只包含这些类型对象的Tuple
;值value
支持Number
、Tuple
、Tensor
、List
、Dictionary
和None
。
支持接口。
keys
:取出dict
里所有的key
值,组成Tuple
返回。
values
:取出dict
里所有的value
值,组成Tuple
返回。
items
:取出dict
里每一对key
和value
组成的Tuple
,最终组成List
返回。
get
:dict.get(key[, value])
返回指定key
对应的value
值,如果指定key
不存在,返回默认值None
或者设置的默认值value
。
clear
:删除dict
里所有的元素。
has_key
:dict.has_key(key)
判断dict
里是否存在指定key
。
update
:dict1.update(dict2)
把dict2
中的元素更新到dict1
中。
fromkeys
:dict.fromkeys(seq([, value]))
用于创建新的Dictionary
,以序列seq
中的元素做Dictionary
的key
,value
为所有key
对应的初始值。
示例如下,其中返回值中的x
和new_dict
是一个Dictionary
,在图模式JIT语法支持级别选项为LAX下扩展支持,更多Dictionary的高阶使用请参考本文的支持Dictionary的高阶用法章节。
import mindspore as ms
import numpy as np
x = {"a": ms.Tensor(np.array([1, 2, 3])), "b": ms.Tensor(np.array([4, 5, 6])), "c": ms.Tensor(np.array([7, 8, 9]))}
@ms.jit()
def test_dict():
x_keys = x.keys()
x_values = x.values()
x_items = x.items()
value_a = x.get("a")
check_key = x.has_key("a")
y = {"a": ms.Tensor(np.array([0, 0, 0]))}
x.update(y)
new_dict = x.fromkeys("abcd", 123)
return x_keys, x_values, x_items, value_a, check_key, x, new_dict
x_keys, x_values, x_items, value_a, check_key, new_x, new_dict = test_dict()
print('x_keys:{}'.format(x_keys))
print('x_values:{}'.format(x_values))
print('x_items:{}'.format(x_items))
print('value_a:{}'.format(value_a))
print('check_key:{}'.format(check_key))
print('new_x:{}'.format(new_x))
print('new_dict:{}'.format(new_dict))
结果如下:
x_keys:('a', 'b', 'c')
x_values:(Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), Tensor(shape=[3], dtype=Int64, value= [4, 5, 6]), Tensor(shape=[3], dtype=Int64, value= [7, 8, 9]))
x_items:[('a', Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])), ('b', Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])), ('c', Tensor(shape=[3], dtype=Int64, value= [7, 8, 9]))]
value_a:[1 2 3]
check_key:True
new_x:{'a': Tensor(shape=[3], dtype=Int64, value= [0, 0, 0]), 'b': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6]), 'c': Tensor(shape=[3], dtype=Int64, value= [7, 8, 9])}
new_dict:{'a': 123, 'b': 123, 'c': 123, 'd': 123}
Tensor
Tensor的属性与接口详见Tensor API文档。
支持在静态图模式下创建和使用Tensor。创建方式有使用tensor函数接口和使用Tensor
类接口。推荐使用tensor函数接口,用户可以使用指定所需要的dtype类型。代码用例如下。
import mindspore as ms
import mindspore.nn as nn
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
@ms.jit
def construct(self, x):
return ms.tensor(x.asnumpy(), dtype=ms.float32)
ms.set_context(mode=ms.GRAPH_MODE)
net = Net()
x = ms.Tensor(1, dtype=ms.int32)
print(net(x))
示例如下:
import mindspore as ms
from mindspore import nn, ops, Tensor, set_context
import numpy as np
set_context(mode=ms.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super().__init__()
def construct(self, x):
reduce_sum = ops.ReduceSum(True) #支持在construct里构造`Primitive`及其子类的实例
ret = reduce_sum(x, axis=2)
return ret
x = Tensor(np.random.randn(3, 4, 5, 6).astype(np.float32))
net = Net()
ret = net(x)
print('ret.shape:{}'.format(ret.shape))
上面所定义的网络里,reduce_sum(x, axis=2)的参数不支持通过键值对方式传入,只能通过位置参数方式传入,即reduce_sum(x, 2)。
结果报错如下:
ValueError: For 'ReduceSum', the second input type should be tensor or scalar, but got invalid abstract type:AbstractKeywordArg.
当前不支持在网络调用Primitive
及其子类相关属性和接口。
当前已定义的Primitive
详见Primitive API文档。
Cell
当前支持在网络里构造Cell
及其子类的实例,即支持语法cell = Cell(args...)
。
但在调用时,参数只能通过位置参数方式传入,不支持通过键值对方式传入,即不支持在语法cell = Cell(arg_name=value)
。
当前不支持在网络调用Cell
及其子类相关属性和接口,除非是在Cell
自己的construct
中通过self
调用。
Cell
定义详见Cell API文档。
Parameter
Parameter
是变量张量,代表在训练网络时,需要被更新的参数。
Parameter
的定义和使用详见Parameter API文档。
该属性在Cell的__init__
函数中完成初始化且其为Parameter类型。
在JIT语法支持级别选项为LAX
时,可以支持更多情况的属性修改,具体详见支持属性设置与修改。
示例如下:
import mindspore as ms
from mindspore import nn, set_context
set_context(mode=ms.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super().__init__()
self.weight = ms.Parameter(ms.Tensor(3, ms.float32), name="w")
self.m = 2
def construct(self, x, y):
self.weight = x # 满足条件可以修改
# self.m = 3 # self.m 非Parameter类型禁止修改
# y.weight = x # y不是self,禁止修改
return x
net = Net()
ret = net(1, 2)
print('ret:{}'.format(ret))
结果如下:
ret:1
索引取值
对序列Tuple
、List
、Dictionary
、Tensor
的索引取值操作(Python称为抽取)。
Tuple
的索引取值请参考本文的Tuple章节。
List
的索引取值请参考本文的List章节。
Dictionary
的索引取值请参考本文的Dictionary章节。
Tensor
的索引取详见Tensor 索引取值文档。
所谓调用就是附带可能为空的一系列参数来执行一个可调用对象(例如:Cell
、Primitive
)。
示例如下:
import mindspore as ms
from mindspore import nn, ops, set_context
import numpy as np
set_context(mode=ms.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super().__init__()
self.matmul = ops.MatMul()
def construct(self, x, y):
out = self.matmul(x, y) # Primitive调用
return out
x = ms.Tensor(np.ones(shape=[1, 3]), ms.float32)
y = ms.Tensor(np.ones(shape=[3, 4]), ms.float32)
net = Net()
ret = net(x, y)
print('ret:{}'.format(ret))
结果如下:
ret:[[3. 3. 3. 3.]]
当前静态图模式支持部分Python语句,包括raise语句、assert语句、pass语句、return语句、break语句、continue语句、if语句、for语句、while语句、with语句、列表生成式、生成器表达式、函数定义语句等,详见Python语句。
Python内置函数
当前静态图模式支持部分Python内置函数,其使用方法与对应的Python内置函数类似,详见Python内置函数。
网络定义
网络入参
在对整网入参求梯度的时候,会忽略非Tensor
的入参,只计算Tensor
入参的梯度。
示例如下。整网入参(x, y, z)
中,x
和z
是Tensor
,y
是非Tensor
。因此,grad_net
在对整网入参(x, y, z)
求梯度的时候,会自动忽略y
的梯度,只计算x
和z
的梯度,返回(grad_x, grad_z)
。
import numpy as np
import mindspore as ms
from mindspore import nn
ms.set_context(mode=ms.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
def construct(self, x, y, z):
return x + y + z
class GradNet(nn.Cell):
def __init__(self, net):
super(GradNet, self).__init__()
self.forward_net = net
def construct(self, x, y, z):
return ms.grad(self.forward_net, grad_position=(0, 1, 2))(x, y, z)
input_x = ms.Tensor([1])
input_y = 2
input_z = ms.Tensor([3])
net = Net()
grad_net = GradNet(net)
ret = grad_net(input_x, input_y, input_z)
print('ret:{}'.format(ret))
结果如下:
ret:(Tensor(shape=[1], dtype=Int64, value= [1]), Tensor(shape=[1], dtype=Int64, value= [1]))
图模式下的执行图是从源码转换而来,并不是所有的Python语法都能支持。下面介绍在基础语法下存在的一些语法约束。更多网络编译问题可见网络编译。
当construct
函数里,使用未定义的类成员时,将抛出AttributeError
异常。示例如下:
import mindspore as ms
from mindspore import nn, set_context
set_context(mode=ms.GRAPH_MODE)
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
def construct(self, x):
return x + self.y
net = Net()
net(1)
结果报错如下:
AttributeError: External object has no attribute y
nn.Cell
不支持classmethod
修饰的类方法。示例如下:
import mindspore as ms
ms.set_context(mode=ms.GRAPH_MODE)
class Net(ms.nn.Cell):
@classmethod
def func(cls, x, y):
return x + y
def construct(self, x, y):
return self.func(x, y)
net = Net()
out = net(ms.Tensor(1), ms.Tensor(2))
print(out)
结果报错如下:
TypeError: The parameters number of the function is 3, but the number of provided arguments is 2.
在图模式下,有些Python语法难以转换成图模式下的中间表示MindIR。对标Python的关键字,存在部分关键字在图模式下是不支持的:AsyncFunctionDef、Delete、AnnAssign、AsyncFor、AsyncWith、Match、Try、Import、ImportFrom、Nonlocal、NamedExpr、Set、SetComp、Await、Yield、YieldFrom、Starred。如果在图模式下使用相关的语法,将会有相应的报错信息提醒用户。
如果使用Try语句,示例如下:
import mindspore as ms
@ms.jit
def test_try_except(x, y):
global_out = 1
try:
global_out = x / y
except ZeroDivisionError:
print("division by zero, y is zero.")
return global_out
test_try_except_out = test_try_except(1, 0)
print("out:", test_try_except_out)
结果报错如下:
RuntimeError: Unsupported statement 'Try'.
对标Python内置数据类型,除去当前图模式下支持的Python内置数据类型,复数complex
和集合set
类型是不支持的。列表list
和字典dictionary
的一些高阶用法在基础语法场景下是不支持的,需要在JIT语法支持级别选项jit_syntax_level
为LAX
时才支持,更多请参考本文的扩展语法(LAX级别)章节。
对标Python的内置函数,在基础语法场景下,除去当前图模式下支持的Python内置函数,仍存在部分内置函数在图模式下是不支持的,例如:basestring、bin、bytearray、callable、chr、cmp、compile、 delattr、dir、divmod、eval、execfile、file、frozenset、hash、hex、id、input、issubclass、iter、locals、long、memoryview、next、object、oct、open、ord、property、raw_input、reduce、reload、repr、reverse、set、slice、sorted、unichr、unicode、vars、xrange、__import__。
Python提供了很多第三方库,通常需要通过import语句调用。在图模式下JIT语法支持级别为STRICT时,不能直接使用第三方库。如果需要在图模式下使用第三方库的数据类型或者调用第三方库的方法,需要在JIT语法支持级别选项jit_syntax_level
为LAX
时才支持,更多请参考本文的扩展语法(LAX级别)中的调用第三方库章节。
在图模式下JIT语法支持级别为STRICT时,不能直接使用自定义类的对象,属性和方法。如果需要在图模式下使用自定义类的信息,更多请参考本文的扩展语法(LAX级别)中的支持自定义类的使用章节。
import mindspore as ms
ms.set_context(mode=ms.GRAPH_MODE, jit_syntax_level=ms.STRICT)
class GetattrClass():
def __init__(self):
self.attr1 = 99
self.attr2 = 1
def method1(self, x):
return x + self.attr2
class GetattrClassNet(ms.nn.Cell):
def __init__(self):
super(GetattrClassNet, self).__init__()
self.cls = GetattrClass()
def construct(self):
return self.cls.method1(self.cls.attr1)
net = GetattrClassNet()
out = net()
assert out == 100
将会有相关报错:
TypeError: Do not support to convert <class '__main__.GetattrClass'> object into graph node.
Python内置模块和Python标准库。例如os
、sys
、math
、time
等模块。
第三方代码库。路径在Python安装目录的site-packages
目录下,需要先安装后导入,例如NumPy
、SciPy
等。需要注意的是,mindyolo
、mindflow
等MindSpore套件不被视作第三方库。
通过环境变量MS_JIT_IGNORE_MODULES
指定的模块。与之相对的有环境变量MS_JIT_MODULES
,具体使用方法请参考环境变量。
支持第三方库的数据类型,允许调用和返回第三方库的对象。
示例如下:
import numpy as np
import mindspore as ms
@ms.jit
def func():
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
out = a + b
return out
print(func())
结果如下: