Skip to content
Open
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
113 changes: 113 additions & 0 deletions cuda_core/cuda/core/_device.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ from cuda.core._memory._buffer import Buffer, MemoryResource
from cuda.core._stream import IsStreamType, Stream
from cuda.core._utils.cuda_utils import ComputeCapability
from cuda.core.graph import GraphBuilder
from cuda.core.texture import (MipmappedArray, MipmappedArrayOptions,
OpaqueArray, OpaqueArrayOptions,
ResourceDescriptor, SurfaceObject,
TextureObject, TextureObjectOptions)


class DeviceProperties:
Expand Down Expand Up @@ -909,5 +913,114 @@ class Device:
Newly created graph builder object.

"""

def create_opaque_array(self, options: OpaqueArrayOptions) -> OpaqueArray:
"""Create an :obj:`~cuda.core.texture.OpaqueArray` on the current device.

Allocates an opaque, hardware-laid-out CUDA array for texture/surface
access. The array is created in the current CUDA context, so make this
device current with :meth:`set_current` before calling (mirroring
:meth:`create_stream` / :meth:`create_event`).

Note
----
Device must be initialized.

Parameters
----------
options : :obj:`~cuda.core.texture.OpaqueArrayOptions`
Allocation options (shape, format, channels, surface flag).

Returns
-------
:obj:`~cuda.core.texture.OpaqueArray`
Newly created opaque array.

.. versionadded:: 1.1.0
"""

def create_mipmapped_array(self, options: MipmappedArrayOptions) -> MipmappedArray:
"""Create a :obj:`~cuda.core.texture.MipmappedArray` on the current device.

Allocates a mipmapped CUDA array for texture/surface access across
levels. The array is created in the current CUDA context, so make this
device current with :meth:`set_current` before calling (mirroring
:meth:`create_stream` / :meth:`create_event`).

Note
----
Device must be initialized.

Parameters
----------
options : :obj:`~cuda.core.texture.MipmappedArrayOptions`
Allocation options (shape, format, channels, levels, surface flag).

Returns
-------
:obj:`~cuda.core.texture.MipmappedArray`
Newly created mipmapped array.

.. versionadded:: 1.1.0
"""

def create_texture_object(self, *, resource: ResourceDescriptor, options: TextureObjectOptions | None=None) -> TextureObject:
"""Create a :obj:`~cuda.core.texture.TextureObject` on the current device.

Binds a resource (an :obj:`~cuda.core.texture.OpaqueArray` /
:obj:`~cuda.core.texture.MipmappedArray` / linear or pitch2d
:obj:`~cuda.core.Buffer`, wrapped in a
:obj:`~cuda.core.texture.ResourceDescriptor`) as a bindless texture for
kernel-side sampled reads. The object is created in the current CUDA
context, so make this device current with :meth:`set_current` before
calling (mirroring :meth:`create_stream` / :meth:`create_event`).

Note
----
Device must be initialized.

Parameters
----------
resource : :obj:`~cuda.core.texture.ResourceDescriptor`
The memory backing the texture.
options : :obj:`~cuda.core.texture.TextureObjectOptions`
Sampling state (address/filter/read modes, normalization, etc.).

Returns
-------
:obj:`~cuda.core.texture.TextureObject`
Newly created texture object.

.. versionadded:: 1.1.0
"""

def create_surface_object(self, *, resource: ResourceDescriptor) -> SurfaceObject:
"""Create a :obj:`~cuda.core.texture.SurfaceObject` on the current device.

Binds an :obj:`~cuda.core.texture.OpaqueArray` (via a
:obj:`~cuda.core.texture.ResourceDescriptor`) as a bindless surface for
kernel-side typed load/store. The backing array must have been created
with ``is_surface_load_store=True``. The object is created in the
current CUDA context, so make this device current with
:meth:`set_current` before calling (mirroring :meth:`create_stream` /
:meth:`create_event`).

Note
----
Device must be initialized.

Parameters
----------
resource : :obj:`~cuda.core.texture.ResourceDescriptor`
Must wrap an :obj:`~cuda.core.texture.OpaqueArray` allocated with
``is_surface_load_store=True``.

Returns
-------
:obj:`~cuda.core.texture.SurfaceObject`
Newly created surface object.

.. versionadded:: 1.1.0
"""
_tls = threading.local()
_lock = threading.Lock()
137 changes: 137 additions & 0 deletions cuda_core/cuda/core/_device.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
import cuda.core.system # no-cython-lint
from cuda.core.graph import GraphBuilder
from cuda.core.texture import (
MipmappedArray,
MipmappedArrayOptions,
OpaqueArray,
OpaqueArrayOptions,
ResourceDescriptor,
SurfaceObject,
TextureObject,
TextureObjectOptions,
)

# TODO: I prefer to type these as "cdef object" and avoid accessing them from within Python,
# but it seems it is very convenient to expose them for testing purposes...
Expand Down Expand Up @@ -1456,6 +1466,133 @@ class Device:
self._check_context_initialized()
return GraphBuilder._init(self.create_stream())

def create_opaque_array(self, options: OpaqueArrayOptions) -> OpaqueArray:
"""Create an :obj:`~cuda.core.texture.OpaqueArray` on the current device.

Allocates an opaque, hardware-laid-out CUDA array for texture/surface
access. The array is created in the current CUDA context, so make this
device current with :meth:`set_current` before calling (mirroring
:meth:`create_stream` / :meth:`create_event`).
Comment on lines +1472 to +1475

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.

See #2311. I think this behavior (using the current context rather than the device specified by self) is buggy, but it matches other methods like Device.create_stream and Device.create_event. Fixing it is out of scope for this PR.


Note
----
Device must be initialized.

Parameters
----------
options : :obj:`~cuda.core.texture.OpaqueArrayOptions`
Allocation options (shape, format, channels, surface flag).

Returns
-------
:obj:`~cuda.core.texture.OpaqueArray`
Newly created opaque array.

.. versionadded:: 1.1.0
"""
from cuda.core.texture._array import _create_opaque_array

self._check_context_initialized()
return _create_opaque_array(options)

def create_mipmapped_array(self, options: MipmappedArrayOptions) -> MipmappedArray:
"""Create a :obj:`~cuda.core.texture.MipmappedArray` on the current device.

Allocates a mipmapped CUDA array for texture/surface access across
levels. The array is created in the current CUDA context, so make this
device current with :meth:`set_current` before calling (mirroring
:meth:`create_stream` / :meth:`create_event`).

Note
----
Device must be initialized.

Parameters
----------
options : :obj:`~cuda.core.texture.MipmappedArrayOptions`
Allocation options (shape, format, channels, levels, surface flag).

Returns
-------
:obj:`~cuda.core.texture.MipmappedArray`
Newly created mipmapped array.

.. versionadded:: 1.1.0
"""
from cuda.core.texture._mipmapped_array import _create_mipmapped_array

self._check_context_initialized()
return _create_mipmapped_array(options)

def create_texture_object(
self, *, resource: ResourceDescriptor, options: TextureObjectOptions | None = None
) -> TextureObject:
"""Create a :obj:`~cuda.core.texture.TextureObject` on the current device.

Binds a resource (an :obj:`~cuda.core.texture.OpaqueArray` /
:obj:`~cuda.core.texture.MipmappedArray` / linear or pitch2d
:obj:`~cuda.core.Buffer`, wrapped in a
:obj:`~cuda.core.texture.ResourceDescriptor`) as a bindless texture for
kernel-side sampled reads. The object is created in the current CUDA
context, so make this device current with :meth:`set_current` before
calling (mirroring :meth:`create_stream` / :meth:`create_event`).

Note
----
Device must be initialized.

Parameters
----------
resource : :obj:`~cuda.core.texture.ResourceDescriptor`
The memory backing the texture.
options : :obj:`~cuda.core.texture.TextureObjectOptions`
Sampling state (address/filter/read modes, normalization, etc.).

Returns
-------
:obj:`~cuda.core.texture.TextureObject`
Newly created texture object.

.. versionadded:: 1.1.0
"""
from cuda.core.texture._texture import _create_texture_object

self._check_context_initialized()
return _create_texture_object(resource, options)

def create_surface_object(self, *, resource: ResourceDescriptor) -> SurfaceObject:
"""Create a :obj:`~cuda.core.texture.SurfaceObject` on the current device.

Binds an :obj:`~cuda.core.texture.OpaqueArray` (via a
:obj:`~cuda.core.texture.ResourceDescriptor`) as a bindless surface for
kernel-side typed load/store. The backing array must have been created
with ``is_surface_load_store=True``. The object is created in the
current CUDA context, so make this device current with
:meth:`set_current` before calling (mirroring :meth:`create_stream` /
:meth:`create_event`).

Note
----
Device must be initialized.

Parameters
----------
resource : :obj:`~cuda.core.texture.ResourceDescriptor`
Must wrap an :obj:`~cuda.core.texture.OpaqueArray` allocated with
``is_surface_load_store=True``.

Returns
-------
:obj:`~cuda.core.texture.SurfaceObject`
Newly created surface object.

.. versionadded:: 1.1.0
"""
from cuda.core.texture._surface import _create_surface_object

self._check_context_initialized()
return _create_surface_object(resource)


cdef inline int Device_ensure_cuda_initialized() except? -1:
"""Initialize CUDA driver and check version compatibility (once per process)."""
Expand Down
25 changes: 13 additions & 12 deletions cuda_core/cuda/core/texture/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,31 @@

Import these types from here, e.g.::

from cuda.core.texture import OpaqueArray, TextureObject, TextureDescriptor
from cuda.core.texture import OpaqueArray, TextureObject, TextureObjectOptions

The associated enumerations (:class:`~cuda.core.typing.ArrayFormatType`,
:class:`~cuda.core.typing.AddressModeType`,
:class:`~cuda.core.typing.FilterModeType`,
:class:`~cuda.core.typing.ReadModeType`) live in :mod:`cuda.core.typing`
alongside the other ``cuda.core`` enumerations.
"""

from cuda.core.texture._array import ArrayFormat, OpaqueArray
from cuda.core.texture._mipmapped_array import MipmappedArray
from cuda.core.texture._array import OpaqueArray, OpaqueArrayOptions
from cuda.core.texture._mipmapped_array import MipmappedArray, MipmappedArrayOptions
from cuda.core.texture._surface import SurfaceObject
from cuda.core.texture._texture import (
AddressMode,
FilterMode,
ReadMode,
ResourceDescriptor,
TextureDescriptor,
TextureObject,
TextureObjectOptions,
)

__all__ = [
"AddressMode",
"ArrayFormat",
"FilterMode",
"MipmappedArray",
"MipmappedArrayOptions",
"OpaqueArray",
"ReadMode",
"OpaqueArrayOptions",
"ResourceDescriptor",
"SurfaceObject",
"TextureDescriptor",
"TextureObject",
"TextureObjectOptions",
]
Loading
Loading