未验证 提交 c9c48ab3 编写于 作者: J Jacek Czaja 提交者: GitHub

[oneDNN] Design doc on oneDNN inplace pass (#2024)

上级 52b1c8f5
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="305pt" height="479pt"
viewBox="0.00 0.00 304.64 479.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 475)">
<title>G</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-475 300.6419,-475 300.6419,4 -4,4"/>
<g id="clust1" class="cluster">
<title>cluster_0</title>
<polygon fill="none" stroke="#000000" points="90.6419,-136 90.6419,-355 288.6419,-355 288.6419,-136 90.6419,-136"/>
<text text-anchor="middle" x="189.6419" y="-339.8" font-family="Times,serif" font-size="14.00" fill="#000000">in&#45;placed</text>
</g>
<!-- e1 -->
<g id="node1" class="node">
<title>e1</title>
<ellipse fill="none" stroke="#000000" cx="225.6419" cy="-381" rx="29.4969" ry="18"/>
<text text-anchor="middle" x="225.6419" y="-377.3" font-family="Times,serif" font-size="14.00" fill="#000000">relu</text>
</g>
<!-- b -->
<g id="node5" class="node">
<title>b</title>
<ellipse fill="none" stroke="#000000" cx="225.6419" cy="-306" rx="27" ry="18"/>
<text text-anchor="middle" x="225.6419" y="-302.3" font-family="Times,serif" font-size="14.00" fill="#000000">b</text>
</g>
<!-- e1&#45;&gt;b -->
<g id="edge2" class="edge">
<title>e1&#45;&gt;b</title>
<path fill="none" stroke="#000000" d="M225.6419,-362.8446C225.6419,-354.3401 225.6419,-344.0076 225.6419,-334.4964"/>
<polygon fill="#000000" stroke="#000000" points="229.142,-334.2481 225.6419,-324.2482 222.142,-334.2482 229.142,-334.2481"/>
</g>
<!-- e2 -->
<g id="node2" class="node">
<title>e2</title>
<ellipse fill="none" stroke="#000000" cx="189.6419" cy="-234" rx="90.9839" ry="18"/>
<text text-anchor="middle" x="189.6419" y="-230.3" font-family="Times,serif" font-size="14.00" fill="#000000">elementwise_add</text>
</g>
<!-- e -->
<g id="node6" class="node">
<title>e</title>
<ellipse fill="none" stroke="#000000" cx="158.6419" cy="-162" rx="27" ry="18"/>
<text text-anchor="middle" x="158.6419" y="-158.3" font-family="Times,serif" font-size="14.00" fill="#000000">b</text>
</g>
<!-- e2&#45;&gt;e -->
<g id="edge5" class="edge">
<title>e2&#45;&gt;e</title>
<path fill="none" stroke="#000000" d="M181.8193,-215.8314C178.2891,-207.6323 174.0482,-197.7824 170.1646,-188.7624"/>
<polygon fill="#000000" stroke="#000000" points="173.3105,-187.2184 166.1412,-179.4177 166.8811,-189.9867 173.3105,-187.2184"/>
</g>
<!-- e3 -->
<g id="node3" class="node">
<title>e3</title>
<ellipse fill="none" stroke="#000000" cx="91.6419" cy="-90" rx="91.784" ry="18"/>
<text text-anchor="middle" x="91.6419" y="-86.3" font-family="Times,serif" font-size="14.00" fill="#000000">elementwise_mul</text>
</g>
<!-- g -->
<g id="node9" class="node">
<title>g</title>
<ellipse fill="none" stroke="#000000" cx="91.6419" cy="-18" rx="27" ry="18"/>
<text text-anchor="middle" x="91.6419" y="-14.3" font-family="Times,serif" font-size="14.00" fill="#000000">g</text>
</g>
<!-- e3&#45;&gt;g -->
<g id="edge8" class="edge">
<title>e3&#45;&gt;g</title>
<path fill="none" stroke="#000000" d="M91.6419,-71.8314C91.6419,-64.131 91.6419,-54.9743 91.6419,-46.4166"/>
<polygon fill="#000000" stroke="#000000" points="95.142,-46.4132 91.6419,-36.4133 88.142,-46.4133 95.142,-46.4132"/>
</g>
<!-- a -->
<g id="node4" class="node">
<title>a</title>
<ellipse fill="none" stroke="#000000" cx="225.6419" cy="-453" rx="27" ry="18"/>
<text text-anchor="middle" x="225.6419" y="-449.3" font-family="Times,serif" font-size="14.00" fill="#000000">a</text>
</g>
<!-- a&#45;&gt;e1 -->
<g id="edge1" class="edge">
<title>a&#45;&gt;e1</title>
<path fill="none" stroke="#000000" d="M225.6419,-434.8314C225.6419,-427.131 225.6419,-417.9743 225.6419,-409.4166"/>
<polygon fill="#000000" stroke="#000000" points="229.142,-409.4132 225.6419,-399.4133 222.142,-409.4133 229.142,-409.4132"/>
</g>
<!-- b&#45;&gt;e2 -->
<g id="edge3" class="edge">
<title>b&#45;&gt;e2</title>
<path fill="none" stroke="#000000" d="M216.9273,-288.5708C212.8191,-280.3544 207.8223,-270.3608 203.2329,-261.1821"/>
<polygon fill="#000000" stroke="#000000" points="206.2549,-259.3996 198.6522,-252.0206 199.9939,-262.5301 206.2549,-259.3996"/>
</g>
<!-- e&#45;&gt;e3 -->
<g id="edge6" class="edge">
<title>e&#45;&gt;e3</title>
<path fill="none" stroke="#000000" d="M144.1039,-146.3771C135.7005,-137.3466 124.9236,-125.7654 115.3258,-115.4514"/>
<polygon fill="#000000" stroke="#000000" points="117.6495,-112.8107 108.2749,-107.8744 112.525,-117.5794 117.6495,-112.8107"/>
</g>
<!-- d -->
<g id="node7" class="node">
<title>d</title>
<ellipse fill="none" stroke="#000000" cx="153.6419" cy="-306" rx="27" ry="18"/>
<text text-anchor="middle" x="153.6419" y="-302.3" font-family="Times,serif" font-size="14.00" fill="#000000">d</text>
</g>
<!-- d&#45;&gt;e2 -->
<g id="edge4" class="edge">
<title>d&#45;&gt;e2</title>
<path fill="none" stroke="#000000" d="M162.3565,-288.5708C166.4647,-280.3544 171.4615,-270.3608 176.0508,-261.1821"/>
<polygon fill="#000000" stroke="#000000" points="179.2899,-262.5301 180.6316,-252.0206 173.0289,-259.3996 179.2899,-262.5301"/>
</g>
<!-- f -->
<g id="node8" class="node">
<title>f</title>
<ellipse fill="none" stroke="#000000" cx="55.6419" cy="-162" rx="27" ry="18"/>
<text text-anchor="middle" x="55.6419" y="-158.3" font-family="Times,serif" font-size="14.00" fill="#000000">f</text>
</g>
<!-- f&#45;&gt;e3 -->
<g id="edge7" class="edge">
<title>f&#45;&gt;e3</title>
<path fill="none" stroke="#000000" d="M64.3565,-144.5708C68.4647,-136.3544 73.4615,-126.3608 78.0508,-117.1821"/>
<polygon fill="#000000" stroke="#000000" points="81.2899,-118.5301 82.6316,-108.0206 75.0289,-115.3996 81.2899,-118.5301"/>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="792pt" height="436pt"
viewBox="0.00 0.00 792.00 435.74" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 431.7401)">
<title>G</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-431.7401 788,-431.7401 788,4 -4,4"/>
<g id="clust1" class="cluster">
<title>cluster_before</title>
<polygon fill="none" stroke="#000000" stroke-dasharray="1,5" points="8,-8 8,-419.7401 398,-419.7401 398,-8 8,-8"/>
<text text-anchor="middle" x="203" y="-404.5401" font-family="Times,serif" font-size="14.00" fill="#000000">before</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_0</title>
<polygon fill="none" stroke="#000000" points="104,-169.7401 104,-388.7401 302,-388.7401 302,-169.7401 104,-169.7401"/>
<text text-anchor="middle" x="203" y="-373.5401" font-family="Times,serif" font-size="14.00" fill="#000000">to be in&#45;placed</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_after</title>
<polygon fill="none" stroke="#000000" stroke-dasharray="1,5" points="406,-8 406,-419.7401 776,-419.7401 776,-8 406,-8"/>
<text text-anchor="middle" x="591" y="-404.5401" font-family="Times,serif" font-size="14.00" fill="#000000">after</text>
</g>
<g id="clust4" class="cluster">
<title>cluster_0b</title>
<polygon fill="none" stroke="#000000" points="492,-169.7401 492,-388.7401 690,-388.7401 690,-169.7401 492,-169.7401"/>
<text text-anchor="middle" x="591" y="-373.5401" font-family="Times,serif" font-size="14.00" fill="#000000">applied in&#45;placed</text>
</g>
<!-- op1 -->
<g id="node1" class="node">
<title>op1</title>
<ellipse fill="none" stroke="#000000" cx="203" cy="-267.7401" rx="90.9839" ry="18"/>
<text text-anchor="middle" x="203" y="-264.0401" font-family="Times,serif" font-size="14.00" fill="#000000">elementwise_add</text>
</g>
<!-- c -->
<g id="node4" class="node">
<title>c</title>
<ellipse fill="none" stroke="#000000" cx="203" cy="-195.7401" rx="27" ry="18"/>
<text text-anchor="middle" x="203" y="-192.0401" font-family="Times,serif" font-size="14.00" fill="#000000">c</text>
</g>
<!-- op1&#45;&gt;c -->
<g id="edge3" class="edge">
<title>op1&#45;&gt;c</title>
<path fill="none" stroke="#000000" d="M203,-249.5715C203,-241.8711 203,-232.7145 203,-224.1567"/>
<polygon fill="#000000" stroke="#000000" points="206.5001,-224.1533 203,-214.1534 199.5001,-224.1534 206.5001,-224.1533"/>
</g>
<!-- op2 -->
<g id="node2" class="node">
<title>op2</title>
<ellipse fill="none" stroke="#000000" cx="105" cy="-114.8701" rx="89.191" ry="26.7407"/>
<text text-anchor="middle" x="105" y="-118.6701" font-family="Times,serif" font-size="14.00" fill="#000000">top_k</text>
<text text-anchor="middle" x="105" y="-103.6701" font-family="Times,serif" font-size="14.00" fill="#000000">inputs_vars{c}</text>
</g>
<!-- d -->
<g id="node7" class="node">
<title>d</title>
<ellipse fill="none" stroke="#000000" cx="84" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="84" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">d</text>
</g>
<!-- op2&#45;&gt;d -->
<g id="edge6" class="edge">
<title>op2&#45;&gt;d</title>
<path fill="none" stroke="#000000" d="M98.0073,-87.9415C95.8358,-79.579 93.4381,-70.3458 91.2495,-61.9176"/>
<polygon fill="#000000" stroke="#000000" points="94.6139,-60.9481 88.7128,-52.1488 87.8386,-62.7075 94.6139,-60.9481"/>
</g>
<!-- e -->
<g id="node8" class="node">
<title>e</title>
<ellipse fill="none" stroke="#000000" cx="156" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="156" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">e</text>
</g>
<!-- op2&#45;&gt;e -->
<g id="edge7" class="edge">
<title>op2&#45;&gt;e</title>
<path fill="none" stroke="#000000" d="M121.6993,-88.3902C127.5384,-79.1312 134.0793,-68.7595 139.8709,-59.5756"/>
<polygon fill="#000000" stroke="#000000" points="142.9853,-61.1985 145.3592,-50.873 137.0644,-57.4645 142.9853,-61.1985"/>
</g>
<!-- op3 -->
<g id="node3" class="node">
<title>op3</title>
<ellipse fill="none" stroke="#000000" cx="301" cy="-114.8701" rx="89.191" ry="26.7407"/>
<text text-anchor="middle" x="301" y="-118.6701" font-family="Times,serif" font-size="14.00" fill="#000000">top_k</text>
<text text-anchor="middle" x="301" y="-103.6701" font-family="Times,serif" font-size="14.00" fill="#000000">inputs_vars{c}</text>
</g>
<!-- g -->
<g id="node9" class="node">
<title>g</title>
<ellipse fill="none" stroke="#000000" cx="249" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="249" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">g</text>
</g>
<!-- op3&#45;&gt;g -->
<g id="edge8" class="edge">
<title>op3&#45;&gt;g</title>
<path fill="none" stroke="#000000" d="M283.9733,-88.3902C277.9576,-79.0347 271.2115,-68.5433 265.261,-59.289"/>
<polygon fill="#000000" stroke="#000000" points="268.2019,-57.3913 259.8495,-50.873 262.314,-61.1772 268.2019,-57.3913"/>
</g>
<!-- h -->
<g id="node10" class="node">
<title>h</title>
<ellipse fill="none" stroke="#000000" cx="321" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="321" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">h</text>
</g>
<!-- op3&#45;&gt;h -->
<g id="edge9" class="edge">
<title>op3&#45;&gt;h</title>
<path fill="none" stroke="#000000" d="M307.6597,-87.9415C309.7278,-79.579 312.0113,-70.3458 314.0957,-61.9176"/>
<polygon fill="#000000" stroke="#000000" points="317.5084,-62.6967 316.5116,-52.1488 310.7131,-61.0161 317.5084,-62.6967"/>
</g>
<!-- c&#45;&gt;op2 -->
<g id="edge4" class="edge">
<title>c&#45;&gt;op2</title>
<path fill="none" stroke="#000000" d="M185.9297,-181.6536C174.2695,-172.0316 158.3368,-158.8838 143.691,-146.798"/>
<polygon fill="#000000" stroke="#000000" points="145.6628,-143.8874 135.7221,-140.2221 141.2074,-149.2865 145.6628,-143.8874"/>
</g>
<!-- c&#45;&gt;op3 -->
<g id="edge5" class="edge">
<title>c&#45;&gt;op3</title>
<path fill="none" stroke="#000000" d="M220.0703,-181.6536C231.7305,-172.0316 247.6632,-158.8838 262.309,-146.798"/>
<polygon fill="#000000" stroke="#000000" points="264.7926,-149.2865 270.2779,-140.2221 260.3372,-143.8874 264.7926,-149.2865"/>
</g>
<!-- a -->
<g id="node5" class="node">
<title>a</title>
<ellipse fill="none" stroke="#000000" cx="239" cy="-339.7401" rx="27" ry="18"/>
<text text-anchor="middle" x="239" y="-336.0401" font-family="Times,serif" font-size="14.00" fill="#000000">a</text>
</g>
<!-- a&#45;&gt;op1 -->
<g id="edge1" class="edge">
<title>a&#45;&gt;op1</title>
<path fill="none" stroke="#000000" d="M230.2854,-322.3109C226.1772,-314.0945 221.1804,-304.1009 216.5911,-294.9222"/>
<polygon fill="#000000" stroke="#000000" points="219.613,-293.1397 212.0103,-285.7607 213.352,-296.2703 219.613,-293.1397"/>
</g>
<!-- b -->
<g id="node6" class="node">
<title>b</title>
<ellipse fill="none" stroke="#000000" cx="167" cy="-339.7401" rx="27" ry="18"/>
<text text-anchor="middle" x="167" y="-336.0401" font-family="Times,serif" font-size="14.00" fill="#000000">b</text>
</g>
<!-- b&#45;&gt;op1 -->
<g id="edge2" class="edge">
<title>b&#45;&gt;op1</title>
<path fill="none" stroke="#000000" d="M175.7146,-322.3109C179.8228,-314.0945 184.8196,-304.1009 189.4089,-294.9222"/>
<polygon fill="#000000" stroke="#000000" points="192.648,-296.2703 193.9897,-285.7607 186.387,-293.1397 192.648,-296.2703"/>
</g>
<!-- op1b -->
<g id="node11" class="node">
<title>op1b</title>
<ellipse fill="none" stroke="#000000" cx="591" cy="-267.7401" rx="90.9839" ry="18"/>
<text text-anchor="middle" x="591" y="-264.0401" font-family="Times,serif" font-size="14.00" fill="#000000">elementwise_add</text>
</g>
<!-- cb -->
<g id="node14" class="node">
<title>cb</title>
<ellipse fill="none" stroke="#000000" cx="591" cy="-195.7401" rx="27" ry="18"/>
<text text-anchor="middle" x="591" y="-192.0401" font-family="Times,serif" font-size="14.00" fill="#000000">a</text>
</g>
<!-- op1b&#45;&gt;cb -->
<g id="edge12" class="edge">
<title>op1b&#45;&gt;cb</title>
<path fill="none" stroke="#000000" d="M591,-249.5715C591,-241.8711 591,-232.7145 591,-224.1567"/>
<polygon fill="#000000" stroke="#000000" points="594.5001,-224.1533 591,-214.1534 587.5001,-224.1534 594.5001,-224.1533"/>
</g>
<!-- op2b -->
<g id="node12" class="node">
<title>op2b</title>
<ellipse fill="none" stroke="#000000" cx="498" cy="-114.8701" rx="84.2917" ry="26.7407"/>
<text text-anchor="middle" x="498" y="-118.6701" font-family="Times,serif" font-size="14.00" fill="#000000">top_k</text>
<text text-anchor="middle" x="498" y="-103.6701" font-family="Times,serif" font-size="14.00" fill="#000000">input_vars{a}</text>
</g>
<!-- db -->
<g id="node17" class="node">
<title>db</title>
<ellipse fill="none" stroke="#000000" cx="476" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="476" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">d</text>
</g>
<!-- op2b&#45;&gt;db -->
<g id="edge15" class="edge">
<title>op2b&#45;&gt;db</title>
<path fill="none" stroke="#000000" d="M490.6743,-87.9415C488.3994,-79.579 485.8876,-70.3458 483.5947,-61.9176"/>
<polygon fill="#000000" stroke="#000000" points="486.9396,-60.8794 480.9372,-52.1488 480.1851,-62.7169 486.9396,-60.8794"/>
</g>
<!-- eb -->
<g id="node18" class="node">
<title>eb</title>
<ellipse fill="none" stroke="#000000" cx="548" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="548" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">e</text>
</g>
<!-- op2b&#45;&gt;eb -->
<g id="edge16" class="edge">
<title>op2b&#45;&gt;eb</title>
<path fill="none" stroke="#000000" d="M514.3719,-88.3902C520.0965,-79.1312 526.5091,-68.7595 532.1872,-59.5756"/>
<polygon fill="#000000" stroke="#000000" points="535.2859,-61.2192 537.5678,-50.873 529.332,-57.538 535.2859,-61.2192"/>
</g>
<!-- op3b -->
<g id="node13" class="node">
<title>op3b</title>
<ellipse fill="none" stroke="#000000" cx="684" cy="-114.8701" rx="84.2917" ry="26.7407"/>
<text text-anchor="middle" x="684" y="-118.6701" font-family="Times,serif" font-size="14.00" fill="#000000">top_k</text>
<text text-anchor="middle" x="684" y="-103.6701" font-family="Times,serif" font-size="14.00" fill="#000000">input_vars{a}</text>
</g>
<!-- gb -->
<g id="node19" class="node">
<title>gb</title>
<ellipse fill="none" stroke="#000000" cx="633" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="633" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">g</text>
</g>
<!-- op3b&#45;&gt;gb -->
<g id="edge17" class="edge">
<title>op3b&#45;&gt;gb</title>
<path fill="none" stroke="#000000" d="M667.3007,-88.3902C661.4616,-79.1312 654.9207,-68.7595 649.1291,-59.5756"/>
<polygon fill="#000000" stroke="#000000" points="651.9356,-57.4645 643.6408,-50.873 646.0147,-61.1985 651.9356,-57.4645"/>
</g>
<!-- hb -->
<g id="node20" class="node">
<title>hb</title>
<ellipse fill="none" stroke="#000000" cx="705" cy="-34" rx="27" ry="18"/>
<text text-anchor="middle" x="705" y="-30.3" font-family="Times,serif" font-size="14.00" fill="#000000">h</text>
</g>
<!-- op3b&#45;&gt;hb -->
<g id="edge18" class="edge">
<title>op3b&#45;&gt;hb</title>
<path fill="none" stroke="#000000" d="M690.9927,-87.9415C693.1642,-79.579 695.5619,-70.3458 697.7505,-61.9176"/>
<polygon fill="#000000" stroke="#000000" points="701.1614,-62.7075 700.2872,-52.1488 694.3861,-60.9481 701.1614,-62.7075"/>
</g>
<!-- cb&#45;&gt;op2b -->
<g id="edge13" class="edge">
<title>cb&#45;&gt;op2b</title>
<path fill="none" stroke="#000000" d="M574.3735,-181.2822C563.4548,-171.7876 548.7254,-158.9793 535.1151,-147.1443"/>
<polygon fill="#000000" stroke="#000000" points="537.1109,-144.2416 527.2682,-140.3209 532.5176,-149.5238 537.1109,-144.2416"/>
</g>
<!-- cb&#45;&gt;op3b -->
<g id="edge14" class="edge">
<title>cb&#45;&gt;op3b</title>
<path fill="none" stroke="#000000" d="M607.6265,-181.2822C618.5452,-171.7876 633.2746,-158.9793 646.8849,-147.1443"/>
<polygon fill="#000000" stroke="#000000" points="649.4824,-149.5238 654.7318,-140.3209 644.8891,-144.2416 649.4824,-149.5238"/>
</g>
<!-- ab -->
<g id="node15" class="node">
<title>ab</title>
<ellipse fill="none" stroke="#000000" cx="627" cy="-339.7401" rx="27" ry="18"/>
<text text-anchor="middle" x="627" y="-336.0401" font-family="Times,serif" font-size="14.00" fill="#000000">a</text>
</g>
<!-- ab&#45;&gt;op1b -->
<g id="edge10" class="edge">
<title>ab&#45;&gt;op1b</title>
<path fill="none" stroke="#000000" d="M618.2854,-322.3109C614.1772,-314.0945 609.1804,-304.1009 604.5911,-294.9222"/>
<polygon fill="#000000" stroke="#000000" points="607.613,-293.1397 600.0103,-285.7607 601.352,-296.2703 607.613,-293.1397"/>
</g>
<!-- bb -->
<g id="node16" class="node">
<title>bb</title>
<ellipse fill="none" stroke="#000000" cx="555" cy="-339.7401" rx="27" ry="18"/>
<text text-anchor="middle" x="555" y="-336.0401" font-family="Times,serif" font-size="14.00" fill="#000000">b</text>
</g>
<!-- bb&#45;&gt;op1b -->
<g id="edge11" class="edge">
<title>bb&#45;&gt;op1b</title>
<path fill="none" stroke="#000000" d="M563.7146,-322.3109C567.8228,-314.0945 572.8196,-304.1009 577.4089,-294.9222"/>
<polygon fill="#000000" stroke="#000000" points="580.648,-296.2703 581.9897,-285.7607 574.387,-293.1397 580.648,-296.2703"/>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (0)
-->
<!-- Title: G Pages: 1 -->
<svg width="186pt" height="406pt"
viewBox="0.00 0.00 186.19 406.48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 402.4802)">
<title>G</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-402.4802 182.1909,-402.4802 182.1909,4 -4,4"/>
<g id="clust1" class="cluster">
<title>cluster_0</title>
<polygon fill="none" stroke="#000000" points="8.0955,-153.7401 8.0955,-390.4802 170.0955,-390.4802 170.0955,-153.7401 8.0955,-153.7401"/>
<text text-anchor="middle" x="89.0955" y="-375.2802" font-family="Times,serif" font-size="14.00" fill="#000000">in&#45;placed</text>
</g>
<!-- e1 -->
<g id="node1" class="node">
<title>e1</title>
<ellipse fill="none" stroke="#000000" cx="89.0955" cy="-260.6102" rx="72.6644" ry="26.7407"/>
<text text-anchor="middle" x="89.0955" y="-264.4102" font-family="Times,serif" font-size="14.00" fill="#000000">softmax</text>
<text text-anchor="middle" x="89.0955" y="-249.4102" font-family="Times,serif" font-size="14.00" fill="#000000">&lt;oneDNN&gt;</text>
</g>
<!-- c -->
<g id="node3" class="node">
<title>c</title>
<ellipse fill="none" stroke="#000000" cx="89.0955" cy="-179.7401" rx="27" ry="18"/>
<text text-anchor="middle" x="89.0955" y="-176.0401" font-family="Times,serif" font-size="14.00" fill="#000000">b</text>
</g>
<!-- e1&#45;&gt;c -->
<g id="edge2" class="edge">
<title>e1&#45;&gt;c</title>
<path fill="none" stroke="#000000" d="M89.0955,-233.6816C89.0955,-225.4111 89.0955,-216.2888 89.0955,-207.9358"/>
<polygon fill="#000000" stroke="#000000" points="92.5956,-207.8889 89.0955,-197.8889 85.5956,-207.889 92.5956,-207.8889"/>
</g>
<!-- e2 -->
<g id="node2" class="node">
<title>e2</title>
<ellipse fill="none" stroke="#000000" cx="89.0955" cy="-98.8701" rx="89.191" ry="26.7407"/>
<text text-anchor="middle" x="89.0955" y="-102.6701" font-family="Times,serif" font-size="14.00" fill="#000000">layer_norm</text>
<text text-anchor="middle" x="89.0955" y="-87.6701" font-family="Times,serif" font-size="14.00" fill="#000000">&lt;Paddle CPU&gt;</text>
</g>
<!-- e -->
<g id="node4" class="node">
<title>e</title>
<ellipse fill="none" stroke="#000000" cx="89.0955" cy="-18" rx="27" ry="18"/>
<text text-anchor="middle" x="89.0955" y="-14.3" font-family="Times,serif" font-size="14.00" fill="#000000">a</text>
</g>
<!-- e2&#45;&gt;e -->
<g id="edge4" class="edge">
<title>e2&#45;&gt;e</title>
<path fill="none" stroke="#000000" d="M89.0955,-71.9415C89.0955,-63.6709 89.0955,-54.5487 89.0955,-46.1957"/>
<polygon fill="#000000" stroke="#000000" points="92.5956,-46.1488 89.0955,-36.1488 85.5956,-46.1489 92.5956,-46.1488"/>
</g>
<!-- c&#45;&gt;e2 -->
<g id="edge3" class="edge">
<title>c&#45;&gt;e2</title>
<path fill="none" stroke="#000000" d="M89.0955,-161.3894C89.0955,-153.8196 89.0955,-144.7601 89.0955,-135.9182"/>
<polygon fill="#000000" stroke="#000000" points="92.5956,-135.7406 89.0955,-125.7407 85.5956,-135.7407 92.5956,-135.7406"/>
</g>
<!-- a -->
<g id="node5" class="node">
<title>a</title>
<ellipse fill="none" stroke="#000000" cx="89.0955" cy="-341.4802" rx="27" ry="18"/>
<text text-anchor="middle" x="89.0955" y="-337.7802" font-family="Times,serif" font-size="14.00" fill="#000000">a</text>
</g>
<!-- a&#45;&gt;e1 -->
<g id="edge1" class="edge">
<title>a&#45;&gt;e1</title>
<path fill="none" stroke="#000000" d="M89.0955,-323.1296C89.0955,-315.5597 89.0955,-306.5002 89.0955,-297.6583"/>
<polygon fill="#000000" stroke="#000000" points="92.5956,-297.4808 89.0955,-287.4808 85.5956,-297.4808 92.5956,-297.4808"/>
</g>
</g>
</svg>
MKL-DNN IN-PLACE execution support
--------------------------------------
.. toctree::
:maxdepth: 1
inplace.md
## Introduction
PaddlePaddle is implementing concept of in-place execution of some of operators.
The idea of in-place execution is present on following picture:
![](images/inplace.svg)
Exemplary graph presents three operators where one of them (type of elementwise_add) is to be performing in-place computation. In-place computation means that input variable (Tensor) is used for both input and output. This means that one of inputs will be overwritten with computational results. In presented picture in-place operator (elementwise_add) is
having two input nodes: *b* and *d* and output *b*. So *b* is used for input and output and underneath it is represented by a one, shared Tensor. So this means that variable *b* is initially holding some input data and after the operator computation, input data is lost and replaced by computation's result.
Currently assumption is that if operator can have in-place processing then all its kernel (including oneDNN) should be able to work properly in in-place mode. To match this functionality oneDNN integration was extended to support in-place execution for some of its operators:
- activations
- softmax
- elementwise_add
- gelu*
- sum**
Adventages of in-place computation are:
* lower memory usage
* improved performance of operators
To have in-place computation, we need to analyze graph to search for where in-place execution could happen
and then make some of variables to be shared by input and output of in-place capable operator.
Hence there are two parts of in-place support:
- in-place execution support within an operator
- oneDNN inplace C-API pass
#### in-place execution support within an operator
For in-place execution, oneDNN primitive needs to have the same oneDNN memory object passed as input (src) and output (dst). More precisely, we check if pointers to allocated buffers are the same for input and output
and this indicates if we use one oneDNN memory object or two. For example:
`auto src_memory_p = handler.AcquireSrcMemory(x);`
`auto dst_memory_p = x->IsSharedBufferWith(*y) ?
src_memory_p : handler.AcquireDstMemory(y);`
#### oneDNN in-place pass
As mentioned earlier, idea of in-place pass is to locate operators with oneDNN kerenels that can perform in-place execution and then modify output node's variables to match input node's variable of the operator.
##### Identifying operators with oneDNN kernels capable of in-place execution
This identification is a result of two checks:
- Whether operator does have *inplaceInferer* structure
- Whether operator is on a list of oneDNN's in-place supported operators
*InplaceInferer* is a struct that declares a mapping (one of inputs to one of outputs) indicating that
considered operator can perform in-place execution and both vars (mentioned input and output in *InplaceInferer*) will
share a tensor. This is not enough for oneDNN in-place C-API execution as oneDNN library may not provide in-place
computation for all required (to have in-place execution) operators of PaddlePaddle and some of operators would have to
simulate in-place computation through the external buffer which would not bring any benefits, so there is no point enabling those in-place computations for C-API inference.
##### Restrictions
oneDNN in-place pass is taking advantage of graph pattern detector. So pattern consists of:
Node (Var 1) -> Node (oneDNN Op to be inplaced) -> Node (Var2) -> Node (next op - any type, oneDNN/native CPU - after in-placed one) -> Node (Var3)
Pattern is restricted so that in-placed to be op is of oneDNN type. Due to fact that some operators have
more than one input and their output may be consumed by more than one operator it is expected that pattern
maybe detected multiple times for the same operator e.g. once for one input, then for second input etc..
Just having oneDNN operator capable of in-place is not enough to have in-place execution enabled, hence follwing rules
are checked by oneDNN in-place pass:
1. If input node to in-place operator is also an input to different operator, then in-place computation cannot be performed, as there is a risk that other operator consuming in-placed op operator will be executed after in-placed operator and therefore get invalid input data (overwritten by in-place computation).
2. If after in-placed operator there is another operator that is reusing in-place op's input var then in-place cannot happen unless next op can perform in-place computation. Next picture presents the idea.
![](images/unwanted-inplace.svg)
In the picture we are seeing that in-place pass is considering to enable in-place execution for softmax oneDNN kernel. All is fine, but next operator after softmax is layer norm (non-oneDNN). Layer norm is already reusing input of softmax due to some earlier memory optimization pass being applied. If we make softmax op to perform in-place computation, then
it will also make layer norm to work in-place (b -> a). The thing is that layer norm cannot work in-place (InplaceInferer is not present), so if we force it do so layer norm will produce invalid result.
##### In-place pass modification to graph when applied
When sub-graph is aligned with restrictions then in-place computation can be enabled. This is done by:
1. Changing the name of output node of in-place op to be match input node of in-place op.
2. Renaming output var in output lists of node representing operator.
3. Changing the name of input var in next op inputs list.
4. If next Op is performing in-place computation then we need to updated next op's output as well not to break its
in-place computation.
5. if there are multiple operators after our in-place operator then we need to update all of them (their input vars). Idea is presented in the following picture:
![](images/multi-output-inplace.svg)
We can see that there are two *top_k* operators after *elementwise_add* operator that is set to work in-placed. Each of *top_k* is having its own list of input vars, so we need to rename relevant input var to new name. As in-place pattern
consists of: input node -> in-place op -> output node -> next op -> next op's output. For presented graph, there will be 8 patterns detected:
- b -> elementwise_add -> c -> top_k (left one) -> d
- b -> elementwise_add -> c -> top_k (left one) -> e
- b -> elementwise_add -> c -> top_k (right one) -> g
- b -> elementwise_add -> c -> top_k (right one) -> h
- a -> elementwise_add -> c -> top_k (left one) -> d
- a -> elementwise_add -> c -> top_k (left one) -> e
- a -> elementwise_add -> c -> top_k (right one) -> g
- a -> elementwise_add -> c -> top_k (right one) -> h
Important thing is to remember original name of output, before it is renamed, so later we can
replace this original name in all of next op instances.
\* oneDNN gelu kernel is able to perform in-place execution, but currently gelu op does not support in-place execution.
\*\* sum kernel is using oneDNN sum primitive that does not provide in-place exection, so in-place computation is done faked through external buffer. So it was not added into oneDNN inplace pass.
digraph G {
overlap=false
e1[label="relu"]
e2[label="elementwise_add"]
e3[label="elementwise_mul"]
a -> e1
e1 -> b
b[label="b"]
e[label="b"]
subgraph cluster_0 {
label="in-placed"
b -> e2
d -> e2
e2 -> e
}
e -> e3
f -> e3 -> g
}
digraph G {
subgraph cluster_before {
label="before"
style=dotted
op1[label="elementwise_add"]
op2[label="top_k\ninputs_vars{c}"]
op3[label="top_k\ninputs_vars{c}"]
c[label="c"]
subgraph cluster_0 {
style=solid
label="to be in-placed"
a -> op1
b-> op1
op1 -> c
}
c -> op2
c -> op3
op2 -> d
op2 -> e
op3 -> g
op3 -> h
}
subgraph cluster_after {
label="after"
style=dotted
op1b[label="elementwise_add"]
op2b[label="top_k\ninput_vars{a}"]
op3b[label="top_k\ninput_vars{a}"]
cb[label="a"]
ab[label="a"]
bb[label="b"]
db[label="d"]
eb[label="e"]
gb[label="g"]
hb[label="h"]
subgraph cluster_0b {
style=solid
label="applied in-placed"
ab -> op1b
bb-> op1b
op1b -> cb
}
cb -> op2b
cb -> op3b
op2b -> db
op2b -> eb
op3b -> gb
op3b -> hb
}
}
digraph G {
e1[label="softmax\n<oneDNN>"]
e2[label="layer_norm\n<Paddle CPU>"]
c[label="b"]
e[label="a"]
subgraph cluster_0 {
label="in-placed"
a -> e1
e1 -> c
}
c -> e2
e2 -> e
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册