Created by: Aurelius84
In this PR, IsControlFlowIfVisitor
is added to distinguish if/else
is plain python statement or control_flow statement.
There are some case should be considered as control flow if/else
:
-
case 1:
if Tensor.numpy()[i] > 2
orif fluid.layers.XXX(x).numpy()[i] > 2
-
case 2:
if Tensor.shape[i] > 2
whereTensor.shape[i]
is-1
orNone
in compile time.
Currently, we firstly support control flow statement case 1:
- involve
Tensor.numpy()[i]
In case 2,Tensor.shape is unknown in gast and should be inferred by other method. Moreover, pred in ConditionalBlock require variable, which means all vars should be Tensor or transformed into Tensor, like fill_constant(shape=[1], dtype='int32', value=Tensor.shape[i]).
** Examples:**
# node is not ast.Compare
node = gast.parse("a + b")
is_control_flow_if(node) == False
# node is not ast.Compare
node = gast.parse("a + x.numpy()[1]")
is_control_flow_if(node) == False
# node is not dependent on Tensor
node = gast.parse("x is None")
is_control_flow_if(node) == False
# `is None` is not dependent on Tensor.data
node = gast.parse("fluid.layers.sum(x) is None")
is_control_flow_if(node) == False
node = gast.parse("fluid.layers.sum(x).numpy() != None")
is_control_flow_if(node) == False
# .numpy() is Dygraph api and return shape=[1] boolean
node = gast.parse("x.numpy()[1] > 1")
is_control_flow_if(node) == True
# complex statement, but include control flow `if` in sub_expr
node = gast.parse("x is not None and 1 < x.numpy()[1]")
is_control_flow_if(node) == True
node = gast.parse("1 < fluid.layers.sum(x).numpy()[2] or x+y < 0")
is_control_flow_if(node) == True
Advanced features will be implemented while we test in real models.