diff --git a/docs/source_en/design.rst b/docs/source_en/design.rst index a34e1d088ddecf7ea109fd421c409b1abf6a689a..359add5edcdd0d373da5eb99037c88cf5bfd99e7 100644 --- a/docs/source_en/design.rst +++ b/docs/source_en/design.rst @@ -5,6 +5,7 @@ Design :maxdepth: 1 architecture + design/mindspore/ir design/mindinsight/training_visual_design design/mindinsight/graph_visual_design design/mindinsight/tensor_visual_design \ No newline at end of file diff --git a/docs/source_en/design/mindspore/images/ir/cf.dot b/docs/source_en/design/mindspore/images/ir/cf.dot new file mode 100644 index 0000000000000000000000000000000000000000..9da78b45beb7ea56365a300e601c79af4a55e130 --- /dev/null +++ b/docs/source_en/design/mindspore/images/ir/cf.dot @@ -0,0 +1,183 @@ +digraph mindspore { +compound=true +subgraph cluster_0x8b8cc30{ +id=cluster_0x8b8cc30 +label="fibonacci[managed]" +fontname="Courier New" +node0x8bde4b0_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]0)
>,] +node0x8bee780_0[fontname="Courier New",shape=plaintext,label=< + + +
0
CNode([CNode]1)
>,] +node0x8bee900_0[fontname="Courier New",shape=plaintext,label=< + + +
0123
CNode([CNode]2)
>,] +node0x8b702a0_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]54)
>,] +node0x8b6db30_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]37)
>,] +node0x8bc0bb0_0[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x8b768b0_1[fontname="Courier New",shape=plaintext,label=<
Primitive
switch
>,] +node0x8b6c9f0_2[fontname="Courier New",shape=oval,label="✓fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b91500",] +node0x8bd9410_3[fontname="Courier New",shape=plaintext,label=<
Primitive
Partial
>,] +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=<
PrimitivePy
scalar_lt
>,] +node0x8b7bab0_30[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,] +node0x8b90f50_31[fontname="Courier New",shape=plaintext,label=<
Int32Imm
1
>,] +parameters_0x8b8cc30[shape=plaintext label=<
parameters
n
>,];} +subgraph cluster_0x8bda550{ +id=cluster_0x8bda550 +label="✗fibonacci[managed]" +fontname="Courier New" +node0x8b6acd0_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]3)
>,] +node0x8b6dff0_0[fontname="Courier New",shape=plaintext,label=< + + +
0
CNode([CNode]4)
>,] +node0x8b7d410_0[fontname="Courier New",shape=plaintext,label=< + + +
0123
CNode([CNode]5)
>,] +node0x8b83a80_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]55)
>,] +node0x8b8c2a0_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]35)
>,] +node0x8b62c70_6[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x8bbe5f0_7[fontname="Courier New",shape=plaintext,label=<
Primitive
switch
>,] +node0x8b8a0f0_8[fontname="Courier New",shape=oval,label="✓✗fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b64c50",] +node0x8b8dbb0_9[fontname="Courier New",shape=plaintext,label=<
Primitive
Partial
>,] +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=<
PrimitivePy
scalar_eq
>,] +node0x8b76290_25[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,] +node0x8b7da70_26[fontname="Courier New",shape=plaintext,label=<
Int32Imm
1
>,] +parameters_0x8bda550[shape=plaintext label=<
parameters
n
>,];} +subgraph cluster_0x8bedfe0{ +id=cluster_0x8bedfe0 +label="✗✗fibonacci[managed]" +fontname="Courier New" +node0x8b8e4a0_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]6)
>,] +node0x8bb9b70_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]33)
>,] +node0x8b7d610_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]8)
>,] +node0x8beae20_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]31)
>,] +node0x8b76cd0_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]11)
>,] +node0x8b849b0_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]31)
>,] +node0x8b85200_12[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x8b84310_13[fontname="Courier New",shape=plaintext,label=<
PrimitivePy
scalar_add
>,] +node0x8bc14b0_14[fontname="Courier New",shape=oval,label="fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b8cc30",] +node0x8b8d2e0_15[fontname="Courier New",shape=plaintext,label=<
PrimitivePy
scalar_sub
>,] +node0x8bbc810_16[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,] +node0x8b8d3d0_17[fontname="Courier New",shape=plaintext,label=<
Int32Imm
2
>,] +node0x8bd5920_18[fontname="Courier New",shape=oval,label="fibonacci",style=filled,fillcolor=palegreen,URL="#cluster_0x8b8cc30",] +node0x8bc15a0_19[fontname="Courier New",shape=plaintext,label=<
PrimitivePy
scalar_sub
>,] +node0x8bbc810_20[fontname="Courier New",shape=octagon,label="n",style=filled,fillcolor=paleturquoise,] +node0x8b83990_21[fontname="Courier New",shape=plaintext,label=<
Int32Imm
1
>,] +parameters_0x8bedfe0[shape=plaintext label=<
parameters
n
>,];} +subgraph cluster_0x8b64c50{ +id=cluster_0x8b64c50 +label="✓✗fibonacci[managed]" +fontname="Courier New" +node0x8be8e20_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]15)
>,] +node0x8bd5440_22[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x8b89ee0_23[fontname="Courier New",shape=plaintext,label=<
Int32Imm
1
>,] +parameters_0x8b64c50[shape=plaintext label=<
parameters
>,];} +subgraph cluster_0x8b91500{ +id=cluster_0x8b91500 +label="✓fibonacci[managed]" +fontname="Courier New" +node0x8bdacb0_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]18)
>,] +node0x8b7d900_27[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x8bb9e90_28[fontname="Courier New",shape=plaintext,label=<
Int32Imm
0
>,] +parameters_0x8b91500[shape=plaintext label=<
parameters
>,];} +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,] +} diff --git a/docs/source_en/design/mindspore/images/ir/cf.png b/docs/source_en/design/mindspore/images/ir/cf.png new file mode 100644 index 0000000000000000000000000000000000000000..196be66c223022c34fe34848d30c10985efa94c7 Binary files /dev/null and b/docs/source_en/design/mindspore/images/ir/cf.png differ diff --git a/docs/source_en/design/mindspore/images/ir/closure.dot b/docs/source_en/design/mindspore/images/ir/closure.dot new file mode 100644 index 0000000000000000000000000000000000000000..fd3d402bf48b3410e2d92964c1e1ef5e289dda40 --- /dev/null +++ b/docs/source_en/design/mindspore/images/ir/closure.dot @@ -0,0 +1,93 @@ +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=< + + +
01
CNode([CNode]0)
>,] +node0x1976cf00_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]1)
>,] +node0x1963d630_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode(out2)
>,] +node0x196d87f0_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode(closure)
>,] +node0x196c2270_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode(out1)
>,] +node0x19e328a0_0[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x19e5e7c0_1[fontname="Courier New",shape=plaintext,label=<
DoSignaturePrimitive
S-Prim-make_tuple
>,] +node0x19b6a3d0_2[fontname="Courier New",shape=plaintext,label=<
Int32Imm
2
>,] +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=<
Int32Imm
1
>,] +node0x19e23c10_5[fontname="Courier New",shape=plaintext,label=<
Int32Imm
2
>,] +node0x19e1c020_14[fontname="Courier New",shape=plaintext,label=<
Int32Imm
1
>,] +parameters_0x19e608f0[shape=plaintext label=<
parameters
>,];} +subgraph cluster_0x19e63830{ +id=cluster_0x19e63830 +label="func_outer[managed]" +fontname="Courier New" +node0x19e69550_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]5)
>,] +node0x19e68f90_6[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +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=<
parameters
a
b
>,];} +subgraph cluster_0x19e64130{ +id=cluster_0x19e64130 +label="func_inner[managed]" +fontname="Courier New" +node0x19e68c80_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]6)
>,] +node0x19e68ae0_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]7)
>,] +node0x19e682c0_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]8)
>,] +node0x19e50a00_8[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x19c7ced0_9[fontname="Courier New",shape=plaintext,label=<
DoSignaturePrimitive
S-Prim-add
>,] +node0x19e645e0_10[fontname="Courier New",shape=octagon,label="c",style=filled,fillcolor=paleturquoise,] +node0x19e68790_11[fontname="Courier New",shape=plaintext,label=<
DoSignaturePrimitive
S-Prim-add
>,] +parameters_0x19e64130[shape=plaintext label=<
parameters
c
>,];} +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,] +} diff --git a/docs/source_en/design/mindspore/images/ir/closure.png b/docs/source_en/design/mindspore/images/ir/closure.png new file mode 100644 index 0000000000000000000000000000000000000000..6a618dd46d4bceeabb0b68ddbd187babc24a16aa Binary files /dev/null and b/docs/source_en/design/mindspore/images/ir/closure.png differ diff --git a/docs/source_en/design/mindspore/images/ir/hof.dot b/docs/source_en/design/mindspore/images/ir/hof.dot new file mode 100644 index 0000000000000000000000000000000000000000..c0102eef9d47393572e241610f6dd1a2c303fb57 --- /dev/null +++ b/docs/source_en/design/mindspore/images/ir/hof.dot @@ -0,0 +1,85 @@ +digraph mindspore { +compound=true +subgraph cluster_0x1b3c23b0{ +id=cluster_0x1b3c23b0 +label="hof[managed]" +fontname="Courier New" +node0x1b32ae50_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]0)
>,] +node0x1b064930_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode(res)
>,] +node0x1b3c0040_0[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +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=<
parameters
x
>,];} +subgraph cluster_0x1b3c50c0{ +id=cluster_0x1b3c50c0 +label="f[managed]" +fontname="Courier New" +node0x1ab4e190_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]1)
>,] +node0x1ab61220_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]2)
>,] +node0x1b3c59e0_4[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x1b3bf5e0_5[fontname="Courier New",shape=plaintext,label=<
DoSignaturePrimitive
S-Prim-add
>,] +node0x1b348630_6[fontname="Courier New",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,] +node0x1b3c60f0_7[fontname="Courier New",shape=plaintext,label=<
Int32Imm
3
>,] +parameters_0x1b3c50c0[shape=plaintext label=<
parameters
x
>,];} +subgraph cluster_0x1b3be6c0{ +id=cluster_0x1b3be6c0 +label="g[managed]" +fontname="Courier New" +node0x1b3bfa50_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]4)
>,] +node0x1a9fb8c0_0[fontname="Courier New",shape=plaintext,label=< + + +
012
CNode([CNode]5)
>,] +node0x1a39f7a0_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]6)
>,] +node0x1a4daa20_0[fontname="Courier New",shape=plaintext,label=< + + +
01
CNode([CNode]7)
>,] +node0x1b3adfd0_8[fontname="Courier New",shape=plaintext,label=<
Primitive
return
>,] +node0x1b3c2920_9[fontname="Courier New",shape=plaintext,label=<
DoSignaturePrimitive
S-Prim-mul
>,] +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=<
parameters
function
x
>,];} +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,] +} diff --git a/docs/source_en/design/mindspore/images/ir/hof.png b/docs/source_en/design/mindspore/images/ir/hof.png new file mode 100644 index 0000000000000000000000000000000000000000..b7aed07a68798c31561de9461c94814ecec17d33 Binary files /dev/null and b/docs/source_en/design/mindspore/images/ir/hof.png differ diff --git a/docs/source_en/design/mindspore/images/ir/ir.dot b/docs/source_en/design/mindspore/images/ir/ir.dot new file mode 100644 index 0000000000000000000000000000000000000000..50faab23bdcd63c5199303cb8fdcbef1ccb3163c --- /dev/null +++ b/docs/source_en/design/mindspore/images/ir/ir.dot @@ -0,0 +1,73 @@ +digraph mindspore { +compound=true +subgraph cluster_0x55c9669c3c70{ +id=cluster_0x55c9669c3c70 +label="test_f" +fontname="HuaweiSans" +node0x55c9669c6cc0_0[fontname="HuaweiSans",shape=plaintext,label=< + + +
01
CNode([CNode]0)
>,] +node0x55c9669c66a0_0[fontname="HuaweiSans",shape=plaintext,label=< + + +
012
CNode(c)
>,] +node0x55c9669c6960_0[fontname="HuaweiSans",shape=plaintext,label=< + + +
012
CNode([CNode]1)
>,] +node0x55c9669c58a0_0[fontname="HuaweiSans",shape=plaintext,label=< + + +
012
CNode(b)
>,] +node0x55c9669c4fb0_0[fontname="HuaweiSans",shape=plaintext,label=< + + +
012
CNode(a)
>,] +node0x55c9669c6b60_0[fontname="HuaweiSans",shape=plaintext,label=<
Primitive
return
>,] +node0x55c9669c9720_1[fontname="HuaweiSans",shape=plaintext,label=<
MultitypeFuncGraph
mul
>,] +node0x55c9669c9dd0_2[fontname="HuaweiSans",shape=oval,label="func",style=filled,fillcolor="palegreen",URL="#cluster_0x55c9669c7310",] +node0x55c9669c9800_3[fontname="HuaweiSans",shape=plaintext,label=<
MultitypeFuncGraph
add
>,] +node0x55c9669c4430_4[fontname="HuaweiSans",shape=octagon,label="y",style=filled,fillcolor=paleturquoise,] +node0x55c9669c9e80_5[fontname="HuaweiSans",shape=plaintext,label=<
MultitypeFuncGraph
sub
>,] +node0x55c9669c3fc0_6[fontname="HuaweiSans",shape=octagon,label="x",style=filled,fillcolor=paleturquoise,] +node0x55c96692eeb0_7[fontname="HuaweiSans",shape=plaintext,label=<
Int32Imm
1
>,] +parameters_0x55c9669c3c70[shape=plaintext label=<
parameters
x
y
>,];} +subgraph cluster_0x55c9669c7310{ +id=cluster_0x55c9669c7310 +label="func" +fontname="HuaweiSans" +node0x55c9669cc740_0[fontname="HuaweiSans",shape=plaintext,label=< + + +
01
CNode([CNode]7)
>,] +node0x55c9669cc5c0_0[fontname="HuaweiSans",shape=plaintext,label=< + + +
012
CNode([CNode]8)
>,] +node0x55c9669cafc0_8[fontname="HuaweiSans",shape=plaintext,label=<
Primitive
return
>,] +node0x55c9669cc930_9[fontname="HuaweiSans",shape=plaintext,label=<
MultitypeFuncGraph
div
>,] +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=<
parameters
x
y
>,];} +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,] +} diff --git a/docs/source_en/design/mindspore/images/ir/ir.png b/docs/source_en/design/mindspore/images/ir/ir.png new file mode 100644 index 0000000000000000000000000000000000000000..364c5de500557324c8af86e4d1c5bc0a8f347bf5 Binary files /dev/null and b/docs/source_en/design/mindspore/images/ir/ir.png differ diff --git a/docs/source_en/design/mindspore/ir.md b/docs/source_en/design/mindspore/ir.md new file mode 100644 index 0000000000000000000000000000000000000000..4837ba94baccb0f15638d6bb744ec13f9035bb1b --- /dev/null +++ b/docs/source_en/design/mindspore/ir.md @@ -0,0 +1,166 @@ + +# MindSpore IR (MindIR) + +`Framework Development` `Intermediate` `Expert` `Contributor` + + + +- [MindSpore IR (MindIR)](#mindspore-ir-mindir) + - [Overview](#overview) + - [Syntax](#syntax) + - [Example](#example) + - [Saving IR](#saving-ir) + - [Function-style Semantics](#function-style-semantics) + - [Higher-Order Functions](#higher-order-functions) + - [Control Flows](#control-flows) + - [Free Variables and Closures](#free-variables-and-closures) + - [References](#references) + + + + + +## Overview +An intermediate representation (IR) is a representation of a program between the source and target languages, which facilitates program analysis and optimization for the compiler. Therefore, the IR design needs to consider the difficulty in converting the source language to the target language, as well as the ease-of-use and performance of program analysis and optimization. + +MindSpore IR (MindIR) is a function-style IR based on graph representation. Its core purpose is to serve automatic differential transformation. Automatic differentiation uses the transformation method based on the function-style programming framework. Therefore, IR uses the semantics close to that of the ANF function. In addition, a manner of representation based on an explicit dependency graph is used by referring to excellent designs of Sea of Nodes[1] and Thorin[2]. + +## Syntax +ANF is a simple IR commonly used during functional programming. The ANF syntax is defined as follows: +``` + ::= NUMBER | STRING | VAR | BOOLEAN | PRIMOP + | (lambda (VAR …) ) + ::= ( …) + | (if ) + ::= (let ([VAR ]) ) | | + +``` +Expressions in the ANF are classified into atomic expressions (aexp) and compound expressions (cexp). An atomic expression indicates a constant value, a variable, or an anonymous function. A compound expression consists of multiple atomic expressions, indicating that an anonymous function or primitive function call. The first input expression of a compound expression is the called function, and the other input expressions are the called parameters. + +The syntax of MindIR is inherited from the ANF and is defined as follows: +``` + ::= | + ::= Parameter + ::= Scalar | Named | Tensor | Type | Shape + | Primitive | MetaFuncGraph | FuncGraph + ::= ( …) + ::= | +``` +ANode in a MindIR corresponds to the atomic expression of ANF. ANode has two subclasses: ValueNode and ParameterNode. ValueNode refers to a constant node, which can carry a constant value (such as a scalar, symbol, tensor, type, and dimension), a primitive function (Primitive), a metafunction (MetaFuncGraph), or a common function (FuncGraph). In functional programming, the function definition itself is a value. ParameterNode refers to a parameter node, which indicates the formal parameter of a function. + +CNode in a MindIR corresponds to the compound expression of ANF, indicating a function call. + +During automatic differentiation of MindSpore, the gradient contribution of ParameterNode and CNode are calculated, and the final gradient of ParameterNode is returned. The gradient of ValueNode is not calculated. + +## Example +The following uses a program code segment as an example to help you understand 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 +``` +The ANF corresponding to the Python code is as follows: +``` +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 +``` +The corresponding MindIR is [ir.dot](./images/ir/ir.dot). + +![](./images/ir/ir.png) + +In a MindIR, a function graph (FuncGraph) indicates the definition of a common function. A directed acyclic graph (DAG) usually consists of ParameterNode, ValueNode, and CNode, which clearly shows the calculation process from parameters to return values. As shown in the preceding figure, the `test_f` and `func` functions in the Python code are converted into two function graphs. The `x` and `y` parameters are converted into ParameterNode in the function graphs, and each expression is converted into a CNode. The first input of CNode links to the called functions, for example, `add`, `func`, and `return` in the figure. It should be noted that these nodes are all `ValueNode` because they are considered as constant function values. Other input of CNode links to the called parameters. The parameter values can be obtained from the ParameterNode, ValueNode, and other CNode. + +In the ANF, each expression is bound as a variable by using the let expression, and the dependency on the expression output is represented by referencing the variable. In the MindIR, each expression is bound as a node, and the dependency is represented by using the directed edges between nodes. + +## Saving IR +`context.set_context(save_graphs=True)` is used to save the intermediate code in each compilation phase. The intermediate code can be saved in two formats. One is the text format with the suffix `.ir`, and the other is the graphical format with the suffix `.dot`. When the network scale is small, you are advised to use the graphical format that is more intuitive. When the network scale is large, you are advised to use the text format that is more efficient. + +You can run the graphviz command to convert a .dot file to the picture format. For example, you can run the `dot -Tpng *.dot -o *.png` command to convert a .dot file to a .png file. + +## Function-style Semantics +Compared with traditional computational graphs, MindIR can not only express data dependency between operators, but also express rich function-style semantics. +### Higher-Order Functions +In a MindIR, a function is defined by a subgraph. However, the function itself can be transferred as the input or output of other higher-order functions. +In the following simple example, the `f` function is transferred as a parameter into the `g` function. Therefore, the `g` function is a higher-order function that receives function input, and the actual call site of the `f` function is inside the `g` function. + +``` +@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 +``` + +The corresponding MindIR is [hof.dot](./images/ir/hof.dot). +![](./images/ir/hof.png) + +In the actual network training scripts, the automatic derivation generic function `GradOperation` and `Partial` and `HyperMap` that are commonly used in the optimizer are typical high-order functions. Higher-order semantics greatly improve the flexibility and simplicity of MindSpore representations. + +### Control Flows +In a MindIR, control flows are expressed in the form of high-order function selection and calling. This form transforms a control flow into a data flow of higher-order functions, making the automatic differential algorithm more powerful. It not only supports automatic differentiation of data flows, but also supports automatic differentiation of control flows such as conditional jumps, loops, and recursion. + +The following uses a simple Fibonacci instance as an example. +```python +@ms_function +def fibonacci(n): + if(n < 1): + return 0 + elif(n == 1): + return 1 + else: + return fibonacci(n-1) + fibonacci(n-2) +``` + +The corresponding MindIR is [cf.dot](./images/ir/cf.dot). +![](./images/ir/cf.png) + +`fibonacci` is a top-level function graph. Two function graphs at the top level are selected and called by `switch`. `✓fibonacci` is the True branch of the first `if`, and `✗fibonacci` is the False branch of the first `if`. `✓✗fibonacci` called in `✗fibonacci` is the True branch of `elif`, and `✗✗fibonacci` is the False branch of `elif`. The key is, in a MindIR, conditional jumps and recursion are represented in the form of higher-order control flows. For example, `✓✗fibonacci` and `✗fibonacci` are transferred in as parameters of the `switch` operator. `switch` selects a function as the return value based on the condition parameter. In this way, `switch` performs a binary selection operation on the input functions as common values and does not call the functions. The real function call is completed on CNode following `switch`. + + +### Free Variables and Closures +Closure is a programming language feature that refers to the combination of code blocks and scope environment. A free variable refers to a variable in the scope environment referenced in a code block instead of a local variable. In a MindIR, a code block is represented as a function graph. The scope environment can be considered as the context where the function is called. The capture method of free variables is value copy instead of reference. + +A typical closure instance is as follows: +```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 +``` + +The corresponding MindIR is [closure.dot](./images/ir/closure.dot). +![](./images/ir/closure.png) + +In the example, `a` and `b` are free variables because the variables `a` and `b` in `func_inner` are parameters defined in the referenced parent graph `func_outer`. The variable `closure` is a closure, which is the combination of the function `func_inner` and its context `func_outer(1, 2)`. Therefore, the result of `out1` is 4, which is equivalent to `1+2+1`, and the result of `out2` is 5, which is equivalent to `1+2+2`. + +## References +[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