MindSpore完成从用户源码到计算图的编译,用户源码基于Python语法编写,当前MindSpore支持将普通函数或者继承自nn.Cell的实例转换生成计算图,暂不支持将任意Python源码转换成计算图,所以对于用户源码支持的写法有所限制,主要包括语法约束和网络定义约束两方面。随着MindSpore的演进,这些约束可能会发生变化。
int
、float
、bool
,不支持复数类型。key
只支持String类型操作名 | 具体操作 |
---|---|
一元操作符 |
+ 、- 、not ,其中+ 操作符只支持标量。 |
数学表达式 |
+ 、- 、* 、/ 、% 、** 、//
|
if 表达式 |
例如a = x if x < y else y 。 |
比较表达式 |
> 、>= 、< 、<= 、== 、!=
|
逻辑表达式 |
and 、 or
|
lambda 表达式 |
例如lambda x, y: x + y 。 |
保留关键字类型 |
True 、False 、None
|
语句 | 与Python对比 |
---|---|
for |
迭代序列必须是Tuple/List,部分嵌套场景支持。 |
while |
部分嵌套场景支持。 |
if |
与Python使用原则一致,但if条件的输入只支持常量。 |
in |
仅支持Dictionary |
not in |
仅支持Dictionary |
def |
相同。 |
赋值语句 | List和Dictionary的多重下标访问不支持作为左值。 |
Tensor
类型数据,支持int
、float
、bool
、None
、str
、tuple
、list
、dict
类型数据。运算符 | 支持类型 |
---|---|
+ |
标量、Tensor 、tuple 、string
|
- |
标量、Tensor
|
* |
标量、Tensor
|
/ |
标量、Tensor
|
** |
标量、Tensor
|
// |
标量、Tensor
|
% |
标量、Tensor
|
[] |
操作对象类型支持list 、tuple 、Tensor ,支持多重下标访问作为右值,但不支持多重下标访问作为左值,且索引类型不支持Tensor;Tuple、Tensor类型访问限制见切片操作中的说明。 |
索引操作包含tuple
和Tensor
的索引操作。下面重点介绍一下Tensor
的索引取值和赋值操作,取值以tensor_x[index]
为例,赋值以tensor_x[index] = u
为例进行详细说明。其中tensor_x是一个Tensor
,对其进行切片操作;index表示索引,u表示赋予的值,可以是scalar
或者Tensor(size=1)
。索引类型如下:
切片索引:index为slice
tensor_x[start:stop:step]
,其中Slice(start:stop:step)与Python的语法相同,这里不再赘述。tensor_x[start:stop:step]=u
。Ellipsis索引:index为ellipsis
tensor_x[...]
。tensor_x[...]=u
。布尔常量索引:index为True
,index为False
暂不支持。
tensor_x[True]
。Tensor索引:index为Tensor
tensor_x[index]
,index
必须是int32
、int64
类型的Tensor
,元素取值范围在[0, tensor_x.shape[0])
。tensor_x[index]=U
。
tensor_x
的数据类型必须是下面一种: float16
,float32
,int8
,uint8
。index
必须是int32
类型的Tensor
,元素取值范围在[0, tensor_x.shape[0])
。U
可以是Number
,Tensor
,只包含Number
的Tuple
,只包含Tensor
的Tuple
。
Number
和Tuple
里的每个Number
必须与tensor_x
的数据类型属于同一类,即
当tensor_x
的数据类型是uint8
或者int8
时,Number
类型应该是int
;
当tensor_x
的数据类型是float16
或者float32
时,Number
类型应该是float
。Tensor
和Tuple
里的每个Tensor
必须与tensor_x
的数据类型一致,
单个Tensor
时,其shape
需等于或者可广播为index.shape + tensor_x.shape[1:]
。Number
的Tuple
需满足下面条件:
len(Tuple) = (index.shape + tensor_x.shape[1:])[-1]
。Tensor
的Tuple
需满足下面条件:
每个Tensor
的shape
一样;
(len(Tuple),) + Tensor.shape
等于或者可广播为index.shape + tensor_x.shape[1:]
。None常量索引:index为None
tensor_x[None]
,结果与numpy保持一致。tuple索引:index为tuple
tensor_x[::, :4, 3:0:-1]
。tensor_x[::, :4, 3:0:-1]=u
。tensor_x[2,1]
。tensor_x[1,4]=u
。tensor_x[..., ::, 1:]
tensor_x[..., ::, 1:]=u
另外tuple也支持切片取值操作,tuple_x[start:stop:step]
,与Python的效果相同,这里不再赘述。
目前在网络构造函数里面暂不支持以下语法:
raise
、 yield
、 async for
、 with
、 async with
、 assert
、 import
、 await
。
在ME前端图优化过程中,会将DataClass类型、Dictionary、List、键值对操作转换为Tuple相关操作。
类别 | 内容 |
---|---|
Cell 实例 |
mindspore/nn/*、自定义Cell。 |
Cell 实例的成员函数 |
Cell的construct中可以调用其他类成员函数。 |
函数 | 自定义Python函数、前文中列举的系统函数。 |
dataclass实例 | 使用@dataclass装饰的类。 |
Primitive算子 | mindspore/ops/operations/* |
Composite算子 | mindspore/ops/composite/* |
constexpr生成算子 | 使用@constexpr生成的值计算算子。 |
整网construct函数输入的参数以及使用ms_function装饰器修饰的函数的参数在图编译过程中会进行泛化,不能作为常量输入传给算子使用,如下例所示:
错误的写法如下:
class ExpandDimsTest(Cell):
def __init__(self):
super(ExpandDimsTest, self).__init__()
self.expandDims = P.ExpandDims()
def construct(self, input_x, input_axis):
return self.expandDims(input_x, input_axis)
expand_dim = ExpandDimsTest()
input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32))
expand_dim(input_x, 0)
在示例中,ExpandDimsTest是一个只有单算子的网络,网络的输入有input_x和input_axis两个。因为ExpandDims算子的第二个输入需要是常量,这是因为在图编译过程中推导ExpandDims算子输出维度的时候需要用到,而input_axis作为网络参数输入会泛化成变量,无法确定其值,从而无法推导算子的输出维度导致图编译失败。所以在图编译阶段需要值推导的输入都应该是常量输入。在API中,这类算子需要常量输入的参数会进行说明,标注"constant input is needed"。
正确的写法是在construct函数里面对算子的常量输入直接填入需要的值或者是一个类的成员变量,如下:
class ExpandDimsTest(Cell):
def __init__(self, axis):
super(ExpandDimsTest, self).__init__()
self.expandDims = P.ExpandDims()
self.axis = axis
def construct(self, input_x):
return self.expandDims(input_x, self.axis)
axis = 0
expand_dim = ExpandDimsTest(axis)
input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32))
expand_dim(input_x)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。