diff --git a/.github/scripts/fbgemm_gpu_install.bash b/.github/scripts/fbgemm_gpu_install.bash index 50353efa4..84c105083 100644 --- a/.github/scripts/fbgemm_gpu_install.bash +++ b/.github/scripts/fbgemm_gpu_install.bash @@ -8,6 +8,8 @@ # shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/utils_base.bash" +# shellcheck disable=SC1091,SC2128 +. "$( dirname -- "$BASH_SOURCE"; )/utils_pip.bash" ################################################################################ # FBGEMM_GPU Install Functions @@ -78,72 +80,14 @@ install_fbgemm_gpu_pip () { echo "" fi - test_network_connection || return 1 - - # Set the package variant - if [ "$fbgemm_gpu_variant_type" == "cuda" ]; then - # Extract the CUDA version or default to 11.8.0 - local cuda_version="${fbgemm_gpu_variant_version:-11.8.0}" - # shellcheck disable=SC2206 - local cuda_version_arr=(${cuda_version//./ }) - # Convert, i.e. cuda 11.7.1 => cu117 - local fbgemm_gpu_variant="cu${cuda_version_arr[0]}${cuda_version_arr[1]}" - elif [ "$fbgemm_gpu_variant_type" == "rocm" ]; then - # Extract the ROCM version or default to 5.5.1 - local rocm_version="${fbgemm_gpu_variant_version:-5.5.1}" - # shellcheck disable=SC2206 - local rocm_version_arr=(${rocm_version//./ }) - # Convert, i.e. rocm 5.5.1 => rocm5.5 - local fbgemm_gpu_variant="rocm${rocm_version_arr[0]}.${rocm_version_arr[1]}" - else - local fbgemm_gpu_variant_type="cpu" - local fbgemm_gpu_variant="cpu" - fi - echo "[INSTALL] Extracted FBGEMM-GPU variant: ${fbgemm_gpu_variant}" - - # Set the package name and installation channel -# if [ "$fbgemm_gpu_version" == "nightly" ] || [ "$fbgemm_gpu_version" == "test" ]; then -# local fbgemm_gpu_package="--pre fbgemm-gpu" -# local fbgemm_gpu_channel="https://download.pytorch.org/whl/${fbgemm_gpu_version}/${fbgemm_gpu_variant}/" -# elif [ "$fbgemm_gpu_version" == "latest" ]; then -# local fbgemm_gpu_package="fbgemm-gpu" -# local fbgemm_gpu_channel="https://download.pytorch.org/whl/${fbgemm_gpu_variant}/" -# else -# local fbgemm_gpu_package="fbgemm-gpu==${fbgemm_gpu_version}+${fbgemm_gpu_variant}" -# local fbgemm_gpu_channel="https://download.pytorch.org/whl/${fbgemm_gpu_variant}/" -# fi - - if [ "$fbgemm_gpu_variant_type" == "cuda" ]; then - if [ "$fbgemm_gpu_version" == "nightly" ]; then - local fbgemm_gpu_package="fbgemm-gpu-nightly" - elif [ "$fbgemm_gpu_version" == "latest" ]; then - local fbgemm_gpu_package="fbgemm-gpu" - else - local fbgemm_gpu_package="fbgemm-gpu==${fbgemm_gpu_version}" - fi - - elif [ "$fbgemm_gpu_variant_type" == "rocm" ]; then - echo "ROCm is currently not supported in PyPI!" - return 1 - - else - if [ "$fbgemm_gpu_version" == "nightly" ]; then - local fbgemm_gpu_package="fbgemm-gpu-nightly-cpu" - elif [ "$fbgemm_gpu_version" == "latest" ]; then - local fbgemm_gpu_package="fbgemm-gpu-cpu" - else - local fbgemm_gpu_package="fbgemm-gpu-cpu==${fbgemm_gpu_version}" - fi - fi - # shellcheck disable=SC2155 local env_prefix=$(env_name_or_prefix "${env_name}") - echo "[INSTALL] Attempting to install FBGEMM-GPU ${fbgemm_gpu_version}+${fbgemm_gpu_variant} through PIP ..." - # shellcheck disable=SC2086 - (exec_with_retries conda run ${env_prefix} pip install ${fbgemm_gpu_package}) || return 1 + # Install the package from PyTorch PIP (not PyPI) + install_from_pytorch_pip "${env_name}" fbgemm_gpu "${fbgemm_gpu_version}" "${fbgemm_gpu_variant_type}" "${fbgemm_gpu_variant_version}" || return 1 + # Run post-installation checks __fbgemm_gpu_post_install_checks || return 1 - echo "[INSTALL] FBGEMM-GPU installation through PIP completed ..." + echo "[INSTALL] Successfully installed FBGEMM-GPU through PyTorch PIP" } diff --git a/.github/scripts/setup_env.bash b/.github/scripts/setup_env.bash index e26b95c72..e37fdd0a1 100755 --- a/.github/scripts/setup_env.bash +++ b/.github/scripts/setup_env.bash @@ -10,10 +10,14 @@ # shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/utils_system.bash" # shellcheck disable=SC1091,SC2128 +. "$( dirname -- "$BASH_SOURCE"; )/utils_build.bash" +# shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/utils_conda.bash" # shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/utils_cuda.bash" # shellcheck disable=SC1091,SC2128 +. "$( dirname -- "$BASH_SOURCE"; )/utils_pip.bash" +# shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/utils_rocm.bash" # shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/utils_pytorch.bash" @@ -27,228 +31,3 @@ . "$( dirname -- "$BASH_SOURCE"; )/fbgemm_gpu_lint.bash" # shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/fbgemm_gpu_test.bash" - -################################################################################ -# Bazel Setup Functions -################################################################################ - -setup_bazel () { - local bazel_version="${1:-6.1.1}" - echo "################################################################################" - echo "# Setup Bazel" - echo "#" - echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" - echo "################################################################################" - echo "" - - test_network_connection || return 1 - - local bazel_variant="$PLATFORM_NAME_LC" - echo "[SETUP] Downloading installer Bazel ${bazel_version} (${bazel_variant}) ..." - print_exec wget -q "https://github.com/bazelbuild/bazel/releases/download/${bazel_version}/bazel-${bazel_version}-installer-${bazel_variant}.sh" -O install-bazel.sh - - echo "[SETUP] Installing Bazel ..." - print_exec bash install-bazel.sh - print_exec rm -f install-bazel.sh - - print_exec bazel --version - echo "[SETUP] Successfully set up Bazel" -} - - -################################################################################ -# Build Tools Setup Functions -################################################################################ - -install_cxx_compiler () { - local env_name="$1" - local use_system_package_manager="$2" - if [ "$env_name" == "" ]; then - echo "Usage: ${FUNCNAME[0]} ENV_NAME [USE_YUM]" - echo "Example(s):" - echo " ${FUNCNAME[0]} build_env # Install C/C++ compilers through Conda" - echo " ${FUNCNAME[0]} build_env 1 # Install C/C++ compilers through the system package manager" - return 1 - else - echo "################################################################################" - echo "# Install C/C++ Compilers" - echo "#" - echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" - echo "################################################################################" - echo "" - fi - - test_network_connection || return 1 - - if [ "$use_system_package_manager" != "" ]; then - echo "[INSTALL] Installing C/C++ compilers through the system package manager ..." - install_system_packages gcc gcc-c++ - - else - # Install gxx_linux- from conda-forge instead of from anaconda channel. - # sysroot_linux- needs to be installed alongside this: - # - # https://root-forum.cern.ch/t/error-timespec-get-has-not-been-declared-with-conda-root-package/45712/6 - # https://github.com/conda-forge/conda-forge.github.io/issues/1625 - # https://conda-forge.org/docs/maintainer/knowledge_base.html#using-centos-7 - # https://github.com/conda/conda-build/issues/4371 - # - # NOTE: We install g++ 10.x instead of 11.x becaue 11.x builds binaries that - # reference GLIBCXX_3.4.29, which may not be available on systems with older - # versions of libstdc++.so.6 such as CentOS Stream 8 and Ubuntu 20.04 - local archname="" - if [ "$MACHINE_NAME_LC" = "x86_64" ]; then - archname="64" - elif [ "$MACHINE_NAME_LC" = "aarch64" ] || [ "$MACHINE_NAME_LC" = "arm64" ]; then - archname="aarch64" - else - archname="$MACHINE_NAME_LC" - fi - - # shellcheck disable=SC2155 - local env_prefix=$(env_name_or_prefix "${env_name}") - - echo "[INSTALL] Installing C/C++ compilers through Conda (architecture = ${archname}) ..." - # shellcheck disable=SC2086 - (exec_with_retries conda install ${env_prefix} -y "gxx_linux-${archname}"=10.4.0 "sysroot_linux-${archname}"=2.17 -c conda-forge) || return 1 - - # The compilers are visible in the PATH as `x86_64-conda-linux-gnu-cc` and - # `x86_64-conda-linux-gnu-c++`, so symlinks will need to be created - echo "[INSTALL] Setting the C/C++ compiler symlinks ..." - # shellcheck disable=SC2155,SC2086 - local cc_path=$(conda run ${env_prefix} printenv CC) - # shellcheck disable=SC2155,SC2086 - local cxx_path=$(conda run ${env_prefix} printenv CXX) - - print_exec ln -s "${cc_path}" "$(dirname "$cc_path")/cc" - print_exec ln -s "${cc_path}" "$(dirname "$cc_path")/gcc" - print_exec ln -s "${cxx_path}" "$(dirname "$cxx_path")/c++" - print_exec ln -s "${cxx_path}" "$(dirname "$cxx_path")/g++" - fi - - # Check C/C++ compilers are visible - (test_binpath "${env_name}" cc) || return 1 - (test_binpath "${env_name}" gcc) || return 1 - (test_binpath "${env_name}" c++) || return 1 - (test_binpath "${env_name}" g++) || return 1 - - # https://stackoverflow.com/questions/2224334/gcc-dump-preprocessor-defines - echo "[INFO] Printing out all preprocessor defines in the C compiler ..." - # shellcheck disable=SC2086 - print_exec conda run ${env_prefix} cc -dM -E - - - # https://stackoverflow.com/questions/2224334/gcc-dump-preprocessor-defines - echo "[INFO] Printing out all preprocessor defines in the C++ compiler ..." - # shellcheck disable=SC2086 - print_exec conda run ${env_prefix} c++ -dM -E -x c++ - - - # Print out the C++ version - # shellcheck disable=SC2086 - print_exec conda run ${env_prefix} c++ --version - - # https://stackoverflow.com/questions/4991707/how-to-find-my-current-compilers-standard-like-if-it-is-c90-etc - echo "[INFO] Printing the default version of the C standard used by the compiler ..." - print_exec "conda run ${env_prefix} cc -dM -E - | grep __STDC_VERSION__" - - # https://stackoverflow.com/questions/2324658/how-to-determine-the-version-of-the-c-standard-used-by-the-compiler - echo "[INFO] Printing the default version of the C++ standard used by the compiler ..." - print_exec "conda run ${env_prefix} c++ -dM -E -x c++ - | grep __cplusplus" - - echo "[INSTALL] Successfully installed C/C++ compilers" -} - -install_build_tools () { - local env_name="$1" - if [ "$env_name" == "" ]; then - echo "Usage: ${FUNCNAME[0]} ENV_NAME" - echo "Example(s):" - echo " ${FUNCNAME[0]} build_env" - return 1 - else - echo "################################################################################" - echo "# Install Build Tools" - echo "#" - echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" - echo "################################################################################" - echo "" - fi - - test_network_connection || return 1 - - # shellcheck disable=SC2155 - local env_prefix=$(env_name_or_prefix "${env_name}") - - echo "[INSTALL] Installing build tools ..." - # shellcheck disable=SC2086 - (exec_with_retries conda install ${env_prefix} -y \ - click \ - cmake \ - hypothesis \ - jinja2 \ - ninja \ - numpy \ - scikit-build \ - wheel) || return 1 - - # Check binaries are visible in the PAATH - (test_binpath "${env_name}" cmake) || return 1 - (test_binpath "${env_name}" ninja) || return 1 - - # Check Python packages are importable - local import_tests=( click hypothesis jinja2 numpy skbuild wheel ) - for p in "${import_tests[@]}"; do - (test_python_import_package "${env_name}" "${p}") || return 1 - done - - echo "[INSTALL] Successfully installed all the build tools" -} - - -################################################################################ -# PyPI Publish Functions -################################################################################ - -publish_to_pypi () { - local env_name="$1" - local package_name="$2" - local pypi_token="$3" - if [ "$pypi_token" == "" ]; then - echo "Usage: ${FUNCNAME[0]} ENV_NAME PACKAGE_NAME PYPI_TOKEN" - echo "Example(s):" - echo " ${FUNCNAME[0]} build_env fbgemm_gpu_nightly-*.whl MY_TOKEN" - echo "" - echo "PYPI_TOKEN is missing!" - return 1 - else - echo "################################################################################" - echo "# Publish to PyPI" - echo "#" - echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" - echo "################################################################################" - echo "" - fi - - test_network_connection || return 1 - - # shellcheck disable=SC2155 - local env_prefix=$(env_name_or_prefix "${env_name}") - - echo "[INSTALL] Installing twine ..." - # shellcheck disable=SC2086 - print_exec conda install ${env_prefix} -y twine - (test_python_import_package "${env_name}" twine) || return 1 - (test_python_import_package "${env_name}" OpenSSL) || return 1 - - echo "[PUBLISH] Uploading package(s) to PyPI: ${package_name} ..." - # shellcheck disable=SC2086 - conda run ${env_prefix} \ - python -m twine upload \ - --username __token__ \ - --password "${pypi_token}" \ - --skip-existing \ - --verbose \ - "${package_name}" - - echo "[PUBLISH] Successfully published package(s) to PyPI: ${package_name}" - echo "[PUBLISH] NOTE: The publish command is a successful no-op if the wheel version already existed in PyPI; please double check!" -} diff --git a/.github/scripts/utils_build.bash b/.github/scripts/utils_build.bash new file mode 100644 index 000000000..12febee99 --- /dev/null +++ b/.github/scripts/utils_build.bash @@ -0,0 +1,185 @@ +#!/bin/bash +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + + +# shellcheck disable=SC1091,SC2128 +. "$( dirname -- "$BASH_SOURCE"; )/utils_base.bash" + +################################################################################ +# Bazel Setup Functions +################################################################################ + +setup_bazel () { + local bazel_version="${1:-6.1.1}" + echo "################################################################################" + echo "# Setup Bazel" + echo "#" + echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" + echo "################################################################################" + echo "" + + test_network_connection || return 1 + + local bazel_variant="$PLATFORM_NAME_LC" + echo "[SETUP] Downloading installer Bazel ${bazel_version} (${bazel_variant}) ..." + print_exec wget -q "https://github.com/bazelbuild/bazel/releases/download/${bazel_version}/bazel-${bazel_version}-installer-${bazel_variant}.sh" -O install-bazel.sh + + echo "[SETUP] Installing Bazel ..." + print_exec bash install-bazel.sh + print_exec rm -f install-bazel.sh + + print_exec bazel --version + echo "[SETUP] Successfully set up Bazel" +} + + +################################################################################ +# Build Tools Setup Functions +################################################################################ + +install_cxx_compiler () { + local env_name="$1" + local use_system_package_manager="$2" + if [ "$env_name" == "" ]; then + echo "Usage: ${FUNCNAME[0]} ENV_NAME [USE_YUM]" + echo "Example(s):" + echo " ${FUNCNAME[0]} build_env # Install C/C++ compilers through Conda" + echo " ${FUNCNAME[0]} build_env 1 # Install C/C++ compilers through the system package manager" + return 1 + else + echo "################################################################################" + echo "# Install C/C++ Compilers" + echo "#" + echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" + echo "################################################################################" + echo "" + fi + + test_network_connection || return 1 + + if [ "$use_system_package_manager" != "" ]; then + echo "[INSTALL] Installing C/C++ compilers through the system package manager ..." + install_system_packages gcc gcc-c++ + + else + # Install gxx_linux- from conda-forge instead of from anaconda channel. + # sysroot_linux- needs to be installed alongside this: + # + # https://root-forum.cern.ch/t/error-timespec-get-has-not-been-declared-with-conda-root-package/45712/6 + # https://github.com/conda-forge/conda-forge.github.io/issues/1625 + # https://conda-forge.org/docs/maintainer/knowledge_base.html#using-centos-7 + # https://github.com/conda/conda-build/issues/4371 + # + # NOTE: We install g++ 10.x instead of 11.x becaue 11.x builds binaries that + # reference GLIBCXX_3.4.29, which may not be available on systems with older + # versions of libstdc++.so.6 such as CentOS Stream 8 and Ubuntu 20.04 + local archname="" + if [ "$MACHINE_NAME_LC" = "x86_64" ]; then + archname="64" + elif [ "$MACHINE_NAME_LC" = "aarch64" ] || [ "$MACHINE_NAME_LC" = "arm64" ]; then + archname="aarch64" + else + archname="$MACHINE_NAME_LC" + fi + + # shellcheck disable=SC2155 + local env_prefix=$(env_name_or_prefix "${env_name}") + + echo "[INSTALL] Installing C/C++ compilers through Conda (architecture = ${archname}) ..." + # shellcheck disable=SC2086 + (exec_with_retries conda install ${env_prefix} -y "gxx_linux-${archname}"=10.4.0 "sysroot_linux-${archname}"=2.17 -c conda-forge) || return 1 + + # The compilers are visible in the PATH as `x86_64-conda-linux-gnu-cc` and + # `x86_64-conda-linux-gnu-c++`, so symlinks will need to be created + echo "[INSTALL] Setting the C/C++ compiler symlinks ..." + # shellcheck disable=SC2155,SC2086 + local cc_path=$(conda run ${env_prefix} printenv CC) + # shellcheck disable=SC2155,SC2086 + local cxx_path=$(conda run ${env_prefix} printenv CXX) + + print_exec ln -s "${cc_path}" "$(dirname "$cc_path")/cc" + print_exec ln -s "${cc_path}" "$(dirname "$cc_path")/gcc" + print_exec ln -s "${cxx_path}" "$(dirname "$cxx_path")/c++" + print_exec ln -s "${cxx_path}" "$(dirname "$cxx_path")/g++" + fi + + # Check C/C++ compilers are visible + (test_binpath "${env_name}" cc) || return 1 + (test_binpath "${env_name}" gcc) || return 1 + (test_binpath "${env_name}" c++) || return 1 + (test_binpath "${env_name}" g++) || return 1 + + # https://stackoverflow.com/questions/2224334/gcc-dump-preprocessor-defines + echo "[INFO] Printing out all preprocessor defines in the C compiler ..." + # shellcheck disable=SC2086 + print_exec conda run ${env_prefix} cc -dM -E - + + # https://stackoverflow.com/questions/2224334/gcc-dump-preprocessor-defines + echo "[INFO] Printing out all preprocessor defines in the C++ compiler ..." + # shellcheck disable=SC2086 + print_exec conda run ${env_prefix} c++ -dM -E -x c++ - + + # Print out the C++ version + # shellcheck disable=SC2086 + print_exec conda run ${env_prefix} c++ --version + + # https://stackoverflow.com/questions/4991707/how-to-find-my-current-compilers-standard-like-if-it-is-c90-etc + echo "[INFO] Printing the default version of the C standard used by the compiler ..." + print_exec "conda run ${env_prefix} cc -dM -E - | grep __STDC_VERSION__" + + # https://stackoverflow.com/questions/2324658/how-to-determine-the-version-of-the-c-standard-used-by-the-compiler + echo "[INFO] Printing the default version of the C++ standard used by the compiler ..." + print_exec "conda run ${env_prefix} c++ -dM -E -x c++ - | grep __cplusplus" + + echo "[INSTALL] Successfully installed C/C++ compilers" +} + +install_build_tools () { + local env_name="$1" + if [ "$env_name" == "" ]; then + echo "Usage: ${FUNCNAME[0]} ENV_NAME" + echo "Example(s):" + echo " ${FUNCNAME[0]} build_env" + return 1 + else + echo "################################################################################" + echo "# Install Build Tools" + echo "#" + echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" + echo "################################################################################" + echo "" + fi + + test_network_connection || return 1 + + # shellcheck disable=SC2155 + local env_prefix=$(env_name_or_prefix "${env_name}") + + echo "[INSTALL] Installing build tools ..." + # shellcheck disable=SC2086 + (exec_with_retries conda install ${env_prefix} -y \ + click \ + cmake \ + hypothesis \ + jinja2 \ + ninja \ + numpy \ + scikit-build \ + wheel) || return 1 + + # Check binaries are visible in the PAATH + (test_binpath "${env_name}" cmake) || return 1 + (test_binpath "${env_name}" ninja) || return 1 + + # Check Python packages are importable + local import_tests=( click hypothesis jinja2 numpy skbuild wheel ) + for p in "${import_tests[@]}"; do + (test_python_import_package "${env_name}" "${p}") || return 1 + done + + echo "[INSTALL] Successfully installed all the build tools" +} diff --git a/.github/scripts/utils_pip.bash b/.github/scripts/utils_pip.bash new file mode 100644 index 000000000..f649be68e --- /dev/null +++ b/.github/scripts/utils_pip.bash @@ -0,0 +1,144 @@ +#!/bin/bash +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + + +# shellcheck disable=SC1091,SC2128 +. "$( dirname -- "$BASH_SOURCE"; )/utils_base.bash" + +################################################################################ +# PyTorch PIP Install Functions +################################################################################ + +install_from_pytorch_pip () { + local env_name="$1" + local package_name="$2" + local package_version="$3" + local package_variant_type="$4" + local package_variant_version="$5" + if [ "$package_variant_type" == "" ]; then + echo "Usage: ${FUNCNAME[0]} ENV_NAME PACKAGE_NAME PACKAGE_VERSION PACKAGE_VARIANT_TYPE [PACKAGE_VARIANT_VERSION]" + echo "Example(s):" + echo " ${FUNCNAME[0]} build_env torch 1.11.0 cpu # Install the CPU variant a specific version" + echo " ${FUNCNAME[0]} build_env torch latest cpu # Install the CPU variant of the latest stable version" + echo " ${FUNCNAME[0]} build_env fbgemm_gpu test cuda 11.7.1 # Install the variant for CUDA 11.7" + echo " ${FUNCNAME[0]} build_env fbgemm_gpu nightly rocm 5.3 # Install the variant for ROCM 5.3" + return 1 + else + echo "################################################################################" + echo "# Install ${package_name} (PyTorch PIP)" + echo "#" + echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" + echo "################################################################################" + echo "" + fi + + test_network_connection || return 1 + + # Set the package variant + if [ "$package_variant_type" == "cuda" ]; then + # Extract the CUDA version or default to 11.8.0 + local cuda_version="${package_variant_version:-11.8.0}" + # shellcheck disable=SC2206 + local cuda_version_arr=(${cuda_version//./ }) + # Convert, i.e. cuda 11.7.1 => cu117 + local package_variant="cu${cuda_version_arr[0]}${cuda_version_arr[1]}" + elif [ "$package_variant_type" == "rocm" ]; then + # Extract the ROCM version or default to 5.5.1 + local rocm_version="${package_variant_version:-5.5.1}" + # shellcheck disable=SC2206 + local rocm_version_arr=(${rocm_version//./ }) + # Convert, i.e. rocm 5.5.1 => rocm5.5 + local package_variant="rocm${rocm_version_arr[0]}.${rocm_version_arr[1]}" + else + local package_variant_type="cpu" + local package_variant="cpu" + fi + echo "[INSTALL] Extracted package variant: ${package_variant}" + + # Set the package name and installation channel + if [ "$package_version" == "nightly" ] || [ "$package_version" == "test" ]; then + local package_package="--pre ${package_name}" + local package_channel="https://download.pytorch.org/whl/${package_version}/${package_variant}/" + elif [ "$package_version" == "latest" ]; then + local package_package="${package_name}" + local package_channel="https://download.pytorch.org/whl/${package_variant}/" + else + local package_package="${package_name}==${package_version}+${package_variant}" + local package_channel="https://download.pytorch.org/whl/${package_variant}/" + fi + + # shellcheck disable=SC2155 + local env_prefix=$(env_name_or_prefix "${env_name}") + + echo "[INSTALL] Attempting to install [${package_name}, ${package_version}+${package_variant}] through PIP using channel ${package_channel} ..." + # shellcheck disable=SC2086 + (exec_with_retries conda run ${env_prefix} pip install ${package_package} --extra-index-url ${package_channel}) || return 1 + + # Check only applies to non-CPU variants + if [ "$package_variant_type" != "cpu" ]; then + # Ensure that the package build is of the correct variant + # This test usually applies to the nightly builds + # shellcheck disable=SC2086 + if conda run ${env_prefix} pip list "${package_name}" | grep "${package_name}" | grep "${package_variant}"; then + echo "[CHECK] The installed package [${package_name}, ${package_version}] is the correct variant (${package_variant})" + else + echo "[CHECK] The installed package [${package_name}, ${package_version}] appears to be an incorrect variant as it is missing references to ${package_variant}!" + echo "[CHECK] This can happen if the variant of the package (e.g. GPU, nightly) for the MAJOR.MINOR version of CUDA or ROCm presently installed on the system is not available." + return 1 + fi + fi +} + + +################################################################################ +# PyPI Publish Functions +################################################################################ + +publish_to_pypi () { + local env_name="$1" + local package_name="$2" + local pypi_token="$3" + if [ "$pypi_token" == "" ]; then + echo "Usage: ${FUNCNAME[0]} ENV_NAME PACKAGE_NAME PYPI_TOKEN" + echo "Example(s):" + echo " ${FUNCNAME[0]} build_env fbgemm_gpu_nightly-*.whl MY_TOKEN" + echo "" + echo "PYPI_TOKEN is missing!" + return 1 + else + echo "################################################################################" + echo "# Publish to PyPI" + echo "#" + echo "# [TIMESTAMP] $(date --utc +%FT%T.%3NZ)" + echo "################################################################################" + echo "" + fi + + test_network_connection || return 1 + + # shellcheck disable=SC2155 + local env_prefix=$(env_name_or_prefix "${env_name}") + + echo "[INSTALL] Installing twine ..." + # shellcheck disable=SC2086 + print_exec conda install ${env_prefix} -y twine + (test_python_import_package "${env_name}" twine) || return 1 + (test_python_import_package "${env_name}" OpenSSL) || return 1 + + echo "[PUBLISH] Uploading package(s) to PyPI: ${package_name} ..." + # shellcheck disable=SC2086 + conda run ${env_prefix} \ + python -m twine upload \ + --username __token__ \ + --password "${pypi_token}" \ + --skip-existing \ + --verbose \ + "${package_name}" + + echo "[PUBLISH] Successfully published package(s) to PyPI: ${package_name}" + echo "[PUBLISH] NOTE: The publish command is a successful no-op if the wheel version already existed in PyPI; please double check!" +} diff --git a/.github/scripts/utils_pytorch.bash b/.github/scripts/utils_pytorch.bash index c586bc4dd..8aaea9f4f 100644 --- a/.github/scripts/utils_pytorch.bash +++ b/.github/scripts/utils_pytorch.bash @@ -10,6 +10,8 @@ . "$( dirname -- "$BASH_SOURCE"; )/utils_base.bash" # shellcheck disable=SC1091,SC2128 . "$( dirname -- "$BASH_SOURCE"; )/utils_conda.bash" +# shellcheck disable=SC1091,SC2128 +. "$( dirname -- "$BASH_SOURCE"; )/utils_pip.bash" ################################################################################ # PyTorch Setup Functions @@ -73,8 +75,8 @@ install_pytorch_conda () { (test_python_import_package "${env_name}" torch.distributed) || return 1 # Print out the actual installed PyTorch version - # shellcheck disable=SC2086 - installed_pytorch_version=$(conda run ${env_prefix} python -c "import torch; print(torch.__version__)") + # shellcheck disable=SC2086,SC2155 + local installed_pytorch_version=$(conda run ${env_prefix} python -c "import torch; print(torch.__version__)") echo "[CHECK] NOTE: The installed version is: ${installed_pytorch_version}" # Run check for GPU variant @@ -123,73 +125,24 @@ install_pytorch_pip () { echo "" fi - test_network_connection || return 1 - - # Set the package variant - if [ "$pytorch_variant_type" == "cuda" ]; then - # Extract the CUDA version or default to 11.8.0 - local cuda_version="${pytorch_variant_version:-11.8.0}" - # shellcheck disable=SC2206 - local cuda_version_arr=(${cuda_version//./ }) - # Convert, i.e. cuda 11.7.1 => cu117 - local pytorch_variant="cu${cuda_version_arr[0]}${cuda_version_arr[1]}" - elif [ "$pytorch_variant_type" == "rocm" ]; then - # Extract the ROCM version or default to 5.5.1 - local rocm_version="${pytorch_variant_version:-5.5.1}" - # shellcheck disable=SC2206 - local rocm_version_arr=(${rocm_version//./ }) - # Convert, i.e. rocm 5.5.1 => rocm5.5 - local pytorch_variant="rocm${rocm_version_arr[0]}.${rocm_version_arr[1]}" - else - local pytorch_variant_type="cpu" - local pytorch_variant="cpu" - fi - echo "[INSTALL] Extracted PyTorch variant: ${pytorch_variant}" - - # Set the package name and installation channel - if [ "$pytorch_version" == "nightly" ] || [ "$pytorch_version" == "test" ]; then - local pytorch_package="--pre torch" - local pytorch_channel="https://download.pytorch.org/whl/${pytorch_version}/${pytorch_variant}/" - elif [ "$pytorch_version" == "latest" ]; then - local pytorch_package="torch" - local pytorch_channel="https://download.pytorch.org/whl/${pytorch_variant}/" - else - local pytorch_package="torch==${pytorch_version}+${pytorch_variant}" - local pytorch_channel="https://download.pytorch.org/whl/${pytorch_variant}/" - fi - # shellcheck disable=SC2155 local env_prefix=$(env_name_or_prefix "${env_name}") - echo "[INSTALL] Attempting to install PyTorch ${pytorch_version}+${pytorch_variant} through PIP using channel ${pytorch_channel} ..." - # shellcheck disable=SC2086 - (exec_with_retries conda run ${env_prefix} pip install ${pytorch_package} --extra-index-url ${pytorch_channel}) || return 1 + # Install the package from PyTorch PIP (not PyPI) + install_from_pytorch_pip "${env_name}" torch "${pytorch_version}" "${pytorch_variant_type}" "${pytorch_variant_version}" || return 1 # Check that PyTorch is importable (test_python_import_package "${env_name}" torch.distributed) || return 1 # Print out the actual installed PyTorch version - # shellcheck disable=SC2086 - installed_pytorch_version=$(conda run ${env_prefix} python -c "import torch; print(torch.__version__)") + # shellcheck disable=SC2086,SC2155 + local installed_pytorch_version=$(conda run ${env_prefix} python -c "import torch; print(torch.__version__)") echo "[CHECK] NOTE: The installed version is: ${installed_pytorch_version}" - if [ "$pytorch_variant_type" != "cpu" ]; then - # Ensure that the PyTorch build is of the correct variant - # This test usually applies to the PyTorch nightly builds - # shellcheck disable=SC2086 - if conda run ${env_prefix} pip list torch | grep torch | grep "${pytorch_variant}"; then - echo "[CHECK] The installed PyTorch ${pytorch_version} is the correct variant (${pytorch_variant})" - else - echo "[CHECK] The installed PyTorch ${pytorch_version} appears to be an incorrect variant as it is missing references to ${pytorch_variant}!" - echo "[CHECK] This can happen if the variant of PyTorch (e.g. GPU, nightly) for the MAJOR.MINOR version of CUDA or ROCm presently installed on the system is not available." - return 1 - fi - fi - if [ "$pytorch_variant_type" == "cuda" ]; then # Ensure that the PyTorch-CUDA headers are properly installed (test_filepath "${env_name}" cuda_cmake_macros.h) || return 1 fi - echo "[INSTALL] Successfully installed PyTorch through PIP" + echo "[INSTALL] Successfully installed PyTorch through PyTorch PIP" }