提交 5513df48 编写于 作者: M mindspore-ci-bot 提交者: Gitee

!731 doc(MindIR): Add MindIR specification

Merge pull request !731 from gongchen/mindir
设计文档
===========
.. toctree::
:maxdepth: 1
architecture
technical_white_paper
design/mindspore/distributed_training_design
design/mindinsight/profiler_design
design/mindinsight/training_visual_design
design/mindinsight/graph_visual_design
design/mindinsight/tensor_visual_design
design/mindarmour/differential_privacy_design
设计文档
===========
.. toctree::
:maxdepth: 1
architecture
technical_white_paper
design/mindspore/ir
design/mindspore/distributed_training_design
design/mindinsight/profiler_design
design/mindinsight/training_visual_design
design/mindinsight/graph_visual_design
design/mindinsight/tensor_visual_design
design/mindarmour/differential_privacy_design
digraph mindspore {
compound=true
subgraph cluster_0x8b8cc30{
id=cluster_0x8b8cc30
label="fibonacci[managed]"
fontname="Courier New"
node0x8bde4b0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]0)</td></tr>
</table>>,]
node0x8bee780_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td></tr>
<tr><td colspan='1' bgcolor='cornsilk'>CNode([CNode]1)</td></tr>
</table>>,]
node0x8bee900_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td><td port='3'>3</td></tr>
<tr><td colspan='4' bgcolor='cornsilk'>CNode([CNode]2)</td></tr>
</table>>,]
node0x8b702a0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]54)</td></tr>
</table>>,]
node0x8b6db30_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]37)</td></tr>
</table>>,]
node0x8bc0bb0_0[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b768b0_1[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>switch</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b6c9f0_2[fontname="Courier New",shape=oval,label="✓fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b91500",]
node0x8bd9410_3[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>Partial</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b85110_4[fontname="Courier New",shape=oval,label="✗fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8bda550",]
node0x8b7bab0_5[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,]
node0x8b76120_29[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>PrimitivePy</td></tr><tr><td>scalar_lt</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b7bab0_30[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,]
node0x8b90f50_31[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>1</td></tr></table>>,]
parameters_0x8b8cc30[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>n</td></tr></table>>,];}
subgraph cluster_0x8bda550{
id=cluster_0x8bda550
label="✗fibonacci[managed]"
fontname="Courier New"
node0x8b6acd0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]3)</td></tr>
</table>>,]
node0x8b6dff0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td></tr>
<tr><td colspan='1' bgcolor='cornsilk'>CNode([CNode]4)</td></tr>
</table>>,]
node0x8b7d410_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td><td port='3'>3</td></tr>
<tr><td colspan='4' bgcolor='cornsilk'>CNode([CNode]5)</td></tr>
</table>>,]
node0x8b83a80_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]55)</td></tr>
</table>>,]
node0x8b8c2a0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]35)</td></tr>
</table>>,]
node0x8b62c70_6[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8bbe5f0_7[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>switch</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b8a0f0_8[fontname="Courier New",shape=oval,label="✓✗fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b64c50",]
node0x8b8dbb0_9[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>Partial</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8bc0680_10[fontname="Courier New",shape=oval,label="✗✗fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8bedfe0",]
node0x8b76290_11[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,]
node0x8b90c20_24[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>PrimitivePy</td></tr><tr><td>scalar_eq</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b76290_25[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,]
node0x8b7da70_26[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>1</td></tr></table>>,]
parameters_0x8bda550[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>n</td></tr></table>>,];}
subgraph cluster_0x8bedfe0{
id=cluster_0x8bedfe0
label="✗✗fibonacci[managed]"
fontname="Courier New"
node0x8b8e4a0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]6)</td></tr>
</table>>,]
node0x8bb9b70_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]33)</td></tr>
</table>>,]
node0x8b7d610_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]8)</td></tr>
</table>>,]
node0x8beae20_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]31)</td></tr>
</table>>,]
node0x8b76cd0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]11)</td></tr>
</table>>,]
node0x8b849b0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]31)</td></tr>
</table>>,]
node0x8b85200_12[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b84310_13[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>PrimitivePy</td></tr><tr><td>scalar_add</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8bc14b0_14[fontname="Courier New",shape=oval,label="fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b8cc30",]
node0x8b8d2e0_15[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>PrimitivePy</td></tr><tr><td>scalar_sub</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8bbc810_16[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,]
node0x8b8d3d0_17[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>2</td></tr></table>>,]
node0x8bd5920_18[fontname="Courier New",shape=oval,label="fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b8cc30",]
node0x8bc15a0_19[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>PrimitivePy</td></tr><tr><td>scalar_sub</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8bbc810_20[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,]
node0x8b83990_21[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>1</td></tr></table>>,]
parameters_0x8bedfe0[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>n</td></tr></table>>,];}
subgraph cluster_0x8b64c50{
id=cluster_0x8b64c50
label="✓✗fibonacci[managed]"
fontname="Courier New"
node0x8be8e20_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]15)</td></tr>
</table>>,]
node0x8bd5440_22[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8b89ee0_23[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>1</td></tr></table>>,]
parameters_0x8b64c50[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr></table>>,];}
subgraph cluster_0x8b91500{
id=cluster_0x8b91500
label="✓fibonacci[managed]"
fontname="Courier New"
node0x8bdacb0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]18)</td></tr>
</table>>,]
node0x8b7d900_27[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x8bb9e90_28[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>0</td></tr></table>>,]
parameters_0x8b91500[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr></table>>,];}
node0x8bc0bb0_0:core->node0x8bde4b0_0:0[arrowhead=vee,style=dashed]
node0x8bee780_0:core->node0x8bde4b0_0:1[arrowhead=vee,]
node0x8bee900_0:core->node0x8bee780_0:0[arrowhead=vee,]
node0x8b768b0_1:core->node0x8bee900_0:0[arrowhead=vee,style=dashed]
node0x8b6db30_0:core->node0x8bee900_0:1[arrowhead=vee,]
node0x8b6c9f0_2->node0x8bee900_0:2[arrowhead=vee,]
node0x8b6c9f0_2->node0x8bdacb0_0[lhead=cluster_0x8b91500,dir=both,arrowhead=dot,style=filled,color=blue]
node0x8b702a0_0:core->node0x8bee900_0:3[arrowhead=vee,]
node0x8bd9410_3:core->node0x8b702a0_0:0[arrowhead=vee,style=dashed]
node0x8b85110_4->node0x8b702a0_0:1[arrowhead=vee,]
node0x8b85110_4->node0x8b6acd0_0[lhead=cluster_0x8bda550,dir=both,arrowhead=dot,style=filled,color=blue]
node0x8b7bab0_5->node0x8b702a0_0:2[arrowhead=vee,]
node0x8b62c70_6:core->node0x8b6acd0_0:0[arrowhead=vee,style=dashed]
node0x8b6dff0_0:core->node0x8b6acd0_0:1[arrowhead=vee,]
node0x8b7d410_0:core->node0x8b6dff0_0:0[arrowhead=vee,]
node0x8bbe5f0_7:core->node0x8b7d410_0:0[arrowhead=vee,style=dashed]
node0x8b8c2a0_0:core->node0x8b7d410_0:1[arrowhead=vee,]
node0x8b8a0f0_8->node0x8b7d410_0:2[arrowhead=vee,]
node0x8b8a0f0_8->node0x8be8e20_0[lhead=cluster_0x8b64c50,dir=both,arrowhead=dot,style=filled,color=blue]
node0x8b83a80_0:core->node0x8b7d410_0:3[arrowhead=vee,]
node0x8b8dbb0_9:core->node0x8b83a80_0:0[arrowhead=vee,style=dashed]
node0x8bc0680_10->node0x8b83a80_0:1[arrowhead=vee,]
node0x8bc0680_10->node0x8b8e4a0_0[lhead=cluster_0x8bedfe0,dir=both,arrowhead=dot,style=filled,color=blue]
node0x8b76290_11->node0x8b83a80_0:2[arrowhead=vee,]
node0x8b85200_12:core->node0x8b8e4a0_0:0[arrowhead=vee,style=dashed]
node0x8bb9b70_0:core->node0x8b8e4a0_0:1[arrowhead=vee,]
node0x8b84310_13:core->node0x8bb9b70_0:0[arrowhead=vee,style=dashed]
node0x8b76cd0_0:core->node0x8bb9b70_0:1[arrowhead=vee,]
node0x8b7d610_0:core->node0x8bb9b70_0:2[arrowhead=vee,]
node0x8bc14b0_14->node0x8b7d610_0:0[arrowhead=vee,style=dashed]
node0x8bc14b0_14->node0x8bde4b0_0[lhead=cluster_0x8b8cc30,dir=both,arrowhead=dot,style=filled,color=blue]
node0x8beae20_0:core->node0x8b7d610_0:1[arrowhead=vee,]
node0x8b8d2e0_15:core->node0x8beae20_0:0[arrowhead=vee,style=dashed]
node0x8bbc810_16->node0x8beae20_0:1[arrowhead=vee,]
node0x8b8d3d0_17:core->node0x8beae20_0:2[arrowhead=vee,]
node0x8bd5920_18->node0x8b76cd0_0:0[arrowhead=vee,style=dashed]
node0x8bd5920_18->node0x8bde4b0_0[lhead=cluster_0x8b8cc30,dir=both,arrowhead=dot,style=filled,color=blue]
node0x8b849b0_0:core->node0x8b76cd0_0:1[arrowhead=vee,]
node0x8bc15a0_19:core->node0x8b849b0_0:0[arrowhead=vee,style=dashed]
node0x8bbc810_20->node0x8b849b0_0:1[arrowhead=vee,]
node0x8b83990_21:core->node0x8b849b0_0:2[arrowhead=vee,]
node0x8bd5440_22:core->node0x8be8e20_0:0[arrowhead=vee,style=dashed]
node0x8b89ee0_23:core->node0x8be8e20_0:1[arrowhead=vee,]
node0x8b90c20_24:core->node0x8b8c2a0_0:0[arrowhead=vee,style=dashed]
node0x8b76290_25->node0x8b8c2a0_0:1[arrowhead=vee,]
node0x8b7da70_26:core->node0x8b8c2a0_0:2[arrowhead=vee,]
node0x8b7d900_27:core->node0x8bdacb0_0:0[arrowhead=vee,style=dashed]
node0x8bb9e90_28:core->node0x8bdacb0_0:1[arrowhead=vee,]
node0x8b76120_29:core->node0x8b6db30_0:0[arrowhead=vee,style=dashed]
node0x8b7bab0_30->node0x8b6db30_0:1[arrowhead=vee,]
node0x8b90f50_31:core->node0x8b6db30_0:2[arrowhead=vee,]
}
digraph mindspore {
compound=true
subgraph cluster_0x19e608f0{
id=cluster_0x19e608f0
label="ms_closure[managed]"
fontname="Courier New"
node0x19269490_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]0)</td></tr>
</table>>,]
node0x1976cf00_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]1)</td></tr>
</table>>,]
node0x1963d630_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode(out2)</td></tr>
</table>>,]
node0x196d87f0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode(closure)</td></tr>
</table>>,]
node0x196c2270_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode(out1)</td></tr>
</table>>,]
node0x19e328a0_0[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x19e5e7c0_1[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>DoSignaturePrimitive</td></tr><tr><td>S-Prim-make_tuple</td></tr><tr><td align='left'></td></tr></table>>,]
node0x19b6a3d0_2[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>2</td></tr></table>>,]
node0x19e68e20_3[fontname="Courier New",shape=oval,label="func_outer[func_outer]",style=filled,fillcolor=palegreen,URL="#cluster_0x19e63830",]
node0x19e38e00_4[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>1</td></tr></table>>,]
node0x19e23c10_5[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>2</td></tr></table>>,]
node0x19e1c020_14[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>1</td></tr></table>>,]
parameters_0x19e608f0[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr></table>>,];}
subgraph cluster_0x19e63830{
id=cluster_0x19e63830
label="func_outer[managed]"
fontname="Courier New"
node0x19e69550_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]5)</td></tr>
</table>>,]
node0x19e68f90_6[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x19e69100_7[fontname="Courier New",shape=oval,label="func_inner",style=filled,fillcolor=palegreen,URL="#cluster_0x19e64130",]
node0x19e035b0_12[fontname="Courier New",shape=octagon,label="a",style=filled,fillcolor=paleturquoise,]
node0x19e036b0_13[fontname="Courier New",shape=octagon,label="b",style=filled,fillcolor=paleturquoise,]
parameters_0x19e63830[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>a</td></tr><tr><td>b</td></tr></table>>,];}
subgraph cluster_0x19e64130{
id=cluster_0x19e64130
label="func_inner[managed]"
fontname="Courier New"
node0x19e68c80_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]6)</td></tr>
</table>>,]
node0x19e68ae0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]7)</td></tr>
</table>>,]
node0x19e682c0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]8)</td></tr>
</table>>,]
node0x19e50a00_8[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x19c7ced0_9[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>DoSignaturePrimitive</td></tr><tr><td>S-Prim-add</td></tr><tr><td align='left'></td></tr></table>>,]
node0x19e645e0_10[fontname="Courier New",shape=octagon,label="c",style=filled,fillcolor=paleturquoise,]
node0x19e68790_11[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>DoSignaturePrimitive</td></tr><tr><td>S-Prim-add</td></tr><tr><td align='left'></td></tr></table>>,]
parameters_0x19e64130[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>c</td></tr></table>>,];}
node0x19e328a0_0:core->node0x19269490_0:0[arrowhead=vee,style=dashed]
node0x1976cf00_0:core->node0x19269490_0:1[arrowhead=vee,]
node0x19e5e7c0_1:core->node0x1976cf00_0:0[arrowhead=vee,style=dashed]
node0x196c2270_0:core->node0x1976cf00_0:1[arrowhead=vee,]
node0x1963d630_0:core->node0x1976cf00_0:2[arrowhead=vee,]
node0x196d87f0_0:core->node0x1963d630_0:0[arrowhead=vee,style=dashed]
node0x19b6a3d0_2:core->node0x1963d630_0:1[arrowhead=vee,]
node0x19e68e20_3->node0x196d87f0_0:0[arrowhead=vee,style=dashed]
node0x19e68e20_3->node0x19e69550_0[lhead=cluster_0x19e63830,dir=both,arrowhead=dot,style=filled,color=blue]
node0x19e38e00_4:core->node0x196d87f0_0:1[arrowhead=vee,]
node0x19e23c10_5:core->node0x196d87f0_0:2[arrowhead=vee,]
node0x19e68f90_6:core->node0x19e69550_0:0[arrowhead=vee,style=dashed]
node0x19e69100_7->node0x19e69550_0:1[arrowhead=vee,]
node0x19e69100_7->node0x19e68c80_0[lhead=cluster_0x19e64130,dir=both,arrowhead=dot,style=filled,color=blue]
node0x19e50a00_8:core->node0x19e68c80_0:0[arrowhead=vee,style=dashed]
node0x19e68ae0_0:core->node0x19e68c80_0:1[arrowhead=vee,]
node0x19c7ced0_9:core->node0x19e68ae0_0:0[arrowhead=vee,style=dashed]
node0x19e682c0_0:core->node0x19e68ae0_0:1[arrowhead=vee,]
node0x19e645e0_10->node0x19e68ae0_0:2[arrowhead=vee,]
node0x19e68790_11:core->node0x19e682c0_0:0[arrowhead=vee,style=dashed]
node0x19e035b0_12->node0x19e682c0_0:1[arrowhead=vee,]
node0x19e036b0_13->node0x19e682c0_0:2[arrowhead=vee,]
node0x196d87f0_0:core->node0x196c2270_0:0[arrowhead=vee,style=dashed]
node0x19e1c020_14:core->node0x196c2270_0:1[arrowhead=vee,]
}
digraph mindspore {
compound=true
subgraph cluster_0x1b3c23b0{
id=cluster_0x1b3c23b0
label="hof[managed]"
fontname="Courier New"
node0x1b32ae50_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]0)</td></tr>
</table>>,]
node0x1b064930_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode(res)</td></tr>
</table>>,]
node0x1b3c0040_0[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x1b3bfbf0_1[fontname="Courier New",shape=oval,label="g",style=filled,fillcolor=palegreen,URL="#cluster_0x1b3be6c0",]
node0x1b3bfed0_2[fontname="Courier New",shape=oval,label="f",style=filled,fillcolor=palegreen,URL="#cluster_0x1b3c50c0",]
node0x1b3c6870_3[fontname="Courier New",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,]
parameters_0x1b3c23b0[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>x</td></tr></table>>,];}
subgraph cluster_0x1b3c50c0{
id=cluster_0x1b3c50c0
label="f[managed]"
fontname="Courier New"
node0x1ab4e190_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]1)</td></tr>
</table>>,]
node0x1ab61220_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]2)</td></tr>
</table>>,]
node0x1b3c59e0_4[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x1b3bf5e0_5[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>DoSignaturePrimitive</td></tr><tr><td>S-Prim-add</td></tr><tr><td align='left'></td></tr></table>>,]
node0x1b348630_6[fontname="Courier New",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,]
node0x1b3c60f0_7[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>3</td></tr></table>>,]
parameters_0x1b3c50c0[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>x</td></tr></table>>,];}
subgraph cluster_0x1b3be6c0{
id=cluster_0x1b3be6c0
label="g[managed]"
fontname="Courier New"
node0x1b3bfa50_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]4)</td></tr>
</table>>,]
node0x1a9fb8c0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]5)</td></tr>
</table>>,]
node0x1a39f7a0_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]6)</td></tr>
</table>>,]
node0x1a4daa20_0[fontname="Courier New",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]7)</td></tr>
</table>>,]
node0x1b3adfd0_8[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr><tr><td align='left'></td></tr></table>>,]
node0x1b3c2920_9[fontname="Courier New",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>DoSignaturePrimitive</td></tr><tr><td>S-Prim-mul</td></tr><tr><td align='left'></td></tr></table>>,]
node0x1b3120e0_10[fontname="Courier New",shape=octagon,label="function",style=filled,fillcolor=paleturquoise,]
node0x1b3121e0_11[fontname="Courier New",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,]
node0x1b3120e0_12[fontname="Courier New",shape=octagon,label="function",style=filled,fillcolor=paleturquoise,]
node0x1b3121e0_13[fontname="Courier New",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,]
parameters_0x1b3be6c0[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>function</td></tr><tr><td>x</td></tr></table>>,];}
node0x1b3c0040_0:core->node0x1b32ae50_0:0[arrowhead=vee,style=dashed]
node0x1b064930_0:core->node0x1b32ae50_0:1[arrowhead=vee,]
node0x1b3bfbf0_1->node0x1b064930_0:0[arrowhead=vee,style=dashed]
node0x1b3bfbf0_1->node0x1b3bfa50_0[lhead=cluster_0x1b3be6c0,dir=both,arrowhead=dot,style=filled,color=blue]
node0x1b3bfed0_2->node0x1b064930_0:1[arrowhead=vee,]
node0x1b3bfed0_2->node0x1ab4e190_0[lhead=cluster_0x1b3c50c0,dir=both,arrowhead=dot,style=filled,color=blue]
node0x1b3c6870_3->node0x1b064930_0:2[arrowhead=vee,]
node0x1b3c59e0_4:core->node0x1ab4e190_0:0[arrowhead=vee,style=dashed]
node0x1ab61220_0:core->node0x1ab4e190_0:1[arrowhead=vee,]
node0x1b3bf5e0_5:core->node0x1ab61220_0:0[arrowhead=vee,style=dashed]
node0x1b348630_6->node0x1ab61220_0:1[arrowhead=vee,]
node0x1b3c60f0_7:core->node0x1ab61220_0:2[arrowhead=vee,]
node0x1b3adfd0_8:core->node0x1b3bfa50_0:0[arrowhead=vee,style=dashed]
node0x1a9fb8c0_0:core->node0x1b3bfa50_0:1[arrowhead=vee,]
node0x1b3c2920_9:core->node0x1a9fb8c0_0:0[arrowhead=vee,style=dashed]
node0x1a4daa20_0:core->node0x1a9fb8c0_0:1[arrowhead=vee,]
node0x1a39f7a0_0:core->node0x1a9fb8c0_0:2[arrowhead=vee,]
node0x1b3120e0_10->node0x1a39f7a0_0:0[arrowhead=vee,style=dashed]
node0x1b3121e0_11->node0x1a39f7a0_0:1[arrowhead=vee,]
node0x1b3120e0_12->node0x1a4daa20_0:0[arrowhead=vee,style=dashed]
node0x1b3121e0_13->node0x1a4daa20_0:1[arrowhead=vee,]
}
digraph mindspore {
compound=true
subgraph cluster_0x55c9669c3c70{
id=cluster_0x55c9669c3c70
label="test_f"
fontname="HuaweiSans"
node0x55c9669c6cc0_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]0)</td></tr>
</table>>,]
node0x55c9669c66a0_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode(c)</td></tr>
</table>>,]
node0x55c9669c6960_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]1)</td></tr>
</table>>,]
node0x55c9669c58a0_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode(b)</td></tr>
</table>>,]
node0x55c9669c4fb0_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode(a)</td></tr>
</table>>,]
node0x55c9669c6b60_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr></table>>,]
node0x55c9669c9720_1[fontname="HuaweiSans",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>MultitypeFuncGraph</td></tr><tr><td>mul</td></tr></table>>,]
node0x55c9669c9dd0_2[fontname="HuaweiSans",shape=oval,label="func",style=filled,fillcolor="palegreen",URL="#cluster_0x55c9669c7310",]
node0x55c9669c9800_3[fontname="HuaweiSans",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>MultitypeFuncGraph</td></tr><tr><td>add</td></tr></table>>,]
node0x55c9669c4430_4[fontname="HuaweiSans",shape=octagon,label="y",style=filled,fillcolor=paleturquoise,]
node0x55c9669c9e80_5[fontname="HuaweiSans",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>MultitypeFuncGraph</td></tr><tr><td>sub</td></tr></table>>,]
node0x55c9669c3fc0_6[fontname="HuaweiSans",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,]
node0x55c96692eeb0_7[fontname="HuaweiSans",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Int32Imm</td></tr><tr><td>1</td></tr></table>>,]
parameters_0x55c9669c3c70[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>x</td></tr><tr><td>y</td></tr></table>>,];}
subgraph cluster_0x55c9669c7310{
id=cluster_0x55c9669c7310
label="func"
fontname="HuaweiSans"
node0x55c9669cc740_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td></tr>
<tr><td colspan='2' bgcolor='cornsilk'>CNode([CNode]7)</td></tr>
</table>>,]
node0x55c9669cc5c0_0[fontname="HuaweiSans",shape=plaintext,label=<<table port='core'>
<tr><td port='0'>0</td><td port='1'>1</td><td port='2'>2</td></tr>
<tr><td colspan='3' bgcolor='cornsilk'>CNode([CNode]8)</td></tr>
</table>>,]
node0x55c9669cafc0_8[fontname="HuaweiSans",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>Primitive</td></tr><tr><td>return</td></tr></table>>,]
node0x55c9669cc930_9[fontname="HuaweiSans",shape=plaintext,label=<<table port='core' cellborder='0' cellspacing='2' bgcolor='lavender'><tr><td bgcolor='white'>MultitypeFuncGraph</td></tr><tr><td>div</td></tr></table>>,]
node0x55c9669cab20_10[fontname="HuaweiSans",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,]
node0x55c9669cacf0_11[fontname="HuaweiSans",shape=octagon,label="y",style=filled,fillcolor=paleturquoise,]
parameters_0x55c9669c7310[shape=plaintext label=<<table bgcolor='paleturquoise' cellspacing='0' cellborder='1' border='0'><tr><td>parameters</td></tr><tr><td>x</td></tr><tr><td>y</td></tr></table>>,];}
node0x55c9669c6b60_0:core->node0x55c9669c6cc0_0:0[arrowhead=vee,style=dashed]
node0x55c9669c66a0_0:core->node0x55c9669c6cc0_0:1[arrowhead=vee,]
node0x55c9669c9720_1:core->node0x55c9669c66a0_0:0[arrowhead=vee,style=dashed]
node0x55c9669c58a0_0:core->node0x55c9669c66a0_0:1[arrowhead=vee,]
node0x55c9669c6960_0:core->node0x55c9669c66a0_0:2[arrowhead=vee,]
node0x55c9669c9dd0_2->node0x55c9669c6960_0:0[arrowhead=vee,style=dashed]
node0x55c9669c9dd0_2->node0x55c9669cc740_0[lhead=cluster_0x55c9669c7310,dir=both,arrowhead=dot,style=filled,color="#444444"]
node0x55c9669c4fb0_0:core->node0x55c9669c6960_0:1[arrowhead=vee,]
node0x55c9669c58a0_0:core->node0x55c9669c6960_0:2[arrowhead=vee,]
node0x55c9669c9800_3:core->node0x55c9669c58a0_0:0[arrowhead=vee,style=dashed]
node0x55c9669c4fb0_0:core->node0x55c9669c58a0_0:1[arrowhead=vee,]
node0x55c9669c4430_4->node0x55c9669c58a0_0:2[arrowhead=vee,]
node0x55c9669c9e80_5:core->node0x55c9669c4fb0_0:0[arrowhead=vee,style=dashed]
node0x55c9669c3fc0_6->node0x55c9669c4fb0_0:1[arrowhead=vee,]
node0x55c96692eeb0_7:core->node0x55c9669c4fb0_0:2[arrowhead=vee,]
node0x55c9669cafc0_8:core->node0x55c9669cc740_0:0[arrowhead=vee,style=dashed]
node0x55c9669cc5c0_0:core->node0x55c9669cc740_0:1[arrowhead=vee,]
node0x55c9669cc930_9:core->node0x55c9669cc5c0_0:0[arrowhead=vee,style=dashed]
node0x55c9669cab20_10->node0x55c9669cc5c0_0:1[arrowhead=vee,]
node0x55c9669cacf0_11->node0x55c9669cc5c0_0:2[arrowhead=vee,]
}
# MindSpore IR(MindIR)
`框架开发` `中级` `高级` `贡献者`
<!-- TOC -->
- [MindSpore IR(MindIR)](#mindspore-irmindir)
- [简介](#简介)
- [文法定义](#文法定义)
- [示例](#示例)
- [如何保存IR](#如何保存ir)
- [函数式语义](#函数式语义)
- [高阶函数](#高阶函数)
- [控制流](#控制流)
- [自由变量和闭包](#自由变量和闭包)
- [参考文献](#参考文献)
<!-- /TOC -->
<a href="https://gitee.com/mindspore/docs/blob/master/docs/source_zh_cn/design/mindspore/ir.md" target="_blank"><img src="../../_static/logo_source.png"></a>
## 简介
中间表示(IR)是程序编译过程中介于源语言和目标语言之间的程序表示,以方便编译器进行程序分析和优化,因此IR的设计需要考虑从源语言到目标语言的转换难度,同时考虑程序分析和优化的易用性和性能。
MindIR是一种基于图表示的函数式IR,其最核心的目的是服务于自动微分变换。自动微分采用的是基于函数式编程框架的变换方法,因此IR采用了接近于ANF函数式的语义。此外,借鉴Sea of Nodes[1]和Thorin[2]的优秀设计,采用了一种基于显性依赖图的表示方式。
## 文法定义
ANF是函数式编程中常用且简洁的中间表示,其文法定义如下所示:
```
<aexp> ::= NUMBER | STRING | VAR | BOOLEAN | PRIMOP
| (lambda (VAR …) <exp>)
<cexp> ::= (<aexp> <aexp> …)
| (if <aexp> <exp> <exp>)
<exp> ::= (let ([VAR <cexp>]) <exp>) | <cexp> | <aexp>
```
ANF中表达式分为原子表达式(aexp)和复合表达式(cexp),原子表达式表示一个常数值或一个变量或一个匿名函数;复合表达式由多个原子表达式复合组成,表示一个匿名函数或原语函数调用,组合的第一个输入是调用的函数,其余输入是调用的参数。
MindIR文法继承于ANF,其定义如下所示:
```
<ANode> ::= <ValueNode> | <ParameterNode>
<ParameterNode> ::= Parameter
<ValueNode> ::= Scalar | Named | Tensor | Type | Shape
| Primitive | MetaFuncGraph | FuncGraph
<CNode> ::= (<AnfNode> …)
<AnfNode> ::= <CNode> | <ANode>
```
MindIR中的ANode对应于ANF的原子表达式,ANode有两个子类分别为ValueNode和ParameterNode。ValueNode表示常数节点,可承载一个常数值(标量、符号、张量、类型、维度等),也可以是一个原语函数(Primitive)或一个元函数(MetaFuncGraph)或一个普通函数(FuncGraph),因为在函数式编程中函数定义本身也是一个值。ParameterNode是参数节点,表示函数的形参。
MindIR中CNode对应于ANF的复合表达式,表示一次函数调用。
在MindSpore自动微分时,会计算ParameterNode和CNode的梯度贡献,并返回最终ParameterNode的梯度,而不计算ValueNode的梯度。
## 示例
下面以一段程序作为示例,对比理解MindIR。
```python
def func(x, y):
return x / y
@ms_function
def test_f(x, y):
a = x - 1
b = a + y
c = b * func(a, b)
return c
```
这段Python代码对应的ANF表达为:
```
lambda (x, y)
let a = x - 1 in
let b = a + y in
let func = lambda (x, y)
let ret = x / y in
ret end in
let %1 = func(a, b) in
let c = b * %1 in
c end
```
对应的MindIR为[ir.dot](./images/ir/ir.dot)
![](./images/ir/ir.png)
在MindIR中,一个函数图(FuncGraph)表示一个普通函数的定义,函数图一般由ParameterNode、ValueNode和CNode组成有向无环图,可以清晰地表达出从参数到返回值的计算过程。在上图中可以看出,python代码中两个函数`test_f``func`转换成了两个函数图,其参数`x``y`转换为函数图的ParameterNode,每一个表达式转换为一个CNode。CNode的第一个输入链接着调用的函数,例如图中的`add``func``return`。值得注意的是这些节点均是`ValueNode`,因为它们被理解为常数函数值。CNode的其他输入链接这调用的参数,参数值可以来自于ParameterNode、ValueNode和其他CNode。
在ANF中每个表达式都用let表达式绑定为一个变量,通过对变量的引用来表示对表达式输出的依赖,而在MindIR中每个表达式都绑定为一个节点,通过节点与节点之间的有向边表示依赖关系。
## 如何保存IR
通过`context.set_context(save_graphs=True)`来保存各个编译阶段的中间代码。被保存的中间代码有两种格式,一个是后缀名为`.ir`的文本格式,一个是后缀名为`.dot`的图形化格式。当网络规模不大时,建议使用更直观的图形化格式来查看,当网络规模较大时建议使用更高效的文本格式来查看。
DOT文件可以通过graphviz转换为图片格式来查看,例如将dot转换为png的命令是`dot -Tpng *.dot -o *.png`
## 函数式语义
MindIR较传统计算图的一个重要特性是不仅可以表达算子之间的数据依赖,还可以表达丰富的函数式语义。
### 高阶函数
在MindIR中,函数的定义是由一个子图来定义,但其本身可以是一个被传递的值,作为其他高阶函数的输入或输出。
例如下面一个简单的示例中,函数`f`作为参数传入了函数`g`,因此函数`g`是一个接收函数输入的高阶函数,函数`f`真正的调用点是在函数`g`内部。
```
@ms_function
def hof(x):
def f(x):
return x + 3
def g(function, x):
return function(x) * function(x)
res = g(f, x)
return res
```
对应的MindIR为[hof.dot](./images/ir/hof.dot)
![](./images/ir/hof.png)
在实际网络训练脚本中,自动求导泛函`GradOperation`和优化器中常用到的`Partial``HyperMap`都是典型的高阶函数。高阶语义极大地提升了MindSpore表达的灵活性和简洁性。
### 控制流
控制流在MindIR中是以高阶函数选择调用的形式表达。这样的形式把控制流转换为高阶函数的数据流,从而使得自动微分算法更加强大。不仅可以支持数据流的自动微分,还可以支持条件跳转、循环和递归等控制流的自动微分。
下面以一个简单的斐波那契用例来演示说明。
```python
@ms_function
def fibonacci(n):
if(n < 1):
return 0
elif(n == 1):
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
```
对应的MindIR为[cf.dot](./images/ir/cf.dot)
![](./images/ir/cf.png)
其中`fibonacci`是顶层函数图,在顶层中有两个函数图被`switch`选择调用。`✓fibonacci`是第一个`if`的True分支,`✗fibonacci`是第一个`if`的False分支。在`✗fibonacci`中被调用的`✓✗fibonacci``elif`的True分支,`✗✗fibonacci``elif`的False分支。这里需要理解的关键是在MindIR中,条件跳转和递归是以高阶控制流的形式表达的。例如,`✓fibonacci``✗fibonacci`是作为`switch`算子的参数传入,`switch`根据条件参数选择哪一个函数作为返回值。因此,`switch`是把输入的函数当成普通的值做了一个二元选择操作,并没有调用,而真正的函数调用是在紧随`switch`后的CNode上完成。
### 自由变量和闭包
闭包(closure)是一种编程语言特性,它指的是代码块和作用域环境的结合。自由变量(free variable)是指在代码块中引用作用域环境中的变量而非局部变量。在MindIR中,代码块是以函数图呈现的,而作用域环境可以理解为该函数被调用时的上下文环境,自由变量的捕获方式是值拷贝而非引用。
一个典型的闭包用例如下:
```python
@ms_function
def func_outer(a, b):
def func_inner(c):
return a + b + c
return func_inner
@ms_function
def ms_closure():
closure = func_outer(1, 2)
out1 = closure(1)
out2 = closure(2)
return out1, out2
```
对应的MindIR为[closure.dot](./images/ir/closure.dot)
![](./images/ir/closure.png)
在例子中,`a``b`是自由变量,因为`func_inner`中变量`a``b`是引用的其父图`func_outer`中定义的参数。变量`closure`是一个闭包,它是函数`func_inner`与其上下文`func_outer(1, 2)`的结合。因此,`out1`的结果是4,因为其等价于`1+2+1``out2`的结果是5,因为其等价于`1+2+2`
## 参考文献
[1] C. Click and M. Paleczny. A simple graph-based intermediate representation.
SIGPLAN Not., 30:35–49, March 1995.
[2] Roland Leißa, Marcel Köster, and Sebastian Hack. A graph-based higher-order intermediate
representation. In Proceedings of the 13th Annual IEEE/ACM International Symposium on
Code Generation and Optimization, pages 202–212. IEEE Computer Society, 2015.
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册