(module_name, sources, headers=None, source_dir=None, **build_kwargs)
| 57 | _cached_plugins = dict() |
| 58 | |
| 59 | def get_plugin(module_name, sources, headers=None, source_dir=None, **build_kwargs): |
| 60 | assert verbosity in ['none', 'brief', 'full'] |
| 61 | if headers is None: |
| 62 | headers = [] |
| 63 | if source_dir is not None: |
| 64 | sources = [os.path.join(source_dir, fname) for fname in sources] |
| 65 | headers = [os.path.join(source_dir, fname) for fname in headers] |
| 66 | |
| 67 | # Already cached? |
| 68 | if module_name in _cached_plugins: |
| 69 | return _cached_plugins[module_name] |
| 70 | |
| 71 | # Print status. |
| 72 | if verbosity == 'full': |
| 73 | print(f'Setting up PyTorch plugin "{module_name}"...') |
| 74 | elif verbosity == 'brief': |
| 75 | print(f'Setting up PyTorch plugin "{module_name}"... ', end='', flush=True) |
| 76 | verbose_build = (verbosity == 'full') |
| 77 | |
| 78 | # Compile and load. |
| 79 | try: # pylint: disable=too-many-nested-blocks |
| 80 | # Make sure we can find the necessary compiler binaries. |
| 81 | if os.name == 'nt' and os.system("where cl.exe >nul 2>nul") != 0: |
| 82 | compiler_bindir = _find_compiler_bindir() |
| 83 | if compiler_bindir is None: |
| 84 | raise RuntimeError(f'Could not find MSVC/GCC/CLANG installation on this computer. Check _find_compiler_bindir() in "{__file__}".') |
| 85 | os.environ['PATH'] += ';' + compiler_bindir |
| 86 | |
| 87 | # Some containers set TORCH_CUDA_ARCH_LIST to a list that can either |
| 88 | # break the build or unnecessarily restrict what's available to nvcc. |
| 89 | # Unset it to let nvcc decide based on what's available on the |
| 90 | # machine. |
| 91 | os.environ['TORCH_CUDA_ARCH_LIST'] = '' |
| 92 | |
| 93 | # Incremental build md5sum trickery. Copies all the input source files |
| 94 | # into a cached build directory under a combined md5 digest of the input |
| 95 | # source files. Copying is done only if the combined digest has changed. |
| 96 | # This keeps input file timestamps and filenames the same as in previous |
| 97 | # extension builds, allowing for fast incremental rebuilds. |
| 98 | # |
| 99 | # This optimization is done only in case all the source files reside in |
| 100 | # a single directory (just for simplicity) and if the TORCH_EXTENSIONS_DIR |
| 101 | # environment variable is set (we take this as a signal that the user |
| 102 | # actually cares about this.) |
| 103 | # |
| 104 | # EDIT: We now do it regardless of TORCH_EXTENSIOS_DIR, in order to work |
| 105 | # around the *.cu dependency bug in ninja config. |
| 106 | # |
| 107 | all_source_files = sorted(sources + headers) |
| 108 | all_source_dirs = set(os.path.dirname(fname) for fname in all_source_files) |
| 109 | if len(all_source_dirs) == 1: # and ('TORCH_EXTENSIONS_DIR' in os.environ): |
| 110 | |
| 111 | # Compute combined hash digest for all source files. |
| 112 | hash_md5 = hashlib.md5() |
| 113 | for src in all_source_files: |
| 114 | with open(src, 'rb') as f: |
| 115 | hash_md5.update(f.read()) |
| 116 |
nothing calls this directly
no test coverage detected