Constraints on Network Construction Using Python
Linux
Ascend
GPU
CPU
Model Development
Beginner
Intermediate
Expert
Overview
MindSpore can compile user source code based on the Python syntax into computational graphs, and can convert common functions or instances inherited from nn.Cell into computational graphs. Currently, MindSpore does not support conversion of any Python source code into computational graphs. Therefore, there are constraints on source code compilation, including syntax constraints and network definition constraints. As MindSpore evolves, the constraints may change.
Syntax Constraints
Supported Python Data Types
Number: supports
int
,float
, andbool
. Complex numbers are not supported.String
List: supports the append method only. Updating a list will generate a new list.
Tuple
Dictionary: The type of key should be String.
MindSpore Extended Data Type
Tensor: Tensor variables must be defined instances.
Expression Types
Operation |
Description |
---|---|
Unary operator |
|
Binary operator |
|
|
For example, |
Comparison expression |
|
Logical expression |
|
|
For example, |
Reserved keyword type |
|
Statement Types
Statement |
Compared with Python |
---|---|
|
Same as that in Python. |
|
Nested for loops are partially supported. Iteration sequences must be tuples or lists. |
|
Nested while loops are partially supported. Grad of net with while is not supported. |
|
Same as that in Python. |
|
Same as that in Python. The input of the |
|
Only supports judging whether constants exist in Tuple/List/Dictionary whose elements are all constants. |
|
Only support Dictionary. |
|
Only support |
|
Only support |
Assignment statement |
Accessed multiple subscripts of lists and dictionaries cannot be used as l-value. |
System Functions/Classes
Functions/Class |
Compared with Python |
---|---|
|
The usage principle is consistent with Python, and the returned result is consistent with Python, returning int. |
|
The usage principle is consistent with Python, and the returned result is inconsistent with Python, returning function. |
|
The usage principle is consistent with Python, and the returned result is inconsistent with Python, returning tuple. |
|
The usage principle is consistent with Python, and the returned result is inconsistent with Python, returning tuple. |
|
The usage principle is consistent with Python, and the returned result is inconsistent with Python, returning tuple. |
|
The usage principle is consistent with Python, and the returned result is inconsistent with Python, returning tuple. |
|
The usage principle is consistent with Python, and the returned result is inconsistent with Python, returning the namespace defined by mindspore. |
|
The usage principle is consistent with Python, but the second input parameter can only be the type defined by mindspore. |
Function Parameters
Default parameter value: The data types
int
,float
,bool
,None
,str
,tuple
,list
, anddict
are supported, whereasTensor
is not supported.Variable parameter: Functions with variable arguments is supported for training and inference.
Key-value pair parameter: Functions with key-value pair parameters cannot be used for backward propagation on computational graphs.
Variable key-value pair parameter: Functions with variable key-value pairs cannot be used for backward propagation on computational graphs.
Operators
Operator |
Supported Type |
---|---|
|
Scalar, |
|
Scalar and |
|
Scalar and |
|
Scalar and |
|
Scalar and |
|
Scalar and |
|
Scalar and |
|
The operation object type can be |
Index operation
The index operation includes tuple
and Tensor
. The following focuses on the index value assignment and assignment operation of Tensor
. The value takestensor_x [index]
as an example, and the assignment takes tensor_x [index] = u
as an example for detailed description. Among them, tensor_x is a Tensor
, which is sliced; index means the index, u means the assigned value, which can be scalar
or Tensor (size = 1)
. The index types are as follows:
Slice index: index is
slice
Value:
tensor_x[start: stop: step]
, where Slice (start: stop: step) has the same syntax as Python, and will not be repeated here.Assignment:
tensor_x[start: stop: step] = u
.
Ellipsis index: index is
ellipsis
Value:
tensor_x [...]
.Assignment:
tensor_x [...] = u
.
Boolean constant index: index is
True
, index isFalse
is not supported temporarily.Value:
tensor_x[True]
.Assignment: Not supported yet.
Tensor index: index is
Tensor
Value:
tensor_x [index]
,index
must beTensor
of data typeint32
orint64
, the element value range is[0, tensor_x.shape[0])
.Assignment:
tensor_x [index] = U
.tensor_x
data type must be one of the following:float16
,float32
,int8
,uint8
.index
must beTensor
of data typeint32
, the element value range is[0, tensor_x.shape [0])
.U
can beNumber
,Tensor
,Tuple
only containingNumber
,Tuple
only containingTensor
.Single
Number
or everyNumber
inTuple
must be the same type astensor_x
, ie When the data type oftensor_x
isuint8
orint8
, theNumber
type should beint
; When the data type oftensor_x
isfloat16
orfloat32
, theNumber
type should befloat
.Single
Tensor
or everyTensor in Tuple
must be consistent with the data type oftensor_x
, when singleTensor
, theshape
should be equal to or broadcast asindex.shape + tensor_x.shape [1:]
.Tuple
containingNumber
must meet requirement:len (Tuple) = (index.shape + tensor_x.shape [1:]) [-1]
.Tuple
containingTensor
must meet requirements: theshape
of eachTensor
should be the same,(len (Tuple),) + Tensor.shape
should be equal to or broadcast asindex.shape + tensor_x.shape [1:]
.
None constant index: index is
None
Value:
tensor_x[None]
, results are consistent with numpy.Assignment: Not supported yet.
tuple index: index is
tuple
The tuple element is a slice:
Value: for example
tensor_x[::,: 4, 3: 0: -1]
.Assignment: for example
tensor_x[::,: 4, 3: 0: -1] = u
.
The tuple element is Number:
Value: for example
tensor_x[2,1]
.Assignment: for example
tensor_x[1,4] = u
.
The tuple element is a mixture of slice and ellipsis:
Value: for example
tensor_x[..., ::, 1:]
.Assignment: for example
tensor_x[..., ::, 1:] = u
.
Not supported in other situations
The index value operation of tuple and list type, we need to focus on the index value operation of tuple or list whose element type is nn.Cell
. This operation is currently only supported by the GPU backend in Graph mode, and its syntax format is like layers[index](*inputs)
, the example code is as follows:
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):
x = self.layers[index](x)
return x
The grammar has the following constraints:
Only the index value operation of tuple or list whose element type is
nn.Cell
is supported.The index is a scalar
Tensor
of typeint32
, with a value range of[-n, n)
, wheren
is the size of the tuple, and the maximum supported tuple size is 1000.The number, type and shape of the input data of the
Construct
function of each Cell element in the tuple are the same, and the number of data output after theConstruct
function runs, the type and shape are also the same.Each element in the tuple needs to be defined before the tuple is defined.
This syntax does not support running branches as if, while, for and other control flow, except if the control condition of the control flow is constant. for example:
Supported example:
class Net(nn.Cell): def __init__(self, flag=True): super(Net, self).__init__() self.flag = flag self.relu = nn.ReLU() self.softmax = nn.Softmax() self.layers = (self.relu, self.softmax) def construct(self, x, index): if self.flag: x = self.layers[index](x) return x
Unsupported example:
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, flag): if flag: x = self.layers[index](x) return x
Tuple also support slice value operations, but do not support slice type as Tensor, support tuple_x [start: stop: step]
, which has the same effect as Python, and will not be repeated here.
Unsupported Syntax
Currently, the following syntax is not supported in network constructors:
raise
, yield
, async for
, with
, async with
, assert
, import
, and await
.
Network Definition Constraints
Instance Types on the Entire Network
Common Python function with the @ms_function decorator.
Cell subclass inherited from nn.Cell.
Network Input Type
The training data input parameters of the entire network must be of the Tensor type.
The generated ANF diagram cannot contain the following constant nodes: string constants, constants with nested tuples, and constants with nested lists.
Network Graph Optimization
During graph optimization at the ME frontend, the dataclass, dictionary, list, and key-value pair types are converted to tuple types, and the corresponding operations are converted to tuple operations.
Network Construction Components
Category |
Content |
---|---|
|
mindspore/nn/*, and custom Cell. |
Member function of a |
Member functions of other classes in the construct function of Cell can be called. |
Function |
Custom Python functions and system functions listed in the preceding content. |
Dataclass instance |
Class decorated with @dataclass. |
Primitive operator |
|
Composite operator |
|
Operator generated by constexpr |
Uses the value generated by @constexpr to calculate operators. |
Other Constraints
Input parameters of the
construct
function on the entire network and parameters of functions modified by thems_function
decorator are generalized during the graph compilation and cannot be passed to operators as constant input. Therefore, in graph mode, the parameter passed to the entry network can only beTensor
. As shown in the following example:The following is an example of incorrect input:
class ExpandDimsTest(Cell): def __init__(self): super(ExpandDimsTest, self).__init__() self.expandDims = ops.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)
In the example,
ExpandDimsTest
is a single-operator network with two inputs:input_x
andinput_axis
. The second input of theExpandDims
operator must be a constant. This is becauseinput_axis
is required when the output dimension of theExpandDims
operator is deduced during graph compilation. As the network parameter input, the value ofinput_axis
is generalized into a variable and cannot be determined. As a result, the output dimension of the operator cannot be deduced, causing the graph compilation failure. Therefore, the input required by deduction in the graph compilation phase must be a constant. In the API, the parameters of this type of operator that require constant input will be explained, markedconst input is needed
.Directly enter the needed value or a member variable in a class for the constant input of the operator in the construct function. The following is an example of correct input:
class ExpandDimsTest(Cell): def __init__(self, axis): super(ExpandDimsTest, self).__init__() self.expandDims = ops.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)
It is not allowed to modify
non-Parameter
type data members of the network. Examples are as follows:class Net(Cell): def __init__(self): super(Net, self).__init__() self.num = 2 self.par = Parameter(Tensor(np.ones((2, 3, 4))), name="par") def construct(self, x, y): return x + y
In the network defined above,
self.num
is not aParameter
and cannot be modified, butself.par
is aParameter
and can be modified.When an undefined class member is used in the
construct
function, it will be treated asNone
instead of throwingAttributeError
like the Python interpreter. Examples are as follows:class Net(Cell): def __init__(self): super(Net, self).__init__() def construct(self, x): return x + self.y
In the network defined above, the undefined class member
self.y
is used inconstruct
, andself.y
will be treated asNone
.