Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable Intel MKLDNN library and Intel MKL small package #2940

Merged
merged 12 commits into from
Jul 21, 2017
11 changes: 8 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ include(simd)
################################ Configurations #######################################
option(WITH_GPU "Compile PaddlePaddle with NVIDIA GPU" ${CUDA_FOUND})
option(WITH_AVX "Compile PaddlePaddle with AVX intrinsics" ${AVX_FOUND})
option(WITH_MKLDNN "Compile PaddlePaddle with mkl-dnn support." ON)
option(WITH_MKLDNN "Compile PaddlePaddle with mkl-dnn support." ${AVX_FOUND})
option(WITH_MKL_LITE "Compile PaddlePaddle with mkl lite package." ${AVX_FOUND})
option(WITH_DSO "Compile PaddlePaddle with dynamic linked CUDA" ON)
option(WITH_TESTING "Compile PaddlePaddle with unit testing" ON)
option(WITH_SWIG_PY "Compile PaddlePaddle with inference api" ON)
Expand Down Expand Up @@ -76,6 +77,10 @@ if(ANDROID)
"Disable PYTHON when cross-compiling for Android" FORCE)
set(WITH_RDMA OFF CACHE STRING
"Disable RDMA when cross-compiling for Android" FORCE)
set(WITH_MKLDNN OFF CACHE STRING
"Disable MKLDNN when cross-compiling for Android" FORCE)
set(WITH_MKL_LITE OFF CACHE STRING
"Disable MKL lite package when cross-compiling for Android" FORCE)
endif(ANDROID)

set(THIRD_PARTY_PATH "${CMAKE_BINARY_DIR}/third_party" CACHE STRING
Expand All @@ -89,14 +94,15 @@ endif()

########################################################################################

include(external/mkllite) # download mkl minimal lite package
include(external/zlib) # download, build, install zlib
include(external/gflags) # download, build, install gflags
include(external/glog) # download, build, install glog
include(external/gtest) # download, build, install gtest
include(external/protobuf) # download, build, install protobuf
include(external/python) # download, build, install python
include(external/mkldnn) # download, build, install mkldnn
include(external/openblas) # download, build, install openblas
include(external/mkldnn) # download, build, install mkldnn
include(external/swig) # download, build, install swig
include(external/warpctc) # download, build, install warpctc
include(external/any) # download libn::any
Expand Down Expand Up @@ -139,7 +145,6 @@ if(WITH_GPU)
endif(WITH_GPU)

if(WITH_MKLDNN)
message(STATUS "MKLDNN_LIBRARY: ${MKLDNN_LIBRARY}")
list(APPEND EXTERNAL_LIBS ${MKLDNN_LIBRARY} ${MKL_LITE_LIB_IOMP})
endif()

Expand Down
17 changes: 16 additions & 1 deletion cmake/cblas.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,22 @@

set(CBLAS_FOUND OFF)

## Find MKL First.
## Find MKL Lite First.
if(WITH_MKL_LITE AND MKL_LITE_INC_DIR AND MKL_LITE_LIB)
set(CBLAS_FOUND ON)
set(CBLAS_PROVIDER MKL_LITE)
set(CBLAS_INC_DIR ${MKL_LITE_INC_DIR})
set(CBLAS_LIBRARIES ${MKL_LITE_LIB})

add_definitions(-DPADDLE_USE_MKL_LITE)
add_definitions(-DLAPACK_FOUND)

message(STATUS "Found cblas and lapack in MKL Lite "
"(include: ${CBLAS_INC_DIR}, library: ${CBLAS_LIBRARIES})")
return()
endif()

## Then find MKL.
set(INTEL_MKL_ROOT "/opt/intel/mkl" CACHE PATH "Folder contains intel mkl libs")
set(MKL_ROOT $ENV{MKL_ROOT} CACHE PATH "Folder contains env MKL")

Expand Down
22 changes: 20 additions & 2 deletions cmake/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,26 @@ endif(NOT WITH_GPU)

if(WITH_MKLDNN)
add_definitions(-DPADDLE_USE_MKLDNN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
if (WITH_MKL_LITE AND MKLDNN_IOMP_DIR)
message(STATUS "Enable Intel OpenMP at ${MKLDNN_IOMP_DIR}")
set(OPENMP_FLAGS "-fopenmp")
set(CMAKE_C_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS ${OPENMP_FLAGS})
set(CMAKE_CXX_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS ${OPENMP_FLAGS})
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L${MKLDNN_IOMP_DIR} -liomp5 -Wl,--as-needed")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${MKLDNN_IOMP_DIR} -liomp5 -Wl,--as-needed")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When compiling Paddle with make -j12, I met the following error:

/home/liuyiqun01/.jumbo/opt/binutils/bin/ld: cannot find -liomp5
collect2: error: ld returned 1 exit status
make[2]: *** [paddle/pybind/libpaddle_pybind.so] Error 1
make[1]: *** [paddle/pybind/CMakeFiles/paddle_pybind.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
100%[===========================================================================================>] 67,379,285  1.02M/s   in 67s     

2017-07-20 02:58:31 (984 KB/s) - `/home/liuyiqun01/github/Paddle/build/third_party/mkllite/mklml_lnx_2018.0.20170425.tgz' saved [67379285/67379285]

[ 26%] No update step for 'extern_mkllite'
[ 26%] No patch step for 'extern_mkllite'
[ 26%] No configure step for 'extern_mkllite'
[ 26%] No build step for 'extern_mkllite'
[ 27%] No install step for 'extern_mkllite'
[ 28%] No test step for 'extern_mkllite'
[ 28%] Completed 'extern_mkllite'
[ 28%] Built target extern_mkllite
make: *** [all] Error 2

Copy link
Contributor Author

@tensor-tang tensor-tang Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where did you set make -j12 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same error, but I use make. I can't find liomp5 too.

Copy link
Contributor Author

@tensor-tang tensor-tang Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give the details error message? @luotao1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tensor-tang I think we need use make -j12 to speed up the building process.

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENMP_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENMP_FLAGS}")
else()
find_package(OpenMP)
if(OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
else()
message(WARNING "Can not find OpenMP."
"Some performance features in MKLDNN may not be available")
endif()
endif()

endif(WITH_MKLDNN)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SIMD_FLAG}")
Expand Down
44 changes: 16 additions & 28 deletions cmake/external/mkldnn.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ SET(MKLDNN_SOURCES_DIR ${THIRD_PARTY_PATH}/mkldnn)
SET(MKLDNN_INSTALL_DIR ${THIRD_PARTY_PATH}/install/mkldnn)
SET(MKLDNN_INCLUDE_DIR "${MKLDNN_INSTALL_DIR}/include" CACHE PATH "mkldnn include directory." FORCE)

# The following magic numbers should be updated regularly to keep latest version
SET(MKLDNN_TAG "v0.9")
SET(MKLDNN_MKL_VER "mklml_lnx_2018.0.20170425")

IF(WIN32)
MESSAGE(WARNING "It is not supported compiling with mkldnn in windows Paddle yet."
"Force WITH_MKLDNN=OFF")
Expand All @@ -42,37 +38,29 @@ ENDIF(WIN32)

INCLUDE_DIRECTORIES(${MKLDNN_INCLUDE_DIR})

SET(MKLDNN_CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
SET(MKLDNN_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
IF(${CBLAS_PROVIDER} STREQUAL "MKL_LITE")
SET(MKLDNN_DEPENDS ${MKL_LITE_PROJECT})
SET(MKLDNN_MKLROOT ${MKL_LITE_ROOT})
SET(MKLDNN_IOMP_DIR ${MKL_LITE_LIB_DIR})
ENDIF()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no mkl-lite, should we abort the building process of mkl-dnn?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will not bother by mkl_lite if WITH_MKL_LITE=OFF


ExternalProject_Add(
${MKLDNN_PROJECT}
${EXTERNAL_PROJECT_LOG_ARGS}
GIT_REPOSITORY "https://github.com/01org/mkl-dnn.git"
GIT_TAG "${MKLDNN_TAG}"
PREFIX ${MKLDNN_SOURCES_DIR}
PATCH_COMMAND cd <SOURCE_DIR>/scripts && ./prepare_mkl.sh
UPDATE_COMMAND ""
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
CMAKE_ARGS -DCMAKE_CXX_FLAGS=${MKLDNN_CMAKE_CXX_FLAGS}
CMAKE_ARGS -DCMAKE_C_FLAGS=${MKLDNN_CMAKE_C_FLAGS}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${MKLDNN_INSTALL_DIR}
CMAKE_ARGS -DCMAKE_INSTALL_LIBDIR=${MKLDNN_INSTALL_DIR}/lib
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${MKLDNN_INSTALL_DIR}
-DCMAKE_INSTALL_LIBDIR:PATH=${MKLDNN_INSTALL_DIR}/lib
-DCMAKE_BUILD_TYPE:STRING=Release
DEPENDS ${MKLDNN_DEPENDS}
GIT_REPOSITORY "https://github.com/01org/mkl-dnn.git"
GIT_TAG "v0.9"
PREFIX ${MKLDNN_SOURCES_DIR}
CONFIGURE_COMMAND mkdir -p <SOURCE_DIR>/build
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you specify mkdir, cmake and make install? In ExternalProject_Add, its BUILD_COMMAND and INSTALL_COMMAND are real CMake commands. You don't need to hard-code.

For instance

ExternalProject_Add(
    zlib
    ${EXTERNAL_PROJECT_LOG_ARGS}
    GIT_REPOSITORY  "https://github.com/madler/zlib.git"
    GIT_TAG         "v1.2.8"
    PREFIX          ${ZLIB_SOURCES_DIR}
    UPDATE_COMMAND  ""
    CMAKE_ARGS      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
    CMAKE_ARGS      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
    CMAKE_ARGS      -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
    CMAKE_ARGS      -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
    CMAKE_ARGS      -DCMAKE_INSTALL_PREFIX=${ZLIB_INSTALL_DIR}
    CMAKE_ARGS      -DBUILD_SHARED_LIBS=OFF
    CMAKE_ARGS      -DCMAKE_POSITION_INDEPENDENT_CODE=ON
    CMAKE_ARGS      -DCMAKE_MACOSX_RPATH=ON
    CMAKE_ARGS      -DCMAKE_BUILD_TYPE=Release
    CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${ZLIB_INSTALL_DIR}
                     -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
                     -DCMAKE_BUILD_TYPE:STRING=Release
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last time used the way you prefer, but since MKL_LITE has been separated from it, it's prefer to let MKLDNN to choose what env it needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @gangliao , the ExternalProject_Add can be simplified because there are some default values and default command to do the building process.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tensor-tang it's ok to use the way you like, as long as Travis CI and TeamCity can successfully build. Thanks for your work.

BUILD_COMMAND cd <SOURCE_DIR>/build
&& cmake .. -DCMAKE_INSTALL_PREFIX=${MKLDNN_INSTALL_DIR} -DMKLROOT=${MKLDNN_MKLROOT}
&& make all -j${CPU_CORES}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not clear with your point about make j12, since I have used make all -j${CPU_CORES} @Xreki

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... I see, what is the total cores number in you system? more than 12 right?

INSTALL_COMMAND cd <SOURCE_DIR>/build && make install
UPDATE_COMMAND ""
)

SET(MKL_LITE_DIR ${MKLDNN_SOURCES_DIR}/src/${MKLDNN_PROJECT}/external/${MKLDNN_MKL_VER})
SET(MKL_LITE_INC_DIR ${MKL_LITE_DIR}/include)
SET(MKL_LITE_LIB ${MKL_LITE_DIR}/lib/libmklml_intel.so)
SET(MKL_LITE_LIB_IOMP ${MKL_LITE_DIR}/lib/libiomp5.so)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" "${MKL_LITE_DIR}/lib")

ADD_LIBRARY(mkldnn STATIC IMPORTED GLOBAL)
SET_PROPERTY(TARGET mkldnn PROPERTY IMPORTED_LOCATION ${MKLDNN_LIBRARY})
ADD_DEPENDENCIES(mkldnn ${MKLDNN_PROJECT})

MESSAGE(STATUS "Mkldnn library: ${MKLDNN_LIBRARY}")
LIST(APPEND external_project_dependencies mkldnn)
61 changes: 61 additions & 0 deletions cmake/external/mkllite.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright (c) 2017 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed 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.

IF(NOT ${WITH_MKL_LITE})
return()
ENDIF(NOT ${WITH_MKL_LITE})

INCLUDE(ExternalProject)

SET(MKL_LITE_PROJECT "extern_mkllite")
SET(MKL_LITE_VER "mklml_lnx_2018.0.20170425")
SET(MKL_LITE_URL "https://github.com/01org/mkl-dnn/releases/download/v0.9/${MKL_LITE_VER}.tgz")
SET(MKL_LITE_DOWNLOAD_DIR ${THIRD_PARTY_PATH}/mkllite)

SET(MKL_LITE_ROOT ${MKL_LITE_DOWNLOAD_DIR}/${MKL_LITE_VER})
SET(MKL_LITE_INC_DIR ${MKL_LITE_ROOT}/include)
SET(MKL_LITE_LIB_DIR ${MKL_LITE_ROOT}/lib)
SET(MKL_LITE_LIB ${MKL_LITE_LIB_DIR}/libmklml_intel.so)
SET(MKL_LITE_IOMP_LIB ${MKL_LITE_LIB_DIR}/libiomp5.so)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}" "${MKL_LITE_ROOT}/lib")

INCLUDE_DIRECTORIES(${MKL_LITE_INC_DIR})

ExternalProject_Add(
${MKL_LITE_PROJECT}
${EXTERNAL_PROJECT_LOG_ARGS}
PREFIX ${MKL_LITE_DOWNLOAD_DIR}
DOWNLOAD_DIR ${MKL_LITE_DOWNLOAD_DIR}
DOWNLOAD_COMMAND wget --no-check-certificate ${MKL_LITE_URL}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not GIT_REPOSITORY and GIT_TAG?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For instance,

ExternalProject_Add(
    zlib
    ${EXTERNAL_PROJECT_LOG_ARGS}
    GIT_REPOSITORY  "https://github.com/madler/zlib.git"
    GIT_TAG         "v1.2.8"
    PREFIX          ${ZLIB_SOURCES_DIR}
    UPDATE_COMMAND  ""
    CMAKE_ARGS      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
    CMAKE_ARGS      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
    CMAKE_ARGS      -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
    CMAKE_ARGS      -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
    CMAKE_ARGS      -DCMAKE_INSTALL_PREFIX=${ZLIB_INSTALL_DIR}
    CMAKE_ARGS      -DBUILD_SHARED_LIBS=OFF
    CMAKE_ARGS      -DCMAKE_POSITION_INDEPENDENT_CODE=ON
    CMAKE_ARGS      -DCMAKE_MACOSX_RPATH=ON
    CMAKE_ARGS      -DCMAKE_BUILD_TYPE=Release
    CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${ZLIB_INSTALL_DIR}
                     -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
                     -DCMAKE_BUILD_TYPE:STRING=Release
)

hard-code might not works in our internal system

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a git, just a tar package. GIT_REPOSITORY and GIT_TAG not applicable here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, I found swig used this way too

ExternalProject_Add(swig
GIT_REPOSITORY https://github.com/swig/swig.git
GIT_TAG rel-3.0.10
PREFIX ${SWIG_SOURCES_DIR}
CONFIGURE_COMMAND cd <SOURCE_DIR> && ./autogen.sh && ./configure
--prefix=${SWIG_INSTALL_DIR} --without-pcre
BUILD_COMMAND cd <SOURCE_DIR> && make
INSTALL_COMMAND cd <SOURCE_DIR> && make install
UPDATE_COMMAND ""
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gangliao I tried to use the following command instead and met some error. It is the same as #2666, because the downloading source is a https source, and the pre-built cmake use their built-in libcurl which does not support https. To enable https, we need to build a new cmake from source.

ExternalProject_Add(
    ${MKL_LITE_PROJECT}
    ${EXTERNAL_PROJECT_LOG_ARGS}
    URL                   ${MKL_LITE_URL}
    PREFIX                ${MKL_LITE_DOWNLOAD_DIR}
    UPDATE_COMMAND        ""
    CONFIGURE_COMMAND     ""
    BUILD_COMMAND         ""
    INSTALL_COMMAND       ""
    TEST_COMMAND          ""
)

However, @tensor-tang the DOWNLOAD_COMMAND need to be changed to wget --no-check-certificate -O ${MKL_LITE_DOWNLOAD_DIR}/${MKL_LITE_VER}.tgz ${MKL_LITE_URL}, or I'll meet the same error I commented before.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tensor-tang swig uses autoconf tools instead of cmake, so we need to specify the CONFIGURE_COMMAND, BUILD_COMMAND and INSTALL_COMMAND. For cmake project, such as gflags, it can be simplified.

&& tar -xzf ${MKL_LITE_DOWNLOAD_DIR}/${MKL_LITE_VER}.tgz
DOWNLOAD_NO_PROGRESS 1
UPDATE_COMMAND ""
PATCH_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

IF (${CMAKE_VERSION} VERSION_LESS "3.3.0")
SET(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/mkllite_dummy.c)
FILE(WRITE ${dummyfile} "const char * dummy_mkllite = \"${dummyfile}\";")
ADD_LIBRARY(mkllite STATIC ${dummyfile})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dummyfile is needed for those header-only libraries, libany, eigen and pybind11. Since mkl-lite is a library, it should be treated as an imported library.

ELSE()
ADD_LIBRARY(mkllite INTERFACE)
ENDIF()

ADD_DEPENDENCIES(mkllite ${MKL_LITE_PROJECT})

LIST(APPEND external_project_dependencies mkllite)