Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
fbdebfa
Move files WITHOUT trying to make anything work.
rwgk Jun 22, 2025
731256d
First pass changing imports from cuda.bindings → cuda.path_finder WIT…
rwgk Jun 22, 2025
6e0ec6c
Move README.md one level up.
rwgk Jun 22, 2025
07e1385
Move find_sub_dirs.py → ../_utils/find_sub_dirs.py
rwgk Jun 22, 2025
68aa8d5
Move files from cuda_bindings/tests to cuda_path_finder/tests WITHOUT…
rwgk Jun 22, 2025
fafa998
First VERY ROUGH version of pyproject.toml
rwgk Jun 22, 2025
4eff7d2
Change imports in tests/ WITHOUT trying to make anything work.
rwgk Jun 22, 2025
db0f540
Clean up pyproject.toml (with the help of ChatGPT) WITHOUT trying to …
rwgk Jun 22, 2025
9fea2e7
ruff automatic fix: Replace deprecated typing.Sequence with collectio…
rwgk Jun 22, 2025
c494ef2
Add `dynamic = ["version"]` in pyproject.toml and cuda/path_finder/__…
rwgk Jun 23, 2025
78b8c6d
Modernize `[project] license` line.
rwgk Jun 23, 2025
5690d96
Change dir/file names: path_finder → pathfinder
rwgk Jun 23, 2025
81b9bd9
Change imports: path_finder → pathfinder
rwgk Jun 23, 2025
b9be5cb
Fix up broken imports.
rwgk Jun 23, 2025
79a8019
add [project.optional-dependencies] test
rwgk Jun 23, 2025
975ba0b
Adopt cuda_core license.
rwgk Jun 25, 2025
3678fb4
cuda.pathfinder.nvidia_dynamic_libs.load_lib → cuda.pathfinder.load_n…
rwgk Jun 25, 2025
c25184e
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 1, 2025
58b2513
Revert "cuda.pathfinder.nvidia_dynamic_libs.load_lib → cuda.pathfinde…
rwgk Jul 1, 2025
050f857
Simple name changes for consistency: library -> lib
rwgk Jul 1, 2025
1933869
Implement consensus API
rwgk Jul 1, 2025
50f4f8e
Use suggested version number 0.1.0
rwgk Jul 1, 2025
787236c
Fix oversight: `license =` line in pyproject.toml
rwgk Jul 1, 2025
5b5078b
Simplify `description =` line in pyproject.toml
rwgk Jul 1, 2025
13e08ae
Remove Maintenance Requirements from main README. Add the list of "Li…
rwgk Jul 1, 2025
97f9dc8
Adjust cuda_bindings/cuda/bindings/path_finder.py to changes in cuda_…
rwgk Jul 1, 2025
e18cf05
First guess at what changes are needed to include cuda_pathfinder in …
rwgk Jul 1, 2025
b015bbe
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 2, 2025
36491c8
git mv nvidia_dynamic_libs.py __init__.py
rwgk Jul 2, 2025
c6187db
Do not use `cibuildwheel` for a `noarch` package (`cuda-pathfinder`).…
rwgk Jul 2, 2025
346e8b9
twine cleanup
rwgk Jul 2, 2025
9207966
Hard-wire cuda-pathfinder artifact name and path for simplicity, simi…
rwgk Jul 2, 2025
3682f7d
Change to __version__ = "1.0.0"
rwgk Jul 2, 2025
7742c5c
Import __version__ in cuda/pathfinder/__init__.py
rwgk Jul 2, 2025
92c8441
Add missing line in step `name: List the cuda.pathfinder artifacts di…
rwgk Jul 2, 2025
a5b7190
`Install cuda.pathfinder` before ` Build cuda.bindings Cython tests`
rwgk Jul 2, 2025
db0ea56
Add missing line in step `name: Check cuda.pathfinder wheel`
rwgk Jul 3, 2025
9a9f1d7
fix build workflow
leofang Jul 3, 2025
aac1cf7
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 3, 2025
989db08
Remove `__all__` in cuda/pathfinder/__init__.py
rwgk Jul 3, 2025
222df6c
Fix `Check if the script was called with exactly 1 argument` implemen…
rwgk Jul 3, 2025
0b8af00
Add pathfinder install & test into ci/tools/run-tests
rwgk Jul 3, 2025
f902dc9
Add Download cuda-pathfinder, Run cuda.pathfinder tests in test-whee…
rwgk Jul 3, 2025
481f8de
Download cuda-pathfinder-wheel into `./cuda_pathfinder` (not `.`)
rwgk Jul 3, 2025
fd18e1e
Run cuda.pathfinder tests only after cuda.bindings tests, so that all…
rwgk Jul 3, 2025
796bd46
Drive-by fix: test_find_or_load → test_load
rwgk Jul 3, 2025
06763af
Introduce CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS env…
rwgk Jul 3, 2025
b2135cf
CUDA_PATHFINDER_TEST_LOAD_NVIDIA_DYNAMIC_LIB_STRICTNESS=supported_mus…
rwgk Jul 3, 2025
bf48142
Add cuda-pathfinder in .github/workflows/build-docs.yml
rwgk Jul 3, 2025
135a37d
Remove 32-bit DLLs from SUPPORTED_WINDOWS_DLLS
rwgk Jul 5, 2025
48c6d63
Add guard: RuntimeError: cuda.pathfinder.load_nvidia_dynamic_lib() r…
rwgk Jul 5, 2025
7ab201a
is_suppressed_dll_file(): return path_basename.startswith(("cudart32_…
rwgk Jul 5, 2025
9f3e9a4
Add nvidia_wheels_cu12 to [project.optional-dependencies] in cuda_pat…
rwgk Jul 5, 2025
00c8b6a
Install cuda.pathfinder nvidia_wheels_cu12 and run-tests pathfinder a…
rwgk Jul 5, 2025
034286a
ci/tools/run-tests: use bash `-v` instead of `-z` to test if CUDA_PAT…
rwgk Jul 6, 2025
aaed5f2
Add missing `shell: bash` line in test-wheel-windows.yml
rwgk Jul 6, 2025
9d8c70c
test_load_nvidia_dynamic_lib: increase timeout to 120 seconds for Win…
rwgk Jul 6, 2025
8440f90
Add test_load_nvidia_dynamic_lib::test_runtime_error_on_non_64bit_python
rwgk Jul 6, 2025
98ae874
Add DynamicLibNotFound exception type in load_dl_common.py and simpli…
rwgk Jul 6, 2025
9686c2f
Run cuda.pathfinder tests with see_what_works before running any othe…
rwgk Jul 6, 2025
f3c0006
Use `if: startsWith(matrix.CUDA_VER, 12.)` to guard pathfinder tests …
rwgk Jul 6, 2025
8f015d2
Get rid of "partially supported" concept.
rwgk Jul 6, 2025
9f17cd1
Consistently use `IS_WINDOWS` (instead of `sys.platform == "win32"`).
rwgk Jul 6, 2025
db7933a
Rename toolshed/build_pathfinder*.py scripts (no functional changes).
rwgk Jul 6, 2025
1b9a929
Rename toolshed/run_cuda_pathfinder.py
rwgk Jul 6, 2025
b69bf23
Make output of toolshed/build_pathfinder_dlls.py usable as-is.
rwgk Jul 6, 2025
80ebbda
Add DynamicLibNotFound to cuda/pathfinder/__init__.py
rwgk Jul 7, 2025
1c8d315
Merge branch 'move_path_finder_to_top' of https://github.com/rwgk/cud…
rwgk Jul 7, 2025
52e1369
Fix accident in previous commit (DynamicLibNotFound)
rwgk Jul 7, 2025
70d1c14
Update README.md
rwgk Jul 7, 2025
342ca49
mypy cleanup
rwgk Jul 7, 2025
4e0033c
Run mypy from pre-commit
rwgk Jul 7, 2025
74ef126
Use SHA for mypy version in .pre-commit-config.yaml (generated with `…
rwgk Jul 7, 2025
5e85328
cuda_bindings/pyproject.toml: constrain "cuda-pathfinder ~= 1.0"
rwgk Jul 7, 2025
46fd972
Make LoadedDL.handle an unsigned integer also for Windows. (cuda_path…
rwgk Jul 9, 2025
428a2dc
Rename LoadedDL.handle → LoadedDL._handle_uint
rwgk Jul 9, 2025
4096885
Move `_handle_uint` last in `LoadedDL`, to emphasize that this is pri…
rwgk Jul 9, 2025
5e6c7e5
Implement TEMPORARY BACKWARD COMPATIBILITY in /cuda/bindings/path_fin…
rwgk Jul 9, 2025
d787a4c
Fix oversight discovered via local Windows testing.
rwgk Jul 9, 2025
60918d5
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 9, 2025
933a889
Merge branch 'main' into move_path_finder_to_top
rwgk Jul 11, 2025
c0509be
Put the changes from https://github.com/NVIDIA/cuda-python/pull/751 o…
rwgk Jul 11, 2025
eedf658
Add `cuda-pathfinder` to `options` in .github/workflows/release.yml
rwgk Jul 11, 2025
58ca181
Move temporary backward compatibility code to _path_finder/temporary_…
rwgk Jul 12, 2025
b73f421
Consolidate mypy configuration into pyproject.toml
rwgk Jul 14, 2025
88c4ebc
Change "slated" to "deprecated and slated ... in the next ... major v…
rwgk Jul 14, 2025
ee19b0c
Remove mention of LoadedDL handle in README.md (it was an oversight t…
rwgk Jul 14, 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
57 changes: 1 addition & 56 deletions cuda_bindings/cuda/bindings/_path_finder/README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1 @@
# `cuda.bindings.path_finder` Module

## Public API (Work in Progress)

Currently exposes two primary interfaces:

```
cuda.bindings.path_finder._SUPPORTED_LIBNAMES # ('nvJitLink', 'nvrtc', 'nvvm')
cuda.bindings.path_finder._load_nvidia_dynamic_library(libname: str) -> LoadedDL
```

**Note:**
These APIs are prefixed with an underscore because they are considered
experimental while undergoing active development, although already
reasonably well-tested through CI pipelines.

## Library Loading Search Priority

The `load_nvidia_dynamic_library()` function implements a hierarchical search
strategy for locating NVIDIA shared libraries:

0. **Check if a library was loaded into the process already by some other means.**
- If yes, there is no alternative to skipping the rest of the search logic.
The absolute path of the already loaded library will be returned, along
with the handle to the library.

1. **NVIDIA Python wheels**
- Scans all site-packages to find libraries installed via NVIDIA Python wheels.

2. **OS default mechanisms / Conda environments**
- Falls back to native loader:
- `dlopen()` on Linux
- `LoadLibraryW()` on Windows
- Conda installations are expected to be discovered:
- Linux: Via `$ORIGIN/../lib` on `RPATH` (of the `python` binary;
note that this preempts `LD_LIBRARY_PATH` and `/etc/ld.so.conf.d/`)
- Windows: Via `%CONDA_PREFIX%\Library\bin` on system `PATH`
- CTK installations with system config updates are expected to be discovered:
- Linux: Via `/etc/ld.so.conf.d/*cuda*.conf`
- Windows: Via `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y\bin` on system `PATH`

3. **Environment variables**
- Relies on `CUDA_HOME` or `CUDA_PATH` environment variables if set
(in that order).

Note that the search is done on a per-library basis. There is no centralized
mechanism that ensures all libraries are found in the same way.

## Maintenance Requirements

These key components must be updated for new CUDA Toolkit releases:

- `supported_libs.SUPPORTED_LIBNAMES`
- `supported_libs.SUPPORTED_WINDOWS_DLLS`
- `supported_libs.SUPPORTED_LINUX_SONAMES`
- `supported_libs.EXPECTED_LIB_SYMBOLS`
# The `cuda.bindings.path_finder` module was moved → `cuda.pathfinder`
36 changes: 0 additions & 36 deletions cuda_bindings/cuda/bindings/_path_finder/load_dl_common.py

This file was deleted.

7 changes: 2 additions & 5 deletions cuda_bindings/cuda/bindings/path_finder.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
# Copyright 2024-2025 NVIDIA Corporation. All rights reserved.
#
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE

from cuda.bindings._path_finder.load_nvidia_dynamic_library import (
load_nvidia_dynamic_library as _load_nvidia_dynamic_library,
)
from cuda.bindings._path_finder.supported_libs import SUPPORTED_LIBNAMES as _SUPPORTED_LIBNAMES
from cuda.pathfinder import SUPPORTED_NVIDIA_LIBNAMES as _SUPPORTED_LIBNAMES
from cuda.pathfinder import load_nvidia_dynamic_lib as _load_nvidia_dynamic_library

__all__ = [
"_load_nvidia_dynamic_library",
Expand Down
177 changes: 177 additions & 0 deletions cuda_pathfinder/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.

"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.

"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.

"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.

"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.

"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.

"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).

"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.

"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."

"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:

(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and

(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and

(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and

(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.

You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS
51 changes: 51 additions & 0 deletions cuda_pathfinder/cuda/pathfinder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# `cuda.pathfinder` Module

## Public API (Work in Progress)

Currently exposes two primary interfaces:

```
cuda.pathfinder.SUPPORTED_LIBNAMES # ('nvJitLink', 'nvrtc', 'nvvm')
cuda.pathfinder.nvidia_dynamic_libs.load_lib(libname: str) -> LoadedDL
```

## Dynamic Library Loading Search Priority

The `cuda.pathfinder.nvidia_dynamic_libs.load_lib` function implements a
hierarchical search strategy for locating NVIDIA shared libraries:

0. **Check if a library was loaded into the process already by some other means.**
- If yes, there is no alternative to skipping the rest of the search logic.
The absolute path of the already loaded library will be returned, along
with the handle to the library.

1. **NVIDIA Python wheels**
- Scans all site-packages to find libraries installed via NVIDIA Python wheels.

2. **OS default mechanisms / Conda environments**
- Falls back to native loader:
- `dlopen()` on Linux
- `LoadLibraryW()` on Windows
- Conda installations are expected to be discovered:
- Linux: Via `$ORIGIN/../lib` on `RPATH` (of the `python` binary;
note that this preempts `LD_LIBRARY_PATH` and `/etc/ld.so.conf.d/`)
- Windows: Via `%CONDA_PREFIX%\Library\bin` on system `PATH`
- CTK installations with system config updates are expected to be discovered:
- Linux: Via `/etc/ld.so.conf.d/*cuda*.conf`
- Windows: Via `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y\bin` on system `PATH`

3. **Environment variables**
- Relies on `CUDA_HOME` or `CUDA_PATH` environment variables if set
(in that order).

Note that the search is done on a per-library basis. Currently there is no
centralized mechanism that ensures all libraries are found in the same way.

## Maintenance Requirements

These key components must be updated for new CUDA Toolkit releases:

- `supported_nvidia_libs.SUPPORTED_LIBNAMES`
- `supported_nvidia_libs.SUPPORTED_WINDOWS_DLLS`
- `supported_nvidia_libs.SUPPORTED_LINUX_SONAMES`
- `supported_nvidia_libs.EXPECTED_LIB_SYMBOLS`
23 changes: 23 additions & 0 deletions cuda_pathfinder/cuda/pathfinder/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

from cuda.pathfinder._dynamic_libs import load_nvidia_dynamic_lib as _load_nvidia_dynamic_lib
from cuda.pathfinder._dynamic_libs.load_dl_common import LoadedDL
from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import SUPPORTED_LIBNAMES as SUPPORTED_NVIDIA_LIBNAMES

__all__ = ["SUPPORTED_NVIDIA_LIBNAMES", "load_nvidia_dynamic_lib"]


def load_nvidia_dynamic_lib(libname: str) -> LoadedDL:
"""Load a NVIDIA dynamic library by name.

Args:
libname: The name of the library to load (e.g. "cudart", "nvvm", etc.)

Returns:
A LoadedDL object containing the library handle and path

Raises:
RuntimeError: If the library cannot be found or loaded
"""
return _load_nvidia_dynamic_lib.load_lib(libname)
Copy link
Contributor

Choose a reason for hiding this comment

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

You could define this wrapper function in the _dynamic_libs module and just import it here. This way your __init__.py here wouldn't have a ton of function definitions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This file is meant to be the public API in one view.

This way your __init__.py here wouldn't have a ton of function definitions.

I understood exactly that was your goal: a flat list of available APIs.

Note that I moved the docstring here.

Copy link
Contributor

Choose a reason for hiding this comment

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

This file is meant to be the public API in one view.

Indeed, everything we define (or import) here that is not prefixed with _ constitutes the public API of the module cuda.path_finder. My above suggestion is just that we import load_nvidia_dynamic_lib rather than define it here.

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 would make the public API far less obvious. E.g. to see the docstring, they'd need to open a private file.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think that's true. They could still do:

from cuda.path_finder import load_nvidia_dynamic_lib
help(load_nvidia_dynamic_lib)

Same as they would do now?

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'll only work interactively.

What I have now can be inspected in obvious ways directly in the sources, e.g. when looking at the sources on github. I can send URLs pointing to specific APIs in this init.py file.

Each function here will just be:

def function(...) -> ...:
    """docstring""
    return call_into_private_code(...)

That's exactly the public API, with a one-line call that's easy to ignore.

What's the point of hiding that away, especially hiding away the docstring and the type hints?

Copy link
Contributor

@shwina shwina Jun 25, 2025

Choose a reason for hiding this comment

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

That'll only work interactively.

The docstrings and type hints would also get picked up:

  • Sphinx (which we use to generate API docs
    -pydoc
  • the developers' IDEs/lsp

Those are primarily the ways consumers of a package interact with docstrings or type hints, rather than looking directly at the source.

What's the point of hiding that away, especially hiding away the docstring and the type hints?

It tightens the scope of __init__.py, whose job is:

  • to include any initialization code for the module
  • to import stuff from submodules that the module wants to expose
  • to define __all__ for the module if needed

As examples, we can look at the __init__.py from some other popular libraries:

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It tightens the scope of init.py, whose job is

The most important job: Show the public API

You didn't answer why you want to hide that away.

Copy link
Contributor

@shwina shwina Jun 25, 2025

Choose a reason for hiding this comment

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

I'm advocating for keeping function and type definitions outside of __init__.py. I don't think that "hides" anything from the user as we still import them here.

The main reason I'm advocating for that is because __init__.py typically only defines functions and types needed for module initialization, and imports anything else. I think the examples I linked to above are a good demonstration of that.

Defining functions and types beyond that serves to clutter __init__.py.

I would argue it makes the code base less navigable than more for people looking at the source. Do I expect the function load_nvidia_dynamic_libs to be defined in a file called _dynamic_libs.py, or a file called __init__.py?

If this all seems nitpicky, I apologize. While I do have a strong opinion here, I don't mind at all if another reviewer (or you, as the author of this PR) made the final call about this.

Copy link
Member

@leofang leofang Jun 25, 2025

Choose a reason for hiding this comment

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

cuda.core's __init__.py is a good example for what Ashwin suggested. As a developer who occasionally peeks into someone else's __init__.py, I certainly get confused why we are defining things in there directly, as opposed to properly organizing them in respective public/private modules, and just import them. What's imported are considered public APIs (including types). Does it make sense?

Loading