Cuda home discovery without torch init
Skill kjuhwa/skills-hub/skills/pytorch-integration/cuda-home-discovery-without-torch-init
Discover CUDA_HOME at module import time without touching PyTorch's internal cuda-home helper, because in some versions it initializes CUDA — which then breaks subsequent `multiprocessing` forks.From its SKILL.md
npx -y skills add kjuhwa/skills-hub --skill cuda-home-discovery-without-torch-initAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.6 KB, 754 tokens by cl100k_base, as published. Nobody here has run it
Discover CUDA_HOME Without Initializing CUDA
When to use
Your package's __init__.py needs a CUDA toolkit path (for NVCC invocations or include dirs) at import time. The obvious call is torch.utils.cpp_extension._find_cuda_home(). In some PyTorch versions that function touches torch.cuda, which eagerly initializes the CUDA driver on the parent process. Later torch.multiprocessing.spawn-style forks then fail with:
RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method
You need a fallback that is fork-safe.
Steps
- Environment first. Check the standard vars:
cuda_home = os.environ.get('CUDA_HOME') or os.environ.get('CUDA_PATH') - Fallback:
which nvcc, then walk two directories up:if cuda_home is None: try: 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 = Nonewhichis a subprocess — it doesn't touch PyTorch's CUDA state at all. - Final fallback:
/usr/local/cuda(the canonical Linux default), but only if it exists:if cuda_home is None: cuda_home = '/usr/local/cuda' if not os.path.exists(cuda_home): cuda_home = None - Assert and pass through.
assert cuda_home is not None, 'CUDA_HOME could not be discovered'. - Do NOT import
torch.utils.cpp_extensionduring this discovery. Even importing sometimes drags in parts oftorch.cuda. Save that import for actual build time, not import time. - Pass the discovered path into your JIT init. For DeepGEMM that's:
_C.init( os.path.dirname(os.path.abspath(__file__)), # library root _find_cuda_home() # CUDA home )
Evidence (from DeepGEMM)
deep_gemm/__init__.py:103-118: the full_find_cuda_home(). The top comment is explicit:# For some PyTorch versions, the original `_find_cuda_home` will initialize CUDA, # which is incompatible with process forksdeep_gemm/__init__.py:121-124: the single-call initialization of the C++ extension.
Counter / Caveats
- Windows doesn't have
which, usewhere.exeor skip to the filesystem check. DeepGEMM is Linux-only so it doesn't branch. /usr/local/cudacan be a symlink to a specific version (cuda-12.9). That's fine —os.path.existsreturns True on valid symlinks.- If you find
nvccbut the siblinginclude/is missing, you discovered a broken install. Add a secondaryos.path.exists(os.path.join(cuda_home, 'include'))check if your caller assumes it. torch.version.cudais a different question — that's the CUDA version PyTorch was built against, not the installed toolkit. Don't conflate them.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.