fbgemm_gpu/setup.py (144 lines of code) (raw):

# 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. import argparse import os import random import re import subprocess import sys from datetime import date from typing import Optional, List import torch from skbuild import setup def get_version(): # get version string from version.py # TODO: ideally the version.py should be generated when setup is run version_file = os.path.join(os.path.dirname(__file__), "version.py") version_regex = r"__version__ = ['\"]([^'\"]*)['\"]" with open(version_file, "r") as f: version = re.search(version_regex, f.read(), re.M).group(1) return version def get_nightly_version(): today = date.today() return f"{today.year}.{today.month}.{today.day}" def parse_args(argv: List[str]) -> argparse.Namespace: parser = argparse.ArgumentParser(description="fbgemm_gpu setup") parser.add_argument( "--cpu_only", dest="cpu_only", action="store_true", help="build for cpu-only (no GPU support)", ) parser.add_argument( "--package_name", type=str, default="fbgemm_gpu", help="the name of this output wheel", ) return parser.parse_known_args(argv) def nvcc_ok(cuda_home: str, major: int, minor: int) -> bool: if not cuda_home: return False nvcc_path = f"{cuda_home}/bin/nvcc" if not os.path.exists(nvcc_path): return False try: # Extract version from version string - inspired my NVIDIA/apex output = subprocess.check_output([nvcc_path, "-V"], text=True) fragments = output.split() version = fragments[fragments.index("release") + 1] version_fragments = version.split(".") major_nvcc = int(version_fragments[0]) minor_nvcc = int(version_fragments[1].split(",")[0]) result = major == major_nvcc and minor == minor_nvcc except BaseException: result = False return result def find_cuda(major: int, minor: int) -> Optional[str]: cuda_home = os.environ.get("CUDA_BIN_PATH") if nvcc_ok(cuda_home, major, minor): return cuda_home cuda_nvcc = os.environ.get("CUDACXX") if cuda_nvcc and os.path.exists(cuda_nvcc): cuda_home = os.path.dirname(os.path.dirname(cuda_nvcc)) if nvcc_ok(cuda_home, major, minor): return cuda_home # Search standard installation location with version first cuda_home = f"/usr/local/cuda-{major}.{minor}" if nvcc_ok(cuda_home, major, minor): return cuda_home cuda_home = "/usr/local/cuda" if nvcc_ok(cuda_home, major, minor): return cuda_home try: # Try to find nvcc with which with open(os.devnull, "w") as devnull: nvcc = ( subprocess.check_output(["which", "nvcc"], stderr=devnull) .decode() .rstrip("\r\n") ) cuda_home = os.path.dirname(os.path.dirname(nvcc)) except Exception: cuda_home = None if nvcc_ok(cuda_home, major, minor): return cuda_home return None def main(argv: List[str]) -> None: # Handle command line args before passing to main setup() method. args, unknown = parse_args(argv) print("args: ", args) if len(unknown) != 0 and (len(unknown) != 1 or unknown[0] != "clean"): print("unknown: ", unknown) if not args.cpu_only: cub_include_path = os.getenv("CUB_DIR", None) if cub_include_path is None: print( "CUDA CUB directory environment variable not set. Using default CUB location." ) cuda_version = torch.version.cuda.split(".") cuda_home = find_cuda(int(cuda_version[0]), int(cuda_version[1])) if cuda_home: print(f"Using CUDA = {cuda_home}") os.environ["CUDA_BIN_PATH"] = cuda_home os.environ["CUDACXX"] = f"{cuda_home}/bin/nvcc" # Get the long description from the relevant file cur_dir = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(cur_dir, "README.md"), encoding="utf-8") as f: long_description = f.read() torch_root = os.path.dirname(torch.__file__) os.environ["CMAKE_BUILD_PARALLEL_LEVEL"] = str(os.cpu_count() // 2) cmake_args = [f"-DCMAKE_PREFIX_PATH={torch_root}"] if args.cpu_only: cmake_args.append("-DFBGEMM_CPU_ONLY=ON") name = args.package_name print("name: ", name) is_nightly = "nightly" in name is_test = "test" in name version = get_nightly_version() if is_nightly else get_version() if is_test: version = (f"0.0.{random.randint(0, 1000)}",) print(f"-- {name} building version: {version}") # Repair command line args for setup. sys.argv = [sys.argv[0]] + unknown setup( # Metadata name=name, version=version, author="FBGEMM Team", author_email="packages@pytorch.org", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/pytorch/fbgemm", license="BSD-3", keywords=[ "PyTorch", "Recommendation Models", "High Performance Computing", "GPU", "CUDA", ], packages=["fbgemm_gpu"], cmake_args=cmake_args, # PyPI package information. classifiers=[ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Topic :: Scientific/Engineering :: Artificial Intelligence", ], ) if __name__ == "__main__": print(sys.argv) main(sys.argv[1:])