mirror of
https://github.com/zebrajr/pytorch.git
synced 2025-12-07 00:21:07 +01:00
Summary: Pull Request resolved: https://github.com/pytorch/pytorch/pull/46057 The code analyser (that uses LLVM and runs in the OSS PyTorch git repo) already produces a YAML file which contains base operator names and the operators that they depend on. Currently, this operator dependency graph is converted into a python dictionary to be imported in BUCK and used there. However, it is mostly fed into other executables by serializing the JSON and the consumer pieces this JSON together by concatenating each argument together. This seems unnecessary. Instead, this diff retains the original YAML file and makes all consumers consume that same YAML file. ghstack-source-id: 114641582 Test Plan: Build Lite Predictor + sandcastle. Reviewed By: iseeyuan Differential Revision: D24186303 fbshipit-source-id: eecf41bf673d90b960c3efe7a1271249f0a4867f
149 lines
4.1 KiB
Bash
Executable File
149 lines
4.1 KiB
Bash
Executable File
#!/bin/bash
|
|
##############################################################################
|
|
# Build LLVM code analyzer and analyze torch code dependency.
|
|
##############################################################################
|
|
#
|
|
# Example usage:
|
|
#
|
|
# 1. Analyze torch and generate yaml file of op dependency transitive closure:
|
|
# LLVM_DIR=${HOME}/src/llvm8/build/install \
|
|
# ANALYZE_TORCH=1 tools/code_analyzer/build.sh
|
|
#
|
|
# 2. Analyze test project and compare with expected result:
|
|
# LLVM_DIR=${HOME}/src/llvm8/build/install \
|
|
# ANALYZE_TEST=1 tools/code_analyzer/build.sh
|
|
#
|
|
# 3. Analyze torch and generate yaml file of op dependency with debug path:
|
|
# LLVM_DIR=${HOME}/src/llvm8/build/install \
|
|
# ANALYZE_TORCH=1 tools/code_analyzer/build.sh -debug_path=true
|
|
#
|
|
# If you're a Facebook employee, chances are you're running on CentOS 8.
|
|
# If that's the case, you can install all the dependencies you need with:
|
|
#
|
|
# sudo dnf install llvm-devel llvm-static clang ncurses-devel
|
|
#
|
|
# and then set LLVM_DIR=/usr
|
|
|
|
set -ex
|
|
|
|
SRC_ROOT="$( cd "$(dirname "$0")"/../.. ; pwd -P)"
|
|
ANALYZER_SRC_HOME="${SRC_ROOT}/tools/code_analyzer"
|
|
|
|
# Clang/LLVM path
|
|
export LLVM_DIR="${LLVM_DIR:-/usr/lib/llvm-8}"
|
|
export CC="${LLVM_DIR}/bin/clang"
|
|
export CXX="${LLVM_DIR}/bin/clang++"
|
|
EXTRA_ANALYZER_FLAGS=$@
|
|
|
|
BUILD_ROOT="${BUILD_ROOT:-${SRC_ROOT}/build_code_analyzer}"
|
|
WORK_DIR="${BUILD_ROOT}/work"
|
|
|
|
rm -rf "${BUILD_ROOT}"
|
|
mkdir -p "${BUILD_ROOT}"
|
|
mkdir -p "${WORK_DIR}"
|
|
cd "${BUILD_ROOT}"
|
|
|
|
build_analyzer() {
|
|
cmake "${ANALYZER_SRC_HOME}" -DCMAKE_BUILD_TYPE=Release
|
|
|
|
if [ -z "${MAX_JOBS}" ]; then
|
|
if [ "$(uname)" == 'Darwin' ]; then
|
|
MAX_JOBS=$(sysctl -n hw.ncpu)
|
|
else
|
|
MAX_JOBS=$(nproc)
|
|
fi
|
|
fi
|
|
|
|
make "-j${MAX_JOBS}"
|
|
}
|
|
|
|
build_torch_mobile() {
|
|
TORCH_BUILD_ROOT="${BUILD_ROOT}/build_mobile"
|
|
TORCH_INSTALL_PREFIX="${TORCH_BUILD_ROOT}/install"
|
|
|
|
BUILD_ROOT="${TORCH_BUILD_ROOT}" "${SRC_ROOT}/scripts/build_mobile.sh" \
|
|
-DCMAKE_CXX_FLAGS="-S -emit-llvm -DSTRIP_ERROR_MESSAGES" \
|
|
${MOBILE_BUILD_FLAGS}
|
|
}
|
|
|
|
build_test_project() {
|
|
TEST_SRC_ROOT="${SRC_ROOT}/test/mobile/op_deps"
|
|
TEST_BUILD_ROOT="${BUILD_ROOT}/build_test"
|
|
TEST_INSTALL_PREFIX="${TEST_BUILD_ROOT}/install"
|
|
|
|
BUILD_ROOT="${TEST_BUILD_ROOT}" \
|
|
TORCH_INSTALL_PREFIX="${TORCH_INSTALL_PREFIX}" \
|
|
"${TEST_SRC_ROOT}/build.sh" \
|
|
-DCMAKE_CXX_FLAGS="-S -emit-llvm -DSTRIP_ERROR_MESSAGES"
|
|
}
|
|
|
|
call_analyzer() {
|
|
ANALYZER_BIN="${BUILD_ROOT}/analyzer" \
|
|
INPUT="${INPUT}" OUTPUT="${OUTPUT}" \
|
|
EXTRA_ANALYZER_FLAGS="${EXTRA_ANALYZER_FLAGS}" \
|
|
"${ANALYZER_SRC_HOME}/run_analyzer.sh"
|
|
}
|
|
|
|
analyze_torch_mobile() {
|
|
INPUT="${WORK_DIR}/torch.ll"
|
|
OUTPUT="${WORK_DIR}/torch_result.yaml"
|
|
|
|
if [ ! -f "${INPUT}" ]; then
|
|
# Link libtorch into a single module
|
|
# TODO: invoke llvm-link from cmake directly to avoid this hack.
|
|
# TODO: include *.c.o when there is meaningful fan-out from pure-c code.
|
|
"${LLVM_DIR}/bin/llvm-link" -S \
|
|
$(find "${TORCH_BUILD_ROOT}" -name '*.cpp.o' -o -name '*.cc.o') \
|
|
-o "${INPUT}"
|
|
fi
|
|
|
|
# Analyze dependency
|
|
call_analyzer
|
|
}
|
|
|
|
print_output_file_path() {
|
|
echo "Deployed file at: ${OUTPUT}"
|
|
}
|
|
|
|
analyze_test_project() {
|
|
INPUT="${WORK_DIR}/test.ll"
|
|
OUTPUT="${WORK_DIR}/test_result.yaml"
|
|
|
|
# Link into a single module (only need c10 and OpLib srcs)
|
|
# TODO: invoke llvm-link from cmake directly to avoid this hack.
|
|
"${LLVM_DIR}/bin/llvm-link" -S \
|
|
$(find "${TORCH_BUILD_ROOT}" -path '*/c10*' \( -name '*.cpp.o' -o -name '*.cc.o' \)) \
|
|
$(find "${TEST_BUILD_ROOT}" -path '*/OpLib*' \( -name '*.cpp.o' -o -name '*.cc.o' \)) \
|
|
-o "${INPUT}"
|
|
|
|
# Analyze dependency
|
|
call_analyzer
|
|
}
|
|
|
|
check_test_result() {
|
|
if cmp -s "${OUTPUT}" "${TEST_SRC_ROOT}/expected_deps.yaml"; then
|
|
echo "Test result is the same as expected."
|
|
else
|
|
echo "Test result is DIFFERENT from expected!"
|
|
diff -u "${TEST_SRC_ROOT}/expected_deps.yaml" "${OUTPUT}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
build_analyzer
|
|
|
|
if [ -n "${ANALYZE_TORCH}" ]; then
|
|
build_torch_mobile
|
|
analyze_torch_mobile
|
|
if [ -n "${DEPLOY}" ]; then
|
|
print_output_file_path
|
|
fi
|
|
fi
|
|
|
|
if [ -n "${ANALYZE_TEST}" ]; then
|
|
build_torch_mobile
|
|
build_test_project
|
|
analyze_test_project
|
|
check_test_result
|
|
fi
|