Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Commit

Permalink
[FEATURE] Enable dynamic linking with MKL and compiler based OpenMP (#…
Browse files Browse the repository at this point in the history
…20474)

OneMKL 2021.3 fixed linking OpenMP while using SDL and MKL_THREADING_LAYER set to GNU.

* Disabling SDL with MKL threading on Windows

* Use multi-threading 'on' as the default option

* Sets the interface layer for Intel oneAPI MKL at runtime

* Clean up the apt cache

* Moving mkl runtime initialization to the function

* Cleaning MKL find_path cmake directories

* [WIP] Adding github runner for MAC OS to check MKL specific changes

This is a temporary change to check if adding MKL runtime support
won't crash MacOS.

* clang format + mkl workflow rename

* Fixing some formatting + installing patchelf

* setting up Mac OS rpath for MKL libraries

* Run only mkl tests

* Fix for finding MKL libraries on MacOs by FindBLAS.cmake
Turn off SDL for MKL on MacOS as it need fixes.

* Enable linking MxNET with MKL static libraries on MacOS

Add proper mkl_threading flags for Mac Os.
Enable all tests that are for MacOS + MKL tests.
Rebuild numpy with MKL BLAS (instead of OpenBLAS).

* Excluding MKL bf16 tests as CI MacOs machines seems not to have avx512
support.
  • Loading branch information
akarbown authored Oct 13, 2021
1 parent 0d09770 commit abd293f
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 24 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/os_x_mklbuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: mkl continuous build

on: [push, pull_request]

jobs:
macosx-x86_64:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Compilation cache
uses: actions/cache@v2
with:
path: ~/.ccache
# We include the commit sha in the cache key, as new cache entries are
# only created if there is no existing entry for the key yet.
key: ${{ runner.os }}-ccache-${{ github.sha }}
# Restore any ccache cache entry, if none for
# ${{ runner.os }}-ccache-${{ github.sha }} exists
restore-keys: |
${{ runner.os }}-ccache
- name: Setup python
uses: actions/setup-python@v2
with:
python-version: '3.6'
architecture: x64

- name: Install Dependencies
run: |
brew install nasm automake ninja libtool cmake pkgconfig protobuf hdf5 zlib ccache
ccache -M 500M # Limit the ccache size; Github's overall cache limit is 5GB
python -m pip install -r ci/docker/install/requirements
shell: bash

- name: Build project
run: |
./tools/staticbuild/build.sh cpu mkl
- name: Setup Python
run: |
python -m pip install --user -e python
- name: Test project
run: |
python -m pytest -n 4 --durations=50 --verbose tests/python/unittest/ -k 'not test_operator and not (test_subgraph or test_custom_op or test_external_op or test_recordimage_dataset_with_data_loader_multiworker or test_multi_worker or test_multi_worker_shape or test_multi_worker_forked_data_loader or test_multi_worker_dataloader_release_pool)' -m 'not serial'
MXNET_ENGINE_TYPE=NaiveEngine python -m pytest -n 4 --durations=50 --verbose tests/python/unittest/ -k 'test_operator and not (test_subgraph or test_custom_op or test_external_op or test_recordimage_dataset_with_data_loader_multiworker or test_multi_worker or test_multi_worker_shape or test_multi_worker_forked_data_loader or test_multi_worker_dataloader_release_pool)' -m 'not serial'
python -m pytest --durations=50 --verbose tests/python/unittest/ -k 'not (test_subgraph or test_custom_op or test_external_op or test_recordimage_dataset_with_data_loader_multiworker or test_multi_worker or test_multi_worker_shape or test_multi_worker_forked_data_loader or test_multi_worker_dataloader_release_pool)' -m 'serial'
python -m pytest -n 4 --durations=50 --verbose tests/python/mkl -k 'not test_bf16_operator'
12 changes: 6 additions & 6 deletions ci/docker/Dockerfile.build.ubuntu
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ WORKDIR /work/deps
SHELL ["/bin/bash", "-c"]
RUN export DEBIAN_FRONTEND=noninteractive && \
export OS_RELEASE="$(cat /etc/os-release)" && \
apt-get clean && \
apt-get update && \
apt-get install -y wget software-properties-common && \
if [[ ${OS_RELEASE} == *"Bionic"* ]]; then \
wget -qO - wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB | apt-key add -; \
apt-add-repository "deb https://apt.repos.intel.com/mkl all main"; \
INTEL_MKL="-2020.0-088"; \
fi && \
wget -qO - wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB -O - | apt-key add -; \
add-apt-repository "deb https://apt.repos.intel.com/oneapi all main"; \
INTEL_MKL="-2021.3.0"; \
apt-get update && \
apt-get install -y \
## Utilities
Expand All @@ -65,7 +64,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
g++ \
g++-7 \
g++-8 \
intel-mkl${INTEL_MKL} \
intel-oneapi-mkl${INTEL_MKL} \
intel-oneapi-mkl-devel${INTEL_MKL} \
libomp-dev \
## Dependencies
libgomp1 \
Expand Down
33 changes: 24 additions & 9 deletions cmake/ChooseBlas.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ set(INTEL_OPT_ROOT "/opt/intel" CACHE PATH "Folder contains root-installed intel

if(DEFINED USE_BLAS)
set(BLAS "${USE_BLAS}")
else()
# Setting up BLAS_mkl_MKLROOT for non-Ubuntu 20.04 OSes
find_path(BLAS_mkl_MKLROOT mkl PATHS $ENV{MKLROOT} ${INTEL_HOME_ROOT} ${INTEL_OPT_ROOT})
if(NOT BLAS_mkl_MKLROOT STREQUAL "BLAS_mkl_MKLROOT-NOTFOUND")
endif()
if(USE_BLAS MATCHES "MKL" OR USE_BLAS MATCHES "mkl" OR NOT DEFINED USE_BLAS)
find_path(MKL_INCLUDE_DIR mkl_version.h
PATHS $ENV{MKLROOT} ${INTEL_HOME_ROOT}/mkl ${INTEL_OPT_ROOT}/mkl ${INTEL_OPT_ROOT}/oneapi/mkl/latest
PATH_SUFFIXES mkl latest include)
if(NOT MKL_INCLUDE_DIR STREQUAL "MKL_INCLUDE_DIR-NOTFOUND")
set(BLAS "MKL")
endif()
endif()
Expand Down Expand Up @@ -122,15 +124,20 @@ set(FORTRAN_DIR \\\"\$\{CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES\}\\\")
endif()
elseif(BLAS STREQUAL "MKL" OR BLAS STREQUAL "mkl")
# ---[ MKL Options
file(STRINGS ${MKL_INCLUDE_DIR}/mkl_version.h MKL_VERSION_DEF REGEX "INTEL_MKL_VERSION")
string(REGEX MATCH "([0-9]+)" MKL_VERSION ${MKL_VERSION_DEF})
if(UNIX)
# Single dynamic library interface leads to conflicts between intel omp and llvm omp
# https://github.com/apache/incubator-mxnet/issues/17641
option(MKL_USE_SINGLE_DYNAMIC_LIBRARY "Use single dynamic library interface" OFF)
# Fixed in oneMKL 2021.3: [MKLD-11109] MKL is opening libgomp.so instead of
# libgomp.so.1 while SDL=1 & MKL_THREADING_LAYER=GNU
cmake_dependent_option(MKL_USE_SINGLE_DYNAMIC_LIBRARY "Use single dynamic library interface" ON
"NOT BLA_STATIC;MKL_VERSION GREATER_EQUAL 20210003" OFF)
else()
option(MKL_USE_SINGLE_DYNAMIC_LIBRARY "Use single dynamic library interface" ON)
endif()
cmake_dependent_option(BLA_STATIC "Use static libraries" ON "NOT MKL_USE_SINGLE_DYNAMIC_LIBRARY" OFF)
cmake_dependent_option(MKL_MULTI_THREADED "Use multi-threading" ON "NOT MKL_USE_SINGLE_DYNAMIC_LIBRARY" OFF)
option(MKL_MULTI_THREADED "Use multi-threading" ON)

if(BLA_VENDOR)
message(FATAL_ERROR "Do not set BLA_VENDOR manually. MKL version (BLA_VENDOR) is selected based on MKL_USE_SINGLE_DYNAMIC_LIBRARY, "
Expand Down Expand Up @@ -160,15 +167,23 @@ elseif(BLAS STREQUAL "MKL" OR BLAS STREQUAL "mkl")
endif()
endif()
endif()
# Setting up BLAS_mkl_MKLROOT for non-Ubuntu 20.04 OSes
find_path(BLAS_mkl_MKLROOT mkl PATHS $ENV{MKLROOT} ${INTEL_HOME_ROOT} ${INTEL_OPT_ROOT})
# In case of oneAPI 2021.3 if MKL_INCLUDE_DIR points to the subdirectory 'include',
# use the parent directory 'latest' instead
file(TO_CMAKE_PATH "${MKL_INCLUDE_DIR}" BLAS_mkl_MKLROOT)
get_filename_component(BLAS_mkl_MKLROOT_LAST_DIR "${BLAS_mkl_MKLROOT}" NAME)
if(BLAS_mkl_MKLROOT_LAST_DIR STREQUAL "include")
get_filename_component(BLAS_mkl_MKLROOT "${BLAS_mkl_MKLROOT}" DIRECTORY)
endif()
find_package(BLAS)
find_path(MKL_INCLUDE_DIR mkl.h HINTS ${INTEL_HOME_ROOT}/mkl ${INTEL_OPT_ROOT}/mkl PATHS ENV MKLROOT PATH_SUFFIXES include mkl REQUIRED)
include_directories(SYSTEM ${MKL_INCLUDE_DIR})
list(APPEND mshadow_LINKER_LIBS ${BLAS_LIBRARIES})
if(USE_INT64_TENSOR_SIZE)
add_definitions(-DUSE_INT64_TENSOR_SIZE=1)
endif()
add_definitions(-DMSHADOW_USE_CBLAS=0)
add_definitions(-DMSHADOW_USE_MKL=1)
add_definitions(-DMXNET_USE_BLAS_MKL=1)
message("-- Found MKL (version: ${MKL_VERSION})")
elseif(BLAS STREQUAL "apple")
find_package(Accelerate REQUIRED)
include_directories(SYSTEM ${Accelerate_INCLUDE_DIR})
Expand Down
9 changes: 7 additions & 2 deletions cmake/upstream/FindBLAS.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,10 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
set(BLAS_mkl_DLL_SUFFIX "_dll")
endif()
else()
if(BLA_STATIC)
# MXNET NOTE: The second 2 lines differs from CMake source by ${CMAKE_CURRENT_LIST_DIR}
# replaced with ${CMAKE_ROOT}/Modules
# https://gitlab.kitware.com/cmake/cmake/-/issues/20548
if(BLA_STATIC AND NOT APPLE)
set(BLAS_mkl_START_GROUP "-Wl,--start-group")
set(BLAS_mkl_END_GROUP "-Wl,--end-group")
else()
Expand Down Expand Up @@ -527,7 +530,9 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
"compiler/lib/${BLAS_mkl_ARCH_NAME}"
"mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
"mkl/lib/${BLAS_mkl_ARCH_NAME}"
"lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}")
"lib" "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
"lib/${BLAS_mkl_ARCH_NAME}"
)

foreach(IT ${BLAS_SEARCH_LIBS})
string(REPLACE " " ";" SEARCH_LIBS ${IT})
Expand Down
34 changes: 34 additions & 0 deletions config/distribution/darwin_cpu_mkl.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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.

set(CMAKE_BUILD_TYPE "Distribution" CACHE STRING "Build type")
set(CFLAGS "-mno-avx" CACHE STRING "CFLAGS")
set(CXXFLAGS "-mno-avx" CACHE STRING "CXXFLAGS")

set(USE_BLAS "mkl" CACHE STRING "BLAS Vendor")
set(BLA_STATIC ON CACHE BOOL "Use static libraries")

set(USE_CUDA OFF CACHE BOOL "Build with CUDA support")
set(USE_OPENCV ON CACHE BOOL "Build with OpenCV support")
set(USE_OPENMP OFF CACHE BOOL "Build with Openmp support")
set(USE_ONEDNN ON CACHE BOOL "Build with ONEDNN support")
set(USE_LAPACK ON CACHE BOOL "Build with lapack support")
set(USE_TVM_OP OFF CACHE BOOL "Enable use of TVM operator build system.")
set(USE_SSE ON CACHE BOOL "Build with x86 SSE instruction support")
set(USE_F16C OFF CACHE BOOL "Build with x86 F16C instruction support")
set(USE_LIBJPEG_TURBO ON CACHE BOOL "Build with libjpeg-turbo")
set(USE_DIST_KVSTORE ON CACHE BOOL "Build with DIST_KVSTORE support")
34 changes: 34 additions & 0 deletions config/distribution/linux_cpu_mkl.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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.

set(CMAKE_BUILD_TYPE "Distribution" CACHE STRING "Build type")
set(CFLAGS "-mno-avx" CACHE STRING "CFLAGS")
set(CXXFLAGS "-mno-avx" CACHE STRING "CXXFLAGS")

set(USE_BLAS "mkl" CACHE STRING "BLAS Vendor")
set(BLA_STATIC ON CACHE BOOL "Use static libraries")

set(USE_CUDA OFF CACHE BOOL "Build with CUDA support")
set(USE_OPENCV ON CACHE BOOL "Build with OpenCV support")
set(USE_OPENMP ON CACHE BOOL "Build with Openmp support")
set(USE_ONEDNN ON CACHE BOOL "Build with ONEDNN support")
set(USE_LAPACK ON CACHE BOOL "Build with lapack support")
set(USE_TVM_OP OFF CACHE BOOL "Enable use of TVM operator build system.")
set(USE_SSE ON CACHE BOOL "Build with x86 SSE instruction support")
set(USE_F16C OFF CACHE BOOL "Build with x86 F16C instruction support")
set(USE_LIBJPEG_TURBO ON CACHE BOOL "Build with libjpeg-turbo")
set(USE_DIST_KVSTORE ON CACHE BOOL "Build with DIST_KVSTORE support")
28 changes: 27 additions & 1 deletion src/initialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* \brief initialize mxnet library
*/
#include "initialize.h"

#include <algorithm>
#include <csignal>

Expand Down Expand Up @@ -52,8 +53,9 @@ void win_err(char** err) {
#endif

#include <dmlc/logging.h>
#include <mxnet/engine.h>
#include <mxnet/c_api.h>
#include <mxnet/engine.h>

#include "./engine/openmp.h"
#include "./operator/custom/custom-inl.h"
#if MXNET_USE_OPENCV
Expand All @@ -62,6 +64,10 @@ void win_err(char** err) {
#include "common/utils.h"
#include "engine/openmp.h"

#if defined(MKL_USE_SINGLE_DYNAMIC_LIBRARY)
#include <mkl.h>
#endif

namespace mxnet {

// pthread_atfork handlers, delegated to LibraryInitializer members.
Expand Down Expand Up @@ -89,6 +95,7 @@ LibraryInitializer::LibraryInitializer()
cpu_worker_nthreads_(dmlc::GetEnv("MXNET_CPU_WORKER_NTHREADS", 1)),
mp_cv_num_threads_(dmlc::GetEnv("MXNET_MP_OPENCV_NUM_THREADS", 0)) {
dmlc::InitLogging("mxnet");
init_mkl_dynamic_library();
engine::OpenMP::Get(); // force OpenMP initialization
install_pthread_atfork_handlers();
}
Expand Down Expand Up @@ -223,6 +230,25 @@ void LibraryInitializer::install_pthread_atfork_handlers() {
#endif
}

void LibraryInitializer::init_mkl_dynamic_library() {
#if !(defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__))
#if MKL_USE_SINGLE_DYNAMIC_LIBRARY
#if USE_INT64_TENSOR_SIZE
int interface = MKL_INTERFACE_ILP64;
#else
int interface = MKL_INTERFACE_LP64;
#endif
#if defined(__INTEL_LLVM_COMPILER) || defined(__APPLE__)
mkl_set_threading_layer(MKL_THREADING_INTEL);
#else
mkl_set_threading_layer(MKL_THREADING_GNU);
interface += MKL_INTERFACE_GNU;
#endif
mkl_set_interface_layer(interface);
#endif
#endif
}

#if MXNET_USE_SIGNAL_HANDLER && DMLC_LOG_STACK_TRACE

static inline void printStackTrace(FILE* out = stderr, const unsigned int max_frames = 63) {
Expand Down
8 changes: 7 additions & 1 deletion src/initialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
*/

#include <cstdlib>
#include <string>
#include <map>
#include <string>

#include "dmlc/io.h"

#ifndef MXNET_INITIALIZE_H_
Expand Down Expand Up @@ -91,6 +92,11 @@ class LibraryInitializer {
*/
void install_pthread_atfork_handlers();

/**
* Sets the interface and threading layer for Intel® oneAPI MKL at run time.
* Use with the Single Dynamic Library.
*/
void init_mkl_dynamic_library();
/**
* Install signal handlers (UNIX). Has no effect on Windows.
*/
Expand Down
11 changes: 10 additions & 1 deletion tools/dependencies/make_shared_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ download () {
fi
}

if [[ ! $PLATFORM == 'darwin' ]]; then
if [[ ! $PLATFORM == 'darwin' ]] && [[ ! $BLAS == 'mkl' ]]; then
source ${DIR}/openblas.sh
fi
source $DIR/libz.sh
Expand All @@ -64,6 +64,15 @@ source $DIR/protobuf.sh
source $DIR/cityhash.sh
source $DIR/zmq.sh
source $DIR/lz4.sh
if [[ $BLAS == 'mkl' ]]; then
source ${DIR}/mkl.sh
source ${DIR}/numpy_mkl.sh
if [[ $PLATFORM == 'darwin' ]]; then
# export this path to find iomp5 needed by MKL according to Intel Link Line Advisor
export DYLD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/opt/intel/oneapi/compiler/${INTEL_MKL}/mac/compiler
fi
fi


export LIBRARY_PATH=${LIBRARY_PATH}:$(dirname $(find $DEPS_PATH -type f -name 'libprotoc*' | grep protobuf | head -n 1)):$DEPS_PATH/lib:$DEPS_PATH/lib64
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$(dirname $(find $DEPS_PATH -type f -name 'libprotoc*' | grep protobuf | head -n 1)):$DEPS_PATH/lib:$DEPS_PATH/lib64
Loading

0 comments on commit abd293f

Please sign in to comment.