Unverified Commit 2c8aad97 authored by moto's avatar moto Committed by GitHub
Browse files

Switch to cmake for build (#1187)

* Switch to cmake for build
* Hide symbols
parent 1e887310
...@@ -42,8 +42,8 @@ commands: ...@@ -42,8 +42,8 @@ commands:
description: "installs tools required to build torchaudio" description: "installs tools required to build torchaudio"
steps: steps:
- run: - run:
name: Install cmake and pkg-config name: Install pkg-config
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake pkg-config wget command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config wget
# Disable brew auto update which is very slow # Disable brew auto update which is very slow
binary_common: &binary_common binary_common: &binary_common
......
...@@ -42,8 +42,8 @@ commands: ...@@ -42,8 +42,8 @@ commands:
description: "installs tools required to build torchaudio" description: "installs tools required to build torchaudio"
steps: steps:
- run: - run:
name: Install cmake and pkg-config name: Install pkg-config
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake pkg-config wget command: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config wget
# Disable brew auto update which is very slow # Disable brew auto update which is very slow
binary_common: &binary_common binary_common: &binary_common
......
...@@ -7,10 +7,12 @@ dependencies: ...@@ -7,10 +7,12 @@ dependencies:
- pytest - pytest
- pytest-cov - pytest-cov
- codecov - codecov
- librosa - librosa>=0.8.0
- llvmlite==0.31 # See https://github.com/pytorch/audio/pull/766 - llvmlite==0.31 # See https://github.com/pytorch/audio/pull/766
- pip - pip
- pip: - pip:
- cmake
- ninja
- kaldi-io - kaldi-io
- scipy - scipy
- parameterized - parameterized
......
...@@ -38,6 +38,7 @@ conda install -y -c "pytorch-${UPLOAD_CHANNEL}" pytorch ${cudatoolkit} ...@@ -38,6 +38,7 @@ conda install -y -c "pytorch-${UPLOAD_CHANNEL}" pytorch ${cudatoolkit}
# 2. Install torchaudio # 2. Install torchaudio
printf "* Installing torchaudio\n" printf "* Installing torchaudio\n"
git submodule update --init --recursive
BUILD_TRANSDUCER=1 BUILD_SOX=1 python setup.py install BUILD_TRANSDUCER=1 BUILD_SOX=1 python setup.py install
# 3. Install Test tools # 3. Install Test tools
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# #
# Do not install PyTorch and torchaudio here, otherwise they also get cached. # Do not install PyTorch and torchaudio here, otherwise they also get cached.
set -e set -ex
root_dir="$(git rev-parse --show-toplevel)" root_dir="$(git rev-parse --show-toplevel)"
conda_dir="${root_dir}/conda" conda_dir="${root_dir}/conda"
...@@ -41,12 +41,3 @@ conda activate "${env_dir}" ...@@ -41,12 +41,3 @@ conda activate "${env_dir}"
# 3. Install minimal build tools # 3. Install minimal build tools
pip --quiet install cmake ninja pip --quiet install cmake ninja
# 4. Buld codecs
git submodule update --init --recursive
mkdir -p third_party/build
(
cd third_party/build
cmake -GNinja ..
cmake --build .
)
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# Most of the configurations are taken from PyTorch
# https://github.com/pytorch/pytorch/blob/0c9fb4aff0d60eaadb04e4d5d099fb1e1d5701a9/CMakeLists.txt
# Use compiler ID "AppleClang" instead of "Clang" for XCode.
# Not setting this sometimes makes XCode C compiler gets detected as "Clang",
# even when the C++ one is detected as "AppleClang".
cmake_policy(SET CMP0010 NEW)
cmake_policy(SET CMP0025 NEW)
# Suppress warning flags in default MSVC configuration. It's not
# mandatory that we do this (and we don't if cmake is old), but it's
# nice when it's possible, and it's possible on our Windows configs.
if(NOT CMAKE_VERSION VERSION_LESS 3.15.0)
cmake_policy(SET CMP0092 NEW)
endif()
project(torchaudio)
# check and set CMAKE_CXX_STANDARD
string(FIND "${CMAKE_CXX_FLAGS}" "-std=c++" env_cxx_standard)
if(env_cxx_standard GREATER -1)
message(
WARNING "C++ standard version definition detected in environment variable."
"PyTorch requires -std=c++14. Please remove -std=c++ settings in your environment.")
endif()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_C_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Apple specific
if(APPLE)
# Get clang version on macOS
execute_process( COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE clang_full_version_string )
string(REGEX REPLACE "Apple LLVM version ([0-9]+\\.[0-9]+).*" "\\1" CLANG_VERSION_STRING ${clang_full_version_string})
message( STATUS "CLANG_VERSION_STRING: " ${CLANG_VERSION_STRING} )
# RPATH stuff
set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
endif()
# Options
option(BUILD_SOX "Build libsox statically" OFF)
option(BUILD_TRANSDUCER "Enable transducer" OFF)
option(BUILD_LIBTORCHAUDIO "Build C++ Library" ON)
option(BUILD_PYTHON_EXTENSION "Build Python extension" OFF)
find_package(Torch REQUIRED)
# Set -D_GLIBCXX_USE_CXX11_ABI for third party builds
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_subdirectory(third_party)
add_subdirectory(torchaudio/csrc)
...@@ -2,23 +2,20 @@ import os ...@@ -2,23 +2,20 @@ import os
import platform import platform
import subprocess import subprocess
from pathlib import Path from pathlib import Path
import distutils.sysconfig
from setuptools import Extension
from setuptools.command.build_ext import build_ext
import torch import torch
from torch.utils.cpp_extension import (
CppExtension,
BuildExtension as TorchBuildExtension
)
__all__ = [ __all__ = [
'get_ext_modules', 'get_ext_modules',
'BuildExtension', 'CMakeBuild',
] ]
_THIS_DIR = Path(__file__).parent.resolve() _THIS_DIR = Path(__file__).parent.resolve()
_ROOT_DIR = _THIS_DIR.parent.parent.resolve() _ROOT_DIR = _THIS_DIR.parent.parent.resolve()
_CSRC_DIR = _ROOT_DIR / 'torchaudio' / 'csrc' _TORCHAUDIO_DIR = _ROOT_DIR / 'torchaudio'
_TP_BASE_DIR = _ROOT_DIR / 'third_party'
_TP_INSTALL_DIR = _TP_BASE_DIR / 'install'
def _get_build(var): def _get_build(var):
...@@ -38,132 +35,71 @@ _BUILD_SOX = _get_build("BUILD_SOX") ...@@ -38,132 +35,71 @@ _BUILD_SOX = _get_build("BUILD_SOX")
_BUILD_TRANSDUCER = _get_build("BUILD_TRANSDUCER") _BUILD_TRANSDUCER = _get_build("BUILD_TRANSDUCER")
def _get_eca(debug): def get_ext_modules():
eca = [] if platform.system() == 'Windows':
if debug: return None
eca += ["-O0", "-g"] return [Extension(name='torchaudio._torchaudio', sources=[])]
else:
eca += ["-O3"]
if _BUILD_TRANSDUCER:
eca += ['-DBUILD_TRANSDUCER']
return eca
def _get_ela(debug):
ela = []
if debug:
if platform.system() == "Windows":
ela += ["/DEBUG:FULL"]
else:
ela += ["-O0", "-g"]
else:
ela += ["-O3"]
return ela
def _get_srcs():
srcs = [_CSRC_DIR / 'pybind.cpp']
srcs += list(_CSRC_DIR.glob('sox/**/*.cpp'))
if _BUILD_TRANSDUCER:
srcs += [_CSRC_DIR / 'transducer.cpp']
return [str(path) for path in srcs]
def _get_include_dirs():
dirs = [
str(_ROOT_DIR),
]
if _BUILD_SOX or _BUILD_TRANSDUCER:
dirs.append(str(_TP_INSTALL_DIR / 'include'))
return dirs
def _get_extra_objects():
libs = []
if _BUILD_SOX:
# NOTE: The order of the library listed bellow matters.
#
# (the most important thing is that dependencies come after a library
# e.g., sox comes first, flac/vorbis comes before ogg, and
# vorbisenc/vorbisfile comes before vorbis
libs += [
'libsox.a',
'libmad.a',
'libFLAC.a',
'libmp3lame.a',
'libopusfile.a',
'libopus.a',
'libvorbisenc.a',
'libvorbisfile.a',
'libvorbis.a',
'libogg.a',
'libopencore-amrnb.a',
'libopencore-amrwb.a',
]
if _BUILD_TRANSDUCER:
libs += ['libwarprnnt.a']
return [str(_TP_INSTALL_DIR / 'lib' / lib) for lib in libs]
def _get_libraries():
return [] if _BUILD_SOX else ['sox']
def _get_cxx11_abi():
try:
value = int(torch._C._GLIBCXX_USE_CXX11_ABI)
except ImportError:
value = 0
return f'-D_GLIBCXX_USE_CXX11_ABI={value}'
def _build_third_party(base_build_dir):
build_dir = os.path.join(base_build_dir, 'third_party')
os.makedirs(build_dir, exist_ok=True)
subprocess.run(
args=[
'cmake',
f"-DCMAKE_CXX_FLAGS='{_get_cxx11_abi()}'",
'-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON',
f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',
f'-DBUILD_SOX={"ON" if _BUILD_SOX else "OFF"}',
f'-DBUILD_TRANSDUCER={"ON" if _BUILD_TRANSDUCER else "OFF"}',
f'{_TP_BASE_DIR}'],
cwd=build_dir,
check=True,
)
command = ['cmake', '--build', '.']
if _BUILD_TRANSDUCER:
command += ['--target', 'install']
subprocess.run(
args=command,
cwd=build_dir,
check=True,
)
_EXT_NAME = 'torchaudio._torchaudio'
# Based off of
# https://github.com/pybind/cmake_example/blob/580c5fd29d4651db99d8874714b07c0c49a53f8a/setup.py
class CMakeBuild(build_ext):
def run(self):
try:
subprocess.check_output(['cmake', '--version'])
except OSError:
raise RuntimeError("CMake is not available.")
super().run()
def get_ext_modules(debug=False):
if platform.system() == 'Windows':
return None
return [
CppExtension(
_EXT_NAME,
_get_srcs(),
libraries=_get_libraries(),
include_dirs=_get_include_dirs(),
extra_compile_args=_get_eca(debug),
extra_objects=_get_extra_objects(),
extra_link_args=_get_ela(debug),
),
]
class BuildExtension(TorchBuildExtension):
def build_extension(self, ext): def build_extension(self, ext):
if ext.name == _EXT_NAME and _BUILD_SOX: extdir = os.path.abspath(
_build_third_party(self.build_temp) os.path.dirname(self.get_ext_fullpath(ext.name)))
super().build_extension(ext)
# required for auto-detection of auxiliary "native" libs
if not extdir.endswith(os.path.sep):
extdir += os.path.sep
cfg = "Debug" if self.debug else "Release"
cmake_args = [
f"-DCMAKE_BUILD_TYPE={cfg}",
f"-DCMAKE_PREFIX_PATH={torch.utils.cmake_prefix_path}",
f"-DCMAKE_INSTALL_PREFIX={extdir}",
'-DCMAKE_VERBOSE_MAKEFILE=ON',
f"-DPython_INCLUDE_DIR={distutils.sysconfig.get_python_inc()}",
f"-DBUILD_SOX:BOOL={'ON' if _BUILD_SOX else 'OFF'}",
f"-DBUILD_TRANSDUCER:BOOL={'ON' if _BUILD_TRANSDUCER else 'OFF'}",
"-DBUILD_TORCHAUDIO_PYTHON_EXTENSION:BOOL=ON",
"-DBUILD_LIBTORCHAUDIO:BOOL=OFF",
]
build_args = [
'--target', 'install'
]
# Default to Ninja
if 'CMAKE_GENERATOR' not in os.environ:
cmake_args += ["-GNinja"]
# Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
# across all generators.
if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ:
# self.parallel is a Python 3 only way to set parallel jobs by hand
# using -j in the build_ext call, not supported by pip or PyPA-build.
if hasattr(self, "parallel") and self.parallel:
# CMake 3.12+ only.
build_args += ["-j{}".format(self.parallel)]
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
subprocess.check_call(
["cmake", str(_ROOT_DIR)] + cmake_args, cwd=self.build_temp)
subprocess.check_call(
["cmake", "--build", "."] + build_args, cwd=self.build_temp)
def get_ext_filename(self, fullname):
ext_filename = super().get_ext_filename(fullname)
ext_filename_parts = ext_filename.split('.')
without_abi = ext_filename_parts[:-2] + ext_filename_parts[-1:]
ext_filename = '.'.join(without_abi)
return ext_filename
...@@ -8,7 +8,7 @@ export BUILD_TYPE="wheel" ...@@ -8,7 +8,7 @@ export BUILD_TYPE="wheel"
export NO_CUDA_PACKAGE=1 export NO_CUDA_PACKAGE=1
setup_env 0.8.0 setup_env 0.8.0
setup_wheel_python setup_wheel_python
pip_install numpy future pip_install numpy future cmake ninja
setup_pip_pytorch_version setup_pip_pytorch_version
python setup.py clean python setup.py clean
if [[ "$OSTYPE" == "msys" ]]; then if [[ "$OSTYPE" == "msys" ]]; then
......
...@@ -14,11 +14,12 @@ requirements: ...@@ -14,11 +14,12 @@ requirements:
- python - python
- setuptools - setuptools
- cpuonly - cpuonly
- cmake
- ninja
{{ environ.get('CONDA_PYTORCH_BUILD_CONSTRAINT') }} {{ environ.get('CONDA_PYTORCH_BUILD_CONSTRAINT') }}
run: run:
- python - python
- typing # [py2k]
{{ environ.get('CONDA_PYTORCH_CONSTRAINT') }} {{ environ.get('CONDA_PYTORCH_CONSTRAINT') }}
build: build:
......
...@@ -83,7 +83,7 @@ setup( ...@@ -83,7 +83,7 @@ setup(
packages=find_packages(exclude=["build*", "test*", "torchaudio.csrc*", "third_party*", "build_tools*"]), packages=find_packages(exclude=["build*", "test*", "torchaudio.csrc*", "third_party*", "build_tools*"]),
ext_modules=setup_helpers.get_ext_modules(), ext_modules=setup_helpers.get_ext_modules(),
cmdclass={ cmdclass={
'build_ext': setup_helpers.BuildExtension.with_options(no_python_abi_suffix=True), 'build_ext': setup_helpers.CMakeBuild,
'clean': clean, 'clean': clean,
}, },
install_requires=[pytorch_package_dep], install_requires=[pytorch_package_dep],
......
cmake_minimum_required(VERSION 3.5) set(TORCHAUDIO_THIRD_PARTIES "")
project(torchaudio_third_parties) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
option(BUILD_SOX "Build libsox statically")
option(BUILD_TRANSDUCER "Build transducer statically")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
################################################################################
# sox
################################################################################
add_library(libsox INTERFACE)
if (BUILD_SOX) if (BUILD_SOX)
add_subdirectory(sox) add_subdirectory(sox)
target_include_directories(libsox INTERFACE ${SOX_INCLUDE_DIR})
target_link_libraries(libsox INTERFACE ${SOX_LIBRARIES})
else()
# If not building and linking libsox statically, then we expect that
# sox library and header are found in search path
target_link_libraries(libsox INTERFACE -lsox)
endif() endif()
list(APPEND TORCHAUDIO_THIRD_PARTIES libsox)
if(BUILD_TRANSDUCER) ################################################################################
# transducer
################################################################################
if (BUILD_TRANSDUCER)
add_subdirectory(transducer) add_subdirectory(transducer)
list(APPEND TORCHAUDIO_THIRD_PARTIES warprnnt)
endif() endif()
set_property(GLOBAL PROPERTY TORCHAUDIO_THIRD_PARTIES "${TORCHAUDIO_THIRD_PARTIES}")
...@@ -11,7 +11,7 @@ set(COMMON_ARGS --quiet --disable-shared --enable-static --prefix=${INSTALL_DIR} ...@@ -11,7 +11,7 @@ set(COMMON_ARGS --quiet --disable-shared --enable-static --prefix=${INSTALL_DIR}
set(envs set(envs
"PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig" "PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig"
"LDFLAGS=-L${INSTALL_DIR}/lib $ENV{LDFLAGS}" "LDFLAGS=-L${INSTALL_DIR}/lib $ENV{LDFLAGS}"
"CPPFLAGS=-I${INSTALL_DIR}/include $ENV{CPPFLAGS}" "CFLAGS=-I${INSTALL_DIR}/include -fvisibility=hidden $ENV{CFLAGS}"
) )
ExternalProject_Add(mad ExternalProject_Add(mad
...@@ -207,3 +207,7 @@ ExternalProject_Add(sox ...@@ -207,3 +207,7 @@ ExternalProject_Add(sox
LOG_MERGED_STDOUTERR ON LOG_MERGED_STDOUTERR ON
LOG_OUTPUT_ON_FAILURE ON LOG_OUTPUT_ON_FAILURE ON
) )
add_dependencies(libsox sox)
set(SOX_INCLUDE_DIR ${INSTALL_DIR}/include PARENT_SCOPE)
set(SOX_LIBRARIES ${SOX_LIBRARIES} PARENT_SCOPE)
ADD_DEFINITIONS(-DRNNT_DISABLE_OMP) add_library(warprnnt STATIC submodule/src/rnnt_entrypoint.cpp)
target_compile_definitions(warprnnt PRIVATE RNNT_DISABLE_OMP)
IF(APPLE)
ADD_DEFINITIONS(-DAPPLE)
EXEC_PROGRAM(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
STRING(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
MESSAGE(STATUS "DARWIN_VERSION=${DARWIN_VERSION}")
# for el capitain have to use rpath
IF(DARWIN_VERSION LESS 15)
SET(CMAKE_SKIP_RPATH TRUE)
ENDIF()
ELSE()
# always skip for linux
SET(CMAKE_SKIP_RPATH TRUE)
ENDIF()
ADD_LIBRARY(warprnnt STATIC submodule/src/rnnt_entrypoint.cpp)
target_include_directories(warprnnt PUBLIC submodule/include) target_include_directories(warprnnt PUBLIC submodule/include)
set_target_properties(warprnnt PROPERTIES PUBLIC_HEADER submodule/include/rnnt.h)
INSTALL(
TARGETS warprnnt
ARCHIVE DESTINATION "lib"
PUBLIC_HEADER DESTINATION "include")
get_property(TORCHAUDIO_THIRD_PARTIES GLOBAL PROPERTY TORCHAUDIO_THIRD_PARTIES)
################################################################################
# Stuff common to libtorchaudio and _torchaudio.so
################################################################################
set(
LIBTORCHAUDIO_SOURCES
sox/io.cpp
sox/utils.cpp
sox/effects.cpp
sox/effects_chain.cpp
)
if(BUILD_TRANSDUCER)
list(APPEND LIBTORCHAUDIO_SOURCES transducer.cpp)
endif()
################################################################################
# libtorchaudio.so
################################################################################
if(BUILD_LIBTORCHAUDIO)
add_library(
libtorchaudio
SHARED
${LIBTORCHAUDIO_SOURCES}
)
set_target_properties(libtorchaudio PROPERTIES PREFIX "")
target_include_directories(
libtorchaudio
PRIVATE
${CMAKE_CURRENT_PROJECT_DIR}
)
target_link_libraries(
libtorchaudio
${TORCHAUDIO_THIRD_PARTIES}
${PROJECT_SOURCE_DIR}
)
install(
TARGETS
libtorchaudio
)
set(TORCHAUDIO_LIBRARY -Wl,--no-as-needed libtorchaudio -Wl,--as-needed CACHE INTERNAL "")
endif()
################################################################################
# _torchaudio.so
################################################################################
if (BUILD_TORCHAUDIO_PYTHON_EXTENSION)
add_library(
_torchaudio
SHARED
pybind.cpp
sox/legacy.cpp
${LIBTORCHAUDIO_SOURCES}
)
set_target_properties(_torchaudio PROPERTIES PREFIX "")
if (APPLE)
# https://github.com/facebookarchive/caffe2/issues/854#issuecomment-364538485
# https://github.com/pytorch/pytorch/commit/73f6715f4725a0723d8171d3131e09ac7abf0666
set_target_properties(_torchaudio PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
endif()
target_compile_definitions(
_torchaudio PRIVATE TORCH_API_INCLUDE_EXTENSION_H
)
target_include_directories(
_torchaudio
PRIVATE
${PROJECT_SOURCE_DIR}
${Python_INCLUDE_DIR}
)
# See https://github.com/pytorch/pytorch/issues/38122
find_library(TORCH_PYTHON_LIBRARY torch_python PATHS "${TORCH_INSTALL_PREFIX}/lib")
target_link_libraries(
_torchaudio
${TORCH_LIBRARIES}
${TORCH_PYTHON_LIBRARY}
${TORCHAUDIO_THIRD_PARTIES}
)
install(TARGETS _torchaudio LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX})
endif()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment