提交 b4194f29 编写于 作者: J Jacek Czaja 提交者: Tao Luo

Design doc on NHWC layout support by MKL-DNN integration (#1727)

上级 2d89f9a1
......@@ -13,8 +13,12 @@ We can distinguish following scenarios(presented below on the picture):
### Paddle(CPU) kernel is followed by MKL-DNN kernel
In a situation when Paddle(CPU) kernel finished execution, its outcome is one or many Tensors of Paddle layout. Each of those
Tensors to be feed into MKL-DNN kernel, needs to be transformed to be of MKL-DNN layout. For this scenario conversion of Paddle Tensor to MKL-DNN Tensor is done by just
changing layout flag to MKL-DNN and picking MKL-DNN format that match Paddle Tensor rank. This is computationally cheap operation as there is no real data rearrangement.
Tensors to be feed into MKL-DNN kernel, needs to be transformed to be of MKL-DNN layout. For this scenario conversion of Paddle Tensor to MKL-DNN Tensor is done by:
* changing layout flag to MKL-DNN
* picking MKL-DNN format that match Paddle Tensor rank
* Rearrange dims order to NCHW
Those are computationally cheap operation as there is no real data rearrangement. More information on conversion from Paddle layout to MKL-DNN Tensor can be found in relevant [document](../nhwc/nhwc.md)
This scenario is drawn on the picture with bold lines. Starting from Paddle(CPU) op on the left side , following arrows drawn in bold and finishing with MKL-DNN op on the right side of picture.
......@@ -22,7 +26,7 @@ This scenario is drawn on the picture with bold lines. Starting from Paddle(CPU)
In this situation MKL-DNN kernel finished its execution and as a result it produced one or more output Tensors. Each of those Tensors are of MKL-DNN layout and to be fed into Paddle(CPU) kernel,
they need to be converted into Paddle layout. In a detail MKL-DNN Tensor arrangement (mkl-dnn memory format) is checked if it is compatible with Paddle(CPU) layout and if positive then
just layout of Tensor is set as Paddle and mkl-dnn format is set to ``undef``. In case when MKL-DNN Tensor data arrangement is not compatible with Paddle layout then actual data arrangement
is performed. For example MKL-DNN Tensor is 4D and having format ``NCHW16C`` and to convert it into Paddle layout we need to rearrange data to be ``NCHW`` format. To do so
is performed. For example MKL-DNN Tensor is 4D and having format ``NCHW16C`` and to convert it into Paddle layout of ``NCHW`` we need to rearrange data to be ``NCHW`` format. To do so
MKL-DNN Reorder primitive is created that can do data rearrangement.
This scenario is marked on the picture with outlined, empty inside arrows. Starting from MKL-DNN op on the left side , following empty arrows finishing with Paddle(CPU) op on the right side of picture.
......
<?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.38.0 (20140413.2041)
-->
<!-- Title: G Pages: 1 -->
<svg width="1556pt" height="403pt"
viewBox="0.00 0.00 1555.94 403.09" 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 399.09)">
<title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-399.09 1551.94,-399.09 1551.94,4 -4,4"/>
<!-- feed_op -->
<g id="node1" class="node"><title>feed_op</title>
<ellipse fill="none" stroke="black" cx="47.3762" cy="-301.045" rx="44.5955" ry="44.5955"/>
<text text-anchor="middle" x="47.3762" y="-312.845" font-family="Times,serif" font-size="14.00">Feed Op</text>
<text text-anchor="middle" x="47.3762" y="-281.845" font-family="Times,serif" font-size="14.00">Paddle</text>
</g>
<!-- tensor_feed -->
<g id="node17" class="node"><title>tensor_feed</title>
<polygon fill="none" stroke="black" points="260.752,-327.545 135.752,-327.545 135.752,-274.545 260.752,-274.545 260.752,-327.545"/>
<text text-anchor="middle" x="198.252" y="-312.345" font-family="Times,serif" font-size="14.00">Tensor feed_op</text>
<text text-anchor="middle" x="198.252" y="-297.345" font-family="Times,serif" font-size="14.00">layout=kNCHW</text>
<text text-anchor="middle" x="198.252" y="-282.345" font-family="Times,serif" font-size="14.00">NHWC dim format</text>
</g>
<!-- feed_op&#45;&gt;tensor_feed -->
<g id="edge1" class="edge"><title>feed_op&#45;&gt;tensor_feed</title>
<path fill="none" stroke="black" d="M92.2355,-301.045C92.2355,-301.045 125.696,-301.045 125.696,-301.045"/>
<polygon fill="black" stroke="black" points="125.696,-304.545 135.696,-301.045 125.696,-297.545 125.696,-304.545"/>
</g>
<!-- fetch_op -->
<g id="node2" class="node"><title>fetch_op</title>
<ellipse fill="none" stroke="black" cx="47.3762" cy="-94.0452" rx="47.2526" ry="47.2526"/>
<text text-anchor="middle" x="47.3762" y="-105.845" font-family="Times,serif" font-size="14.00">Fetch Op</text>
<text text-anchor="middle" x="47.3762" y="-74.8452" font-family="Times,serif" font-size="14.00">Paddle</text>
</g>
<!-- mean_op -->
<g id="node3" class="node"><title>mean_op</title>
<ellipse fill="none" stroke="black" cx="1477.94" cy="-302.045" rx="48.1667" ry="48.1667"/>
<text text-anchor="middle" x="1477.94" y="-313.845" font-family="Times,serif" font-size="14.00">Mean Op</text>
<text text-anchor="middle" x="1477.94" y="-282.845" font-family="Times,serif" font-size="14.00">Paddle</text>
</g>
<!-- tensor_output_mean -->
<g id="node15" class="node"><title>tensor_output_mean</title>
<polygon fill="none" stroke="black" points="1540.44,-235.545 1415.44,-235.545 1415.44,-182.545 1540.44,-182.545 1540.44,-235.545"/>
<text text-anchor="middle" x="1477.94" y="-220.345" font-family="Times,serif" font-size="14.00">Tensor mean op</text>
<text text-anchor="middle" x="1477.94" y="-205.345" font-family="Times,serif" font-size="14.00">layout=kNHWC</text>
<text text-anchor="middle" x="1477.94" y="-190.345" font-family="Times,serif" font-size="14.00">NHWC dim format</text>
</g>
<!-- mean_op&#45;&gt;tensor_output_mean -->
<g id="edge9" class="edge"><title>mean_op&#45;&gt;tensor_output_mean</title>
<path fill="none" stroke="black" d="M1477.94,-253.911C1477.94,-253.911 1477.94,-245.855 1477.94,-245.855"/>
<polygon fill="black" stroke="black" points="1481.44,-245.855 1477.94,-235.855 1474.44,-245.855 1481.44,-245.855"/>
</g>
<!-- mean_grad_op -->
<g id="node4" class="node"><title>mean_grad_op</title>
<ellipse fill="none" stroke="black" cx="1477.94" cy="-94.0452" rx="70.0071" ry="70.0071"/>
<text text-anchor="middle" x="1477.94" y="-105.845" font-family="Times,serif" font-size="14.00">Mean Grad Op</text>
<text text-anchor="middle" x="1477.94" y="-74.8452" font-family="Times,serif" font-size="14.00">Paddle</text>
</g>
<!-- tensor_mean_grad -->
<g id="node16" class="node"><title>tensor_mean_grad</title>
<polygon fill="none" stroke="black" points="1371.93,-120.545 1238.93,-120.545 1238.93,-67.5452 1371.93,-67.5452 1371.93,-120.545"/>
<text text-anchor="middle" x="1305.43" y="-105.345" font-family="Times,serif" font-size="14.00">Tensor mean grad op</text>
<text text-anchor="middle" x="1305.43" y="-90.3452" font-family="Times,serif" font-size="14.00">layout=kNHWC</text>
<text text-anchor="middle" x="1305.43" y="-75.3452" font-family="Times,serif" font-size="14.00">NHWC dim format</text>
</g>
<!-- mean_grad_op&#45;&gt;tensor_mean_grad -->
<g id="edge12" class="edge"><title>mean_grad_op&#45;&gt;tensor_mean_grad</title>
<path fill="none" stroke="black" d="M1407.77,-94.0452C1407.77,-94.0452 1382.19,-94.0452 1382.19,-94.0452"/>
<polygon fill="black" stroke="black" points="1382.19,-90.5453 1372.19,-94.0452 1382.19,-97.5453 1382.19,-90.5453"/>
</g>
<!-- conv_mkldnn -->
<g id="node5" class="node"><title>conv_mkldnn</title>
<ellipse fill="none" stroke="black" cx="556.798" cy="-301.045" rx="94.0904" ry="94.0904"/>
<text text-anchor="middle" x="556.798" y="-320.345" font-family="Times,serif" font-size="14.00">Conv Op</text>
<text text-anchor="middle" x="556.798" y="-305.345" font-family="Times,serif" font-size="14.00">data_format=NHWC</text>
<text text-anchor="middle" x="556.798" y="-274.345" font-family="Times,serif" font-size="14.00">MKL&#45;DNN</text>
</g>
<!-- tensor_mkldnn -->
<g id="node9" class="node"><title>tensor_mkldnn</title>
<polygon fill="none" stroke="black" points="814.843,-327.545 689.843,-327.545 689.843,-274.545 814.843,-274.545 814.843,-327.545"/>
<text text-anchor="middle" x="752.343" y="-312.345" font-family="Times,serif" font-size="14.00">Tensor conv op</text>
<text text-anchor="middle" x="752.343" y="-297.345" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="752.343" y="-282.345" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- conv_mkldnn&#45;&gt;tensor_mkldnn -->
<g id="edge4" class="edge"><title>conv_mkldnn&#45;&gt;tensor_mkldnn</title>
<path fill="none" stroke="black" d="M650.847,-301.045C650.847,-301.045 679.779,-301.045 679.779,-301.045"/>
<polygon fill="black" stroke="black" points="679.779,-304.545 689.779,-301.045 679.779,-297.545 679.779,-304.545"/>
</g>
<!-- conv_grad_mkldnn -->
<g id="node6" class="node"><title>conv_grad_mkldnn</title>
<ellipse fill="none" stroke="black" cx="556.798" cy="-94.0452" rx="94.0904" ry="94.0904"/>
<text text-anchor="middle" x="556.798" y="-113.345" font-family="Times,serif" font-size="14.00">Conv Grad Op</text>
<text text-anchor="middle" x="556.798" y="-98.3452" font-family="Times,serif" font-size="14.00">data_format=NHWC</text>
<text text-anchor="middle" x="556.798" y="-67.3452" font-family="Times,serif" font-size="14.00">MKL&#45;DNN</text>
</g>
<!-- tensor_conv_grad_mkldnn -->
<g id="node11" class="node"><title>tensor_conv_grad_mkldnn</title>
<polygon fill="none" stroke="black" points="265.752,-120.545 130.752,-120.545 130.752,-67.5452 265.752,-67.5452 265.752,-120.545"/>
<text text-anchor="middle" x="198.252" y="-105.345" font-family="Times,serif" font-size="14.00">Tensor Conv Grad op</text>
<text text-anchor="middle" x="198.252" y="-90.3452" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="198.252" y="-75.3452" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- conv_grad_mkldnn&#45;&gt;tensor_conv_grad_mkldnn -->
<g id="edge17" class="edge"><title>conv_grad_mkldnn&#45;&gt;tensor_conv_grad_mkldnn</title>
<path fill="none" stroke="black" d="M462.594,-94.0452C462.594,-94.0452 275.784,-94.0452 275.784,-94.0452"/>
<polygon fill="black" stroke="black" points="275.784,-90.5453 265.784,-94.0452 275.784,-97.5453 275.784,-90.5453"/>
</g>
<!-- pool_mkldnn -->
<g id="node7" class="node"><title>pool_mkldnn</title>
<ellipse fill="none" stroke="black" cx="947.888" cy="-301.045" rx="94.0904" ry="94.0904"/>
<text text-anchor="middle" x="947.888" y="-320.345" font-family="Times,serif" font-size="14.00">Pool Op</text>
<text text-anchor="middle" x="947.888" y="-305.345" font-family="Times,serif" font-size="14.00">data_format=NHWC</text>
<text text-anchor="middle" x="947.888" y="-274.345" font-family="Times,serif" font-size="14.00">MKL&#45;DNN</text>
</g>
<!-- tensor_mkldnn2 -->
<g id="node12" class="node"><title>tensor_mkldnn2</title>
<polygon fill="none" stroke="black" points="1202.93,-327.545 1077.93,-327.545 1077.93,-274.545 1202.93,-274.545 1202.93,-327.545"/>
<text text-anchor="middle" x="1140.43" y="-312.345" font-family="Times,serif" font-size="14.00">Tensor pool op</text>
<text text-anchor="middle" x="1140.43" y="-297.345" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="1140.43" y="-282.345" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- pool_mkldnn&#45;&gt;tensor_mkldnn2 -->
<g id="edge6" class="edge"><title>pool_mkldnn&#45;&gt;tensor_mkldnn2</title>
<path fill="none" stroke="black" d="M1042.19,-301.045C1042.19,-301.045 1067.85,-301.045 1067.85,-301.045"/>
<polygon fill="black" stroke="black" points="1067.85,-304.545 1077.85,-301.045 1067.85,-297.545 1067.85,-304.545"/>
</g>
<!-- pool_grad_mkldnn -->
<g id="node8" class="node"><title>pool_grad_mkldnn</title>
<ellipse fill="none" stroke="black" cx="947.888" cy="-94.0452" rx="94.0904" ry="94.0904"/>
<text text-anchor="middle" x="947.888" y="-113.345" font-family="Times,serif" font-size="14.00">Pool Grad Op</text>
<text text-anchor="middle" x="947.888" y="-98.3452" font-family="Times,serif" font-size="14.00">data_format=NHWC</text>
<text text-anchor="middle" x="947.888" y="-67.3452" font-family="Times,serif" font-size="14.00">MKL&#45;DNN</text>
</g>
<!-- tensor_pool_grad_mkldnn -->
<g id="node10" class="node"><title>tensor_pool_grad_mkldnn</title>
<polygon fill="none" stroke="black" points="817.843,-120.545 686.843,-120.545 686.843,-67.5452 817.843,-67.5452 817.843,-120.545"/>
<text text-anchor="middle" x="752.343" y="-105.345" font-family="Times,serif" font-size="14.00">Tensor Pool Grad op</text>
<text text-anchor="middle" x="752.343" y="-90.3452" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="752.343" y="-75.3452" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- pool_grad_mkldnn&#45;&gt;tensor_pool_grad_mkldnn -->
<g id="edge15" class="edge"><title>pool_grad_mkldnn&#45;&gt;tensor_pool_grad_mkldnn</title>
<path fill="none" stroke="black" d="M853.838,-94.0452C853.838,-94.0452 827.96,-94.0452 827.96,-94.0452"/>
<polygon fill="black" stroke="black" points="827.96,-90.5453 817.96,-94.0452 827.96,-97.5453 827.96,-90.5453"/>
</g>
<!-- tensor_mkldnn&#45;&gt;pool_mkldnn -->
<g id="edge5" class="edge"><title>tensor_mkldnn&#45;&gt;pool_mkldnn</title>
<path fill="none" stroke="black" d="M815.021,-301.045C815.021,-301.045 843.511,-301.045 843.511,-301.045"/>
<polygon fill="black" stroke="black" points="843.511,-304.545 853.511,-301.045 843.511,-297.545 843.511,-304.545"/>
</g>
<!-- tensor_pool_grad_mkldnn&#45;&gt;conv_grad_mkldnn -->
<g id="edge16" class="edge"><title>tensor_pool_grad_mkldnn&#45;&gt;conv_grad_mkldnn</title>
<path fill="none" stroke="black" d="M686.685,-94.0452C686.685,-94.0452 661.152,-94.0452 661.152,-94.0452"/>
<polygon fill="black" stroke="black" points="661.152,-90.5453 651.152,-94.0452 661.152,-97.5453 661.152,-90.5453"/>
</g>
<!-- tensor_conv_grad_mkldnn&#45;&gt;fetch_op -->
<g id="edge18" class="edge"><title>tensor_conv_grad_mkldnn&#45;&gt;fetch_op</title>
<path fill="none" stroke="black" d="M130.318,-94.0452C130.318,-94.0452 105.095,-94.0452 105.095,-94.0452"/>
<polygon fill="black" stroke="black" points="105.095,-90.5453 95.0949,-94.0452 105.095,-97.5453 105.095,-90.5453"/>
</g>
<!-- tensor_input_mean -->
<g id="node14" class="node"><title>tensor_input_mean</title>
<polygon fill="none" stroke="black" points="1367.93,-327.545 1242.93,-327.545 1242.93,-274.545 1367.93,-274.545 1367.93,-327.545"/>
<text text-anchor="middle" x="1305.43" y="-312.345" font-family="Times,serif" font-size="14.00">Tensor pool op</text>
<text text-anchor="middle" x="1305.43" y="-297.345" font-family="Times,serif" font-size="14.00">layout=kNHWC</text>
<text text-anchor="middle" x="1305.43" y="-282.345" font-family="Times,serif" font-size="14.00">NHWC dim format</text>
</g>
<!-- tensor_mkldnn2&#45;&gt;tensor_input_mean -->
<g id="edge7" class="edge"><title>tensor_mkldnn2&#45;&gt;tensor_input_mean</title>
<path fill="none" stroke="black" d="M1203.28,-301.045C1203.28,-301.045 1232.76,-301.045 1232.76,-301.045"/>
<polygon fill="black" stroke="black" points="1232.76,-304.545 1242.76,-301.045 1232.76,-297.545 1232.76,-304.545"/>
</g>
<!-- tensor_mean_grad_mkldnn -->
<g id="node13" class="node"><title>tensor_mean_grad_mkldnn</title>
<polygon fill="none" stroke="black" points="1202.93,-120.545 1077.93,-120.545 1077.93,-67.5452 1202.93,-67.5452 1202.93,-120.545"/>
<text text-anchor="middle" x="1140.43" y="-105.345" font-family="Times,serif" font-size="14.00">Tensor Grad mean</text>
<text text-anchor="middle" x="1140.43" y="-90.3452" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="1140.43" y="-75.3452" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- tensor_mean_grad_mkldnn&#45;&gt;pool_grad_mkldnn -->
<g id="edge14" class="edge"><title>tensor_mean_grad_mkldnn&#45;&gt;pool_grad_mkldnn</title>
<path fill="none" stroke="black" d="M1077.92,-94.0452C1077.92,-94.0452 1052.25,-94.0452 1052.25,-94.0452"/>
<polygon fill="black" stroke="black" points="1052.25,-90.5453 1042.25,-94.0452 1052.25,-97.5453 1052.25,-90.5453"/>
</g>
<!-- tensor_input_mean&#45;&gt;mean_op -->
<g id="edge8" class="edge"><title>tensor_input_mean&#45;&gt;mean_op</title>
<path fill="none" stroke="black" d="M1368.2,-301.045C1368.2,-301.045 1419.82,-301.045 1419.82,-301.045"/>
<polygon fill="black" stroke="black" points="1419.82,-304.545 1429.82,-301.045 1419.82,-297.545 1419.82,-304.545"/>
</g>
<!-- tensor_input_mean&#45;&gt;tensor_mean_grad -->
<g id="edge10" class="edge"><title>tensor_input_mean&#45;&gt;tensor_mean_grad</title>
<path fill="none" stroke="black" stroke-dasharray="5,2" d="M1305.94,-274.407C1305.94,-274.407 1305.94,-130.581 1305.94,-130.581"/>
<polygon fill="black" stroke="black" points="1309.44,-130.581 1305.94,-120.581 1302.44,-130.581 1309.44,-130.581"/>
<text text-anchor="middle" x="1275.94" y="-191.294" font-family="Times,serif" font-size="14.00">InferShape</text>
</g>
<!-- tensor_output_mean&#45;&gt;mean_grad_op -->
<g id="edge11" class="edge"><title>tensor_output_mean&#45;&gt;mean_grad_op</title>
<path fill="none" stroke="black" d="M1477.94,-182.373C1477.94,-182.373 1477.94,-174.336 1477.94,-174.336"/>
<polygon fill="black" stroke="black" points="1481.44,-174.336 1477.94,-164.336 1474.44,-174.336 1481.44,-174.336"/>
</g>
<!-- tensor_mean_grad&#45;&gt;tensor_mean_grad_mkldnn -->
<g id="edge13" class="edge"><title>tensor_mean_grad&#45;&gt;tensor_mean_grad_mkldnn</title>
<path fill="none" stroke="black" d="M1238.8,-94.0452C1238.8,-94.0452 1213.04,-94.0452 1213.04,-94.0452"/>
<polygon fill="black" stroke="black" points="1213.04,-90.5453 1203.04,-94.0452 1213.04,-97.5453 1213.04,-90.5453"/>
</g>
<!-- tensor_feed2 -->
<g id="node18" class="node"><title>tensor_feed2</title>
<polygon fill="none" stroke="black" points="426.752,-327.545 301.752,-327.545 301.752,-274.545 426.752,-274.545 426.752,-327.545"/>
<text text-anchor="middle" x="364.252" y="-312.345" font-family="Times,serif" font-size="14.00">Tensor feed_op</text>
<text text-anchor="middle" x="364.252" y="-297.345" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="364.252" y="-282.345" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- tensor_feed&#45;&gt;tensor_feed2 -->
<g id="edge2" class="edge"><title>tensor_feed&#45;&gt;tensor_feed2</title>
<path fill="none" stroke="black" d="M261.01,-301.045C261.01,-301.045 291.681,-301.045 291.681,-301.045"/>
<polygon fill="black" stroke="black" points="291.682,-304.545 301.681,-301.045 291.681,-297.545 291.682,-304.545"/>
</g>
<!-- tensor_feed2&#45;&gt;conv_mkldnn -->
<g id="edge3" class="edge"><title>tensor_feed2&#45;&gt;conv_mkldnn</title>
<path fill="none" stroke="black" d="M426.766,-301.045C426.766,-301.045 452.437,-301.045 452.437,-301.045"/>
<polygon fill="black" stroke="black" points="452.437,-304.545 462.437,-301.045 452.437,-297.545 452.437,-304.545"/>
</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.38.0 (20140413.2041)
-->
<!-- Title: G Pages: 1 -->
<svg width="1598pt" height="410pt"
viewBox="0.00 0.00 1597.92 409.63" 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 405.626)">
<title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-405.626 1593.92,-405.626 1593.92,4 -4,4"/>
<!-- feed_op -->
<g id="node1" class="node"><title>feed_op</title>
<ellipse fill="none" stroke="black" cx="98.9949" cy="-302.631" rx="98.9899" ry="98.9899"/>
<text text-anchor="middle" x="98.9949" y="-314.431" font-family="Times,serif" font-size="14.00">Feed Op (Input signal)</text>
<text text-anchor="middle" x="98.9949" y="-283.431" font-family="Times,serif" font-size="14.00">Paddle</text>
</g>
<!-- input_feed -->
<g id="node9" class="node"><title>input_feed</title>
<polygon fill="none" stroke="black" points="362.99,-318.631 233.99,-318.631 233.99,-268.631 362.99,-268.631 362.99,-318.631"/>
<text text-anchor="start" x="245.49" y="-304.431" font-family="Times,serif" font-size="14.00">Tensor Input signal</text>
<text text-anchor="start" x="252.99" y="-290.431" font-family="Times,serif" font-size="14.00">layout=kNCHW</text>
<text text-anchor="start" x="241.99" y="-276.431" font-family="Times,serif" font-weight="bold" font-size="14.00">NHWC</text>
<text text-anchor="start" x="287.99" y="-276.431" font-family="Times,serif" font-size="14.00"> dim format</text>
</g>
<!-- feed_op&#45;&gt;input_feed -->
<g id="edge1" class="edge"><title>feed_op&#45;&gt;input_feed</title>
<path fill="none" stroke="black" d="M198.164,-298.157C206.767,-297.765 215.376,-297.373 223.729,-296.992"/>
<polygon fill="black" stroke="black" points="223.944,-300.486 233.775,-296.535 223.626,-293.493 223.944,-300.486"/>
</g>
<!-- feed_op2 -->
<g id="node2" class="node"><title>feed_op2</title>
<ellipse fill="none" stroke="black" cx="98.9949" cy="-92.631" rx="92.7622" ry="92.7622"/>
<text text-anchor="middle" x="98.9949" y="-104.431" font-family="Times,serif" font-size="14.00">Feed Op (Filter data)</text>
<text text-anchor="middle" x="98.9949" y="-73.431" font-family="Times,serif" font-size="14.00">Paddle</text>
</g>
<!-- filter_feed -->
<g id="node11" class="node"><title>filter_feed</title>
<polygon fill="none" stroke="black" points="360.99,-188.131 235.99,-188.131 235.99,-135.131 360.99,-135.131 360.99,-188.131"/>
<text text-anchor="middle" x="298.49" y="-172.931" font-family="Times,serif" font-size="14.00">Tensor filter data</text>
<text text-anchor="middle" x="298.49" y="-157.931" font-family="Times,serif" font-size="14.00">layout=kNCHW</text>
<text text-anchor="middle" x="298.49" y="-142.931" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- feed_op2&#45;&gt;filter_feed -->
<g id="edge9" class="edge"><title>feed_op2&#45;&gt;filter_feed</title>
<path fill="none" stroke="black" d="M186.619,-122.895C199.833,-127.512 213.342,-132.232 226.178,-136.716"/>
<polygon fill="black" stroke="black" points="225.253,-140.1 235.847,-140.095 227.561,-133.492 225.253,-140.1"/>
</g>
<!-- fetch_op -->
<g id="node3" class="node"><title>fetch_op</title>
<ellipse fill="none" stroke="black" cx="1377.55" cy="-218.631" rx="47.2526" ry="47.2526"/>
<text text-anchor="middle" x="1377.55" y="-230.431" font-family="Times,serif" font-size="14.00">Fetch Op</text>
<text text-anchor="middle" x="1377.55" y="-199.431" font-family="Times,serif" font-size="14.00">Paddle</text>
</g>
<!-- tensor_fetch -->
<g id="node8" class="node"><title>tensor_fetch</title>
<polygon fill="none" stroke="black" points="1589.92,-243.631 1460.92,-243.631 1460.92,-193.631 1589.92,-193.631 1589.92,-243.631"/>
<text text-anchor="start" x="1480.92" y="-229.431" font-family="Times,serif" font-size="14.00">Tensor fetch_op</text>
<text text-anchor="start" x="1479.92" y="-215.431" font-family="Times,serif" font-size="14.00">layout=kNCHW</text>
<text text-anchor="start" x="1468.92" y="-201.431" font-family="Times,serif" font-weight="bold" font-size="14.00">NHWC</text>
<text text-anchor="start" x="1514.92" y="-201.431" font-family="Times,serif" font-size="14.00"> dim format</text>
</g>
<!-- fetch_op&#45;&gt;tensor_fetch -->
<g id="edge8" class="edge"><title>fetch_op&#45;&gt;tensor_fetch</title>
<path fill="none" stroke="black" d="M1425.1,-218.631C1433.25,-218.631 1441.91,-218.631 1450.59,-218.631"/>
<polygon fill="black" stroke="black" points="1450.75,-222.131 1460.75,-218.631 1450.75,-215.131 1450.75,-222.131"/>
</g>
<!-- conv_mkldnn -->
<g id="node4" class="node"><title>conv_mkldnn</title>
<ellipse fill="none" stroke="black" cx="654.035" cy="-218.631" rx="94.0904" ry="94.0904"/>
<text text-anchor="middle" x="654.035" y="-237.931" font-family="Times,serif" font-size="14.00">conv Op</text>
<text text-anchor="middle" x="654.035" y="-222.931" font-family="Times,serif" font-size="14.00">data_format=NHWC</text>
<text text-anchor="middle" x="654.035" y="-191.931" font-family="Times,serif" font-size="14.00">MKL&#45;DNN</text>
</g>
<!-- tensor_mkldnn -->
<g id="node6" class="node"><title>tensor_mkldnn</title>
<polygon fill="none" stroke="black" points="909.08,-245.131 784.08,-245.131 784.08,-192.131 909.08,-192.131 909.08,-245.131"/>
<text text-anchor="middle" x="846.58" y="-229.931" font-family="Times,serif" font-size="14.00">Tensor conv op</text>
<text text-anchor="middle" x="846.58" y="-214.931" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="846.58" y="-199.931" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- conv_mkldnn&#45;&gt;tensor_mkldnn -->
<g id="edge4" class="edge"><title>conv_mkldnn&#45;&gt;tensor_mkldnn</title>
<path fill="none" stroke="black" d="M748.354,-218.631C756.935,-218.631 765.537,-218.631 773.881,-218.631"/>
<polygon fill="black" stroke="black" points="773.913,-222.131 783.913,-218.631 773.913,-215.131 773.913,-222.131"/>
</g>
<!-- pool_mkldnn -->
<g id="node5" class="node"><title>pool_mkldnn</title>
<ellipse fill="none" stroke="black" cx="1039.13" cy="-218.631" rx="94.0904" ry="94.0904"/>
<text text-anchor="middle" x="1039.13" y="-237.931" font-family="Times,serif" font-size="14.00">pool Op</text>
<text text-anchor="middle" x="1039.13" y="-222.931" font-family="Times,serif" font-size="14.00">data_format=NHWC</text>
<text text-anchor="middle" x="1039.13" y="-191.931" font-family="Times,serif" font-size="14.00">MKL&#45;DNN</text>
</g>
<!-- tensor_mkldnn2 -->
<g id="node7" class="node"><title>tensor_mkldnn2</title>
<polygon fill="none" stroke="black" points="1294.17,-245.131 1169.17,-245.131 1169.17,-192.131 1294.17,-192.131 1294.17,-245.131"/>
<text text-anchor="middle" x="1231.67" y="-229.931" font-family="Times,serif" font-size="14.00">Tensor conv op</text>
<text text-anchor="middle" x="1231.67" y="-214.931" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="1231.67" y="-199.931" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- pool_mkldnn&#45;&gt;tensor_mkldnn2 -->
<g id="edge6" class="edge"><title>pool_mkldnn&#45;&gt;tensor_mkldnn2</title>
<path fill="none" stroke="black" d="M1133.44,-218.631C1142.03,-218.631 1150.63,-218.631 1158.97,-218.631"/>
<polygon fill="black" stroke="black" points="1159,-222.131 1169,-218.631 1159,-215.131 1159,-222.131"/>
</g>
<!-- tensor_mkldnn&#45;&gt;pool_mkldnn -->
<g id="edge5" class="edge"><title>tensor_mkldnn&#45;&gt;pool_mkldnn</title>
<path fill="none" stroke="black" d="M909.182,-218.631C917.388,-218.631 925.976,-218.631 934.656,-218.631"/>
<polygon fill="black" stroke="black" points="934.869,-222.131 944.869,-218.631 934.869,-215.131 934.869,-222.131"/>
</g>
<!-- tensor_mkldnn2&#45;&gt;fetch_op -->
<g id="edge7" class="edge"><title>tensor_mkldnn2&#45;&gt;fetch_op</title>
<path fill="none" stroke="black" d="M1294.52,-218.631C1302.97,-218.631 1311.61,-218.631 1319.95,-218.631"/>
<polygon fill="black" stroke="black" points="1319.96,-222.131 1329.96,-218.631 1319.96,-215.131 1319.96,-222.131"/>
</g>
<!-- input_feed2 -->
<g id="node10" class="node"><title>input_feed2</title>
<polygon fill="none" stroke="black" points="523.99,-285.131 398.99,-285.131 398.99,-232.131 523.99,-232.131 523.99,-285.131"/>
<text text-anchor="middle" x="461.49" y="-269.931" font-family="Times,serif" font-size="14.00">Tensor Input signal</text>
<text text-anchor="middle" x="461.49" y="-254.931" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="461.49" y="-239.931" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- input_feed&#45;&gt;input_feed2 -->
<g id="edge2" class="edge"><title>input_feed&#45;&gt;input_feed2</title>
<path fill="none" stroke="black" d="M363.121,-279.798C371.587,-277.958 380.313,-276.061 388.902,-274.194"/>
<polygon fill="black" stroke="black" points="389.869,-277.565 398.898,-272.021 388.382,-270.725 389.869,-277.565"/>
</g>
<!-- input_feed2&#45;&gt;conv_mkldnn -->
<g id="edge3" class="edge"><title>input_feed2&#45;&gt;conv_mkldnn</title>
<path fill="none" stroke="black" d="M524.091,-245.699C533.049,-243.819 542.462,-241.843 551.953,-239.851"/>
<polygon fill="black" stroke="black" points="552.787,-243.252 561.855,-237.772 551.349,-236.401 552.787,-243.252"/>
</g>
<!-- filter_feed2 -->
<g id="node12" class="node"><title>filter_feed2</title>
<polygon fill="none" stroke="black" points="523.99,-205.131 398.99,-205.131 398.99,-152.131 523.99,-152.131 523.99,-205.131"/>
<text text-anchor="middle" x="461.49" y="-189.931" font-family="Times,serif" font-size="14.00">Tensor filter data</text>
<text text-anchor="middle" x="461.49" y="-174.931" font-family="Times,serif" font-size="14.00">layout=kMKLDNN</text>
<text text-anchor="middle" x="461.49" y="-159.931" font-family="Times,serif" font-size="14.00">NCHW dim format</text>
</g>
<!-- filter_feed&#45;&gt;filter_feed2 -->
<g id="edge10" class="edge"><title>filter_feed&#45;&gt;filter_feed2</title>
<path fill="none" stroke="black" d="M361.276,-168.155C370.232,-169.101 379.515,-170.081 388.647,-171.045"/>
<polygon fill="black" stroke="black" points="388.557,-174.555 398.869,-172.124 389.292,-167.594 388.557,-174.555"/>
</g>
<!-- filter_feed2&#45;&gt;conv_mkldnn -->
<g id="edge11" class="edge"><title>filter_feed2&#45;&gt;conv_mkldnn</title>
<path fill="none" stroke="black" d="M524.091,-191.563C533.049,-193.443 542.462,-195.419 551.953,-197.411"/>
<polygon fill="black" stroke="black" points="551.349,-200.861 561.855,-199.49 552.787,-194.01 551.349,-200.861"/>
</g>
</g>
</svg>
MKL-DNN NHWC support
--------------------------------------
.. toctree::
:maxdepth: 1
nhwc.md
# Design Doc: MKL-DNN NHWC support
This document describes design & implementation of ``NHWC`` models using MKL-DNN engine. For overall
description of Tensors interoperability among Paddle and MKL-DNN Tensors please follow relevant [document](../data_transformation/data_transform.md)
### Introduction
PaddlePaddle does support execution of program/model using ``NCHW`` as well as ``NHWC`` data arrangement. Reasons for introducing data arrangements are:
* Execution performance of some of non MKL-DNN operators in ``NHWC`` may be faster that when ``NCHW`` data arrangement is used
* Convenience of use as sometimes user got his data prepared already in ``NHWC`` data arrangement.
Choice among ``NCHW`` and ``NHWC`` is controlled with ``data_format`` attributes following operators:
* conv
* conv transposed
* pool
* LRN
* batch norm
Other operators (those without data_format) are implemented so that they execute properly regardless the layout, for example elementwise operations.
Having operators to control what layout (data arrangement) input and output data of operators is, allow
in theory to specify models that partially to work on ``NCHW`` and partially to work on ``NHWC`` data arrangement.However it was agreed on that given model will only have one type of data arrangement at during it execution.
Hence either all ``data_format`` attributes are set to ``NCHW`` (default) or to ``NHWC``, there is no support for having some operators having ``data_format`` set to ``NCHW`` while some others to ``NHWC``.
Another element to consider is that PaddlePaddle ``NHWC`` data layout as supported by non-MKLDNN CPU implementations is that ``NHWC`` data arrangement is only applicable to input signal e.g. parameters of listed operators are
always using ``NCHW`` PaddlePaddle layout.
Final element is that PaddlePaddle data layout change how shape of data looks like. For example ``NCHW`` data shape of [2, 3, 4, 5] when being transformed to ``NHWC`` data will have a shape of [2, 4, 5, 3]. This is different from MKL-DNN shape description which is always ``NCHW`` order even if data underneath is ``NHWC``, ``NCHW16C`` or other.
### Architecture of ``NHWC`` support in MKL-DNN integration
Initially a request of ``NHWC`` and ``NCHW`` execution of program were implemented explicitly, e.g. by having MKL-DNN working on that selected data arrangement. This was proved to be very inefficient in terms of performance, as
performance-wise MKL-DNN is designed to work on data arrangements of its own choice (for example blocked formats ``NCHW16C``, ``NCHW8C`` etc.) rather than forcing MKL-DNN to use ``NHWC`` or ``NCHW`` data layout.
Current solution is that MKL-DNN kernels are working on data layout best suitable for their performance, but
when upon completion of final MKL-DNN operator there has to be conversion (reorder) to either ``NCHW`` or ``NHWC`` Paddle data arrangement. Important note is that last operator executing MKL-DNN kernel may not have a ``data_format`` attribute hence there is need to store information on to what PaddlePaddle layout to convert to from MKL-DNN layouts. For this purpose We have global variable kept per thread (Thread Local Storage).
To address the difference with shape description mechanism for shape transformation was added : *platform::MatchShapeToLayout()* which perform needed shape modification upon entering and exiting MKL-DNN execution thread of operators.
Described architecture applied to simple execution of ``NHWC`` model that consists of convolution followed by pooling is presented in the following picture:
![](images/nhwc.svg)
#### Notes on ``NHWC`` grad ops support
Corresponding grad MKL-DNN kernels of operators listed at the beginning of this document, also are supporting
``NHWC`` models execution.
All design concepts described in previous section do apply to MKL-DNN grad operators as well. However there
is also one additional element. Some grad operators like *mean* are inferring shape of their output, based on
shape of data produced during forward. In that situation kernel is actually having no need to operate on actual data, as only shape is needed to infer grad output's shape. In this scenario originally there was no data transformation of given variable, hence in particular no changing of shape of Tensor happened. This could result in having wrong shape send to *InferShape* of Grad op. This behaviour was modified to create dummy Variable that carries the shape of data in expected by grad operator, paddle format.
Described situation is presented in the following picture:
![](images/nhwc-grad.svg)
### Implementation guidelines
Instead of modifying each MKL-DNN operator to match described architecture design, common code was modified which consists of modifications to:
* data transformation code
* *InferShape* of each operator supporting ``data_format`` attribute.
* Also each operator was added overloading of *GetKernelTypeForVar* method.
Hence when enabling any operator to have ``NHWC`` data arrangement supported we need to extend *InferShape* and *GetKernelTypeForVar*
#### *InferShape()* modifications
This modification is related to fact that MKL-DNN kernel does operate on data with shape described in ``NCHW``
order, hence We need to make sure that even if ``data_format`` is having value ``NHWC`` still ``Infershape`` will work on ``NCHW`` order.
Snippet from *PoolOp::InferShape()* that illustrated the idea of modifications to *InferShape*:
// MKL-DNN Kernels are using NCHW order of dims description
// so we ignore data_format consideration for MKL-DNN kernel
const bool channel_last = (this->IsMKLDNNType() == false) &&
(data_format == "NHWC" || data_format == "NDHWC");
#### *GetKernelTypeForVar()* overloading
When performing data transformation we need a value of ``data_format`` and this value is acquired
inside of *GetKernelTypeForVar()* and based on that *data_layout* of Kernel Type is set, to be later
used by data transformation code.
digraph G {
splines=ortho
rankdir=LR
feed_op[shape=circle,label="Feed Op\n\nPaddle"]
fetch_op[shape=circle,label="Fetch Op\n\nPaddle"]
mean_op[shape=circle,label="Mean Op\n\nPaddle"]
mean_grad_op[shape=circle,label="Mean Grad Op\n\nPaddle"]
conv_mkldnn[shape=circle,label="Conv Op\ndata_format=NHWC\n\nMKL-DNN"];
conv_grad_mkldnn[shape=circle,label="Conv Grad Op\ndata_format=NHWC\n\nMKL-DNN"];
pool_mkldnn[shape=circle,label="Pool Op\ndata_format=NHWC\n\nMKL-DNN"];
pool_grad_mkldnn[shape=circle,label="Pool Grad Op\ndata_format=NHWC\n\nMKL-DNN"];
tensor_mkldnn[shape=rectangle,label="Tensor conv op\nlayout=kMKLDNN\nNCHW dim format"]
tensor_pool_grad_mkldnn[shape=rectangle,label="Tensor Pool Grad op\nlayout=kMKLDNN\nNCHW dim format"]
tensor_conv_grad_mkldnn[shape=rectangle,label="Tensor Conv Grad op\nlayout=kMKLDNN\nNCHW dim format"]
tensor_mkldnn2[shape=rectangle,label="Tensor pool op\nlayout=kMKLDNN\nNCHW dim format"]
//tensor_input_data[shape=rectangle,label="Input Data\nlayout=kNCHW\nNCHW dim format"]
tensor_mean_grad_mkldnn[shape=rectangle,label="Tensor Grad mean\nlayout=kMKLDNN\nNCHW dim format"]
//tensor_fetch[shape=rectangle,label="Tensor Fetch_op\nlayout=kNCHW\nNHWC dim format"]
tensor_input_mean[shape=rectangle,label="Tensor pool op\nlayout=kNHWC\nNHWC dim format"]
tensor_output_mean[shape=rectangle,label="Tensor mean op\nlayout=kNHWC\nNHWC dim format"]
tensor_mean_grad[shape=rectangle,label="Tensor mean grad op\nlayout=kNHWC\nNHWC dim format"]
tensor_feed[shape=rectangle,label="Tensor feed_op\nlayout=kNCHW\nNHWC dim format"]
tensor_feed2[shape=rectangle,label="Tensor feed_op\nlayout=kMKLDNN\nNCHW dim format"]
feed_op -> tensor_feed -> tensor_feed2 -> conv_mkldnn -> tensor_mkldnn -> pool_mkldnn -> tensor_mkldnn2 -> tensor_input_mean -> mean_op
mean_op -> tensor_output_mean
tensor_input_mean -> tensor_mean_grad[xlabel="InferShape", style=dashed]
tensor_output_mean -> mean_grad_op
mean_grad_op -> tensor_mean_grad -> tensor_mean_grad_mkldnn -> pool_grad_mkldnn -> tensor_pool_grad_mkldnn -> conv_grad_mkldnn -> tensor_conv_grad_mkldnn -> fetch_op
{rank="same" mean_op; mean_grad_op; tensor_output_mean}
{rank="same" pool_mkldnn; pool_grad_mkldnn}
{rank="same" conv_mkldnn; conv_grad_mkldnn}
{rank="same" tensor_mean_grad; tensor_input_mean}
{rank="same" tensor_mkldnn2; tensor_mean_grad_mkldnn}
{rank="same" tensor_pool_grad_mkldnn; tensor_mkldnn}
{rank="same" tensor_conv_grad_mkldnn; tensor_feed}
{rank="same" fetch_op; feed_op}
//tensor_mkldnn2 -> tensor_mean_grad[label="Infer shape"]
}
digraph G {
rankdir=LR
feed_op[shape=circle,label="Feed Op (Input signal)\n\nPaddle"]
feed_op2[shape=circle,label="Feed Op (Filter data)\n\nPaddle"]
fetch_op[shape=circle,label="Fetch Op\n\nPaddle"]
conv_mkldnn[shape=circle,label="conv Op\ndata_format=NHWC\n\nMKL-DNN"];
pool_mkldnn[shape=circle,label="pool Op\ndata_format=NHWC\n\nMKL-DNN"];
tensor_mkldnn[shape=rectangle,label="Tensor conv op\nlayout=kMKLDNN\nNCHW dim format"]
tensor_mkldnn2[shape=rectangle,label="Tensor conv op\nlayout=kMKLDNN\nNCHW dim format"]
tensor_fetch[shape=rectangle,label=<Tensor fetch_op<br/>layout=kNCHW<br/><b>NHWC</b> dim format>]
input_feed[shape=rectangle,label=<Tensor Input signal<br/>layout=kNCHW<br/><b>NHWC</b> dim format>]
input_feed2[shape=rectangle,label="Tensor Input signal\nlayout=kMKLDNN\nNCHW dim format"]
filter_feed[shape=rectangle,label="Tensor filter data\nlayout=kNCHW\nNCHW dim format"]
filter_feed2[shape=rectangle,label="Tensor filter data\nlayout=kMKLDNN\nNCHW dim format"]
feed_op -> input_feed -> input_feed2 -> conv_mkldnn -> tensor_mkldnn -> pool_mkldnn -> tensor_mkldnn2 -> fetch_op -> tensor_fetch
feed_op2 -> filter_feed -> filter_feed2 -> conv_mkldnn
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册