diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index af63c8931233..076e8e114b73 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -43,30 +43,31 @@ jobs: tag_or_branch="${tag_or_branch#refs/heads/}" # replace directory separators with _ in branch name tag_or_branch="${tag_or_branch//\//_}" + if [[ ${tag_or_branch} == v* ]]; then + # strip trailing v from tag name + tag_or_branch="${tag_or_branch#v}" + # important: version must be fixed in setup.py + sed -i -e "s:^TRITON_VERSION = .*:TRITON_VERSION = '${tag_or_branch}':" setup.py || exit 1 + fi echo "RELEASE_NAME=triton-$tag_or_branch" >> "$GITHUB_ENV" - echo "RELEASE_FILE=triton-$tag_or_branch.tar.gz" >> "$GITHUB_ENV" - name: Create source distribution run: | - # Create new folder with specified name so extracting the archive yields that - rm -rf "/tmp/$RELEASE_NAME" - cp -r "$PWD" "/tmp/$RELEASE_NAME" - mv "/tmp/$RELEASE_NAME" . - # Cleanup - find "$RELEASE_NAME" -name '.git*' -exec rm -rv {} \; || true - # Create archive - tar -czf "$RELEASE_FILE" "$RELEASE_NAME" - echo "Created source archive $RELEASE_FILE with content: $(ls -a "$RELEASE_NAME")" + pip install build || exit 1 + python -m build -s || exit 1 + cd dist || exit 1 + release_file=( *.tar.gz ) + echo "RELEASE_FILE=${release_file}" >> "$GITHUB_ENV" - name: Upload source distribution for release if: ${{ github.event_name == 'release' }} uses: softprops/action-gh-release@v2 with: - files: ${{env.RELEASE_FILE}} + files: dist/${{env.RELEASE_FILE}} - name: Upload source distribution to GHA artifacts for release tags if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && contains(github.ref, 'rc') }} uses: actions/upload-artifact@v4.4.0 with: name: ${{ env.RELEASE_FILE }} - path: ${{ env.RELEASE_FILE }} + path: dist/${{ env.RELEASE_FILE }} - name: Set output id: release_name run: echo "name=release_name::${{ env.RELEASE_NAME }}.tar.gz" >> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index f516d6a3a85f..361effbfe39c 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -82,7 +82,12 @@ jobs: export CIBW_BUILD="cp3{9,10,11,12,13,13t}-manylinux_${{ matrix.config.arch }}" export CIBW_SKIP="cp{35,36,37,38}-*" export CIBW_FREE_THREADED_SUPPORT=1 - python3 -m cibuildwheel python --output-dir wheelhouse + python3 -m cibuildwheel . --output-dir wheelhouse + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-manylinux_2_28_${{ matrix.config.arch }}-wheels-upload + path: ./wheelhouse/*.whl - name: Install Azure CLI if: ${{ steps.check-version.outputs.new_commit == 'true' }} diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 000000000000..aadefd90e4e5 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,18 @@ +graft bin +graft cmake +graft docs +graft include +graft lib +graft python/src +graft python/test +graft python/triton/backends/amd +graft python/triton/backends/nvidia +graft python/triton/tools/extra/cuda +graft test +graft third_party +graft unittest +include CMakeLists.txt +include Makefile +include python/build_helpers.py +include python/requirements.txt +include python/test-requirements.txt diff --git a/Makefile b/Makefile index f984decf3194..ce3b44c9e649 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ dev-install-torch: .PHONY: dev-install-triton dev-install-triton: - $(PYTHON) -m pip install -e python --no-build-isolation -v + $(PYTHON) -m pip install -e . --no-build-isolation -v .PHONY: dev-install .NOPARALLEL: dev-install diff --git a/README.md b/README.md index 979fe434a758..a4fa113078c9 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ git clone https://github.com/triton-lang/triton.git cd triton pip install -r python/requirements.txt # build-time dependencies -pip install -e python +pip install -e . ``` Or with a virtualenv: @@ -84,7 +84,7 @@ python -m venv .venv --prompt triton source .venv/bin/activate pip install -r python/requirements.txt # build-time dependencies -pip install -e python +pip install -e . ``` # Building with a custom LLVM @@ -124,7 +124,7 @@ arbitrary LLVM version. $ LLVM_INCLUDE_DIRS=$LLVM_BUILD_DIR/include \ LLVM_LIBRARY_DIR=$LLVM_BUILD_DIR/lib \ LLVM_SYSPATH=$LLVM_BUILD_DIR \ - pip install -e python + pip install -e . # Tips for building @@ -139,7 +139,7 @@ arbitrary LLVM version. can be changed anytime. - If you're running out of memory when building Triton, specify the `MAX_JOBS` - environment variable (to the `pip install -e python` command) to limit the + environment variable (to the `pip install -e .` command) to limit the number of jobs. - Pass `--no-build-isolation` to `pip install` to make nop builds faster. @@ -150,7 +150,7 @@ arbitrary LLVM version. (probably because, in our build, users don't invoke cmake directly, but instead use setup.py). Teach vscode how to compile Triton as follows. - - Do a local build. Run command `pip install -e python` + - Do a local build. Run command `pip install -e .` - Get the full path to the `compile_commands.json` file produced by the build: `find python/build -name 'compile_commands.json' | xargs readlink -f`. You might get a full path similar to `/Users/{username}/triton/python/build/cmake.macosx-11.1-arm64-cpython-3.12/compile_commands.json` diff --git a/pyproject.toml b/pyproject.toml index 525f303efb6f..09dda337f1ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,6 @@ [build-system] -requires = ["setuptools>=40.8.0", "wheel", "cmake>=3.18", "ninja>=1.11.1"] +requires = ["setuptools>=40.8.0", "cmake>=3.18", "ninja>=1.11.1", "pybind11>=2.13.1"] +build-backend = "setuptools.build_meta" [tool.yapf] based_on_style = "pep8" @@ -9,6 +10,12 @@ each_dict_entry_on_separate_line=false split_before_named_assigns = false split_complex_comprehension = true +# We're incrementally switching from autopep8 to ruff. +[tool.autopep8] +aggressive = 1 +ignore = "E501,E701,E731,W690,W503" +max_line_length = 88 + [tool.ruff] line-length = 120 diff --git a/python/build_helpers.py b/python/build_helpers.py index da2efd30cac3..98f7facc5772 100644 --- a/python/build_helpers.py +++ b/python/build_helpers.py @@ -12,6 +12,6 @@ def get_cmake_dir(): plat_name = sysconfig.get_platform() python_version = sysconfig.get_python_version() dir_name = f"cmake.{plat_name}-{sys.implementation.name}-{python_version}" - cmake_dir = Path(get_base_dir()) / "python" / "build" / dir_name + cmake_dir = Path(get_base_dir()) / "build" / dir_name cmake_dir.mkdir(parents=True, exist_ok=True) return cmake_dir diff --git a/python/pyproject.toml b/python/pyproject.toml deleted file mode 100644 index d96af50a543e..000000000000 --- a/python/pyproject.toml +++ /dev/null @@ -1,15 +0,0 @@ - -[build-system] -requires = ["setuptools>=40.8.0", "wheel", "cmake>=3.18", "ninja>=1.11.1", "pybind11>=2.13.1"] - -# We're incrementally switching from autopep8 to ruff. -[tool.autopep8] -aggressive = 1 -ignore = "E501,E701,E731,W690,W503" -max_line_length = 88 - -[tool.ruff] -line-length = 120 - -[tool.ruff.lint] -ignore = ["E501", "E701", "E731", "E741"] diff --git a/python/triton/_C/include b/python/triton/_C/include deleted file mode 120000 index b85a409837d1..000000000000 --- a/python/triton/_C/include +++ /dev/null @@ -1 +0,0 @@ -../../../include/ \ No newline at end of file diff --git a/python/triton/backends/__init__.py b/python/triton/backends/__init__.py index f2c46ea9e0fe..5725a6d03214 100644 --- a/python/triton/backends/__init__.py +++ b/python/triton/backends/__init__.py @@ -1,10 +1,15 @@ import importlib import inspect -import os +import sys from dataclasses import dataclass from .driver import DriverBase from .compiler import BaseBackend +if sys.version_info >= (3, 10): + from importlib.metadata import entry_points +else: + from importlib_metadata import entry_points + def _find_concrete_subclasses(module, base_class): ret = [] @@ -27,16 +32,11 @@ class Backend: def _discover_backends(): backends = dict() - root = os.path.dirname(__file__) - for name in os.listdir(root): - if not os.path.isdir(os.path.join(root, name)): - continue - if name.startswith('__'): - continue - compiler = importlib.import_module(f"triton.backends.{name}.compiler") - driver = importlib.import_module(f"triton.backends.{name}.driver") - backends[name] = Backend(_find_concrete_subclasses(compiler, BaseBackend), - _find_concrete_subclasses(driver, DriverBase)) + for ep in entry_points().select(group="triton.backends"): + compiler = importlib.import_module(f"{ep.value}.compiler") + driver = importlib.import_module(f"{ep.value}.driver") + backends[ep.name] = Backend(_find_concrete_subclasses(compiler, BaseBackend), + _find_concrete_subclasses(driver, DriverBase)) return backends diff --git a/python/setup.py b/setup.py similarity index 74% rename from python/setup.py rename to setup.py index 333dd58eabea..965b4c2d839d 100644 --- a/python/setup.py +++ b/setup.py @@ -14,29 +14,32 @@ from io import BytesIO from distutils.command.clean import clean from pathlib import Path -from typing import List, Optional +from typing import Optional -from setuptools import Extension, setup +from setuptools import Extension, find_packages, setup from setuptools.command.build_ext import build_ext from setuptools.command.build_py import build_py -from dataclasses import dataclass - -from distutils.command.install import install from setuptools.command.develop import develop -from setuptools.command.egg_info import egg_info -from wheel.bdist_wheel import bdist_wheel +from dataclasses import dataclass import pybind11 -from build_helpers import get_base_dir, get_cmake_dir +try: + from setuptools.command.editable_wheel import editable_wheel +except ImportError: + # create a dummy class, since there is no command to override + class editable_wheel: + pass + + +sys.path.insert(0, os.path.dirname(__file__)) + +from python.build_helpers import get_base_dir, get_cmake_dir @dataclass class Backend: name: str - package_data: List[str] - language_package_data: List[str] - tools_package_data: List[str] src_dir: str backend_dir: str language_dir: Optional[str] @@ -51,7 +54,7 @@ class BackendInstaller: def prepare(backend_name: str, backend_src_dir: str = None, is_external: bool = False): # Initialize submodule if there is one for in-tree backends. if not is_external: - root_dir = os.path.join(os.pardir, "third_party") + root_dir = "third_party" assert backend_name in os.listdir( root_dir), f"{backend_name} is requested for install but not present in {root_dir}" @@ -65,34 +68,24 @@ def prepare(backend_name: str, backend_src_dir: str = None, is_external: bool = backend_src_dir = os.path.join(root_dir, backend_name) - backend_path = os.path.abspath(os.path.join(backend_src_dir, "backend")) + backend_path = os.path.join(backend_src_dir, "backend") assert os.path.exists(backend_path), f"{backend_path} does not exist!" - language_dir = os.path.abspath(os.path.join(backend_src_dir, "language")) + language_dir = os.path.join(backend_src_dir, "language") if not os.path.exists(language_dir): language_dir = None - tools_dir = os.path.abspath(os.path.join(backend_src_dir, "tools")) + tools_dir = os.path.join(backend_src_dir, "tools") if not os.path.exists(tools_dir): tools_dir = None for file in ["compiler.py", "driver.py"]: assert os.path.exists(os.path.join(backend_path, file)), f"${file} does not exist in ${backend_path}" - install_dir = os.path.join(os.path.dirname(__file__), "triton", "backends", backend_name) - package_data = [f"{os.path.relpath(p, backend_path)}/*" for p, _, _, in os.walk(backend_path)] - - language_package_data = [] - if language_dir is not None: - language_package_data = [f"{os.path.relpath(p, language_dir)}/*" for p, _, _, in os.walk(language_dir)] + install_dir = os.path.join(os.path.dirname(__file__), "python", "triton", "backends", backend_name) - tools_package_data = [] - if tools_dir is not None: - tools_package_data = [f"{os.path.relpath(p, tools_dir)}/*" for p, _, _, in os.walk(tools_dir)] - - return Backend(name=backend_name, package_data=package_data, language_package_data=language_package_data, - tools_package_data=tools_package_data, src_dir=backend_src_dir, backend_dir=backend_path, - language_dir=language_dir, tools_dir=tools_dir, install_dir=install_dir, is_external=is_external) + return Backend(name=backend_name, src_dir=backend_src_dir, backend_dir=backend_path, language_dir=language_dir, + tools_dir=tools_dir, install_dir=install_dir, is_external=is_external) # Copy all in-tree backends under triton/third_party. @staticmethod @@ -270,7 +263,7 @@ def update_symlink(link_path, source_path): print(f"creating symlink: {link_path} -> {source_path}", file=sys.stderr) link_path.absolute().parent.mkdir(parents=True, exist_ok=True) # Ensure link's parent directory exists - link_path.symlink_to(source_path, target_is_directory=True) + link_path.symlink_to(source_path.absolute(), target_is_directory=True) def get_thirdparty_packages(packages: list): @@ -331,7 +324,7 @@ def download_and_copy(name, src_func, dst_path, variable, version, url_func): url = url_func(supported[system], arch, version) src_path = src_func(supported[system], arch, version) tmp_path = os.path.join(triton_cache_path, "nvidia", name) # path to cache the download - dst_path = os.path.join(base_dir, os.pardir, "third_party", "nvidia", "backend", dst_path) # final binary path + dst_path = os.path.join(base_dir, "third_party", "nvidia", "backend", dst_path) # final binary path src_path = os.path.join(tmp_path, src_path) download = not os.path.exists(src_path) if os.path.exists(dst_path) and system == "Linux" and shutil.which(dst_path) is not None: @@ -389,6 +382,8 @@ def finalize_options(self): build_ext.finalize_options(self) def run(self): + download_and_copy_dependencies() + try: out = subprocess.check_output(["cmake", "--version"]) except OSError: @@ -511,80 +506,105 @@ def build_extension(self, ext): subprocess.check_call(["cmake", "--build", ".", "--target", "mlir-doc"], cwd=cmake_dir) -nvidia_version_path = os.path.join(get_base_dir(), "cmake", "nvidia-toolchain-version.json") -with open(nvidia_version_path, "r") as nvidia_version_file: - # parse this json file to get the version of the nvidia toolchain - NVIDIA_TOOLCHAIN_VERSION = json.load(nvidia_version_file) - -exe_extension = sysconfig.get_config_var("EXE") -download_and_copy( - name="nvcc", - src_func=lambda system, arch, version: f"cuda_nvcc-{system}-{arch}-{version}-archive/bin/ptxas{exe_extension}", - dst_path="bin/ptxas", - variable="TRITON_PTXAS_PATH", - version=NVIDIA_TOOLCHAIN_VERSION["ptxas"], - url_func=lambda system, arch, version: - f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_nvcc/{system}-{arch}/cuda_nvcc-{system}-{arch}-{version}-archive.tar.xz", -) -download_and_copy( - name="cuobjdump", - src_func=lambda system, arch, version: - f"cuda_cuobjdump-{system}-{arch}-{version}-archive/bin/cuobjdump{exe_extension}", - dst_path="bin/cuobjdump", - variable="TRITON_CUOBJDUMP_PATH", - version=NVIDIA_TOOLCHAIN_VERSION["cuobjdump"], - url_func=lambda system, arch, version: - f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cuobjdump/{system}-{arch}/cuda_cuobjdump-{system}-{arch}-{version}-archive.tar.xz", -) -download_and_copy( - name="nvdisasm", - src_func=lambda system, arch, version: - f"cuda_nvdisasm-{system}-{arch}-{version}-archive/bin/nvdisasm{exe_extension}", - dst_path="bin/nvdisasm", - variable="TRITON_NVDISASM_PATH", - version=NVIDIA_TOOLCHAIN_VERSION["nvdisasm"], - url_func=lambda system, arch, version: - f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_nvdisasm/{system}-{arch}/cuda_nvdisasm-{system}-{arch}-{version}-archive.tar.xz", -) -download_and_copy( - name="nvcc", - src_func=lambda system, arch, version: f"cuda_nvcc-{system}-{arch}-{version}-archive/include", - dst_path="include", - variable="TRITON_CUDACRT_PATH", - version=NVIDIA_TOOLCHAIN_VERSION["cudacrt"], - url_func=lambda system, arch, version: - f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_nvcc/{system}-{arch}/cuda_nvcc-{system}-{arch}-{version}-archive.tar.xz", -) -download_and_copy( - name="cudart", - src_func=lambda system, arch, version: f"cuda_cudart-{system}-{arch}-{version}-archive/include", - dst_path="include", - variable="TRITON_CUDART_PATH", - version=NVIDIA_TOOLCHAIN_VERSION["cudart"], - url_func=lambda system, arch, version: - f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cudart/{system}-{arch}/cuda_cudart-{system}-{arch}-{version}-archive.tar.xz", -) -download_and_copy( - name="cupti", - src_func=lambda system, arch, version: f"cuda_cupti-{system}-{arch}-{version}-archive/include", - dst_path="include", - variable="TRITON_CUPTI_INCLUDE_PATH", - version=NVIDIA_TOOLCHAIN_VERSION["cupti"], - url_func=lambda system, arch, version: - f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cupti/{system}-{arch}/cuda_cupti-{system}-{arch}-{version}-archive.tar.xz", -) -download_and_copy( - name="cupti", - src_func=lambda system, arch, version: f"cuda_cupti-{system}-{arch}-{version}-archive/lib", - dst_path="lib/cupti", - variable="TRITON_CUPTI_LIB_PATH", - version=NVIDIA_TOOLCHAIN_VERSION["cupti"], - url_func=lambda system, arch, version: - f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cupti/{system}-{arch}/cuda_cupti-{system}-{arch}-{version}-archive.tar.xz", -) +def download_and_copy_dependencies(): + nvidia_version_path = os.path.join(get_base_dir(), "cmake", "nvidia-toolchain-version.json") + with open(nvidia_version_path, "r") as nvidia_version_file: + # parse this json file to get the version of the nvidia toolchain + NVIDIA_TOOLCHAIN_VERSION = json.load(nvidia_version_file) + + exe_extension = sysconfig.get_config_var("EXE") + download_and_copy( + name="nvcc", + src_func=lambda system, arch, version: f"cuda_nvcc-{system}-{arch}-{version}-archive/bin/ptxas{exe_extension}", + dst_path="bin/ptxas", + variable="TRITON_PTXAS_PATH", + version=NVIDIA_TOOLCHAIN_VERSION["ptxas"], + url_func=lambda system, arch, version: + f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_nvcc/{system}-{arch}/cuda_nvcc-{system}-{arch}-{version}-archive.tar.xz", + ) + download_and_copy( + name="cuobjdump", + src_func=lambda system, arch, version: + f"cuda_cuobjdump-{system}-{arch}-{version}-archive/bin/cuobjdump{exe_extension}", + dst_path="bin/cuobjdump", + variable="TRITON_CUOBJDUMP_PATH", + version=NVIDIA_TOOLCHAIN_VERSION["cuobjdump"], + url_func=lambda system, arch, version: + f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cuobjdump/{system}-{arch}/cuda_cuobjdump-{system}-{arch}-{version}-archive.tar.xz", + ) + download_and_copy( + name="nvdisasm", + src_func=lambda system, arch, version: + f"cuda_nvdisasm-{system}-{arch}-{version}-archive/bin/nvdisasm{exe_extension}", + dst_path="bin/nvdisasm", + variable="TRITON_NVDISASM_PATH", + version=NVIDIA_TOOLCHAIN_VERSION["nvdisasm"], + url_func=lambda system, arch, version: + f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_nvdisasm/{system}-{arch}/cuda_nvdisasm-{system}-{arch}-{version}-archive.tar.xz", + ) + download_and_copy( + name="nvcc", + src_func=lambda system, arch, version: f"cuda_nvcc-{system}-{arch}-{version}-archive/include", + dst_path="include", + variable="TRITON_CUDACRT_PATH", + version=NVIDIA_TOOLCHAIN_VERSION["cudacrt"], + url_func=lambda system, arch, version: + f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_nvcc/{system}-{arch}/cuda_nvcc-{system}-{arch}-{version}-archive.tar.xz", + ) + download_and_copy( + name="cudart", + src_func=lambda system, arch, version: f"cuda_cudart-{system}-{arch}-{version}-archive/include", + dst_path="include", + variable="TRITON_CUDART_PATH", + version=NVIDIA_TOOLCHAIN_VERSION["cudart"], + url_func=lambda system, arch, version: + f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cudart/{system}-{arch}/cuda_cudart-{system}-{arch}-{version}-archive.tar.xz", + ) + download_and_copy( + name="cupti", + src_func=lambda system, arch, version: f"cuda_cupti-{system}-{arch}-{version}-archive/include", + dst_path="include", + variable="TRITON_CUPTI_INCLUDE_PATH", + version=NVIDIA_TOOLCHAIN_VERSION["cupti"], + url_func=lambda system, arch, version: + f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cupti/{system}-{arch}/cuda_cupti-{system}-{arch}-{version}-archive.tar.xz", + ) + download_and_copy( + name="cupti", + src_func=lambda system, arch, version: f"cuda_cupti-{system}-{arch}-{version}-archive/lib", + dst_path="lib/cupti", + variable="TRITON_CUPTI_LIB_PATH", + version=NVIDIA_TOOLCHAIN_VERSION["cupti"], + url_func=lambda system, arch, version: + f"https://developer.download.nvidia.com/compute/cuda/redist/cuda_cupti/{system}-{arch}/cuda_cupti-{system}-{arch}-{version}-archive.tar.xz", + ) + + backends = [*BackendInstaller.copy(["nvidia", "amd"]), *BackendInstaller.copy_externals()] +def get_package_dirs(): + yield ("", "python") + + for backend in backends: + yield (f"triton.backends.{backend.name}", backend.backend_dir) + + if backend.language_dir: + # Install the contents of each backend's `language` directory into + # `triton.language.extra`. + for x in os.listdir(backend.language_dir): + yield (f"triton.language.extra.{x}", os.path.join(backend.language_dir, x)) + + if backend.tools_dir: + # Install the contents of each backend's `tools` directory into + # `triton.tools.extra`. + for x in os.listdir(backend.tools_dir): + yield (f"triton.tools.extra.{x}", os.path.join(backend.tools_dir, x)) + + if check_env_flag("TRITON_BUILD_PROTON", "ON"): # Default ON + yield ("triton.profiler", "third_party/proton/proton") + + def add_link_to_backends(): for backend in backends: update_symlink(backend.install_dir, backend.backend_dir) @@ -592,7 +612,8 @@ def add_link_to_backends(): if backend.language_dir: # Link the contents of each backend's `language` directory into # `triton.language.extra`. - extra_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "triton", "language", "extra")) + extra_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "python", "triton", "language", + "extra")) for x in os.listdir(backend.language_dir): src_dir = os.path.join(backend.language_dir, x) install_dir = os.path.join(extra_dir, x) @@ -601,7 +622,7 @@ def add_link_to_backends(): if backend.tools_dir: # Link the contents of each backend's `tools` directory into # `triton.tools.extra`. - extra_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "triton", "tools", "extra")) + extra_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "python", "triton", "tools", "extra")) for x in os.listdir(backend.tools_dir): src_dir = os.path.join(backend.tools_dir, x) install_dir = os.path.join(extra_dir, x) @@ -609,8 +630,8 @@ def add_link_to_backends(): def add_link_to_proton(): - proton_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, "third_party", "proton", "proton")) - proton_install_dir = os.path.join(os.path.dirname(__file__), "triton", "profiler") + proton_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "third_party", "proton", "proton")) + proton_install_dir = os.path.join(os.path.dirname(__file__), "python", "triton", "profiler") update_symlink(proton_install_dir, proton_dir) @@ -620,84 +641,18 @@ def add_links(): add_link_to_proton() -class plugin_install(install): - - def run(self): - add_links() - install.run(self) - - class plugin_develop(develop): def run(self): add_links() - develop.run(self) - - -class plugin_bdist_wheel(bdist_wheel): - - def run(self): - add_links() - bdist_wheel.run(self) + super().run() -class plugin_egginfo(egg_info): +class plugin_editable_wheel(editable_wheel): def run(self): add_links() - egg_info.run(self) - - -package_data = { - "triton/tools/extra": sum((b.tools_package_data for b in backends), []), - **{f"triton/backends/{b.name}": b.package_data - for b in backends}, "triton/language/extra": sum((b.language_package_data for b in backends), []) -} - - -def get_extra_packages(extra_name): - packages = [] - extra_file_extensions = {"language": (".py"), "tools": (".c", ".h", ".cpp")} - assert extra_name in extra_file_extensions, f"{extra_name} extra is not valid" - - for backend in backends: - backend_extra_dir = getattr(backend, f"{extra_name}_dir", None) - if backend_extra_dir is None: - continue - - # Walk the specified directory of each backend to enumerate - # any subpackages, which will be added to extra_package. - for dir, dirs, files in os.walk(backend_extra_dir, followlinks=True): - if not any(f for f in files if f.endswith(extra_file_extensions[extra_name])) or dir == backend_extra_dir: - # Ignore directories with no relevant files - # or the root directory - continue - subpackage = os.path.relpath(dir, backend_extra_dir) - package = os.path.join(f"triton/{extra_name}/extra", subpackage) - packages.append(package) - - return list(packages) - - -def get_packages(): - packages = [ - "triton", - "triton/_C", - "triton/compiler", - "triton/language", - "triton/language/extra", - "triton/runtime", - "triton/backends", - "triton/tools", - "triton/tools/extra", - ] - packages += [f'triton/backends/{backend.name}' for backend in backends] - packages += get_extra_packages("language") - packages += get_extra_packages("tools") - if check_env_flag("TRITON_BUILD_PROTON", "ON"): # Default ON - packages += ["triton/profiler"] - - return packages + super().run() def get_entry_points(): @@ -707,6 +662,7 @@ def get_entry_points(): "proton-viewer = triton.profiler.viewer:main", "proton = triton.profiler.proton:main", ] + entry_points["triton.backends"] = [f"{b.name} = triton.backends.{b.name}" for b in backends] return entry_points @@ -734,27 +690,34 @@ def get_git_version_suffix(): return get_git_commit_hash() +# keep it separate for easy substitution +TRITON_VERSION = "3.3.0" + get_git_version_suffix() + os.environ.get("TRITON_WHEEL_VERSION_SUFFIX", "") + +package_dirs = dict(get_package_dirs()) +extra_packages = [x for x in package_dirs if x != ""] + setup( name=os.environ.get("TRITON_WHEEL_NAME", "triton"), - version="3.3.0" + get_git_version_suffix() + os.environ.get("TRITON_WHEEL_VERSION_SUFFIX", ""), + version=TRITON_VERSION, author="Philippe Tillet", author_email="phil@openai.com", description="A language and compiler for custom Deep Learning operations", long_description="", - install_requires=["setuptools>=40.8.0"], - packages=get_packages(), + install_requires=[ + "setuptools>=40.8.0", + "importlib-metadata; python_version < '3.10'", + ], + packages=find_packages(where="python") + extra_packages, + package_dir=package_dirs, entry_points=get_entry_points(), - package_data=package_data, include_package_data=True, ext_modules=[CMakeExtension("triton", "triton/_C/")], cmdclass={ "build_ext": CMakeBuild, "build_py": CMakeBuildPy, "clean": CMakeClean, - "install": plugin_install, "develop": plugin_develop, - "bdist_wheel": plugin_bdist_wheel, - "egg_info": plugin_egginfo, + "editable_wheel": plugin_editable_wheel, }, zip_safe=False, # for PyPI diff --git a/python/MANIFEST.in b/third_party/amd/backend/__init__.py similarity index 100% rename from python/MANIFEST.in rename to third_party/amd/backend/__init__.py diff --git a/third_party/proton/proton/_C/include b/third_party/proton/proton/_C/include deleted file mode 120000 index fe4f4a1aa9bd..000000000000 --- a/third_party/proton/proton/_C/include +++ /dev/null @@ -1 +0,0 @@ -../../csrc/include/ \ No newline at end of file