[Caffe2] Consolidating conda build scripts (#6359)
* Consolidating conda build scripts
* Grep bug
* Naming bug
* Correcting quoting of variable passing
diff --git a/conda/caffe2/cuda/build.sh b/conda/caffe2/cuda/build.sh
deleted file mode 100755
index 0946d1d..0000000
--- a/conda/caffe2/cuda/build.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/bash
-
-# Install script for Anaconda environments with CUDA on linux
-# This script is not supposed to be called directly, but should be run by:
-#
-# $ cd <path to caffe2, e.g. ~/caffe2>
-# $ conda build conda/build
-#
-# If you're debugging this, it may be useful to use the env that conda build is
-# using:
-# $ cd <anaconda_root>/conda-bld/caffe2_<timestamp>
-# $ source activate _h_env_... # some long path with lots of placeholders
-#
-# Also, failed builds will accumulate those caffe2_<timestamp> directories. You
-# can remove them after a succesfull build with
-# $ conda build purge
-#
-
-set -ex
-
-echo "Installing caffe2 to ${PREFIX}"
-
-# This is needed for build variants (packages with multiple variants in
-# conda_build_config.yaml) to remove any files that cmake cached, since
-# conda-build uses the same environment for all the build variants
-rm -rf build
-
-PYTHON_ARGS="$(python ./scripts/get_python_cmake_flags.py)"
-CMAKE_ARGS=()
-
-# Build with minimal required libraries
-# Add CMAKE flags here
-CMAKE_ARGS+=("-DUSE_MPI=OFF")
-
-# Build with CUDA
-CMAKE_ARGS+=("-DUSE_CUDA=ON")
-CMAKE_ARGS+=("-DUSE_NCCL=ON")
-
-# Install under specified prefix
-CMAKE_ARGS+=("-DCMAKE_INSTALL_PREFIX=$PREFIX")
-CMAKE_ARGS+=("-DCMAKE_PREFIX_PATH=$PREFIX")
-
-mkdir -p build
-cd build
-cmake "${CMAKE_ARGS[@]}" $CONDA_CMAKE_BUILD_ARGS $PYTHON_ARGS ..
-make "-j$(nproc)"
-
-make install/fast
diff --git a/conda/caffe2/cuda_full/build.sh b/conda/caffe2/full/build.sh
similarity index 100%
rename from conda/caffe2/cuda_full/build.sh
rename to conda/caffe2/full/build.sh
diff --git a/conda/caffe2/cuda_full/conda_build_config.yaml b/conda/caffe2/full/conda_build_config.yaml
similarity index 100%
rename from conda/caffe2/cuda_full/conda_build_config.yaml
rename to conda/caffe2/full/conda_build_config.yaml
diff --git a/conda/caffe2/cuda_full/meta.yaml b/conda/caffe2/full/meta.yaml
similarity index 100%
rename from conda/caffe2/cuda_full/meta.yaml
rename to conda/caffe2/full/meta.yaml
diff --git a/conda/caffe2/no_cuda/build.sh b/conda/caffe2/no_cuda/build.sh
deleted file mode 100755
index 0ca1d5c..0000000
--- a/conda/caffe2/no_cuda/build.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-
-# Install script for Anaconda environments on macOS and linux.
-# This script is not supposed to be called directly, but should be run by:
-#
-# $ cd <path to caffe2, e.g. ~/caffe2>
-# $ conda build conda
-#
-# This installation uses MKL and does not use CUDA
-#
-# If you're debugging this, it may be useful to use the env that conda build is
-# using:
-# $ cd <anaconda_root>/conda-bld/caffe2_<timestamp>
-# $ source activate _h_env_... # some long path with lots of placeholders
-#
-# Also, failed builds will accumulate those caffe2_<timestamp> directories. You
-# can remove them after a succesfull build with
-# $ conda build purge
-#
-
-set -ex
-
-echo "Installing caffe2 to ${PREFIX}"
-
-# This is needed for build variants (packages with multiple variants in
-# conda_build_config.yaml) to remove any files that cmake cached, since
-# conda-build uses the same environment for all the build variants
-rm -rf build
-
-PYTHON_ARGS="$(python ./scripts/get_python_cmake_flags.py)"
-CMAKE_ARGS=()
-
-# This installation defaults to using MKL because it is much faster. If you
-# want to build without MKL then you should also remove mkl from meta.yaml in
-# addition to removing the flags below
-CMAKE_ARGS+=("-DBLAS=MKL")
-
-# Minimal packages
-CMAKE_ARGS+=("-DUSE_CUDA=OFF")
-CMAKE_ARGS+=("-DUSE_MPI=OFF")
-CMAKE_ARGS+=("-DUSE_NCCL=OFF")
-
-# Install under specified prefix
-CMAKE_ARGS+=("-DCMAKE_INSTALL_PREFIX=$PREFIX")
-CMAKE_ARGS+=("-DCMAKE_PREFIX_PATH=$PREFIX")
-
-mkdir -p build
-cd build
-cmake "${CMAKE_ARGS[@]}" $CONDA_CMAKE_BUILD_ARGS $PYTHON_ARGS ..
-if [ "$(uname)" == 'Darwin' ]; then
- make "-j$(sysctl -n hw.ncpu)"
-else
- make "-j$(nproc)"
-fi
-
-make install/fast
diff --git a/conda/caffe2/no_cuda/meta.yaml b/conda/caffe2/no_cuda/meta.yaml
deleted file mode 100644
index ca62504..0000000
--- a/conda/caffe2/no_cuda/meta.yaml
+++ /dev/null
@@ -1,54 +0,0 @@
-{% set version = "0.8.dev" %}
-
-package:
- name: caffe2
- version: {{ version }}
-
-source:
- path: ../../..
-
-build:
- number: 0
- skip: True # [win]
- script_env:
- - CONDA_CMAKE_BUILD_ARGS
-
-requirements:
- build:
- - cmake
- - future
- - gflags
- - glog
- - leveldb
- - lmdb
- - mkl
- - mkl-include
- - numpy
- - opencv
- - python
- - six
- # other packages here
- run:
- - future
- - gflags
- - glog
- - leveldb
- - lmdb
- - mkl
- - mkl-include
- - numpy
- - opencv
- - protobuf
- - python
- - six
- # other packages here
-
-
-about:
- home: https://caffe2.ai/
- license: BSD
- summary: Caffe2 is a lightweight, modular, and scalable deep learning framework.
-
-extra:
- recipe-maintainers:
- - pjh5
diff --git a/conda/caffe2/normal/build.sh b/conda/caffe2/normal/build.sh
new file mode 100755
index 0000000..79b6ccf
--- /dev/null
+++ b/conda/caffe2/normal/build.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# Install script for Anaconda environments on macOS and linux.
+# This script is not supposed to be called directly, but should be called by
+# scripts/build_anaconda.sh, which handles setting lots of needed flags
+# depending on the current system and user flags.
+#
+# If you're debugging this, it may be useful to use the env that conda build is
+# using:
+# $ cd <anaconda_root>/conda-bld/caffe2_<timestamp>
+# $ source activate _h_env_... # some long path with lots of placeholders
+#
+# Also, failed builds will accumulate those caffe2_<timestamp> directories. You
+# can remove them after a succesfull build with
+# $ conda build purge
+
+set -ex
+
+echo "Installing caffe2 to ${PREFIX}"
+
+PYTHON_ARGS="$(python ./scripts/get_python_cmake_flags.py)"
+
+# Install under specified prefix
+CMAKE_ARGS=()
+CMAKE_ARGS+=("-DCMAKE_INSTALL_PREFIX=$PREFIX")
+CMAKE_ARGS+=("-DCMAKE_PREFIX_PATH=$PREFIX")
+
+# Build Caffe2
+mkdir -p build
+cd build
+cmake "${CMAKE_ARGS[@]}" "$PYTHON_ARGS" $CONDA_CMAKE_BUILD_ARGS ..
+if [ "$(uname)" == 'Darwin' ]; then
+ make "-j$(sysctl -n hw.ncpu)"
+else
+ make "-j$(nproc)"
+fi
+
+make install/fast
diff --git a/conda/caffe2/cuda/meta.yaml b/conda/caffe2/normal/meta.yaml
similarity index 78%
rename from conda/caffe2/cuda/meta.yaml
rename to conda/caffe2/normal/meta.yaml
index 4068f08..93bda14 100644
--- a/conda/caffe2/cuda/meta.yaml
+++ b/conda/caffe2/normal/meta.yaml
@@ -1,7 +1,7 @@
{% set version = "0.8.dev" %}
package:
- name: caffe2-cuda
+ name: caffe2
version: {{ version }}
source:
@@ -17,23 +17,13 @@
build:
- cmake
- future
- - glog
- - gflags
- - leveldb
- - lmdb
- numpy
- - opencv
- python
- six
# other packages here
run:
- future
- - glog
- - gflags
- - leveldb
- - lmdb
- numpy
- - opencv
- protobuf
- python
- six
@@ -45,7 +35,9 @@
about:
home: https://caffe2.ai/
- license: BSD
+ license: BSD 3-Clause
+ license_family: BSD
+ license_file: LICENSE
summary: Caffe2 is a lightweight, modular, and scalable deep learning framework.
extra:
diff --git a/scripts/build_anaconda.sh b/scripts/build_anaconda.sh
index d380deb..dec7f4b 100755
--- a/scripts/build_anaconda.sh
+++ b/scripts/build_anaconda.sh
@@ -1,12 +1,30 @@
#!/bin/bash
-# NOTE: All parameters to this function are forwared directly to conda-build
-# and so will never be seen by the build.sh
-# TODO change arguments to go to cmake by default
-# TODO handle setting flags in build.sh too
+# This script creates and (possibly) uploads a Caffe2 Anaconda package, and
+# then (optionally) installs the package locally into the current activated
+# conda environment. This script handles flags needed by CUDA and gcc versions,
+# and has good default behavior if called with no arguments.
+#
+# Usage:
+# ./build_anaconda.sh [--cuda X.Y] [--cudnn Z] [--conda <flag forwared to conda-build>]... [<flags forwarded to cmake>]...
+#
+# Parameters can also be passed through the BUILD_ENVIRONMENT environment
+# variable, e.g.
+# BUILD_ENVIRONMENT=conda2-cuda8.0-cudnn7-gcc4.8 ./scripts/build_anaconda.sh
+# - Parameters parsed from the BUILD_ENVIRONMENT will be overridden by command
+# line parameters.
+# - The conda version and gcc version given in BUILD_ENVIRONMENT are ignored.
+# These versions are determined by calling the binaries with --version
+#
+# The special flags SKIP_CONDA_TESTS, CAFFE2_ANACONDA_ORG_ACCESS_TOKEN, and
+# ANACONDA_USERNAME can only be passed in as environment variables.
set -ex
+#
+# Functions used in this script
+#
+
# portable_sed: A wrapper around sed that works on both mac and linux, used to
# alter conda-build files such as the meta.yaml. It always adds the inplace
# flag
@@ -19,8 +37,8 @@
fi
}
-# remove_package: Given a package name, removes any line that mentions that
-# file from the meta.yaml
+# remove_package: Given a string, removes any line that mentions that line from
+# the meta.yaml
remove_package () {
portable_sed "/$1/d" "${META_YAML}"
}
@@ -28,41 +46,93 @@
# add_package: Takes a package name and a version and finagles the
# meta.yaml to ask for that version specifically.
# NOTE: this assumes that $META_YAML has already been set
+# The \\"$'\n' is a properly escaped new line
+# Those 4 spaces are there to properly indent the comment
add_package () {
remove_package $1
# This magic string _M_STR is in the requirements sections of the meta.yaml
- # The \\"$'\n' is a properly escaped new line
- # Those 4 spaces are there to properly indent the comment
local _M_STR='# other packages here'
portable_sed "s/$_M_STR/- ${1} ${2}\\"$'\n'" $_M_STR/" "${META_YAML}"
}
-CAFFE2_ROOT="$( cd "$(dirname "$0")"/.. ; pwd -P)"
+# add_feature: Adds a given feature tag to the build section. Takes care to
+# only add the feature section once. Assumes that no feature section exists yet
+add_feature() {
+ local _M_STR='# features go here'
+ if [[ -z $ADDED_A_FEATURE ]]; then
+ portable_sed "s/$_M_STR/features:\\"$'\n'" $_M_STR/" "${META_YAML}"
+ ADDED_A_FEATURE=YES
+ fi
+ portable_sed "s/$_M_STR/- ${1}\\"$'\n'" $_M_STR/" "${META_YAML}"
+}
+
+
+#
+# Parse options from both command line and from BUILD_ENVIRONMENT
+#
CONDA_BUILD_ARGS=()
CMAKE_BUILD_ARGS=()
+CAFFE2_CONDA_CHANNEL=()
+if [[ $BUILD_ENVIRONMENT == *cuda* ]]; then
+ CUDA_VERSION="$(echo $BUILD_ENVIRONMENT | grep --only-matching -P '(?<=cuda)[0-9]\.[0-9]')"
+fi
+if [[ $BUILD_ENVIRONMENT == *cudnn* ]]; then
+ CUDNN_VERSION="$(echo $BUILD_ENVIRONMENT | grep --only-matching -P '(?<=cudnn)[0-9](\.[0-9])?')"
+fi
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --cuda)
+ shift
+ CUDA_VERSION="$1"
+ ;;
+ --cudnn)
+ shift
+ CUDNN_VERSION="$1"
+ ;;
+ --conda)
+ shift
+ CONDA_BUILD_ARGS+=("$1")
+ ;;
+ *)
+ CMAKE_BUILD_ARGS+=("$1")
+ ;;
+ esac
+ shift
+done
-# Reinitialize submodules
-git submodule update --init
+# Verify that the CUDA version is supported
+if [[ -n $CUDA_VERSION ]]; then
+ if [[ $CUDA_VERSION == 9.1* ]]; then
+ CUDA_FEATURE_NAME=cuda91
+ elif [[ $CUDA_VERSION == 9.0* ]]; then
+ CUDA_FEATURE_NAME=cuda90
+ elif [[ $CUDA_VERSION == 8.0* ]]; then
+ CUDA_FEATURE_NAME=cuda80
+ else
+ echo "Unsupported CUDA version $CUDA_VERSION"
+ echo "Changes have already been made to the meta.yaml, you may have to revert them"
+ exit 1
+ fi
+ if [[ -z $CUDNN_VERSION ]]; then
+ echo "No CuDNN version given. Caffe2 will still build against whatever"
+ echo "CuDNN that it finds first, and will break if there is no CuDNN found."
+ fi
+ echo "Detected CUDA_VERSION of $CUDA_VERSION"
+fi
#
# Read python and gcc version
#
-
# Read the gcc version to see what ABI to build for
-if [[ $BUILD_ENVIRONMENT == *gcc4.8* ]]; then
- GCC_USE_C11=0
- GCC_VERSION='4.8'
-fi
-if [ "$(uname)" != 'Darwin' -a -z "${GCC_USE_C11}" ]; then
+if [[ "$(uname)" != 'Darwin' ]]; then
GCC_VERSION="$(gcc --version | grep --only-matching '[0-9]\.[0-9]\.[0-9]*' | head -1)"
- if [[ "$GCC_VERSION" == 4* ]]; then
- GCC_USE_C11=0
- else
- GCC_USE_C11=1
- fi
fi
-
+if [[ "$GCC_VERSION" == 4* ]]; then
+ GCC_USE_C11=0
+else
+ GCC_USE_C11=1
+fi
# Read the python version
# Specifically 3.6 because the latest Anaconda version is 3.6, and so it's site
# packages have 3.6 in the name
@@ -77,16 +147,14 @@
#
# Pick the correct conda-build folder
#
-CAFFE2_CONDA_BUILD_DIR="${CAFFE2_ROOT}/conda/caffe2"
+PYTORCH_ROOT="$( cd "$(dirname "$0")"/.. ; pwd -P)"
+CAFFE2_CONDA_BUILD_DIR="${PYTORCH_ROOT}/conda/caffe2"
if [[ "${BUILD_ENVIRONMENT}" == *full* ]]; then
- CAFFE2_CONDA_BUILD_DIR="${CAFFE2_CONDA_BUILD_DIR}/cuda_full"
-elif [[ "${BUILD_ENVIRONMENT}" == *cuda* ]]; then
- CAFFE2_CONDA_BUILD_DIR="${CAFFE2_CONDA_BUILD_DIR}/cuda"
+ CAFFE2_CONDA_BUILD_DIR="${CAFFE2_CONDA_BUILD_DIR}/full"
else
- CAFFE2_CONDA_BUILD_DIR="${CAFFE2_CONDA_BUILD_DIR}/no_cuda"
+ CAFFE2_CONDA_BUILD_DIR="${CAFFE2_CONDA_BUILD_DIR}/normal"
fi
META_YAML="${CAFFE2_CONDA_BUILD_DIR}/meta.yaml"
-CONDA_BUILD_CONFIG_YAML="${CAFFE2_CONDA_BUILD_DIR}/conda_build_config.yaml"
#
@@ -99,7 +167,7 @@
# the package name in meta.yaml based off of these values, we let Caffe2
# take the CUDA and cuDNN versions that it finds in the build environment,
# and manually set the package name ourself.
- CAFFE2_PACKAGE_NAME="${CAFFE2_PACKAGE_NAME}-cuda${CAFFE2_CUDA_VERSION}-cudnn${CAFFE2_CUDNN_VERSION}"
+ CAFFE2_PACKAGE_NAME="${CAFFE2_PACKAGE_NAME}-cuda${CUDA_VERSION}-cudnn${CUDNN_VERSION}"
fi
if [[ "$(uname)" != 'Darwin' ]]; then
if [[ $GCC_USE_C11 -eq 0 ]]; then
@@ -114,7 +182,7 @@
#
-# Handle skipping tests and uploading
+# Handle skipping tests and uploading built packages to Anaconda.org
#
# If skipping tests, remove the test related lines from the meta.yaml and don't
# upload to Anaconda.org
@@ -122,7 +190,6 @@
portable_sed '/test:/d' "${META_YAML}"
portable_sed '/imports:/d' "${META_YAML}"
portable_sed '/caffe2.python.core/d' "${META_YAML}"
-
elif [ -n "$UPLOAD_TO_CONDA" ]; then
# Upload to Anaconda.org if needed. This is only allowed if testing is
# enabled
@@ -132,29 +199,54 @@
#
-# Change flags based on target gcc ABI
+# Set flags and package requirements
#
+# Add normal packages for all builds
+add_package glog
+add_package gflags
+add_package leveldb
+add_package lmdb
+add_package opencv
+#
+# Handle CUDA related flags
+if [[ -n $CUDA_VERSION ]]; then
+ CMAKE_BUILD_ARGS+=("-DUSE_CUDA=ON")
+ CMAKE_BUILD_ARGS+=("-DUSE_NCCL=ON")
+ #add_feature $CUDA_FEATURE_NAME
+ #add_package $CUDA_FEATURE_NAME
+ #add_feature nccl2
+ #CAFFE2_CONDA_CHANNEL+=('-c pytorch')
+else
+ CMAKE_BUILD_ARGS+=("-DUSE_CUDA=OFF")
+ CMAKE_BUILD_ARGS+=("-DUSE_NCCL=OFF")
+ CMAKE_BUILD_ARGS+=("-DBLAS=MKL")
+ add_package 'mkl'
+ add_package 'mkl-include'
+fi
+#
+# Change flags based on target gcc ABI
if [[ "$(uname)" != 'Darwin' ]]; then
if [ "$GCC_USE_C11" -eq 0 ]; then
- CMAKE_BUILD_ARGS+=("-DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0")
- # Default conda channels use gcc 7.2 (for recent packages), conda-forge uses
- # gcc 4.8.5
- CAFFE2_CONDA_CHANNEL='-c conda-forge'
-
- # opencv 3.3.1 in conda-forge doesn't have imgcodecs
+ # opencv 3.3.1 in conda-forge doesn't have imgcodecs, and opencv 3.1.0
+ # requires numpy 1.12
add_package 'opencv' '==3.1.0'
if [[ "$PYTHON_VERSION" == 3.* ]]; then
- # opencv 3.1.0 for python 3 requires numpy 1.12
add_package 'numpy' '>1.11'
fi
+ # Default conda channels use gcc 7.2 (for recent packages), conda-forge uses
+ # gcc 4.8.5
+ CMAKE_BUILD_ARGS+=("-DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=0")
+ CAFFE2_CONDA_CHANNEL+=('-c conda-forge')
fi
fi
+
+#
# Build Caffe2 with conda-build
#
# If --user and --token are set, then this will also upload the built package
# to Anaconda.org, provided there were no failures and all the tests passed
-CONDA_CMAKE_BUILD_ARGS="$CMAKE_BUILD_ARGS" conda build "${CAFFE2_CONDA_BUILD_DIR}" $CAFFE2_CONDA_CHANNEL ${CONDA_BUILD_ARGS[@]} "$@"
+CONDA_CMAKE_BUILD_ARGS=${CMAKE_BUILD_ARGS[@]} conda build "${CAFFE2_CONDA_BUILD_DIR}" $CAFFE2_CONDA_CHANNEL ${CONDA_BUILD_ARGS[@]} "$@"
# Install Caffe2 from the built package into the local conda environment
if [ -n "$CONDA_INSTALL_LOCALLY" ]; then