#!/bin/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 scripts installs the dependencies and compiles # MXNet source. # # The script also installs the MXNet package for Python. # #set -ex export MXNET_GITPATH="https://github.com/apache/incubator-mxnet" if [ -z ${MXNET_TAG} ]; then export MXNET_BRANCH_TAG="" else export MXNET_BRANCH_TAG="--branch $MXNET_TAG" fi export TARIKH=`/bin/date +%Y-%m-%d-%H:%M:%S` if [ -z ${MXNET_HOME} ]; then export MXNET_HOME="$HOME/mxnet" fi export MXNET_HOME_OLD="$HOME/mxnet_${TARIKH}" export MXNET_LOG=${MXNET_HOME}/buildMXNet_mac.log # Insert the Homebrew directory at the top of your PATH environment variable export PATH="$PATH:/usr/local/bin:/usr/local/sbin" # for brew export PATH="$PATH:/usr/bin:/opt/local/bin" # for macports export MACPORTS_WEB="https://guide.macports.org/chunked/installing.macports.html" export BREW_PKGS="pkg-config python opencv graphviz homebrew/core/openblas" export PORT_PKGS="pkgconfig python36 opencv graphviz openblas-devel" # graphviz, opencv-python skipped since already installed via brew/port export PIP_PKGS_ALL="cython numpy" export PIP_PKGS_USER="requests jupyter" export SLEEP_TIME=2 LINE="########################################################################" print_intro_msg() { # # NOTE: Please test and ensure that the message does NOT scroll # beyond the standard 80x25 format of a terminal shell. # echo $LINE echo " " echo "MXNet is a flexible, efficient and scalable library for Deep Learning." echo " " echo "This script installs MXNet on MacOS in \${MXNET_HOME}" echo "If not set, the default value of \${MXNET_HOME} = ~/mxnet" echo "The current value of \${MXNET_HOME} = ${MXNET_HOME}" echo " " echo "If this directory is already present, it is renamed to retain earlier contents." echo "You may want to check and delete this directory if not required." echo " " echo "This script has been tested on: MacOS El Capitan (10.11) and Sierra (10.12)" echo " " echo "If you face any problems with this script, please let us know at:" echo " https://discuss.mxnet.io/" echo " " echo "Typical run-time for this script is around 10 minutes." echo "If your environment has never been setup for development (e.g. gcc), " echo "it could take up to 30 minutes or longer." echo " " MACOS_VERSION=`/usr/bin/uname -r` echo "Your macOS version is: $MACOS_VERSION" echo " " echo $LINE read -p "Do you want to continue? (y/n): " response echo " " while true; do case $response in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done echo " " echo " " echo "MXNET GIT Path = ${MXNET_GITPATH}" echo "MXNET Tag = ${MXNET_TAG}" echo "You can set \$MXNET_TAG to the appropriate github repo tag" echo "If not set, the default value used is the latest version on master" read -p "Do you want to get a list of available tags? (y/n): " response while true; do case $response in [Yy]* ) echo "Available tags are:" git ls-remote --tags ${MXNET_GITPATH} | sed 's/refs\/tags\///' | grep -v v | grep -v 201 \ | grep -v "{}" | awk '{ print " ", $2 }'; break;; [Nn]* ) break;; * ) echo "Please answer yes or no.";; esac done read -p "Do you want to continue? (y/n): " response echo " " while true; do case $response in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done } # print_intro_msg() # wrapper routine to stop the script if the command invoked returns error chkret() { cmd=$* echo "$cmd" $cmd ret=$? if [[ ${ret} != 0 ]]; then echo " " echo "ERROR: Return value non-zero for: $cmd" echo " " exit 1 fi } # chkret() chk_mac_vers() { export mac_vers=`sw_vers -productVersion | cut -d '.' -f 1,2` if [[ $mac_vers != "10.11" && $mac_vers != "10.12" ]]; then echo " " echo "ERROR: macOS version $mac_vers NOT supported." echo " " echo "Your macOS version is:" sw_vers echo " " exit 1 fi } # chk_mac_vers() install_brew() { echo " " while true; do echo "This script will install/update brew and " echo "following dependent packages required for MXNet." echo " Dependent brew packages: ${BREW_PKGS}" echo " Dependent pip packages: ${PIP_PKGS_ALL} ${PIP_PKGS_USER}" read -p "Do you want to continue? (y/n): " response echo " " case $response in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done echo " " echo "BEGIN: Check/Install/Update Homebrew" BREW_PATH=`which brew` if [[ (-z ${BREW_PATH}) || (! -f ${BREW_PATH}) ]]; then yes '' | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" ret=$? if [[ ${ret} != 0 ]]; then echo " " echo "ERROR: Return value non-zero for: homebrew installation using ruby" echo " " exit 1 fi else chkret brew update fi echo "END: Check/Install/Update Homebrew" echo $LINE echo " " echo "BEGIN: Install dependent brew packages for MXNet: ${BREW_PKGS}" chkret brew tap homebrew/core # install each individually to see progress for each for pkg in ${BREW_PKGS} do chkret brew_pkg_install ${pkg} done echo "END: Install dependent brew packages for MXNet: ${BREW_PKGS}" echo $LINE echo " " } # install_brew() brew_pkg_install () { pkg=$1 brew ls --versions $pkg > /dev/null ret=$? if [[ ${ret} != 0 ]]; then echo "brew install $pkg" brew install $pkg else echo "$pkg already installed" fi } # brew_pkg_install install_port () { echo " " while true; do echo "This script will install/update port and " echo "following dependent packages required for MXNet." echo " Dependent port packages: ${PORT_PKGS}" echo " Dependent pip packages: ${PIP_PKGS_ALL} ${PIP_PKGS_USER}" read -p "Do you want to continue? (y/n): " response echo " " case $response in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done echo " " echo "BEGIN: Check/Install/Update port" MACPORTS_PATH=`which port` if [[ (-z ${MACPORTS_PATH}) || (! -f ${MACPORTS_PATH}) ]]; then echo " " echo "ERROR: Please install port for your macOS version from:" echo " " echo $MACPORTS_WEB echo " " exit 1 else echo "NOTE: Updating port if required" export SLEEP_TIME=2 sudo port upgrade outdated echo " " echo "port version is:" port version echo " " fi echo "END: Check/Install/Update port" echo $LINE echo " " echo "BEGIN: Install dependent port packages for MXNet: ${PORT_PKGS}" echo " " #sudo port install python36-readline # install each individually to see progress for each for pkg in ${PORT_PKGS} do chkret sudo port install ${pkg} done if [[ ! -f /opt/local/include/cblas.h ]]; then sudo ln -s /opt/local/include/cblas_openblas.h /opt/local/include/cblas.h fi #if [[ ! -f /usr/local/opt/openblas/lib/libopenblas.a ]]; #then # sudo mkdir -p /usr/local/opt/openblas/lib # sudo ln -s /opt/local/lib/libopenblas.a /usr/local/opt/openblas/lib/libopenblas.a #fi echo " " echo "END: Install dependent port packages for MXNet: ${PORT_PKGS}" echo $LINE echo " " } # install_port install_mac_pkg_manager() { BREW_PATH=`which brew` if [[ (-z ${BREW_PATH}) || (! -f ${BREW_PATH}) ]]; then echo "NOTE: brew NOT installed" export MAC_BREW=0 else echo "NOTE: brew installed" export MAC_BREW=1 export PKG_MGR="brew" fi MACPORTS_PATH=`which port` if [[ (-z ${MACPORTS_PATH}) || (! -f ${MACPORTS_PATH}) ]]; then echo "NOTE: port NOT installed" export MAC_PORT=0 else echo "NOTE: port installed" export MAC_PORT=1 export PKG_MGR="port" fi if [[ $MAC_PORT -eq 1 && $MAC_BREW -eq 1 ]]; then echo "NOTE: Both port and brew installed" export MAC_PKG_ASK=1 export PKG_MGR="" elif [[ $MAC_PORT -eq 0 && $MAC_BREW -eq 0 ]]; then echo "NOTE: Neither port and brew installed" export MAC_PKG_ASK=1 export PKG_MGR="" else export MAC_PKG_ASK=0 while true; do echo "NOTE: Using the already installed package manager: $PKG_MGR" read -p "Do you want to continue? (y/n): " response echo " " case $response in [Yy]* ) break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done fi if [[ $MAC_PKG_ASK -eq 1 ]]; then export MAC_BREW=0 export MAC_PORT=0 while true; do echo " " echo "NOTE: This script supports Homebrew OR Port package manager." echo " " read -p "Which package manager do you want to use? (b/p): " pkg_mgr echo " " case $pkg_mgr in [Bb]* ) export MAC_BREW=1; break;; [Pp]* ) export MAC_PORT=1; break;; * ) echo "Please answer: b or p";; esac done fi if [[ $MAC_PORT -eq 1 ]]; then install_port else install_brew fi } # install_mac_pkg_manager install_dep_pip_for_mxnet() { echo " " echo "BEGIN: Install dependent pip packages for MXNet: " echo "${PIP_PKGS_ALL} ${PIP_PKGS_USER}" echo " " # NOTE: sudo used here chkret sudo easy_install pip chkret sudo pip install --upgrade pip for pkg in ${PIP_PKGS_ALL} do chkret sudo pip install ${pkg} done #chkret sudo pip install --upgrade numpy # NOTE: no sudo used here for pkg in ${PIP_PKGS_USER} do chkret pip install --user ${pkg} done echo "END: Install dependent pip packages for MXNet: ${PIP_PKGS_ALL} ${PIP_PKGS_USER}" echo $LINE echo " " } # install_dep_pip_for_mxnet() # check if mxnet is already installed through other means chk_mxnet_installed() { mxnet_installed=`pip list --format=columns | grep mxnet` if [ "$mxnet_installed" != "" ] then mxnet_version=`echo $mxnet_installed | awk '{print $2}'` echo "MXNet ${mxnet_version} is already installed." echo "This installation might interfere with current installation attempt." read -p "Do you want to remove installed version? (y/n): " response while true; do case $response in [Yy]* ) sudo -H pip uninstall mxnet chk_mxnet_installed break ;; [Nn]* ) while true; do read -p "Do you want to continue? (y/n): " response1 echo " " case $response1 in [Yy]* ) break 2;; # break out of nested loop [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done ;; * ) echo "Please answer yes or no.";; esac done fi } # chk_mxnet download_mxnet() { echo " " echo "BEGIN: Download MXNet" if [ -d ${MXNET_HOME} ]; then mv ${MXNET_HOME} ${MXNET_HOME_OLD} echo " " echo "Renamed directory ${MXNET_HOME} to ${MXNET_HOME_OLD}" echo "You may want to check and delete this directory if not required." echo " " sleep ${SLEEP_TIME} fi chkret git clone ${MXNET_BRANCH_TAG} ${MXNET_GITPATH}.git ${MXNET_HOME} --recursive sleep ${SLEEP_TIME} cd ${MXNET_HOME} echo " " sleep ${SLEEP_TIME} echo "END: Download MXNet" echo $LINE echo " " } # download_mxnet compile_mxnet() { # Compile MXNet: It assumes MXNet source is in ${MXNET_HOME} echo "BEGIN: Compile MXNet" cd ${MXNET_HOME} chkret cp make/osx.mk ./config.mk.tmp touch ./config.mk # rm any old setting of USE_BLAS, if present in config file egrep -v "^USE_BLAS" ./config.mk.tmp >> ./config.mk # add the new setting of USE_BLAS to the config file echo "USE_BLAS = openblas" >> ./config.mk if [[ $MAC_PORT -eq 1 ]]; then echo "ADD_CFLAGS += -I/opt/local/lib" >> ./config.mk echo "ADD_LDFLAGS += -L/opt/local/lib" >> ./config.mk echo "ADD_LDFLAGS += -L/opt/local/lib/graphviz/" >> ./config.mk else echo "ADD_CFLAGS += -I/usr/local/opt/openblas/include" >> ./config.mk echo "ADD_LDFLAGS += -L/usr/local/opt/openblas/lib" >> ./config.mk echo "ADD_LDFLAGS += -L/usr/local/lib/graphviz/" >> ./config.mk fi echo " " echo "NOTE: The following compile-time configurations will be used." echo " If you want to change any of them, edit the following file" echo " in another terminal window and then press enter to continue." echo " " echo " ${MXNET_HOME}/config.mk" echo " " echo $LINE # remove commented and blank lines egrep -v "^#" ${MXNET_HOME}/config.mk | egrep -v "^$" echo $LINE echo " " read -p "Press enter to continue ..." echo " " echo "Running Make" echo " " chkret make -j$(sysctl -n hw.ncpu) echo "END: Compile MXNet" sleep ${SLEEP_TIME} echo $LINE echo " " } # compile_mxnet install_mxnet_python() { echo " " echo "BEGIN: Install MXNet package for Python" chkret cd ${MXNET_HOME}/python chkret sudo python setup.py install echo "END: Install MXNet package for Python" sleep ${SLEEP_TIME} echo $LINE echo " " } # install_mxnet_python test_mxnet_python() { echo "BEGIN: Test MXNet" rm -f mxnet_test.log python << END > mxnet_test.log import mxnet as mx a = mx.nd.ones((2, 3)); print ((a*2).asnumpy()); END rm -f mxnet_test.expected cat << END > mxnet_test.expected [[2. 2. 2.] [2. 2. 2.]] END diff mxnet_test.log mxnet_test.expected if [[ $? = 0 ]]; then echo " " echo "SUCCESS: MXNet test passed" echo "SUCCESS: MXNet is successfully installed and works fine!" export MXNET_VERSION=`echo "import mxnet as mx; print(mx.__version__)" | python` echo "SUCCESS: MXNet Version is: $MXNET_VERSION" echo "END: Test MXNet" echo ":-)" echo " " echo "FYI : You can fine-tune MXNet run-time behavior using environment variables described at:" echo " http://mxnet.io/faq/env_var.html" echo " " echo "NEXT: Try the tutorials at: http://mxnet.io/tutorials" echo " " echo $LINE echo " " rm -f mxnet_test.log mxnet_test.expected return 0 else echo " " echo "ERROR: Following files differ: mxnet_test.log mxnet_test.expected" echo "ERROR: MXNet test failed" echo "END: Test MXNet" echo " " echo ":-(" exit 1 fi } # test_mxnet_python() main() { print_intro_msg chk_mac_vers install_mac_pkg_manager install_dep_pip_for_mxnet chk_mxnet_installed download_mxnet compile_mxnet install_mxnet_python test_mxnet_python } # main main