Repository: pytorch
Issue: GPU compatibility check without initializing CUDA
Labels: module: cuda,triaged

## 🚀 Feature
<!-- A clear and concise description of the feature proposal -->
Modify the CUDA capability check to return whether there are any devices compatible with PyTorch.

## Motivation

<!-- Please outline the motivation for the proposal. Is your feature request related to a problem? e.g., I'm always frustrated when [...]. If this is related to another GitHub issue, please link here too -->

In the context of checking 3rd party PyTorch installations, for any machine with CUDA installed and an older GPU (unsupported by PyTorch), it is not possible to detect that this is the case without actually try/catching a tensor-to-gpu transfer. This can be expensive because of CUDA initialization, which seems to use around 2GB of memory. In some cases, this memory cost can’t be afforded (in our case, making this check in dozens of parallel processes would leave us with little to no available memory).

## Pitch

<!-- A clear and concise description of what you want to happen. -->
PyTorch could offer a method to find out if there are any CUDA devices compatible with the PyTorch binary, _without_ initializing CUDA.

We think a simple proposal to achieve this would be to modify `torch.cuda.__init__._check_capability()` like this:

```python
def _check_capability():
    incorrect_binary_warn = """
    Found GPU%d %s which requires CUDA_VERSION >= %d to
     work properly, but your PyTorch was compiled
     with CUDA_VERSION %d. Please install the correct PyTorch binary
     using instructions from https://pytorch.org
    """

    old_gpu_warn = """
    Found GPU%d %s which is of cuda capability %d.%d.
    PyTorch no longer supports this GPU because it is too old.
    The minimum cuda capability supported by this library is %d.%d.
    """
    compatible_device_count = 0
    if torch.version.cuda is not None:  # on ROCm we don't want this check
        CUDA_VERSION = torch._C._cuda_getCompiledVersion()
        for d in range(device_count()):
            capability = get_device_capability(d)
            major = capability[0]
            minor = capability[1]
            name = get_device_name(d)
            current_arch = major * 10 + minor
            min_arch = min((int(arch.split("_")[1]) for arch in torch.cuda.get_arch_list()), default=35)
            if current_arch < min_arch:
                warnings.warn(old_gpu_warn.format(d, name, major, minor, min_arch // 10, min_arch % 10))
            elif CUDA_VERSION <= 9000 and major >= 7 and minor >= 5:
                warnings.warn(incorrect_binary_warn % (d, name, 10000, CUDA_VERSION))
            else:
                compatible_device_count += 1

    return compatible_device_count > 0
```
Potentially renaming the method to `is_cuda_compatible()` in the process. 

This would solve the problem. Calling the modified method lets you know if any of the CUDA devices are actually compatible with the PyTorch binary, and it avoids wasting memory.

## Alternatives

<!-- A clear and concise description of any alternative solutions or features you've considered, if any. -->

`torch.cuda.is_available()` does not seem to work, because it does not consider if the PyTorch installation has been compiled to support devices that `torch._C._cuda_getDeviceCount()` counts.

## Additional context

<!-- Add any other context or screenshots about the feature request here. -->
Originally discussed [here](https://discuss.pytorch.org/t/how-to-check-torch-gpu-compatibility-without-initializing-cuda/128528).


cc @ngimel