Skip to content

Commit 28b73d2

Browse files
committed
cuda.core: keep the merged-wheel layout check in the merge script; use pathlib
Review follow-up. The top-level layout assertion moves from build-wheel.yml into ci/tools/merge_cuda_core_wheels.py, which now derives the kept cuNN directories from its input wheels and raises if anything else remains under cuda/core/ after the removal. _extension_sources uses pathlib.
1 parent cb5784e commit 28b73d2

3 files changed

Lines changed: 15 additions & 34 deletions

File tree

‎.github/workflows/build-wheel.yml‎

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -696,27 +696,6 @@ jobs:
696696
"${{ env.CUDA_CORE_ARTIFACTS_DIR }}"/cu"${BUILD_PREV_CUDA_MAJOR}"/cuda_core*.whl \
697697
--output-dir "${{ env.CUDA_CORE_ARTIFACTS_DIR }}"
698698
699-
- name: Check merged cuda.core wheel layout
700-
if: ${{ env.BUILD_CORE == 'true' }}
701-
run: |
702-
# cuda/core/__init__.py rewrites __path__ to the active cuXX/ tree, so
703-
# only the entry points and the two versioned trees belong at the top
704-
# level of cuda/core/; anything else is a dead copy.
705-
python - "${{ env.CUDA_CORE_ARTIFACTS_DIR }}"/cuda_core*.whl <<'EOF'
706-
import os
707-
import sys
708-
import zipfile
709-
710-
prefix = "cuda/core/"
711-
members = zipfile.ZipFile(sys.argv[1]).namelist()
712-
names = {n[len(prefix) :].split("/")[0] for n in members if n.startswith(prefix)}
713-
names.discard("")
714-
expected = {"__init__.py", "_version.py"}
715-
expected |= {f"cu{os.environ[v]}" for v in ("BUILD_CUDA_MAJOR", "BUILD_PREV_CUDA_MAJOR")}
716-
assert names == expected, f"unexpected top-level entries under cuda/core/: {sorted(names ^ expected)}"
717-
print("merged wheel top level:", sorted(names))
718-
EOF
719-
720699
- name: Check cuda.core wheel
721700
if: ${{ env.BUILD_CORE == 'true' }}
722701
run: |

‎ci/tools/merge_cuda_core_wheels.py‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,11 @@ def merge_wheels(wheels: list[Path], output_dir: Path, show_wheel_contents: bool
133133
# Copy version-specific directories from each wheel into versioned subdirectories
134134
base_dir = Path("cuda") / "core"
135135

136+
versioned_dirs = set()
136137
for i, wheel_dir in enumerate(extracted_wheels):
137138
cuda_version = wheels[i].name.split(".cu")[1].split(".")[0]
138139
versioned_dir = base_wheel / base_dir / f"cu{cuda_version}"
140+
versioned_dirs.add(versioned_dir.name)
139141

140142
# Copy entire directory tree from source wheel to versioned directory
141143
print(f" Copying {wheel_dir / base_dir} to {versioned_dir}", file=sys.stderr)
@@ -147,14 +149,9 @@ def merge_wheels(wheels: list[Path], output_dir: Path, show_wheel_contents: bool
147149
print("\n=== Removing files from cuda/core/ directory ===", file=sys.stderr)
148150
# Only what cuda/core/__init__.py uses before it rewrites __path__ to the
149151
# versioned subpackage stays at top level: it imports _version, then
150-
# redirects every later import into cu12/ or cu13/. Anything else left at
151-
# top level is a dead copy that nothing imports.
152-
items_to_keep = (
153-
"__init__.py",
154-
"_version.py",
155-
"cu12",
156-
"cu13",
157-
)
152+
# redirects every later import into the versioned tree. Anything else
153+
# left at top level is a dead copy that nothing imports.
154+
items_to_keep = {"__init__.py", "_version.py", *versioned_dirs}
158155
all_items = os.scandir(base_wheel / base_dir)
159156
removed_count = 0
160157
for f in all_items:
@@ -169,6 +166,11 @@ def merge_wheels(wheels: list[Path], output_dir: Path, show_wheel_contents: bool
169166
os.remove(f_abspath)
170167
removed_count += 1
171168
print(f"Removed {removed_count} items from cuda/core/ directory", file=sys.stderr)
169+
remaining = {entry.name for entry in os.scandir(base_wheel / base_dir)}
170+
if remaining != items_to_keep:
171+
raise RuntimeError(
172+
f"unexpected top level under cuda/core/: {sorted(remaining)} (expected {sorted(items_to_keep)})"
173+
)
172174

173175
# Repack the merged wheel
174176
output_dir.mkdir(parents=True, exist_ok=True)

‎cuda_core/build_hooks.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,14 @@ def _extension_sources(mod_name):
188188
cuda/core/_cpp/<stem>/, or the single legacy file cuda/core/_cpp/<stem>.cpp.
189189
Example: _tensor_map.pyx compiles _cpp/tensor_map.cpp."""
190190
sources = [f"cuda/core/{mod_name}.pyx"]
191-
cpp_stem = os.path.join("cuda", "core", "_cpp", mod_name.lstrip("_"))
192-
if os.path.isdir(cpp_stem):
193-
cpp_sources = sorted(glob.glob(os.path.join(cpp_stem, "**", "*.cpp"), recursive=True))
191+
cpp_stem = Path("cuda", "core", "_cpp", mod_name.lstrip("_"))
192+
if cpp_stem.is_dir():
193+
cpp_sources = sorted(str(path) for path in cpp_stem.rglob("*.cpp"))
194194
if not cpp_sources:
195195
raise RuntimeError(f"{cpp_stem}/ exists but contains no .cpp files")
196196
sources.extend(cpp_sources)
197-
elif os.path.isfile(cpp_stem + ".cpp"):
198-
sources.append(cpp_stem + ".cpp")
197+
elif cpp_stem.with_suffix(".cpp").is_file():
198+
sources.append(str(cpp_stem.with_suffix(".cpp")))
199199
return sources
200200

201201

0 commit comments

Comments
 (0)