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

[FEATURE] Enable dynamic linking with MKL and compiler based OpenMP #20474

Merged
merged 16 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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).
  • Loading branch information
akarbown committed Oct 12, 2021
commit 51957929de2958e10b6ae0d97ab87f104e113443
6 changes: 3 additions & 3 deletions .github/workflows/os_x_mklbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:

- name: Test project
run: |
# python3 -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 python3 -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'
# python3 -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'
python3 -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 python3 -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'
python3 -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'
python3 -m pytest -n 4 --durations=50 --verbose tests/python/mkl
9 changes: 1 addition & 8 deletions cmake/ChooseBlas.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,13 @@ 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 AND NOT APPLE)
if(UNIX)
# Single dynamic library interface leads to conflicts between intel omp and llvm omp
# https://github.com/apache/incubator-mxnet/issues/17641
# 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)
elseif(APPLE)
# TODO: Do more research on MKL on MacOs as there seems to be some library issues.
# As a consequence link static MKL libraries.
# TODO: Single dynamic library (SDL) interface for MacOS seems to have:
# 'INTEL MKL ERROR: dlopen(/opt/intel/oneapi/mkl/2021.3.0/lib/libmkl_cdft_core.1.dylib,
# 9):Symbol not found: _mkl_dft_dfticomputebackward' issue.
option(MKL_USE_SINGLE_DYNAMIC_LIBRARY "Use single dynamic library interface" OFF)
else()
option(MKL_USE_SINGLE_DYNAMIC_LIBRARY "Use single dynamic library interface" ON)
endif()
Expand Down
1 change: 1 addition & 0 deletions config/distribution/darwin_cpu_mkl.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ 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")
Expand Down
2 changes: 2 additions & 0 deletions config/distribution/linux_cpu_mkl.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ 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")
Expand Down
2 changes: 1 addition & 1 deletion src/initialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ void LibraryInitializer::init_mkl_dynamic_library() {
#else
int interface = MKL_INTERFACE_LP64;
#endif
#if defined(__INTEL_LLVM_COMPILER)
#if defined(__INTEL_LLVM_COMPILER) || defined(__APPLE__)
mkl_set_threading_layer(MKL_THREADING_INTEL);
#else
mkl_set_threading_layer(MKL_THREADING_GNU);
Expand Down
5 changes: 5 additions & 0 deletions tools/dependencies/make_shared_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ 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


Expand Down
6 changes: 3 additions & 3 deletions tools/dependencies/mkl.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
# This script downloads OneMKL
# TODO @akarbown: Get more general link to download the OneMKL (instead of the generated one)
barry-jin marked this conversation as resolved.
Show resolved Hide resolved
set -ex
INTEL_MKL="2021.3.0"
if [[ (! -e /opt/intel/oneapi/mkl/)]]; then
export INTEL_MKL="2021.3.0"
if [[ (! -e /opt/intel/oneapi/mkl/) ]]; then
>&2 echo "Downloading mkl..."

if [[ $PLATFORM == 'darwin' ]]; then
Expand All @@ -43,7 +43,7 @@ if [[ (! -e /opt/intel/oneapi/mkl/)]]; then
rm ${DEPS_PATH}/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
add-apt-repository "deb https://apt.repos.intel.com/oneapi all main"
apt-get update && \
apt install -y intel-oneapi-mkl-${INTEL_MKL} intel-oneapi-mkl-common-${INTEL_MKL} intel-oneapi-mkl-devel
apt install -y intel-oneapi-mkl-${INTEL_MKL} intel-oneapi-mkl-common-${INTEL_MKL} intel-oneapi-mkl-devel-${INTEL_MKL}
else
>&2 echo "Not available"
fi
Expand Down
45 changes: 45 additions & 0 deletions tools/dependencies/numpy_mkl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

# 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.

# This script rebuilds numpy so that it will use MKL BLAS instead of OpenBLAS.
set -x

# check if numpy uses openblas
set +e
python3 -c "from numpy import show_config; show_config()" | grep 'openblas_info'
if [[ $? -eq 0 ]] && [[ -e /opt/intel/oneapi/mkl/ ]] && [[ ! -e ~/.numpy-site.cfg ]]; then
# create file and add to it MKL configuration
if [[ $PLATFORM == 'darwin' ]]; then
echo "[mkl]
library_dirs = /opt/intel/oneapi/compiler/$INTEL_MKL/mac/compiler/lib:/opt/intel/oneapi/mkl/$INTEL_MKL/lib
include_dirs = /opt/intel/oneapi/mkl/$INTEL_MKL/include
libraries = mkl_rt,iomp5
extra_link_args = -Wl,-rpath,/opt/intel/oneapi/mkl/$INTEL_MKL/lib,-rpath,/opt/intel/oneapi/compiler/$INTEL_MKL/mac/compiler/lib" >> ~/.numpy-site.cfg
else
echo "[mkl]
library_dirs = /opt/intel/oneapi/compiler/$INTEL_MKL/linux/compiler/lib/intel64_lin:/opt/intel/oneapi/mkl/$INTEL_MKL/lib/intel64
include_dirs = /opt/intel/oneapi/mkl/$INTEL_MKL/include
libraries = mkl_rt,iomp5
extra_link_args = -Wl,-rpath,/opt/intel/oneapi/mkl/$INTEL_MKL/lib/intel64,-rpath,/opt/intel/oneapi/compiler/$INTEL_MKL/linux/compiler/lib/intel64_lin" >> ~/.numpy-site.cfg
fi

# reinstall numpy to use MKL BLAS
pip3 install numpy==1.19.5 --no-binary numpy --force-reinstall --no-cache-dir
fi
set -e
2 changes: 1 addition & 1 deletion tools/dependencies/opencv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
set -ex
OPENCV_VERSION=3.4.2
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
if [[ $PLATFORM == 'linux' ]] && [[ ! $BLAS == 'mkl' ]]; then
if [[ $PLATFORM == 'linux' ]] && [[ $BLAS == 'open' ]]; then
OPENCV_LAPACK_OPTIONS=" \
-D OpenBLAS_HOME=$DEPS_PATH \
-D OpenBLAS_INCLUDE_DIR=$DEPS_PATH/include \
Expand Down
2 changes: 0 additions & 2 deletions tools/staticbuild/build_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ cmake -GNinja -C $cmake_config \
ninja
if [[ ! $PLATFORM == 'darwin' ]] && [[ $BLAS == 'mkl' ]]; then
patchelf --set-rpath "/opt/intel/oneapi/mkl/${INTEL_MKL}/lib/intel64/:\$ORIGIN" --force-rpath libmxnet.so
Copy link
Contributor

Choose a reason for hiding this comment

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

Will oneapi/mkl always be in /opt/intel? Is there a reason for not asking users to fix their run-time search path environment variables instead (which ideally would automatically be set correctly upon installation of oneapi/mkl)?

Copy link
Contributor Author

@akarbown akarbown Oct 8, 2021

Choose a reason for hiding this comment

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

> Will oneapi/mkl always be in /opt/intel?
I think that if the user do not define explicitly other location, the default location for oneMKL supposed to be /opt/intel/oneapi/ at least the way it was installed in the way as it is in the mkl.sh file.
> Is there a reason for not asking users to fix their run-time search path environment variables instead (which ideally would automatically be set correctly upon installation of oneapi/mkl)?
I've added it for the sake of the tests so that while running them (in the runtime) libmxnet.dylib could see the MKL libraries. It's not the best solution. Now, I think that maybe it would be better to source /opt/intel/oneapi/setvars.sh script just before the test execution (in the *.yml file). What do you think? Or did you have something else in mind?

Copy link
Contributor

Choose a reason for hiding this comment

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

I assume source /opt/intel/oneapi/setvars.sh is also what users would be expected to do if they install MKL on Mac? If so, I think that'll be more robust than hardcoding the rpath

Copy link
Contributor Author

@akarbown akarbown Oct 10, 2021

Choose a reason for hiding this comment

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

Yes, sure. However, I've just realized that when linking with MKL static libraries there is no need to source /opt/intel/oneapi/setvars.sh. It's mandatory in case of linking with MKL dynamic libraries. Thanks for pointing that out!

elif [[ $PLATFORM == 'darwin' ]] && [[ $BLAS == 'mkl' ]]; then
install_name_tool -add_rpath "/opt/intel/oneapi/mkl/${INTEL_MKL}/lib/:/opt/intel/oneapi/compiler/${INTEL_MKL}/mac/compiler/lib/:\$ORIGIN" libmxnet.dylib
fi
cd -

Expand Down