This is an automated email from the ASF dual-hosted git repository. anirudh2290 pushed a commit to branch v1.2.0 in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
commit 18d239cc6776ab8bdc2aae7cf575a8cd85f7caf3 Author: Ashok Emani <ashok.em...@intel.com> AuthorDate: Fri May 11 02:31:28 2018 -0700 [MXNET-365] handle inplace in mkldnn FallBackCompute (#10591) * handle inplace in mkldnn FallBackCompute * add comments * handle kAddTo in mkldnn FallBackCompute * add PR feedback * add unittest for mkldnn inplace sum with cpu data * add back mkldnn engine threading unittest * separate mkldnn install test and fix pylint issue * remove --build from mkldnn jenkins test * update mkldnn unittests * update comments for mkldnn test * remove python test doc string so unittest name is used --- Jenkinsfile | 2 +- src/operator/nn/mkldnn/mkldnn_base.cc | 13 +++- tests/python/mkl/test_mkldnn.py | 132 ++++++++++++-------------------- tests/python/mkl/test_mkldnn_install.py | 56 ++++++++++++++ 4 files changed, 113 insertions(+), 90 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7167f14..eb2160f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -109,7 +109,7 @@ def python3_ut(docker_container_name) { def python3_ut_mkldnn(docker_container_name) { timeout(time: max_time, unit: 'MINUTES') { - sh "ci/build.py --build --platform ${docker_container_name} /work/runtime_functions.sh unittest_ubuntu_python3_cpu_mkldnn" + sh "ci/build.py --platform ${docker_container_name} /work/runtime_functions.sh unittest_ubuntu_python3_cpu_mkldnn" } } diff --git a/src/operator/nn/mkldnn/mkldnn_base.cc b/src/operator/nn/mkldnn/mkldnn_base.cc index 684abd2..8792cbc 100644 --- a/src/operator/nn/mkldnn/mkldnn_base.cc +++ b/src/operator/nn/mkldnn/mkldnn_base.cc @@ -293,10 +293,15 @@ void FallBackCompute(FCompute fn, const nnvm::NodeAttrs &attrs, std::vector<TBlob> out_blobs(outputs.size()); for (size_t i = 0; i < out_blobs.size(); i++) { - if (req[i] == kWriteTo) - const_cast<NDArray &>(outputs[i]).InvalidateMKLDNNData(); - CHECK(outputs[i].IsDefaultData()); - out_blobs[i] = outputs[i].data(); + NDArray output = outputs[i]; + // ensure output does not use mkldnn mem. + // for inplace, we already converted & copied input above. + if ((req[i] == kWriteTo) || (req[i] == kWriteInplace)) + const_cast<NDArray &>(output).InvalidateMKLDNNData(); + else if (req[i] == kAddTo) + output = outputs[i].Reorder2Default(); + CHECK(output.IsDefaultData()); + out_blobs[i] = output.data(); } fn(attrs, ctx, in_blobs, req, out_blobs); } diff --git a/tests/python/mkl/test_mkldnn.py b/tests/python/mkl/test_mkldnn.py index dc9e914..2caf7af 100644 --- a/tests/python/mkl/test_mkldnn.py +++ b/tests/python/mkl/test_mkldnn.py @@ -18,57 +18,19 @@ """ MKL-DNN related test cases """ - -import mxnet as mx +import sys +import os import numpy as np -import sys,os,logging +import mxnet as mx +from mxnet.test_utils import assert_almost_equal from mxnet import gluon from mxnet.gluon import nn curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) sys.path.append(os.path.join(curr_path, '../unittest/')) -from common import setup_module, with_seed -from nose.tools import raises -from mxnet.test_utils import assert_almost_equal - - -def test_mkldnn_install(): - """ - This test will verify that MXNet is built/installed correctly when - compiled with Intel MKL-DNN library. The method will try to import - the mxnet module and see if the mkldnn library is mapped to this - process's address space. - """ - logging.basicConfig(level=logging.INFO) - - if not sys.platform.startswith('linux'): - logging.info("Bypass mkldnn install test for non-Linux OS") - return - - try: - #pylint: disable=unused-variable - import mxnet as mx - except (ImportError, OSError) as e: - assert 0, "Import mxnet error: %s. Please double check your build/" \ - "install steps or environment variable settings" % str(e) - - pid = os.getpid() - rc = os.system("cat /proc/" + str(pid) + - "/maps | grep libmkldnn > /dev/null") - - if rc == 0: - logging.info("MXNet is built/installed correctly with MKL-DNN") - else: - assert 0, "MXNet is built/installed incorrectly with MKL-DNN, please " \ - "double check your build/install steps or environment " \ - "variable settings" +from common import with_seed def test_mkldnn_model(): - """ - This test will run a sample model for couple of iterations. - """ - - import mxnet as mx model = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data", "test_mkldnn_test_mkldnn_model_model1.json") shape = (32, 3, 300, 300) @@ -96,17 +58,19 @@ def test_mkldnn_model(): except: # pylint: disable=bare-except assert 0, "test_mkldnn_model exception in bind and execution" -def test_mkldnn_engine_threading(): - """ - This test will trigger mkldnn engine on different thread of execution. - The test will first kickoff simple model calculation, and then uses a - gluon data iterator to trigger different thread context, and executes - the model on this new thread. - """ +def test_mkldnn_ndarray_slice(): + ctx = mx.cpu() + net = gluon.nn.HybridSequential() + with net.name_scope(): + net.add(gluon.nn.Conv2D(channels=32, kernel_size=3, activation=None)) + net.collect_params().initialize(ctx=ctx) + x = mx.nd.array(np.ones([32, 3, 224, 224]), ctx) + y = net(x) - import mxnet as mx - from mxnet import gluon, nd + # trigger computation on ndarray slice + assert_almost_equal(y[0].asnumpy()[0, 0, 0], 0.3376348) +def test_mkldnn_engine_threading(): net = gluon.nn.HybridSequential() with net.name_scope(): net.add(gluon.nn.Conv2D(channels=32, kernel_size=3, activation=None)) @@ -121,47 +85,30 @@ def test_mkldnn_engine_threading(): X = (32, 3, 32, 32) # trigger mkldnn execution thread - y = net(nd.array(np.ones(X))).asnumpy() + y = net(mx.nd.array(np.ones(X))).asnumpy() # Use Gluon dataloader to trigger different thread. # below line triggers different execution thread for _ in loader: - y = net(nd.array(np.ones(X))).asnumpy() - # output should have 0.3376348 - assert_almost_equal(y[0, 0, 0, 0], 0.3376348) + y = net(mx.nd.array(np.ones(X))).asnumpy() + # output should be 016711406 (non-mkldnn mode output) + assert_almost_equal(y[0, 0, 0, 0], 0.016711406) break -def test_mkldnn_ndarray_slice(): - """ - This test will trigger gluon computation on mkldnn with ndarray slice - """ - - import mxnet as mx - from mxnet import gluon - ctx = mx.cpu() - net = gluon.nn.HybridSequential() - with net.name_scope(): - net.add(gluon.nn.Conv2D(channels=32, kernel_size=3, activation=None)) - net.collect_params().initialize(ctx=ctx) - x = mx.nd.array(np.ones([32, 3, 224, 224]), ctx) - y = net(x) - - # trigger computation on ndarray slice - assert_almost_equal(y[0].asnumpy()[0, 0, 0], 0.3376348) @with_seed() def test_reshape_before_conv(): - """ - This test will test gluon Conv2d computation on mkldnn with ndarray reshape - """ class Net(gluon.HybridBlock): + """ + test Net + """ def __init__(self, **kwargs): super(Net, self).__init__(**kwargs) with self.name_scope(): self.conv0 = nn.Conv2D(10, (3, 3)) self.conv1 = nn.Conv2D(5, (3, 3)) - def hybrid_forward(self, F, x): + def hybrid_forward(self, F, x, *args, **kwargs): x_reshape = x.reshape((0, 0, 20, 5)) y = self.conv0(x_reshape) y_reshape = y.reshape((0, 0, 9, 6)) @@ -185,17 +132,17 @@ def test_reshape_before_conv(): @with_seed() def test_slice_before_conv(): - """ - This test will test gluon Conv2d computation on mkldnn with ndarray slice - """ class Net(gluon.HybridBlock): + """ + test Net + """ def __init__(self, **kwargs): super(Net, self).__init__(**kwargs) with self.name_scope(): self.conv0 = nn.Conv2D(4, (3, 3)) self.conv1 = nn.Conv2D(4, (3, 3)) - def hybrid_forward(self, F, x): + def hybrid_forward(self, F, x, *args, **kwargs): x_slice = x.slice(begin=(0, 0, 0, 0), end=(2, 4, 10, 10)) y = self.conv0(x_slice) y_slice = y.slice(begin=(1, 0, 2, 2), end=(2, 1, 7, 7)) @@ -219,17 +166,17 @@ def test_slice_before_conv(): @with_seed() def test_slice_reshape_before_conv(): - """ - This test will test gluon Conv2d computation on mkldnn with ndarray reshape and slice - """ class Net(gluon.HybridBlock): + """ + test Net + """ def __init__(self, **kwargs): super(Net, self).__init__(**kwargs) with self.name_scope(): self.conv0 = nn.Conv2D(4, (3, 3)) self.conv1 = nn.Conv2D(4, (3, 3)) - def hybrid_forward(self, F, x): + def hybrid_forward(self, F, x, *args, **kwargs): x_slice = x.slice(begin=(0, 0, 0, 0), end=(2, 4, 8, 9)) y = self.conv0(x_slice) y_reshape = y.reshape((0, 0, 14, 3)) @@ -251,5 +198,20 @@ def test_slice_reshape_before_conv(): mx.test_utils.assert_almost_equal(out1.asnumpy(), out2.asnumpy(), rtol=1e-5, atol=1e-6) +def test_mkldnn_sum_inplace_with_cpu_layout(): + + x_shape = (32, 3, 224, 224) + x_npy = np.ones(x_shape) + y_shape = (32, 32, 222, 222) + y_npy = np.ones(y_shape) + x = mx.sym.Variable("x") + y = mx.sym.Variable("y") + z = mx.symbol.Convolution(data=x, num_filter=32, kernel=(3, 3)) + z = mx.sym.add_n(z, y) + exe = z.simple_bind(ctx=mx.cpu(), x=x_shape, y=y_shape) + out = exe.forward(is_train=False, x=x_npy, y=y_npy)[0] + assert_almost_equal(out[0].asnumpy()[0, 0, 0], 1.0) + + if __name__ == '__main__': test_mkldnn_install() diff --git a/tests/python/mkl/test_mkldnn_install.py b/tests/python/mkl/test_mkldnn_install.py new file mode 100644 index 0000000..c2f26df --- /dev/null +++ b/tests/python/mkl/test_mkldnn_install.py @@ -0,0 +1,56 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +MKL-DNN related test cases +""" + +import sys +import os +import logging + + +def test_mkldnn_install(): + """ + This test will verify that MXNet is built/installed correctly when + compiled with Intel MKL-DNN library. The method will try to import + the mxnet module and see if the mkldnn library is mapped to this + process's address space. + """ + logging.basicConfig(level=logging.INFO) + + if not sys.platform.startswith('linux'): + logging.info("Bypass mkldnn install test for non-Linux OS") + return + + try: + #pylint: disable=unused-variable + import mxnet as mx + except (ImportError, OSError) as e: + assert 0, "Import mxnet error: %s. Please double check your build/" \ + "install steps or environment variable settings" % str(e) + + pid = os.getpid() + rc = os.system("cat /proc/" + str(pid) + + "/maps | grep libmkldnn > /dev/null") + + if rc == 0: + logging.info("MXNet is built/installed correctly with MKL-DNN") + else: + assert 0, "MXNet is built/installed incorrectly with MKL-DNN, please " \ + "double check your build/install steps or environment " \ + "variable settings" -- To stop receiving notification emails like this one, please contact anirudh2...@apache.org.