api install needed sudo (#34)
[platform/adaptation/npu/intel-libmvnc.git] / install.sh
1 #!/bin/bash
2 #
3 # Movidius Neural Compute Toolkit installation script.
4
5 # The file ncsdk.conf contains the user configuration options and these
6 # override the defaults set in this script.  The function print_ncsdk_config()
7 # is called if ${VERBOSE} = "yes" to print user config variables and documents what they do.
8 #
9 # Function main at the bottom calls all of the other functions required to install.
10 #
11 # Function check_prerequisites lists the prerequisites required to install
12 #  
13 # Please provide feedback in our support forum if you encountered difficulties.
14 ################################################################################
15 # read in functions shared by installer and uninstaller
16 source $(dirname "$0")/install-utilities.sh
17
18
19 # check_supported_os - require install to be running on a supported OS
20 function check_supported_os()
21 {
22     ### Checking OS and version...
23     # install package lsb-release if application lsb_release isn't installed 
24     RC=0
25     command -v lsb_release > /dev/null || RC=$?
26     [ $RC -ne 0 ] && exec_and_search_errors "$SUDO_PREFIX apt-get install -y lsb-release"
27     
28     DISTRO="$(lsb_release -i 2>/dev/null | cut -f 2)"
29     VERSION="$(lsb_release -r 2>/dev/null | awk '{ print $2 }' | sed 's/[.]//')"
30     OS_DISTRO="${DISTRO:-INVALID}"
31     OS_VERSION="${VERSION:-255}"
32     if [ "${OS_DISTRO,,}" = "ubuntu" ] && [ ${OS_VERSION} = 1604 ]; then
33        # Require 64-bit Ubuntu OS
34         HARDWARE_PLATFORM=$(uname -i)
35         if [ "${HARDWARE_PLATFORM}" != "x86_64" ] ; then
36             echo -e "${RED} You are not running on a 64-bit OS version which is required.  Will exit${NC}"
37             exit 1
38         fi
39         # require AVX support under Ubuntu OS
40         RC=0
41         grep -q avx /proc/cpuinfo || RC=$?
42         if [ ${RC} -ne 0 ] ; then
43             echo -e "${RED}Intel(R) Advanced Vector Extensions, Intel(R) AVX, support required but not detected.  Will exit${NC}"
44             exit 1
45         fi
46         [ "${VERBOSE}" = "yes" ] && echo "Installing on Ubuntu 16.04"
47     elif [ "${OS_DISTRO,,}" = "raspbian" ] && [ ${OS_VERSION} -ge 91 ]; then
48         [ "${VERBOSE}" = "yes" ] && echo "Installing on Raspbian Stretch"
49     elif [ "${OS_DISTRO,,}" = "raspbian" ] && [ ${OS_VERSION} -ge 80 ] && [ ${OS_VERSION} -lt 90 ]; then
50         echo -e "${RED} You are running Raspbian Jessie, which is not supported by NCSDK."
51         echo -e "Please upgrade to Raspbian Stretch and then install NCSDK."
52         echo -e "Error on line $LINENO${NC}"
53         exit 1
54     else
55         echo "Your current combination of Linux distribution and distribution version is not officially supported! Error on line $LINENO.  Will exit"
56         exit 1
57     fi
58     return 0
59 }
60
61
62 # check_prerequisites - tests the prerequisites required to install
63 function check_prerequisites()
64 {
65     prerequisites="sudo sed udevadm tar"
66     for i in $prerequisites; do
67         RC=0
68         # command is a bash builtin to run a command ($i in this case)
69         command -v $i > /dev/null || RC=$?
70         if [ $RC -ne 0 ] ; then
71             echo -e "${RED}Installation prerequisite $i not available on this system.  Error on line $LINENO.  Will exit${NC}"
72             exit 1
73         fi
74     done
75     
76     check_supported_os
77 }
78
79
80 # create_install_logfile - Save a log file of the install in $DIR/setup-logs
81 function create_install_logfile()
82 {
83     # Print stdout and stderr to screen and in logfile
84     d=$(date +%y-%m-%d-%H-%M)
85     LOGFILE="setup_"$d".log"
86     ${SUDO_PREFIX} mkdir -p $DIR/setup-logs
87     ${SUDO_PREFIX} chown $(id -un):$(id -gn) $DIR/setup-logs
88     echo "Saving installation log file in $DIR/setup-logs/$LOGFILE"
89     exec &> >(tee -a "$DIR/setup-logs/$LOGFILE")    
90 }
91
92
93 # print_ncsdk_config - prints out the definition and values of user configurable options
94 function print_ncsdk_config()
95 {
96     echo ""
97     echo "print_ncsdk_config()"
98     echo "INSTALL_DIR - Main installation directory"
99     echo "INSTALL_CAFFE - Flag to install TensorFlow"
100     echo "CAFFE_FLAVOR - Specific 'flavor' of caffe to install"
101     echo "CAFFE_USE_CUDA - Use CUDA enabled version of caffe"
102     echo "INSTALL_TENSORFLOW - Flag to install TensorFlow"
103     echo "INSTALL_TOOLKIT - Flag to install Neural Compute Toolkit"
104     echo "PIP_SYSTEM_INSTALL - Globally install pip packages via sudo -H"
105     echo "VERBOSE - Flag to enable more verbose installation"
106     echo "USE_VIRTUALENV - Flag to enable python virtualenv"
107     echo "MAKE_NJOBS - Number of processes to use for parallel build (i.e. make -j MAKE_NJOBS)"
108     echo ""
109     echo "INSTALL_DIR=${INSTALL_DIR}"
110     echo "INSTALL_CAFFE=${INSTALL_CAFFE}"
111     echo "CAFFE_FLAVOR=${CAFFE_FLAVOR}"
112     echo "CAFFE_USE_CUDA=${CAFFE_USE_CUDA}"
113     echo "INSTALL_TENSORFLOW=${INSTALL_TENSORFLOW}"
114     echo "INSTALL_TOOLKIT=${INSTALL_TOOLKIT}"    
115     echo "PIP_SYSTEM_INSTALL=${PIP_SYSTEM_INSTALL}"
116     echo "VERBOSE=${VERBOSE}"
117     echo "USE_VIRTUALENV=${USE_VIRTUALENV}"
118     echo "MAKE_NJOBS=${MAKE_NJOBS}"
119     echo ""
120 }
121
122
123 # init_installer - 
124 #   sets up installer including error handling, verbosity level, sudo privileges,
125 #   reads ncsdk.conf via read_ncsdk_config function, creates dirs for installation,
126 #   sets global variables CONF_FILE, DIR and NCSDK_VERSION.
127 function init_installer()
128 {
129     # trap errors (function is in install-utilities.sh) 
130     set_error_handling
131
132     ### get constants (function is in install-utilities.sh) 
133     initialize_constants
134     
135     ### Ask for sudo priviledges (function is in install-utilities.sh)
136     ask_sudo_permissions
137
138     ### make sure system has required prerequisites
139     check_prerequisites
140
141     ### check if file exist 
142     VERSION_FILE=version.txt
143     if [ ! -f ${VERSION_FILE} ] ; then
144         echo -e "${RED}Couldn't find file ${VERSION_FILE}. Error on line $LINENO  Will exit${NC}"
145         exit 1
146     fi
147     NCSDK_VERSION=`cat ${VERSION_FILE}`
148     echo "Installer NCSDK version: $NCSDK_VERSION"
149     echo ""
150     
151     ### read config file (function is in install-utilities.sh) 
152     read_ncsdk_config
153
154     ### Set installer verbosity level
155     APT_QUIET=-qq
156     PIP_QUIET=--quiet
157     GIT_QUIET=-q
158     STDOUT_QUIET='>/dev/null'
159     if [ "${VERBOSE}" = "yes" ]; then
160         APT_QUIET=
161         PIP_QUIET=
162         GIT_QUIET=
163         STDOUT_QUIET=
164     fi
165
166     # Install location for sdk and API 
167     DIR=${INSTALL_DIR}/NCSDK
168     SDK_DIR=$DIR/ncsdk-$(eval uname -m)
169     if [ -d /usr/local/lib ]; then
170         SYS_INSTALL_DIR=/usr/local
171     else
172         SYS_INSTALL_DIR=/usr
173     fi
174
175     if [ "${VERBOSE}" = "yes" ] ; then
176         print_ncsdk_config
177     fi
178 }
179
180
181 # make_installer_dirs - creates directories that the install uses
182 function make_installer_dirs()
183 {
184     ### Create Required installation dirs.  
185     ${SUDO_PREFIX} mkdir -p ${INSTALL_DIR}
186     ${SUDO_PREFIX} chown $(id -un):$(id -gn) "$INSTALL_DIR"
187     # Get absolute dir
188     INSTALL_DIR="$( cd ${INSTALL_DIR} && pwd )"
189
190     
191     # Create directories if needed
192     $SUDO_PREFIX mkdir -p $SYS_INSTALL_DIR/include/mvnc2
193     $SUDO_PREFIX mkdir -p $SYS_INSTALL_DIR/lib/mvnc
194 }
195
196
197 # download_and_copy_files - download tarball and copy to install dir
198 function download_and_copy_files()
199 {
200 download_filename=NCSDK-2.10.01.01.tar.gz
201     if [ ! -f ${download_filename} ] ; then
202         ncsdk_link_filename=$(echo $ncsdk_download_link | awk -F / '{print $NF}')
203         # make sure ncsdk_link_filename matches download_filename
204         if [ "${ncsdk_link_filename}" = "${download_filename}" ] ; then
205             echo "Downloading ${download_filename}"
206             exec_and_search_errors "wget -q --no-cache -O ${download_filename} $ncsdk_download_link"
207         else
208             echo -e "${RED}Error file download ($ncsdk_link_filename) doesn't match name based on version.txt ($download_filename)."
209             exit 1
210         fi        
211     else
212         echo "File ${download_filename} exists, will not download again"
213     fi
214     
215     # ncsdk_pkg is the filename without the .tar.gz extension
216     ncsdk_pkg=${download_filename%%.tar.gz}
217
218     # copy files
219     ${SUDO_PREFIX} cp ./$download_filename ${INSTALL_DIR}/ncsdk.tar.gz
220     ${SUDO_PREFIX} cp ./uninstall.sh ${INSTALL_DIR}/
221     ${SUDO_PREFIX} cp ./install-utilities.sh ${INSTALL_DIR}/
222     ${SUDO_PREFIX} cp ./ncsdk.conf ${INSTALL_DIR}/
223     
224     # save current dir
225     FROM_DIR=$PWD
226
227     # untar in INSTALL_DIR 
228     cd ${INSTALL_DIR}
229     if [ "${VERBOSE}" = "yes" ] ; then  
230         TAR_OPTIONS="--no-same-owner -vzxf"
231     else
232         TAR_OPTIONS="--no-same-owner -zxf"
233     fi
234     ${SUDO_PREFIX} tar ${TAR_OPTIONS} ./ncsdk.tar.gz
235     ${SUDO_PREFIX} rm -rf NCSDK
236     ${SUDO_PREFIX} mv $ncsdk_pkg* NCSDK
237     cd ${INSTALL_DIR}/NCSDK
238
239     ${SUDO_PREFIX} cp ${FROM_DIR}/version.txt ${INSTALL_DIR}
240     ${SUDO_PREFIX} cp ${FROM_DIR}/ncsdk.conf ${INSTALL_DIR}/NCSDK 
241     ${SUDO_PREFIX} cp ${FROM_DIR}/uninstall.sh ${INSTALL_DIR}/NCSDK 
242     ${SUDO_PREFIX} cp ${FROM_DIR}/requirements.txt ${INSTALL_DIR}/NCSDK 
243     ${SUDO_PREFIX} cp ${FROM_DIR}/requirements_apt.txt ${INSTALL_DIR}/NCSDK 
244     ${SUDO_PREFIX} cp ${FROM_DIR}/requirements_apt_raspbian.txt ${INSTALL_DIR}/NCSDK 
245 }
246
247
248 # compare_versions - sets global VERCOMP_RETVAL 
249 function compare_versions()
250 {
251     VERCOMP_RETVAL=-1
252     if [ $1 = $2 ]; then
253         VERCOMP_RETVAL=0
254     else
255         if [[ $1 = `echo -e "$1\n$2" | sort -V | head -n1` ]]; then
256             VERCOMP_RETVAL=1
257         else
258             VERCOMP_RETVAL=2
259         fi
260     fi
261 }
262
263
264 # print_previous_ncsdk_install_info - if previous valid install found, print version number
265 function print_previous_ncsdk_install_info()
266 {
267     if [ "${PREV_INSTALL_INFO}" != "unknown" ]; then
268
269         # compare_versions sets VERCOMP_RETVAL to 0, 1 or 2
270         compare_versions ${PREV_NCSDK_VER} ${NCSDK_VERSION}
271         
272         if [ ${VERCOMP_RETVAL} -eq 0 ]; then
273             echo "Previously installed version is the same as installer version, overwriting..."
274         elif [ ${VERCOMP_RETVAL} -eq 1 ]; then
275             echo "Previously installed version is older than installer version, upgrading..."
276         else
277             echo "Previously installed version is more recent than installer version, downgrading..."
278         fi
279     fi
280 }
281
282
283 # install_apt_dependencies - installs dependencies using apt 
284 function install_apt_dependencies()
285 {
286     exec_and_search_errors "$SUDO_PREFIX apt-get $APT_QUIET update"
287     exec_and_search_errors "$SUDO_PREFIX apt-get $APT_QUIET install -y $(cat "$DIR/requirements_apt.txt")"
288     exec_and_search_errors "$SUDO_PREFIX apt-get $APT_QUIET install -y --no-install-recommends libboost-all-dev"
289
290     # Make sure pip2 and pip3 installed correctly
291     RC=0
292     command -v pip2 > /dev/null || RC=$?
293     if [ $RC -ne 0 ] ; then
294         echo -e "${RED} pip2 command not found.  Will exit${NC}"
295         exit 1
296     fi    
297     RC=0
298     command -v pip3 > /dev/null || RC=$?
299     if [ $RC -ne 0 ] ; then
300         echo -e "${RED} pip3 command not found.  Will exit${NC}"
301         exit 1
302     fi
303
304     $SUDO_PREFIX ldconfig
305 }
306
307
308 # setup_virtualenv - Use python virtualenv 
309 function setup_virtualenv()
310 {
311     echo ""
312     echo "USE_VIRTUALENV=${USE_VIRTUALENV} - will use python virtualenv"
313     [ "${VERBOSE}" = "yes" ] && echo "Installing prerequisites for virtualenv"
314     ${SUDO_PREFIX} apt-get $APT_QUIET install python-virtualenv -y
315     echo ""
316     
317     VIRTUALENV_DIR=${INSTALL_DIR}/virtualenv-python
318     # if virtualenv dir exists, try to activate it
319     if [ -d ${VIRTUALENV_DIR} ] ; then
320         RC=0
321         # disable trapping for unset variables due to activate script 
322         set +u
323         source ${VIRTUALENV_DIR}/bin/activate || RC=$?
324         set -u
325         if [ ${RC} -ne 0 ] ; then
326             echo "source ${VIRTUALENV_DIR}/bin/activate gave an error=${RC}"
327             echo "You need to investigate: 1) Either figure out why virtualenv is not activating correctly or"
328             echo "                         2) edit ncsdk.conf to set USE_VIRTUALENV=no to disable virtualenv.  Will exit"
329             exit 1
330             echo ""
331         else
332             echo "virtualenv ${INSTALL_DIR}/virtualenv-python exists, and successfully activated it"
333         fi
334     else
335         # Create new virtualenv and activate it
336         echo "Creating new virtualenv in ${VIRTUALENV_DIR}"
337         ${SUDO_PREFIX} mkdir -p ${VIRTUALENV_DIR}
338         ${SUDO_PREFIX} virtualenv --system-site-packages -p python3 ${VIRTUALENV_DIR}
339         # disable trapping for unset variables due to activate script
340         set +u
341         RC=0        
342         source ${VIRTUALENV_DIR}/bin/activate || RC=$?
343         set -u        
344         if [ ${RC} -ne 0 ] ; then
345             echo "source ${VIRTUALENV_DIR}/bin/activate gave an error=${RC}"
346             echo "This is unexpected and needs to be investigated."
347             echo "virtualenv can be disabled via edit ncsdk.conf to set USE_VIRTUALENV=no.  Will exit"
348             exit 1
349         else
350             echo "Created virtualenv in ${VIRTUALENV_DIR}, and successfully activated it"
351         fi
352     fi
353     echo ""
354     echo "   To activate this virtualenv in the future enter"
355     echo "   source ${VIRTUALENV_DIR}/bin/activate "
356     echo ""
357
358
359 }
360
361
362 # install_python_dependencies - install dependencies using pip2/pip3 
363 function install_python_dependencies()
364 {
365     # Note: If sudo is used and PIP_SYSTEM_INSTALL=yes (set in ncsdk.conf), pip packages
366     #       will be installed in the systems directory, otherwise installed per user
367     echo "Installing python dependencies"
368
369     if [ "${OS_DISTRO,,}" = "ubuntu" ] ; then
370         exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org -r $DIR/requirements.txt"
371         #NPS exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org --upgrade numpy"
372         # Install packages for python 2.x, required for NCSDK python API
373         exec_and_search_errors "$PIP_PREFIX pip2 install $PIP_QUIET --trusted-host files.pythonhosted.org Enum34>=1.1.6"
374         exec_and_search_errors "$PIP_PREFIX pip2 install $PIP_QUIET --trusted-host files.pythonhosted.org numpy==1.15"
375         #NPS exec_and_search_errors "$PIP_PREFIX pip2 install $PIP_QUIET --trusted-host files.pythonhosted.org --upgrade numpy"
376
377         # verify python3 import scipy._lib.decorator working, a potential problem on Ubuntu only.  First check python3 import scipy.  
378         RC=0
379         python3 -c "import scipy" >& /dev/null || RC=$?
380         if [ ${RC} -ne 0 ] ; then
381             echo -e "${RED}Error, cannot import scipy into python3.  Error on line $LINENO.  Will exit${NC}"
382             exit 1
383         fi
384         RC=0
385         python3 -c "import scipy._lib.decorator" >& /dev/null || RC=$?
386         if [ ${RC} -ne 0 ] ; then
387             echo -e "${YELLOW}Problem importing scipy._lib.decorator into python3.  Attempting to fix${NC}"
388             # Get the location of scipy to get the location of decorator.py 
389             RC=0
390             SCIPY_FILE=$(python3 -c "import scipy; print(scipy.__file__)") || RC=$?
391             if [ ${RC} -eq 0 ] ; then
392                 # Get directory decorator.py is in from SCIPY_FILE. If decorator.py isn't a readable file, i.e. from a broken softlink, reinstall via apt
393                 [ ! -f $(dirname $SCIPY_FILE)/decorator.py ] && $SUDO_PREFIX apt install --reinstall python*-decorator
394                 RC=0
395                 python3 -c "import scipy._lib.decorator" >& /dev/null || RC=$?
396                 if [ ${RC} -ne 0 ] ; then
397                     echo -e "${RED}Error, cannot import scipy._lib.decorator even after trying to fix this problem.  Error on line $LINENO.  Will exit${NC}"
398                     exit 1
399                 else
400                     echo "Resolved problem importing scipy._lib.decorator into python3."
401                     echo ""
402                 fi
403             else
404                 echo -e "${RED}Error in python3 importing scipy / printing scipy.__file__.  Error on line $LINENO.  Will exit${NC}"
405                 exit 1
406             fi  
407         fi
408         
409     elif [ "${OS_DISTRO,,}" = "raspbian" ] ; then
410         # for Raspian, use apt with python3-* if available
411         exec_and_search_errors "$SUDO_PREFIX apt-get $APT_QUIET install -y $(cat "$DIR/requirements_apt_raspbian.txt")"
412         exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org Cython"
413         exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org graphviz"
414         exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org scikit-image>=0.13.0,<=0.14.0"
415         #NPS exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org --upgrade numpy"
416         exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org pygraphviz Enum34>=1.1.6 numpy==1.15 networkx>=2.1,<=2.1"
417         # Install packages for python 2.x, required for NCSDK python API
418         exec_and_search_errors "$PIP_PREFIX pip2 install $PIP_QUIET --trusted-host files.pythonhosted.org Enum34>=1.1.6"
419         #NPS exec_and_search_errors "$PIP_PREFIX pip2 install $PIP_QUIET --trusted-host files.pythonhosted.org --upgrade numpy"
420         exec_and_search_errors "$PIP_PREFIX pip2 install $PIP_QUIET --trusted-host files.pythonhosted.org numpy==1.15"
421     fi
422 }
423
424
425 # find_tensorflow - Test if tensorflow is installed and if it's the supported version
426 #                   function arg1 - package name - tensorflow or tensorflow-gpu
427 #                   sets FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION=0 when supported version of TensorFlow is installed
428 #                   sets FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION=1 when an unsupported version of TensorFlow is installed
429 #                   sets FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION=2 when TensorFlow isn't installed
430 function find_tensorflow()
431 {
432     SUPPORTED_TENSORFLOW_VERSION=1.11.0
433     RC=0
434     $PIP_PREFIX pip3 show $1 1> /dev/null || RC=$?
435     if [ $RC -eq 0 ]; then
436         tf_ver_string=$($PIP_PREFIX pip3 show $1 | grep "^Version:")
437         tf_ver=${tf_ver_string##* }
438         if echo "$1" | grep -q "gpu"; then
439             hw="GPU"
440         else
441             hw="CPU"
442         fi
443         echo "Found tensorflow $hw version $tf_ver"
444         if [ $tf_ver = "$SUPPORTED_TENSORFLOW_VERSION" ]; then
445             FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION=0
446         else
447             FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION=1
448         fi
449     else
450         FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION=2
451     fi
452 }
453
454
455 # install_tensorflow - install supported version of tensorflow on system
456 function install_tensorflow()
457 {
458
459     echo "Checking whether tensorflow CPU version is installed..."
460     # find_tensorflow sets FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION to 0, 1 or 2 depending if correct version installed, incorrect version installed or not installed, respectively
461     find_tensorflow "tensorflow" 
462     tf=${FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION}
463     if [ $tf -ne 0 ]; then
464         echo "Checking whether tensorflow GPU version is installed..."
465         find_tensorflow tensorflow-gpu 
466         tf_gpu=${FIND_TENSORFLOW__FOUND_SUPPORTED_VERSION}
467     fi      
468     if [[ $tf -ne 0 && $tf_gpu -ne 0 ]]; then
469         echo "Couldn't find a supported tensorflow version, installing tensorflow $SUPPORTED_TENSORFLOW_VERSION"
470         exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --trusted-host files.pythonhosted.org --trusted-host www.piwheels.org tensorflow==$SUPPORTED_TENSORFLOW_VERSION"
471     else
472         echo "tensorflow already at latest supported version...skipping."
473     fi
474 }
475
476
477 # download_caffe - download caffe sources via git
478 function download_caffe()
479 {
480     if [ -h "caffe" ]; then
481         $SUDO_PREFIX rm caffe
482     fi
483     if [ ! -d $CAFFE_DIR ]; then
484         echo "Downloading Caffe..."
485         eval git clone $GIT_QUIET $CAFFE_SRC $STDOUT_QUIET $CAFFE_DIR
486     fi
487     ln -sf $CAFFE_DIR caffe
488 }
489
490
491 # configure_caffe_options - customize caffe options
492 function configure_caffe_options()
493 {
494     # TODO: Make this configurable. Supports only python3 for now.
495     sed -i 's/python_version "2"/python_version "3"/' CMakeLists.txt
496     # Use/don't use CUDA
497     if [ "$CAFFE_USE_CUDA" = "no" ]; then
498         sed -i 's/CPU_ONLY  "Build Caffe without CUDA support" OFF/CPU_ONLY  "Build Caffe without CUDA support" ON/' CMakeLists.txt
499     fi
500 }
501
502
503 # find_and_try_adjusting_caffe_symlinks - Create caffe soft link to point to specific caffe flavor that was installed
504 function find_and_try_adjusting_caffe_symlinks()
505 {
506     cd ${INSTALL_DIR}
507     if [[ -h "caffe" && -d "$CAFFE_DIR" ]]; then
508         readlink -f caffe | grep -q "$CAFFE_DIR"
509         if [ $? -eq 0 ]; then
510             echo "$CAFFE_DIR present and we're currently pointing to it"
511             FIND_AND_TRY_ADJUSTING_CAFFE_SYMLINKS_FOUND=0
512         else
513             if [ -d "${CAFFE_DIR}" ]; then
514                 echo "$CAFFE_DIR present, but we're not currently using it. Use it."
515             fi
516             $SUDO_PREFIX rm -f caffe
517             $SUDO_PREFIX ln -sf $CAFFE_DIR caffe
518             FIND_AND_TRY_ADJUSTING_CAFFE_SYMLINKS_FOUND=0
519         fi
520     else
521         echo "Possibly stale caffe install, starting afresh"
522         FIND_AND_TRY_ADJUSTING_CAFFE_SYMLINKS_FOUND=1
523     fi
524 }
525
526 # check_opencv_caffe_conflict - Avoid known problem with OpenCV library linking with libprotobuf-lite when using ssd-caffe
527 function check_opencv_caffe_conflict()
528 {
529     # Problem seen with ssd-caffe if built with OpenCV that links with GTK libraries which uses libprotobuf-lite.so.9
530     # Building OpenCV from source on Ubuntu by default has this problem.  OpenCV defaults to linking with GTK libs which use libprotobuf-lite.so
531     # and this causes a conflict as caffe links against libprotobuf.so, and using libprotobuf-lite.so and libprotobuf.so in the same app can cause problems.
532     # Building OpenCV with QT vs. GTK avoids this problems.
533     # Running make install runs ./uninstall-opencv.sh which attempts to remove OpenCV built from source for this reason.
534     # Note: The OpenCV version apt-get installs in /usr/lib doesn't link against libprotobuf-lite.so, so doesn't have this problem.
535     if [ "${CAFFE_FLAVOR}" = "ssd" ]; then
536         LIBOPENCV_HIGHGUI=/usr/local/lib/libopencv_highgui.so.?.?.?
537         RC=0
538         [ -f  ${LIBOPENCV_HIGHGUI} ] && ldd ${LIBOPENCV_HIGHGUI} | grep libprotobuf-lite >& /dev/null || RC=$?
539         if [ $RC -eq 0 ]; then
540             echo ""
541             echo ""
542             echo "**********************************************************************"
543             echo "          ERROR - Compatibility Issue Detected with OpenCV"
544             echo ""
545             echo "The OpenCV library" ${LIBOPENCV_HIGHGUI} "links against libprotobuf-lite"
546             echo "This causes an error with ssd-caffe as it links against libprotobuf (non-lite version)"
547             echo "and these libraries cannot be used together and can cause a crash when deallocating memory."
548             echo "Note building OpenCV with QT vs. the default GTK avoids this issue"
549             echo ""
550             echo "To avoid this, uninstall OpenCV libraries built from sources."
551             echo "The script, uninstall-opencv.sh, attempts to do this and is called by make install"
552             echo "If you have run make install or uninstall-opencv.sh and see this, try uninstalling OpenCV installed in /usr/local/ manually"
553             echo "Will exit"
554             exit 1
555         fi
556     fi
557 }
558
559
560 # install_caffe - test if caffe installed, if not download, configure and build
561 function install_caffe()
562 {
563     # look for potential conflict with OpenCV library
564     check_opencv_caffe_conflict
565
566     CAFFE_SRC="https://github.com/BVLC/caffe.git"
567     CAFFE_VER="1.0"
568     CAFFE_DIR=bvlc-caffe
569     CAFFE_BRANCH=master
570     if [ "${CAFFE_FLAVOR}" = "intel" ] && [ "${OS_DISTRO,,}" = "ubuntu" ]; then
571         CAFFE_SRC="https://github.com/intel/caffe.git"
572         CAFFE_VER="1.0.3"
573         CAFFE_DIR=intel-caffe
574     elif [ "${CAFFE_FLAVOR}" = "ssd" ]; then
575         CAFFE_SRC="https://github.com/weiliu89/caffe.git"
576         CAFFE_VER=""
577         CAFFE_DIR=ssd-caffe
578         CAFFE_BRANCH=ssd
579     fi
580
581     # check if caffe is already installed
582     RC=0
583     python3 -c "import caffe" 2> /dev/null || RC=$?
584     if [ $RC -eq 1 ]; then
585         echo "Caffe not found, installing caffe..."
586     else
587         if [ "${CAFFE_FLAVOR}" = "intel" ] && [ "${OS_DISTRO,,}" = "ubuntu" ]; then
588             # find_and_try_adjusting_caffe_symlinks sets FIND_AND_TRY_ADJUSTING_CAFFE_SYMLINKS_FOUND to 0 or 1
589             find_and_try_adjusting_caffe_symlinks
590             RC=$FIND_AND_TRY_ADJUSTING_CAFFE_SYMLINKS_FOUND
591             # Look for intel caffe specific operation to determine the version of caffe currently running
592             if [[ $RC -eq 0 && -d "caffe" ]]; then
593                 cd caffe
594                 ./build/tools/caffe time -model models/bvlc_googlenet/deploy.prototxt -engine "MKLDNN" -iterations 1 &> /dev/null
595                 if [ $? -eq 1 ]; then
596                     echo "Intel caffe requested but not found, installing Intel caffe..."
597                 else
598                     echo "Intel caffe already installed, skipping..."
599                     return
600                 fi
601             fi
602         else
603             # find_and_try_adjusting_caffe_symlinks sets FIND_AND_TRY_ADJUSTING_CAFFE_SYMLINKS_FOUND to 0 or 1
604             find_and_try_adjusting_caffe_symlinks
605             RC=$FIND_AND_TRY_ADJUSTING_CAFFE_SYMLINKS_FOUND
606             if [ $RC -eq 0 ]; then
607                 echo "Caffe already installed, skipping..."
608                 return
609             fi
610         fi
611     fi
612
613     ### Install caffe
614     cd ${INSTALL_DIR}
615     if [[ -h "caffe" && -d `readlink -f caffe` ]]; then
616         echo `readlink -f caffe`
617         cd `readlink -f caffe`
618         # grep returns 1 if no lines are matched, causing the script to
619         # think that installation failed, so append "true"
620         is_caffe_dir=`git remote show origin 2>&1 | grep -c -i $CAFFE_SRC` || true
621         if [ "$is_caffe_dir" -eq 0 ]; then
622             cd ..
623             echo -e "${YELLOW}The repo $INSTALL_DIR/caffe does not match the caffe project specified"
624             echo -e "in this installation. Installing caffe from $CAFFE_SRC.\n${NC}"
625             download_caffe
626             cd caffe
627         fi
628
629         eval git reset --hard HEAD $STDOUT_QUIET
630         eval git checkout $GIT_QUIET $CAFFE_BRANCH $STDOUT_QUIET
631         eval git branch -D fathom_branch &>/dev/null || true
632         eval git pull $STDOUT_QUIET
633     elif [ -d "caffe" ]; then
634         echo -e "${YELLOW}Found an old version of caffe, removing it to install the version"
635         echo -e "specified in this installer from $CAFFE_SRC.\n${NC}"
636         $SUDO_PREFIX rm -r caffe
637         download_caffe
638     else
639         download_caffe
640     fi
641
642     cd ${INSTALL_DIR}
643     # disable trapping for unset variables in case PYTHONPATH not set
644     set +u
645     if [ -z "${PYTHONPATH}" ] ; then
646         export PYTHONPATH="$INSTALL_DIR/caffe/python"
647     else
648         export PYTHONPATH="$INSTALL_DIR/caffe/python":$PYTHONPATH
649     fi
650     set -u
651
652     # At this point, caffe *must* be a symlink
653     cd `readlink -f caffe`
654
655     if [ "$CAFFE_BRANCH" != "master" ]; then
656         eval git checkout $GIT_QUIET $CAFFE_BRANCH $STDOUT_QUIET
657     fi
658
659     if [ "$CAFFE_VER" != "" ]; then
660         eval git checkout $GIT_QUIET $CAFFE_VER -b fathom_branch $STDOUT_QUIET
661     fi
662
663     configure_caffe_options
664
665     # If you get an error compiling caffe, one possible potential issue is if you
666     # previously compiled an older version of opencv from sources and it is installed into /usr/local.
667     # In that case the compiler will pick up the older version from /usr/local, not the version
668     # this installer installed.  Please provide feedback in our support forum if you encountered difficulties. 
669     echo "Compiling Caffe..."
670     mkdir -p build
671     cd build
672     eval cmake .. $STDOUT_QUIET
673     eval make -j $MAKE_NJOBS all $STDOUT_QUIET
674
675     echo "Installing caffe..."
676     eval make install $STDOUT_QUIET
677     # You can use 'make runtest' to test this stage manually :)
678     
679     # Add PYTHONPATH if not already there
680     printf "Removing previous references to previous caffe installation..."
681     # Remove older references
682     sed -i "\#export PYTHONPATH=\""${INSTALL_DIR}"/caffe/python\":\$PYTHONPATH#d" $HOME/.bashrc
683     printf "done\n"
684     echo "Adding caffe to PYTHONPATH"
685     grep "^export PYTHONPATH=\"\${PYTHONPATH}:$INSTALL_DIR\/caffe\/python\"" $HOME/.bashrc || echo "export PYTHONPATH=\"\${PYTHONPATH}:$INSTALL_DIR/caffe/python\"" >> $HOME/.bashrc
686 }
687
688
689 # install_sdk - installs SDK to $SYS_INSTALL_DIR/bin
690 function install_sdk()
691 {
692     # copy toolkit 
693     $SUDO_PREFIX cp -r $SDK_DIR/tk $SYS_INSTALL_DIR/bin/ncsdk
694
695     check_and_remove_file $SYS_INSTALL_DIR/bin/mvNCCompile
696     check_and_remove_file $SYS_INSTALL_DIR/bin/mvNCCheck
697     check_and_remove_file $SYS_INSTALL_DIR/bin/mvNCProfile
698     $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/bin/ncsdk/mvNCCompile.py $SYS_INSTALL_DIR/bin/mvNCCompile
699     $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/bin/ncsdk/mvNCCheck.py $SYS_INSTALL_DIR/bin/mvNCCheck
700     $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/bin/ncsdk/mvNCProfile.py $SYS_INSTALL_DIR/bin/mvNCProfile
701     echo "NCS Toolkit binaries have been installed in $SYS_INSTALL_DIR/bin"
702 }
703
704
705 # install_api - installs firmware & API 
706 function install_api()
707 {
708     # Copy firmware(FW) to destination
709     $SUDO_PREFIX cp $SDK_DIR/fw/MvNCAPI-*.mvcmd $SYS_INSTALL_DIR/lib/mvnc/
710
711     # Copy C API to destination
712     $SUDO_PREFIX cp $FROM_DIR/api/include/mvnc.h $SYS_INSTALL_DIR/include/mvnc2    
713     $SUDO_PREFIX cp $SDK_DIR/api/c/libmvnc.so.0 $SYS_INSTALL_DIR/lib/mvnc/
714
715     if [ -f $SDK_DIR/api/c/libmvnc_highclass.so.0 ] ; then
716         $SUDO_PREFIX cp $SDK_DIR/api/c/ncHighClass.h $SYS_INSTALL_DIR/include/mvnc2
717         $SUDO_PREFIX cp $SDK_DIR/api/c/libmvnc_highclass.so.0 $SYS_INSTALL_DIR/lib/mvnc/
718     fi
719
720     check_and_remove_file $SYS_INSTALL_DIR/include/mvnc.h
721     check_and_remove_file $SYS_INSTALL_DIR/include/ncHighClass.h
722     $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/include/mvnc2/mvnc.h $SYS_INSTALL_DIR/include/mvnc.h
723     
724     check_and_remove_file $SYS_INSTALL_DIR/lib/libmvnc.so.0
725     check_and_remove_file $SYS_INSTALL_DIR/lib/libmvnc.so
726     check_and_remove_file $SYS_INSTALL_DIR/lib/libmvnc_highclass.so 
727     $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/lib/mvnc/libmvnc.so.0 $SYS_INSTALL_DIR/lib/libmvnc.so.0
728     $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/lib/mvnc/libmvnc.so.0 $SYS_INSTALL_DIR/lib/libmvnc.so
729     if [ -f $SYS_INSTALL_DIR/lib/mvnc/libmvnc_highclass.so.0 ] ; then
730         $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/include/mvnc2/ncHighClass.h $SYS_INSTALL_DIR/include/ncHighClass.h
731         $SUDO_PREFIX ln -s $SYS_INSTALL_DIR/lib/mvnc/libmvnc_highclass.so.0 $SYS_INSTALL_DIR/lib/libmvnc_highclass.so
732     fi
733     echo "NCS Include files have been installed in $SYS_INSTALL_DIR/include"
734     
735     $SUDO_PREFIX ldconfig
736
737     $SUDO_PREFIX cp -r $DIR/version.txt $INSTALL_DIR/
738     $SUDO_PREFIX cp -r $SDK_DIR/LICENSE $INSTALL_DIR/
739
740     # Install python API
741     $SUDO_PREFIX cp ${FROM_DIR}/api/python/mvnc/mvncapi.py $SDK_DIR/api/python/mvnc
742     $SUDO_PREFIX cp ${FROM_DIR}/api/python/mvnc/__init__.py $SDK_DIR/api/python/mvnc
743     exec_and_search_errors "$PIP_PREFIX pip3 install $PIP_QUIET --upgrade --force-reinstall $SDK_DIR/api"
744     exec_and_search_errors "$PIP_PREFIX pip2 install $PIP_QUIET --upgrade --force-reinstall $SDK_DIR/api"
745     echo "NCS Python API has been installed in $INSTALL_DIR, and PYTHONPATH environment variable updated"
746 }
747
748
749 # finalize_installer - complete install
750 #    create $INSTALL_INFO_FILE file with info on installed files locations
751 #    Update udev rules, add user to 'users' group and remove tarball
752 function finalize_installer()
753 {
754     echo "NCS Libraries have been installed in $SYS_INSTALL_DIR/lib"
755
756     INSTALL_INFO_FILE=$INSTALL_DIR/$INSTALL_INFO_FILENAME
757     touch $INSTALL_INFO_FILE
758     echo "ncsdk_path=$INSTALL_DIR" > $INSTALL_INFO_FILE
759     echo "ncs_lib_path=$SYS_INSTALL_DIR/lib" >> $INSTALL_INFO_FILE
760     echo "ncs_inc_path=$SYS_INSTALL_DIR/include" >> $INSTALL_INFO_FILE
761     if [ "${INSTALL_TOOLKIT}" = 'yes' ]; then
762         echo "ncs_bin_path=$SYS_INSTALL_DIR/bin" >> $INSTALL_INFO_FILE
763     fi
764
765     # Update udev rules
766     echo "Updating udev rules..."
767     $SUDO_PREFIX cp $SDK_DIR/udev/97-usbboot.rules /etc/udev/rules.d/
768     RC=0 
769     $SUDO_PREFIX udevadm control --reload-rules || RC=$?
770     if [ $RC -ne 0 ] ; then
771         echo "Warning udevadm control --reload-rules reported an return code = ${RC}"
772     fi
773     RC=0 
774     $SUDO_PREFIX udevadm trigger || RC=$?
775     if [ $RC -ne 0 ] ; then
776         echo "Warning udevadm trigger return code = ${RC}"
777     fi
778     
779     # Final touch up
780     CURRENT_USER=$(id -u -n)    
781     echo "Adding user '$CURRENT_USER' to 'users' group"
782     $SUDO_PREFIX usermod -a -G users ${CURRENT_USER}
783
784     # cleanup
785     if [ -f ${INSTALL_DIR}/ncsdk.tar.gz ] ; then
786         $SUDO_PREFIX rm ${INSTALL_DIR}/ncsdk.tar.gz
787     fi
788
789     if [ "${INSTALL_CAFFE}" = "yes" ] ; then
790         RC=0
791         grep "export PYTHONPATH=" $HOME/.bashrc > /dev/null  2>&1 || RC=$?
792         if [ $RC -eq 0 ] ; then
793             UPDATED_PYTHONPATH_MSG=$(grep "export PYTHONPATH=" $HOME/.bashrc || RC=$?)
794         else
795             echo -e "${RED}Error, cannot find PYTHONPATH= in $HOME/.bashrc.  Error on line $LINENO.  Will exit${NC}"
796             exit 1
797         fi
798     fi
799     
800     echo ""
801     echo -e "${GREEN}Installation is complete.${NC}"
802     echo "Please provide feedback in our support forum if you encountered difficulties."
803
804     if [ "${MOVED_NCAPI1}" == 'yes' ]; then
805         echo ""
806         echo -e "${YELLOW}Installed NCSDK version: $NCSDK_VERSION"
807         echo -e "Moved existing NCSDK 1.x files to ${NCSDK1_ARCHIVE_DIR}${NC}"
808         echo " You need to either"
809         echo "  - Manually update projects to use NCAPI v2."
810         echo "  - Manually configure your projects to use the old NCAPI v1 files which were "
811         echo "    moved to ${NCSDK1_ARCHIVE_DIR}" 
812         echo ""        
813     fi
814
815     if [ "${INSTALL_CAFFE}" = "yes" ] ; then
816         echo ""
817         echo "The PYTHONPATH environment variable was added to your .bashrc as described in the Caffe documentation."
818         echo -e "${YELLOW} New bash processes including new terminals will use the updated value of PYTHONPATH."
819         echo ""
820         echo "To use the NCSDK in this shell, set PYTHONPATH now:"
821         echo ${UPDATED_PYTHONPATH_MSG}
822         echo -e ${NC}
823     fi
824
825     if [ "${USE_VIRTUALENV}" == 'yes' ]; then
826         echo ""
827         echo "USE_VIRTUALENV=${USE_VIRTUALENV} - used virtualenv in ${VIRTUALENV_DIR}"
828         echo "You must activate this virtualenv to use the NCSDK with python"
829         echo -e "${YELLOW} Activate this virtualenv by entering this command now:"
830         echo "   source ${VIRTUALENV_DIR}/bin/activate "
831         echo -e ${NC}
832     fi
833 }
834
835
836 # main - this is the main function that runs the install
837 function main()
838 {
839     echo "Movidius Neural Compute Toolkit Installation"
840     ### initialization phase
841     init_installer
842
843     # If previous install was from NCSDK 1.x release, move them
844     detect_and_move_ncsdk1
845     
846     # Find old installs, if found, print old version and remove it
847     # find_previous_install and remove_previous_install are in install-utilities.sh
848     find_previous_install
849     print_previous_ncsdk_install_info
850     remove_previous_install
851     
852     ### installation phase
853     make_installer_dirs
854     download_and_copy_files
855     install_apt_dependencies
856     create_install_logfile
857     # Optionally use python virtualenv, USE_VIRTUALENV set in ncsdk.conf
858     [ "${USE_VIRTUALENV}" == 'yes' ] && setup_virtualenv
859     install_python_dependencies
860
861     ### Install tensorflow and caffe based on settings in ncsdk.conf
862     [ "${INSTALL_TENSORFLOW}" = "yes" ] && install_tensorflow
863     [ "${INSTALL_CAFFE}" = "yes" ] && install_caffe
864
865     # install SDK based on settings in ncsdk.conf and C/C++ and Python API
866     [ "${INSTALL_TOOLKIT}" = "yes" ] && install_sdk
867     install_api
868
869     finalize_installer
870 }
871 main
872 exit 0