Skip to content

Instantly share code, notes, and snippets.

@vsooda
Created November 30, 2017 14:05
Show Gist options
  • Save vsooda/3f230c233714ecb4955338370f126aac to your computer and use it in GitHub Desktop.
Save vsooda/3f230c233714ecb4955338370f126aac to your computer and use it in GitHub Desktop.
andriod mxnet predict build
FROM pythonlib_cpu:latest
LABEL maintainer="Erwan BERNARD https://github.com/edmBernard/DockerFiles"
ENV OPENCV_DIR "$LIB_DIR/opencv"
RUN mkdir -p "$OPENCV_DIR"
ENV NDK_VERSION "android-ndk-r14b"
ENV NDK_TOOLCHAIN_DIR "$LIB_DIR/arm7-toolchain"
ENV OPENBLAS_DIR "$LIB_DIR/OpenBLAS_build"
ENV MXNET_DIR "$LIB_DIR/mxnet"
# ENV ANDROID_STANDALONE_TOOLCHAIN "$NDK_TOOLCHAIN_DIR"
ENV ANDROID_NDK "$LIB_DIR/$NDK_VERSION"
RUN apt-get update && \
apt-get install -y \
openjdk-8-jre \
openjdk-8-jdk
# Create toolchain
RUN cd "$LIB_DIR" && \
wget https://dl.google.com/android/repository/${NDK_VERSION}-linux-x86_64.zip && \
unzip ${NDK_VERSION}-linux-x86_64.zip && \
rm ${NDK_VERSION}-linux-x86_64.zip
RUN $LIB_DIR/${NDK_VERSION}/build/tools/make_standalone_toolchain.py \
--arch arm --api 21 --install-dir $NDK_TOOLCHAIN_DIR --stl=libc++
# Compile OpenBLAS
ENV PATH "${PATH}:$NDK_TOOLCHAIN_DIR/bin"
RUN cd "$LIB_DIR" && git clone https://github.com/xianyi/OpenBLAS.git && cd OpenBLAS && \
git checkout tags/v0.2.19 && \
make TARGET=ARMV7 HOSTCC=gcc CC=arm-linux-androideabi-gcc NOFORTRAN=1 && \
make PREFIX=$OPENBLAS_DIR install
# Compile MXNet Amalgamation
ENV PATH "${PATH}:$NDK_TOOLCHAIN_DIR/bin"
ENV CC arm-linux-androideabi-clang
ENV CXX arm-linux-androideabi-clang++
RUN cd "$LIB_DIR" && git clone --recursive https://github.com/dmlc/mxnet && cd mxnet/amalgamation && \
git checkout c8f7dce0eb49ab1a62ddc2c7e37b93e9b92c2ae4 && \
git submodule update --init --recursive && \
sed -i "s|/usr/local/opt/openblas|$OPENBLAS_DIR|g" Makefile && \
sed -i -e 's/\(#if defined(__MACH__)\)/#define fopen64 std::fopen\n\1/' amalgamation.py && \
sed -i '1i DEFS += -DMSHADOW_USE_CUDA=0 -DMSHADOW_USE_MKL=0 -DMSHADOW_RABIT_PS=0 -DMSHADOW_DIST_PS=0 -DMSHADOW_USE_SSE=0 -DDMLC_LOG_STACK_TRACE=0 -DMSHADOW_FORCE_STREAM -DMXNET_USE_OPENCV=0 -DMXNET_PREDICT_ONLY=1 -DDISABLE_OPENMP=1' ../nnvm/amalgamation/Makefile && \
sed -i '4i CFLAGS = -std=c++11 -Wall -O3 -Wno-unknown-pragmas -funroll-loops -Iinclude -fPIC $(DEFS)' ../nnvm/amalgamation/Makefile && \
make clean && \
make ANDROID=1
# We can't use multiprocess compilation
# download opencv3
RUN cd "$OPENCV_DIR" && \
wget https://github.com/opencv/opencv/archive/master.zip && \
unzip master.zip && \
rm master.zip
# git clone https://github.com/opencv/opencv.git <-- don't work anymore : GnuTLS recv error
# download opencv3 contrib
RUN cd "$OPENCV_DIR" && \
wget https://github.com/opencv/opencv_contrib/archive/master.zip && \
unzip master.zip && \
rm master.zip
# git clone https://github.com/opencv/opencv_contrib.git <-- don't work anymore : GnuTLS recv error
# Compile opencv3
RUN cd "$OPENCV_DIR/opencv-master/platforms/scripts" && \
sh cmake_android_arm.sh -DANDROID_NATIVE_API_LEVEL=21 -DBUILD_SHARED_LIBS=OFF -DBUILD_opencv_world=ON && \
cd ../build_android_arm && \
make -j$(nproc) && \
make install
CMD ["/bin/bash"]
@vsooda
Copy link
Author

vsooda commented Dec 1, 2017

export MXNET_ROOT=`pwd`/..
export CXX=arm-linux-androideabi-clang++
export CC=arm-linux-androideabi-clang

# Change this to path or specify in make command
ifndef OPENBLAS_ROOT
    export OPENBLAS_ROOT=/Users/sooda/tools/andriod/libs
endif

export NNPACK_ROOT=/Users/sooda/tools/andriod/NNPACK


# Whether use minimum build without blas and SSE, this will make the library super slow
ifndef MIN
	export MIN=0
	DEFS=-DMSHADOW_USE_CBLAS=1
else
	DEFS=-DMSHADOW_USE_CBLAS=0
endif

ifndef ANDROID
    export ANDROID=0
else
    DEFS+=-DMSHADOW_USE_SSE=0
endif

# Use locally installed emscripten if not specified
ifndef EMCC
    EMCC=emcc
endif

ifndef DISABLE_OPENMP
       DEFS+=-DDISABLE_OPENMP=1
endif

.PHONY: all clean


DEFS+=-DMSHADOW_USE_CUDA=0 -DMSHADOW_USE_MKL=0 -DMSHADOW_RABIT_PS=0 -DMSHADOW_DIST_PS=0 -DMSHADOW_USE_SSE=0 -DDMLC_LOG_STACK_TRACE=0
DEFS+=-DMSHADOW_FORCE_STREAM -DMXNET_USE_OPENCV=0 -DMXNET_PREDICT_ONLY=1 -DDISABLE_OPENMP=1 -DMXNET_USE_NNPACK=1 -DMXNET_USE_NNPACK_NUM_THREADS=4

CFLAGS = -std=c++11 -Wall -O3 -Wno-unknown-pragmas -funroll-loops -Iinclude -fPIC  -Wno-c++11-narrowing $(DEFS)
CFLAGS += -I${NNPACK_ROOT}/ -I${NNPACK_ROOT}/include -I${NNPACK_ROOT}/deps/gtest-1.7.0/include -I${NNPACK_ROOT}/deps/gtest-1.7.0 -I${NNPACK_ROOT}/deps/pthreadpool/include -I${NNPACK_ROOT}/deps/FXdiv/include
LDFLAGS += -L${NNPACK_ROOT}/obj/local/armeabi-v7a -lnnpack -lpthreadpool -lnnpack_ukernels -lnnpack_reference -lcpufeatures

ifneq ($(MIN), 1)
	CFLAGS += -I${OPENBLAS_ROOT} -I${OPENBLAS_ROOT}/include
	LDFLAGS+= -L${OPENBLAS_ROOT} -L${OPENBLAS_ROOT}/lib
        
	# Define which blas is installed. Uses OpenBLAS by default.
	ifeq ($(USE_BLAS), atlas)
                LDFLAGS += -lcblas
        else ifeq ($(USE_BLAS), blas)
                LDFLAGS += -lblas
        else
		LDFLAGS += -lopenblas
	endif
endif


all: android libmxnet_predict.a ${MXNET_ROOT}/lib/libmxnet_predict.so

nnvm.d:
	./prep_nnvm.sh

dmlc.d: dmlc-minimum0.cc
	${CXX} ${CFLAGS} -M -MT dmlc-minimum0.o \
	-I ${MXNET_ROOT}/dmlc-core/include \
	-D__MIN__=$(MIN) $+ > dmlc.d


mxnet_predict0.d: mxnet_predict0.cc nnvm.d dmlc.d
	${CXX} ${CFLAGS} -M -MT mxnet_predict0.o \
	-I ${MXNET_ROOT}/ -I ${MXNET_ROOT}/mshadow/ -I ${MXNET_ROOT}/dmlc-core/include -I ${MXNET_ROOT}/dmlc-core/src \
	-I ${MXNET_ROOT}/nnvm/include \
	-I ${MXNET_ROOT}/dlpack/include \
	-I ${MXNET_ROOT}/include \
	-D__MIN__=$(MIN) mxnet_predict0.cc > mxnet_predict0.d
	cat dmlc.d >> mxnet_predict0.d
	cat nnvm.d >> mxnet_predict0.d

mxnet_predict-all.cc:  mxnet_predict0.d dmlc-minimum0.cc nnvm.cc mxnet_predict0.cc
	@echo "Generating amalgamation to " $@
	python ./amalgamation.py $+ $@ $(MIN) $(ANDROID)

mxnet_predict-all.o: mxnet_predict-all.cc
	${CXX} ${CFLAGS} -fPIC -o $@ -c $+

libmxnet_predict.a: mxnet_predict-all.o
	ar rcs libmxnet_predict.a $+

jni_libmxnet_predict.o: mxnet_predict-all.cc jni/predictor.cc 
	${CXX} ${CFLAGS} -fPIC -o $@ -c jni/predictor.cc

jni_libmxnet_predict.so: jni_libmxnet_predict.o
	${CXX} ${CFLAGS} -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)

ifneq ($(ANDROID), 1)
        android:
else
        CFLAGS+=  -mhard-float -D_NDK_MATH_NO_SOFTFP=1 -O3
        LDFLAGS+=  -Wl,--no-warn-mismatch -lm_hard
        android: jni_libmxnet_predict.so
endif

libmxnet_predict.js: mxnet_predict-all.cc
	${EMCC} -std=c++11 -O2 $(DEFS) -DMSHADOW_USE_SSE=0 -D__MXNET_JS__  -o $@ $+ \
	-s EXPORTED_FUNCTIONS="['_MXPredCreate', \
	                        '_MXPredGetOutputShape', \
	                        '_MXPredSetInput', \
	                        '_MXPredForward', \
	                        '_MXPredPartialForward', \
	                        '_MXPredGetOutput', \
	                        '_MXPredFree', \
	                        '_MXNDListCreate', \
	                        '_MXNDListGet', \
	                        '_MXNDListFree']" \
	-s ALLOW_MEMORY_GROWTH=1

${MXNET_ROOT}/lib/libmxnet_predict.so:  mxnet_predict-all.o
	@mkdir -p ${MXNET_ROOT}/lib
	${CXX} ${CFLAGS} -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)
	ls -alh $@

clean:
	rm -f *.d *.o *.so *.a *.js *.js.mem mxnet_predict-all.cc nnvm.cc

@vsooda
Copy link
Author

vsooda commented Dec 1, 2017

nnvm/amalgamation

export NNVM_ROOT=`pwd`/..
DEFS+=-DMSHADOW_USE_CUDA=0 -DMSHADOW_USE_MKL=0 -DMSHADOW_RABIT_PS=0 -DMSHADOW_DIST_PS=0 -DMSHADOW_USE_SSE=0 -DDMLC_LOG_STACK_TRACE=0
DEFS+=-DMSHADOW_FORCE_STREAM -DMXNET_USE_OPENCV=0 -DMXNET_PREDICT_ONLY=1 -DDISABLE_OPENMP=1 -DMXNET_USE_NNPACK=1 -DMXNET_USE_NNPACK_NUM_THREADS=4
CFLAGS = -std=c++11 -Wall -O3 -Wno-unknown-pragmas -funroll-loops -Iinclude -fPIC  -Wno-c++11-narrowing $(DEFS)

CFLAGS += -I${NNPACK_ROOT}/ -I${NNPACK_ROOT}/include -I${NNPACK_ROOT}/deps/gtest-1.7.0/include -I${NNPACK_ROOT}/deps/gtest-1.7.0 -I${NNPACK_ROOT}/deps/pthreadpool/include -I${NNPACK_ROOT}/deps/FXdiv/include
LDFLAGS += -L${NNPACK_ROOT}/obj/local/armeabi-v7a -lnnpack -lpthreadpool -lnnpack_ukernels -lnnpack_reference -lcpufeatures

ifdef DMLC_CORE_PATH
  CFLAGS += -I$(DMLC_CORE_PATH)/include
else
  CFLAGS += -I$(CURDIR)/../dmlc-core/include
endif

.PHONY: all clean

all: libnnvm.a

nnvm.cc:
	python generate.py $@

nnvm.d: nnvm.cc
	${CXX} ${CFLAGS} -M -MT nnvm.o \
		-I ${NNVM_ROOT}/ -I ${NNVM_ROOT}/include \
		-D__MIN__=$(MIN) $+ > nnvm.d

nnvm-all.cc: nnvm.d nnvm.cc
	python ./amalgamation.py $+ $@

nnvm-all.o: nnvm-all.cc
	${CXX} ${CFLAGS} -fPIC -o $@ -c $+

libnnvm.a: nnvm-all.o
	ar rcs $@ $+

clean:
	rm -f *.d *.o *.so *.a nnvm-all.cc nnvm.cc

@vsooda
Copy link
Author

vsooda commented Dec 1, 2017

diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment