Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d174f5a
find_nvidia_headers.py initial version (untested).
rwgk May 27, 2025
5ed86c5
Add tests/test_path_finder_find_headers.py, with hard-coded paths.
rwgk May 28, 2025
a98de70
Better error message: UNKNOWN libname='unknown-libname'
rwgk May 28, 2025
6a93fe7
if libname == "nvshmem" and IS_WINDOWS: return None
rwgk May 28, 2025
3ab9643
Merge branch 'main' into find_nvidia_headers_nvshmem and move/adjust/…
rwgk Aug 12, 2025
c1e9385
Move find_nvidia_headers.py → _headers/find_nvidia_headers.py
rwgk Aug 12, 2025
c3464b3
test_find_nvidia_headers.py: removed hard-wired paths, comments with …
rwgk Aug 12, 2025
627f6d0
Merge branch 'main' into find_nvidia_headers_nvshmem
rwgk Aug 22, 2025
26f94d1
Make _find_nvidia_header_directory private for now.
rwgk Aug 22, 2025
6adddb0
test_find_nvidia_headers.py: Move comments with installation commands…
rwgk Aug 22, 2025
363b649
Add `have_nvidia_nvshmem_package()` function to enable `assert hdr_di…
rwgk Aug 22, 2025
2dd448c
Merge branch 'main' into find_nvidia_headers_nvshmem
rwgk Aug 22, 2025
d3f97e4
Add nvidia-nvshmem-cu12,13 in pyproject.toml
rwgk Aug 22, 2025
6f4d762
assert site-packages or dist-packages
rwgk Aug 22, 2025
dfa3384
Add CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS
rwgk Aug 22, 2025
673c38c
Transfer `ci/`, `.github/` changes from PR #864
rwgk Aug 22, 2025
80cece3
Add CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS in `ci/`, `.g…
rwgk Aug 22, 2025
7c30292
reverse=True in sorting of "/usr/include/nvshmem_*" (find newest first)
rwgk Aug 22, 2025
a300419
Fix: assert site-packages or dist-packages only if have_nvidia_nvshme…
rwgk Aug 22, 2025
3ae15e0
pytest.skip("nvshmem has no Windows support.")
rwgk Aug 22, 2025
e855155
Merge branch 'main' into find_nvidia_headers_nvshmem
rwgk Sep 2, 2025
dc4de43
Merge branch 'main' into find_nvidia_headers_nvshmem
rwgk Sep 3, 2025
eb2e78a
Add new cuda/pathfinder/_utils/conda_env.py and use from find_nvidia_…
rwgk Sep 3, 2025
c90c393
Add new cuda/pathfinder/_utils/env_vars_for_include.py and use from f…
rwgk Sep 4, 2025
cee717a
Revert "Add new cuda/pathfinder/_utils/env_vars_for_include.py and us…
rwgk Sep 5, 2025
a50da30
Revert "Add new cuda/pathfinder/_utils/conda_env.py and use from find…
rwgk Sep 5, 2025
a185f03
Merge branch 'main' into find_nvidia_headers_nvshmem
rwgk Sep 5, 2025
7cfcbfe
Bump pathfinder version to 1.2.2 and add release/1.2.2-notes.rst
rwgk Sep 5, 2025
510f470
Remove os.path.isdir() tests that are not strictly needed.
rwgk Sep 5, 2025
2426260
test_find_nvidia_headers.py: remove check for `dist-packages` because…
rwgk Sep 5, 2025
b74a84c
Additional testing
rwgk Sep 5, 2025
6ee6529
Merge branch 'main' into find_nvidia_headers_nvshmem
rwgk Sep 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test-wheel-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ jobs:
- name: Run cuda.pathfinder tests with see_what_works
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: see_what_works
CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: see_what_works
run: run-tests pathfinder

- name: Run cuda.bindings tests
Expand Down Expand Up @@ -289,4 +290,5 @@ jobs:
- name: Run cuda.pathfinder tests with all_must_work
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: all_must_work
CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: all_must_work
run: run-tests pathfinder
2 changes: 2 additions & 0 deletions .github/workflows/test-wheel-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ jobs:
- name: Run cuda.pathfinder tests with see_what_works
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: see_what_works
CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: see_what_works
shell: bash --noprofile --norc -xeuo pipefail {0}
run: run-tests pathfinder

Expand Down Expand Up @@ -298,5 +299,6 @@ jobs:
- name: Run cuda.pathfinder tests with all_must_work
env:
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS: all_must_work
CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS: all_must_work
shell: bash --noprofile --norc -xeuo pipefail {0}
run: run-tests pathfinder
4 changes: 3 additions & 1 deletion ci/tools/run-tests
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ popd

if [[ "${test_module}" == "pathfinder" ]]; then
pushd ./cuda_pathfinder
echo "Running pathfinder tests with ${CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS}"
echo "Running pathfinder tests with " \
"LD:${CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS} " \
"FH:${CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS}"
pwd
pytest -ra -s -v tests/
popd
Expand Down
3 changes: 3 additions & 0 deletions cuda_pathfinder/cuda/pathfinder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@
from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import (
SUPPORTED_LIBNAMES as SUPPORTED_NVIDIA_LIBNAMES, # noqa: F401
)
from cuda.pathfinder._headers.find_nvidia_headers import (
find_nvidia_header_directory as _find_nvidia_header_directory, # noqa: F401
)
from cuda.pathfinder._version import __version__ as __version__
42 changes: 42 additions & 0 deletions cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

import functools
import glob
import os
from typing import Optional

from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import IS_WINDOWS
from cuda.pathfinder._utils.find_sub_dirs import find_sub_dirs_all_sitepackages


@functools.cache
def find_nvidia_header_directory(libname: str) -> Optional[str]:
if libname != "nvshmem":
raise RuntimeError(f"UNKNOWN {libname=}")

if libname == "nvshmem" and IS_WINDOWS:
# nvshmem has no Windows support.
return None

# Installed from a wheel
nvidia_sub_dirs = ("nvidia", "nvshmem", "include")
hdr_dir: str # help mypy
for hdr_dir in find_sub_dirs_all_sitepackages(nvidia_sub_dirs):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do it in a follow up, but I think we should really move towards using an importlib based resolution method instead of walking the sitepackages ourselves.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we discussed and agreed walking the paths is acceptable since on the PyPI side they are predictable? Any reason to prefer importlib?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point, tx, I created issue #949 to track this.

(I wrote this code before @ZzEeKkAa pointed me to importlib while working on PR #864)

Copy link
Collaborator Author

@rwgk rwgk Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we discussed and agreed walking the paths is acceptable since on the PyPI side they are predictable? Any reason to prefer importlib?

Lines crossed here. Let's review under #949 when we get to it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

864?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, sorry, copy-paste mishap. Corrected (949).

nvshmem_h_path = os.path.join(hdr_dir, "nvshmem.h")
if os.path.isfile(nvshmem_h_path):
return hdr_dir

conda_prefix = os.environ.get("CONDA_PREFIX")
if conda_prefix and os.path.isdir(conda_prefix):
hdr_dir = os.path.join(conda_prefix, "include")
nvshmem_h_path = os.path.join(hdr_dir, "nvshmem.h")
if os.path.isfile(nvshmem_h_path):
return hdr_dir

for hdr_dir in sorted(glob.glob("/usr/include/nvshmem_*"), reverse=True):
nvshmem_h_path = os.path.join(hdr_dir, "nvshmem.h")
if os.path.isfile(nvshmem_h_path):
return hdr_dir

return None
2 changes: 1 addition & 1 deletion cuda_pathfinder/cuda/pathfinder/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

__version__ = "1.2.2a0"
__version__ = "1.2.2"
4 changes: 4 additions & 0 deletions cuda_pathfinder/docs/nv-versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"version": "latest",
"url": "https://nvidia.github.io/cuda-python/cuda-pathfinder/latest/"
},
{
"version": "1.2.2",
"url": "https://nvidia.github.io/cuda-python/cuda-pathfinder/1.2.2/"
},
{
"version": "1.2.1",
"url": "https://nvidia.github.io/cuda-python/cuda-pathfinder/1.2.1/"
Expand Down
1 change: 1 addition & 0 deletions cuda_pathfinder/docs/source/release.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Release Notes
.. toctree::
:maxdepth: 3

1.2.2 <release/1.2.2-notes>
1.2.1 <release/1.2.1-notes>
1.2.0 <release/1.2.0-notes>
1.1.0 <release/1.1.0-notes>
Expand Down
19 changes: 19 additions & 0 deletions cuda_pathfinder/docs/source/release/1.2.2-notes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
.. SPDX-License-Identifier: Apache-2.0

.. module:: cuda.pathfinder

``cuda-pathfinder`` 1.2.2 Release notes
=======================================

Released on Sep 8, 2025


Highlights
----------

* Support nccl library (`PR #945 <https://github.com/NVIDIA/cuda-python/pull/945>`_)

* Add experimental ``cuda.pathfinder._find_nvidia_headers`` API,
currently limited to supporting ``nvshmem``
(`PR #661 <https://github.com/NVIDIA/cuda-python/pull/661>`_)
60 changes: 60 additions & 0 deletions cuda_pathfinder/tests/test_find_nvidia_headers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Currently these installations are only manually tested:

# conda create -y -n nvshmem python=3.12
# conda activate nvshmem
# conda install -y conda-forge::libnvshmem3 conda-forge::libnvshmem-dev

# wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
# sudo dpkg -i cuda-keyring_1.1-1_all.deb
# sudo apt update
# sudo apt install libnvshmem3-cuda-12 libnvshmem3-dev-cuda-12
# sudo apt install libnvshmem3-cuda-13 libnvshmem3-dev-cuda-13

import functools
import importlib.metadata
import os
import re

import pytest

from cuda.pathfinder import _find_nvidia_header_directory as find_nvidia_header_directory
from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import IS_WINDOWS

STRICTNESS = os.environ.get("CUDA_PATHFINDER_TEST_FIND_NVIDIA_HEADERS_STRICTNESS", "see_what_works")
assert STRICTNESS in ("see_what_works", "all_must_work")


@functools.cache
def have_nvidia_nvshmem_package() -> bool:
pattern = re.compile(r"^nvidia-nvshmem-.*$")
return any(
pattern.match(dist.metadata["Name"]) for dist in importlib.metadata.distributions() if "Name" in dist.metadata
)


def test_unknown_libname():
with pytest.raises(RuntimeError, match=r"^UNKNOWN libname='unknown-libname'$"):
find_nvidia_header_directory("unknown-libname")


def test_find_libname_nvshmem(info_summary_append):
hdr_dir = find_nvidia_header_directory("nvshmem")
info_summary_append(f"{hdr_dir=!r}")
if IS_WINDOWS:
assert hdr_dir is None
pytest.skip("nvshmem has no Windows support.")
if hdr_dir:
assert os.path.isdir(hdr_dir)
assert os.path.isfile(os.path.join(hdr_dir, "nvshmem.h"))
if STRICTNESS == "all_must_work" or have_nvidia_nvshmem_package():
assert hdr_dir is not None
if have_nvidia_nvshmem_package():
hdr_dir_parts = hdr_dir.split(os.path.sep)
assert "site-packages" in hdr_dir_parts
elif conda_prefix := os.getenv("CONDA_PREFIX"):
assert hdr_dir.startswith(conda_prefix)
else:
assert hdr_dir.startswith("/usr/include/nvshmem_")
Loading