Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 44 additions & 0 deletions .github/actions/griffe-api-check/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0

name: griffe API check

description: >-
Check a package's public API (as defined by `__all__`) for changes using
griffe.

inputs:
package-name:
description: "Importable package name to check, e.g. cuda.core"
required: true
package-dir:
description: "Directory to search for the package sources, e.g. cuda_core"
required: true
merge-base:
description: >-
Git ref/sha to compare the current code against, typically the PR's
merge-base with its target branch.
required: true

runs:
using: composite
steps:
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: false

- name: Check API
shell: bash --noprofile --norc -euo pipefail {0}
env:
PACKAGE_NAME: ${{ inputs.package-name }}
PACKAGE_DIR: ${{ inputs.package-dir }}
MERGE_BASE: ${{ inputs.merge-base }}
run: |
uvx griffe check "$PACKAGE_NAME" \
--search "$PACKAGE_DIR" \
--find-stubs-packages \
--against "$MERGE_BASE" \
--format github \
2>&1
65 changes: 65 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ jobs:
test_bindings: ${{ steps.compose.outputs.test_bindings }}
test_core: ${{ steps.compose.outputs.test_core }}
test_pathfinder: ${{ steps.compose.outputs.test_pathfinder }}
pr_merge_base: ${{ steps.filter.outputs.merge_base }}
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
Expand Down Expand Up @@ -156,6 +157,7 @@ jobs:
echo "python_meta=$(has_match '^cuda_python/')"
echo "test_helpers=$(has_match '^cuda_python_test_helpers/')"
echo "shared=$(has_match '^(\.github/|ci/|scripts/|toolshed/|conftest\.py$|pyproject\.toml$|pixi\.(toml|lock)$|pytest\.ini$|ruff\.toml$)')"
echo "merge_base=${base}"
} >> "$GITHUB_OUTPUT"

- name: Compose gating outputs
Expand Down Expand Up @@ -228,6 +230,69 @@ jobs:
echo "test_pathfinder=${test_pathfinder}"
} >> "$GITHUB_OUTPUT"

api-check-core-vs-release:
name: API check (cuda_core vs. latest release)
if: >-
${{ !fromJSON(needs.should-skip.outputs.skip) &&
fromJSON(needs.detect-changes.outputs.core) }}
runs-on: ubuntu-latest
needs:
- should-skip
- detect-changes
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# griffe checks out the "against" ref into a worktree internally,
# and finding the latest release tag needs the full tag history, so
# the full commit graph (though not historical blobs) must be
# available locally.
fetch-depth: 0
filter: blob:none

- name: Find latest release tag
id: latest-tag
shell: bash --noprofile --norc -euo pipefail {0}
run: |
tag="$(git describe --tags --match "cuda-core-v*" --abbrev=0 2>/dev/null || true)"
echo "tag=${tag}" >> "$GITHUB_OUTPUT"

- name: Check cuda_core public API
id: griffe
uses: ./.github/actions/griffe-api-check
with:
package-name: cuda.core
package-dir: cuda_core
merge-base: ${{ steps.latest-tag.outputs.tag }}

api-check-core-vs-base:
name: API check (cuda_core vs. merge base)
if: >-
${{ startsWith(github.ref_name, 'pull-request/') &&
!fromJSON(needs.should-skip.outputs.skip) &&
fromJSON(needs.detect-changes.outputs.core) }}
runs-on: ubuntu-latest
needs:
- should-skip
- detect-changes
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
filter: blob:none
- name: Check cuda_core public API
id: griffe
uses: ./.github/actions/griffe-api-check
with:
package-name: cuda.core
package-dir: cuda_core
merge-base: ${{ needs.detect-changes.outputs.pr_merge_base }}

# NOTE: Build jobs are intentionally split by platform rather than using a single
# matrix. This allows each test job to depend only on its corresponding build,
# so faster platforms can proceed through build & test without waiting for slower
Expand Down
42 changes: 42 additions & 0 deletions cuda_core/cuda/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,48 @@ class _PatchedProperty(metaclass=_PatchedPropMeta):
del _patch_rlcompleter_for_cython_properties


__all__ = [

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Q: If this is a must to make griffe happy, should we just unify the style and always use __all__ in every submodule, private or public?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's just needed in the public ones. I think that's a reasonable convention.

"LEGACY_DEFAULT_STREAM",
"PER_THREAD_DEFAULT_STREAM",
"Buffer",
"Context",
"ContextOptions",
"Device",
"DeviceMemoryResource",
"DeviceMemoryResourceOptions",
"DeviceResources",
"Event",
"EventOptions",
"GraphMemoryResource",
"GraphicsResource",
"Host",
"Kernel",
"LaunchConfig",
"LegacyPinnedMemoryResource",
"Linker",
"LinkerOptions",
"ManagedBuffer",
"ManagedMemoryResource",
"ManagedMemoryResourceOptions",
"MemoryResource",
"ObjectCode",
"PinnedMemoryResource",
"PinnedMemoryResourceOptions",
"Program",
"ProgramOptions",
"SMResource",
"SMResourceOptions",
"Stream",
"StreamOptions",
"TensorMapDescriptor",
"TensorMapDescriptorOptions",
"VirtualMemoryResource",
"VirtualMemoryResourceOptions",
"WorkqueueResource",
"WorkqueueResourceOptions",
"launch",
]

from cuda.core import checkpoint, system, utils
from cuda.core._context import Context, ContextOptions
from cuda.core._device import Device
Expand Down
6 changes: 6 additions & 0 deletions cuda_core/cuda/core/graph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
# SPDX-License-Identifier: Apache-2.0

from ._graph_builder import *
from ._graph_builder import __all__ as _graph_builder_all
from ._graph_definition import *
from ._graph_definition import __all__ as _graph_definition_all
from ._graph_node import *
from ._graph_node import __all__ as _graph_node_all
from ._subclasses import *
from ._subclasses import __all__ as _subclasses_all

__all__ = [*_graph_builder_all, *_graph_definition_all, *_graph_node_all, *_subclasses_all]
2 changes: 1 addition & 1 deletion cuda_core/cuda/core/graph/_graph_definition.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class GraphDefinition:
See :meth:`GraphNode.deallocate` for full documentation.
"""

def memset(self, dst: Buffer | int, value, width: int, height: int=1, pitch: int=0, *, dst_owner=None) -> MemsetNode:
def memset(self, dst: Buffer | int, value, width: int, *, height: int=1, pitch: int=0, dst_owner=None) -> MemsetNode:
"""Add an entry-point memset node (no dependencies).

See :meth:`GraphNode.memset` for full documentation.
Expand Down
2 changes: 1 addition & 1 deletion cuda_core/cuda/core/graph/_graph_definition.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ cdef class GraphDefinition:
dst: Buffer | int,
value,
size_t width,
*,
size_t height=1,
size_t pitch=0,
*,
dst_owner=None,
) -> MemsetNode:
"""Add an entry-point memset node (no dependencies).
Expand Down