Skip to content

Commit 8e1e7f0

Browse files
zhenlinluopiiswrong
authored andcommitted
MKL2017 implemented layers integration to improve IA perf. on mxnet (apache#3581)
* Add MKL2017 memory struct support and mklconv into mxnet * fix cuda compile problem Signed-off-by: Lingyan <lingyan.guo@intel.com> * remove mkldnnchunk from memory and add all necessary file for compile * add mkl pooling * add mkl relu support * add mkl lrn * add mkl batch norm * add mkl concat * add mkl elementwise sum * add mkl fc * disable USE_MKL2017 by default Signed-off-by: Lingyan <lingyan.guo@intel.com> * revert mkl for sgemm Signed-off-by: Lingyan <lingyan.guo@intel.com> * add fix mkl path script & README Signed-off-by: Lingyan <lingyan.guo@intel.com> * use prepare_mkl.sh to download mkl Signed-off-by: Lingyan <lingyan.guo@intel.com> * Update for download failed for MKL Signed-off-by: Lingyan <lingyan.guo@intel.com> * add step to avoid mkl lib missing when excute python script Signed-off-by: Lingyan <lingyan.guo@intel.com> * update python install to sudo Signed-off-by: Lingyan <lingyan.guo@intel.com> * rollback padding change in pooling-inh.h Since mxnet update the new inception-bn model do not need to add padding patch to use old model Signed-off-by: Lingyan <lingyan.guo@intel.com> * correct pooling formula * minor change for pooling-inl.h * support new pooling_convention for converter * add MKL support in dropout * fix concat unit test issue since MKL concat don't support cross minbatch * disable external mkl if USE_BLAS is mkl Signed-off-by: Lingyan <lingyan.guo@intel.com> * fix compile error when mkl is disable Signed-off-by: Lingyan <lingyan.guo@intel.com> * remove debug msg and fix lint * remove MKL_DEBUG by default
1 parent ae3b210 commit 8e1e7f0

33 files changed

+4301
-25
lines changed

MKL_README.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# MKL2017 PLUGIN
2+
3+
MKL2017 is one INTEL released library to accelerate Deep Neural Network (DNN) applications on Intel architecture.
4+
This README shows user how to setup and install MKL2017 library with mxnet.
5+
6+
7+
## Build/Install Instructions:
8+
```
9+
Download MKL:
10+
11+
```
12+
13+
## Build/Install MxNet
14+
1. Enable USE_MKL2017=1 in make/config.mk
15+
1.1 USE_BLAS should be atlas by default
16+
1.2 if need USE_BLAS to be mkl, please Navigate here - https://registrationcenter.intel.com/en/forms/?productid=2558&licensetype=2 to do a full MKL installation
17+
2. Run 'make -jX'
18+
2.1 Makefile will execute "prepare_mkl.sh" to download the mkl under root folder.e.g. <MXNET ROOTDIR> /mklml_lnx_2017.0.0.20160801
19+
2.2 if download failed because of proxy setting, please do it manually before make
20+
2.2.1 wget https://github.com/intel/caffe/releases/download/self_containted_MKLGOLD/mklml_lnx_2017.0.0.20160801.tgz
21+
2.2.2 tar zxvf mklml_lnx_2017.0.0.20160801.tgz
22+
23+
3. Navigate into the python directory
24+
4. Run 'sudo python setup.py install'
25+
5. Before excute python scipt, need to set LD_LIBRARY_PATH
26+
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<MXNET ROOTDIR>/mklml_lnx_2017.0.0.20160801/lib
27+
```
28+

Makefile

+19-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ ifeq ($(USE_OPENMP), 1)
5858
CFLAGS += -fopenmp
5959
endif
6060

61+
ifeq ($(USE_MKL2017), 1)
62+
CFLAGS += -DMXNET_USE_MKL2017=1
63+
CFLAGS += -DUSE_MKL=1
64+
ifneq ($(USE_BLAS), mkl)
65+
ICC_ON=0
66+
RETURN_STRING=$(shell ./prepare_mkl.sh $(ICC_ON))
67+
MKLROOT=$(firstword $(RETURN_STRING))
68+
MKL_LDFLAGS=-l$(word 2, $(RETURN_STRING))
69+
MKL_EXTERNAL=$(lastword $(RETURN_STRING))
70+
ifeq ($(MKL_EXTERNAL), 1)
71+
MKL_LDFLAGS+=-Wl,-rpath,$(MKLROOT)/lib
72+
CFLAGS += -I$(MKLROOT)/include
73+
LDFLAGS += -L$(MKLROOT)/lib/ -liomp5 -lmklml_gnu -lmklml_intel
74+
endif
75+
endif
76+
endif
77+
78+
6179
ifeq ($(USE_CUDNN), 1)
6280
CFLAGS += -DMSHADOW_USE_CUDNN=1
6381
LDFLAGS += -lcudnn
@@ -93,7 +111,7 @@ endif
93111

94112
all: lib/libmxnet.a lib/libmxnet.so $(BIN)
95113

96-
SRC = $(wildcard src/*.cc src/*/*.cc)
114+
SRC = $(wildcard src/*.cc src/*/*.cc src/*/*/*.cc)
97115
OBJ = $(patsubst %.cc, build/%.o, $(SRC))
98116
CUSRC = $(wildcard src/*/*.cu)
99117
CUOBJ = $(patsubst %.cu, build/%_gpu.o, $(CUSRC))

include/mxnet/mkl_memory.h

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*******************************************************************************
2+
* Copyright 2016 Intel Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* \file mkl_memory.cc
17+
* \brief
18+
* \author lingyan.guo@intel.com
19+
* zhenlin.luo@intel.com
20+
*
21+
*******************************************************************************/
22+
#ifndef MXNET_MKL_MEMORY_H_
23+
#define MXNET_MKL_MEMORY_H_
24+
25+
#include <string>
26+
#include <vector>
27+
#include <memory>
28+
29+
30+
namespace mxnet {
31+
// Base class
32+
struct PrvMemDescr {
33+
virtual void convert_from_prv(void* cpu_ptr) = 0;
34+
virtual void convert_to_prv(void* cpu_ptr) = 0;
35+
virtual void convert_from_other(std::shared_ptr<PrvMemDescr> other) = 0;
36+
virtual void* prv_ptr() = 0;
37+
// returns true for matching layouts
38+
virtual bool layout_compare(std::shared_ptr<PrvMemDescr> other) = 0;
39+
virtual size_t prv_count() = 0;
40+
virtual size_t prv_size() = 0;
41+
// This might help using prv_ptr_ by different accelerators/engines
42+
enum PrvDescrType {
43+
PRV_DESCR_MKL2017,
44+
PRV_DESCR_MKLDNN
45+
};
46+
virtual PrvDescrType get_descr_type() = 0;
47+
};
48+
49+
struct MKLMemHolder {
50+
public:
51+
virtual std::shared_ptr<PrvMemDescr> get_prv_descriptor() = 0;
52+
};
53+
54+
} // namespace mxnet
55+
#endif // MXNET_MKL_MEMORY_H_

make/config.mk

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ USE_OPENCV = 1
5959
# use openmp for parallelization
6060
USE_OPENMP = 1
6161

62+
# whether use MKL2017 library
63+
USE_MKL2017 = 0
64+
6265
# choose the version of blas you want to use
6366
# can be: mkl, blas, atlas, openblas
6467
# in default use atlas for linux while apple for osx

prepare_mkl.sh

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/bin/bash
2+
# set -ex
3+
#
4+
# All modification made by Intel Corporation: © 2016 Intel Corporation
5+
#
6+
# All contributions by the University of California:
7+
# Copyright (c) 2014, 2015, The Regents of the University of California (Regents)
8+
# All rights reserved.
9+
#
10+
# All other contributions:
11+
# Copyright (c) 2014, 2015, the respective contributors
12+
# All rights reserved.
13+
# For the list of contributors go to https://github.com/BVLC/caffe/blob/master/CONTRIBUTORS.md
14+
#
15+
#
16+
# Redistribution and use in source and binary forms, with or without
17+
# modification, are permitted provided that the following conditions are met:
18+
#
19+
# * Redistributions of source code must retain the above copyright notice,
20+
# this list of conditions and the following disclaimer.
21+
# * Redistributions in binary form must reproduce the above copyright
22+
# notice, this list of conditions and the following disclaimer in the
23+
# documentation and/or other materials provided with the distribution.
24+
# * Neither the name of Intel Corporation nor the names of its contributors
25+
# may be used to endorse or promote products derived from this software
26+
# without specific prior written permission.
27+
#
28+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
32+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38+
#
39+
FindLibrary()
40+
{
41+
case "$1" in
42+
intel|1)
43+
LOCALMKL=`find $DST -name libmklml_intel.so` # name of MKL SDL lib
44+
;;
45+
*)
46+
LOCALMKL=`find $DST -name libmklml_gnu.so` # name of MKL SDL lib
47+
;;
48+
esac
49+
50+
}
51+
52+
GetVersionName()
53+
{
54+
VERSION_LINE=0
55+
if [ $1 ]; then
56+
VERSION_LINE=`grep __INTEL_MKL_BUILD_DATE $1/include/mkl_version.h 2>/dev/null | sed -e 's/.* //'`
57+
fi
58+
if [ -z $VERSION_LINE ]; then
59+
VERSION_LINE=0
60+
fi
61+
echo $VERSION_LINE # Return Version Line
62+
}
63+
64+
# MKL
65+
DST=`dirname $0`
66+
OMP=0
67+
VERSION_MATCH=20160706
68+
ARCHIVE_BASENAME=mklml_lnx_2017.0.0.20160801.tgz
69+
MKL_CONTENT_DIR=`echo $ARCHIVE_BASENAME | rev | cut -d "." -f 2- | rev`
70+
GITHUB_RELEASE_TAG=self_containted_MKLGOLD
71+
MKLURL="https://github.com/intel/caffe/releases/download/$GITHUB_RELEASE_TAG/$ARCHIVE_BASENAME"
72+
# there are diffrent MKL lib to be used for GCC and for ICC
73+
reg='^[0-9]+$'
74+
VERSION_LINE=`GetVersionName $MKLROOT`
75+
# Check if MKLROOT is set if positive then set one will be used..
76+
if [ -z $MKLROOT ] || [ $VERSION_LINE -lt $VERSION_MATCH ]; then
77+
# ..if MKLROOT is not set then check if we have MKL downloaded in proper version
78+
VERSION_LINE=`GetVersionName $DST/$MKL_CONTENT_DIR`
79+
if [ $VERSION_LINE -lt $VERSION_MATCH ] ; then
80+
#...If it is not then downloaded and unpacked
81+
wget --no-check-certificate -P $DST $MKLURL -O $DST/$ARCHIVE_BASENAME
82+
tar -xzf $DST/$ARCHIVE_BASENAME -C $DST
83+
fi
84+
FindLibrary $1
85+
MKLROOT=$PWD/`echo $LOCALMKL | sed -e 's/lib.*$//'`
86+
fi
87+
88+
# Check what MKL lib we have in MKLROOT
89+
if [ -z `find $MKLROOT -name libmkl_rt.so -print -quit` ]; then
90+
LIBRARIES=`basename $LOCALMKL | sed -e 's/^.*lib//' | sed -e 's/\.so.*$//'`
91+
OMP=1
92+
else
93+
LIBRARIES="mkl_rt"
94+
fi
95+
96+
97+
# return value to calling script (Makefile,cmake)
98+
echo $MKLROOT $LIBRARIES $OMP

src/operator/activation.cc

+18
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,30 @@
66
*/
77
#include "./activation-inl.h"
88
#include "./mshadow_op.h"
9+
#if MXNET_USE_MKL2017 == 1
10+
#include <mxnet/mkl_memory.h>
11+
#include "./mkl/mkl_memory-inl.h"
12+
#include "./mkl/mkl_relu-inl.h"
13+
#endif // MXNET_USE_MKL2017
914

1015
namespace mxnet {
1116
namespace op {
1217
template<>
1318
Operator *CreateOp<cpu>(ActivationParam param, int dtype) {
1419
Operator *op = NULL;
20+
#if MXNET_USE_MKL2017 == 1
21+
if (param.act_type == activation::kReLU) {
22+
switch (dtype) {
23+
case mshadow::kFloat32:
24+
return new MKLReluOp<cpu, float>();
25+
case mshadow::kFloat64:
26+
return new MKLReluOp<cpu, double>();
27+
default:
28+
break;
29+
}
30+
}
31+
32+
#endif
1533
MSHADOW_REAL_TYPE_SWITCH(dtype, DType, {
1634
switch (param.act_type) {
1735
case activation::kReLU:

src/operator/batch_norm-inl.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class BatchNormOp : public Operator {
214214
}; // class BatchNormOp
215215

216216
template<typename xpu>
217-
Operator *CreateOp(BatchNormParam param);
217+
Operator *CreateOp(BatchNormParam param, int dtype);
218218

219219

220220
#if DMLC_USE_CXX11
@@ -296,7 +296,13 @@ class BatchNormProp : public OperatorProperty {
296296
return {"moving_mean", "moving_var"};
297297
}
298298

299-
Operator* CreateOperator(Context ctx) const override;
299+
Operator* CreateOperator(Context ctx) const override {
300+
LOG(FATAL) << "Not Implemented.";
301+
return NULL;
302+
}
303+
304+
Operator* CreateOperatorEx(Context ctx, std::vector<TShape> *in_shape,
305+
std::vector<int> *in_type) const override;
300306

301307
private:
302308
BatchNormParam param_;

src/operator/batch_norm.cc

+18-3
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,31 @@
66
*/
77

88
#include "./batch_norm-inl.h"
9+
#if MXNET_USE_MKL2017 == 1
10+
#include <mxnet/mkl_memory.h>
11+
#include "./mkl/mkl_memory-inl.h"
12+
#include "./mkl/mkl_batch_norm-inl.h"
13+
#endif // MXNET_USE_MKL2017
914

1015
namespace mxnet {
1116
namespace op {
1217
template<>
13-
Operator *CreateOp<cpu>(BatchNormParam param) {
18+
Operator *CreateOp<cpu>(BatchNormParam param, int dtype) {
19+
#if MXNET_USE_MKL2017 == 1
20+
return new MKLBatchNormOp<cpu, float>(param);
21+
#else
1422
return new BatchNormOp<cpu>(param);
23+
#endif
1524
}
1625

17-
Operator *BatchNormProp::CreateOperator(Context ctx) const {
18-
DO_BIND_DISPATCH(CreateOp, param_);
26+
// DO_BIND_DISPATCH comes from operator_common.h
27+
Operator *BatchNormProp::CreateOperatorEx(Context ctx, std::vector<TShape> *in_shape,
28+
std::vector<int> *in_type) const {
29+
std::vector<TShape> out_shape, aux_shape;
30+
std::vector<int> out_type, aux_type;
31+
CHECK(InferType(in_type, &out_type, &aux_type));
32+
CHECK(InferShape(in_shape, &out_shape, &aux_shape));
33+
DO_BIND_DISPATCH(CreateOp, param_, (*in_type)[0]);
1934
}
2035

2136
DMLC_REGISTER_PARAMETER(BatchNormParam);

src/operator/batch_norm.cu

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace mxnet {
1212
namespace op {
1313
template<>
14-
Operator *CreateOp<gpu>(BatchNormParam param) {
14+
Operator *CreateOp<gpu>(BatchNormParam param, int dtype) {
1515
#if MXNET_USE_CUDNN == 1 && CUDNN_MAJOR >= 5
1616
if (!param.use_global_stats) {
1717
return new CuDNNBatchNormOp(param);

src/operator/concat.cc

+19
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,31 @@
66
*/
77

88
#include "./concat-inl.h"
9+
#if MXNET_USE_MKL2017 == 1
10+
#include <mxnet/mkl_memory.h>
11+
#include "./mkl/mkl_memory-inl.h"
12+
#include "./mkl/mkl_concat-inl.h"
13+
#endif // MXNET_USE_MKL2017
914

1015
namespace mxnet {
1116
namespace op {
1217
template<>
1318
Operator* CreateOp<cpu>(ConcatParam param, int dtype) {
1419
Operator *op = NULL;
20+
#if MXNET_USE_MKL2017 == 1
21+
if (1 == param.dim) {
22+
switch (dtype) {
23+
case mshadow::kFloat32:
24+
op = new MKLConcatOp<cpu, float>(param);
25+
break;
26+
case mshadow::kFloat64:
27+
op = new MKLConcatOp<cpu, double>(param);
28+
break;
29+
default:
30+
break;
31+
}
32+
}
33+
#endif
1534
MSHADOW_REAL_TYPE_SWITCH(dtype, DType, {
1635
op = new ConcatOp<cpu, DType>(param);
1736
});

src/operator/convolution.cc

+18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
*/
77

88
#include "./convolution-inl.h"
9+
#if MXNET_USE_MKL2017 == 1
10+
#include <mxnet/mkl_memory.h>
11+
#include "./mkl/mkl_memory-inl.h"
12+
#include "./mkl/mkl_convolution-inl.h"
13+
#endif // MXNET_USE_MKL2017
914

1015
namespace mxnet {
1116
namespace op {
@@ -15,6 +20,19 @@ Operator* CreateOp<cpu>(ConvolutionParam param, int dtype,
1520
std::vector<TShape> *out_shape,
1621
Context ctx) {
1722
Operator *op = NULL;
23+
#if MXNET_USE_MKL2017 == 1
24+
if ((param.dilate[0] == 1 && param.dilate[1] == 1)
25+
&& param.kernel.ndim() == 2) {
26+
switch (dtype) {
27+
case mshadow::kFloat32:
28+
return new MKLConvolutionOp<cpu, float>(param);
29+
case mshadow::kFloat64:
30+
return new MKLConvolutionOp<cpu, double>(param);
31+
default:
32+
break;
33+
}
34+
}
35+
#endif
1836
MSHADOW_REAL_TYPE_SWITCH(dtype, DType, {
1937
op = new ConvolutionOp<cpu, DType>(param);
2038
})

0 commit comments

Comments
 (0)