diff --git a/cuda_core/cuda/core/__init__.py b/cuda_core/cuda/core/__init__.py index 33ba03c9c2d..c1b3bc64672 100644 --- a/cuda_core/cuda/core/__init__.py +++ b/cuda_core/cuda/core/__init__.py @@ -110,8 +110,12 @@ class _PatchedProperty(metaclass=_PatchedPropMeta): from cuda.core._tensor_map import TensorMapDescriptor, TensorMapDescriptorOptions # isort: split +# Texture/surface types live under the cuda.core.textures namespace (not the +# flat cuda.core namespace); import the subpackage so it is available as +# `cuda.core.textures` after `import cuda.core`. # Must come after the cuda.core._* extension imports above: loading graph # earlier interacts badly with the merged-wheel __path__ rewrite and leaves # Graph/GraphBuilder/GraphCompleteOptions/GraphDebugPrintOptions missing from # cuda.core.graph. import cuda.core.graph +import cuda.core.textures diff --git a/cuda_core/cuda/core/_array.pxd b/cuda_core/cuda/core/_array.pxd new file mode 100644 index 00000000000..f4e9182addc --- /dev/null +++ b/cuda_core/cuda/core/_array.pxd @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from cuda.bindings cimport cydriver +from cuda.core._resource_handles cimport ArrayHandle + + +cdef class CUDAArray: + + cdef: + # Owning/non-owning + any parent (mipmap) dependency are encoded + # structurally in the C++ box behind this handle, not in Python state. + ArrayHandle _handle + tuple _shape # (w,), (w, h), or (w, h, d) + cydriver.CUarray_format _format + unsigned int _num_channels # 1, 2, or 4 + int _device_id + bint _surface_load_store + + cpdef close(self) + + +# Wrap an existing ArrayHandle as a CUDAArray, querying the driver for the +# array's shape/format/channels/surface-flag metadata. Used by get_level and +# the graphics-interop _from_handle path. +cdef CUDAArray _array_from_handle(ArrayHandle h, int device_id) diff --git a/cuda_core/cuda/core/_array.pyi b/cuda_core/cuda/core/_array.pyi new file mode 100644 index 00000000000..cc1969cbbfa --- /dev/null +++ b/cuda_core/cuda/core/_array.pyi @@ -0,0 +1,174 @@ +# This file was generated by stubgen-pyx v0.2.6 from cuda_core/cuda/core/_array.pyx + +from __future__ import annotations + +from enum import IntEnum + +from cuda.bindings import cydriver + + +class ArrayFormat(IntEnum): + """Element format for a :class:`CUDAArray` allocation. + + Mirrors ``CUarray_format`` from the CUDA driver API. + """ + UINT8 = cydriver.CU_AD_FORMAT_UNSIGNED_INT8 + UINT16 = cydriver.CU_AD_FORMAT_UNSIGNED_INT16 + UINT32 = cydriver.CU_AD_FORMAT_UNSIGNED_INT32 + INT8 = cydriver.CU_AD_FORMAT_SIGNED_INT8 + INT16 = cydriver.CU_AD_FORMAT_SIGNED_INT16 + INT32 = cydriver.CU_AD_FORMAT_SIGNED_INT32 + FLOAT16 = cydriver.CU_AD_FORMAT_HALF + FLOAT32 = cydriver.CU_AD_FORMAT_FLOAT + +class CUDAArray: + """An opaque, hardware-laid-out GPU allocation for texture/surface access. + + Distinct from :class:`Buffer`: a ``CUarray`` has no exposed device pointer + and can only be accessed from kernels through a :class:`TextureObject` or + :class:`SurfaceObject`. Its memory layout is chosen by the driver for 2D/3D + spatial locality. + + **Copy-only interop.** Because the layout is opaque and there is no linear + device pointer, a ``CUDAArray`` cannot expose ``__cuda_array_interface__`` / + DLPack and cannot be shared zero-copy with NumPy, CuPy, numba-cuda, or + PyTorch. Moving data in or out is therefore always a copy: use + :meth:`copy_from` / :meth:`copy_to` against a linear :class:`Buffer` or a + host buffer-protocol object. There is no allocation helper — allocate the + linear :class:`Buffer` yourself (e.g. ``mr.allocate(arr.size_bytes, + stream=s)``) and copy. + + Construct via :meth:`from_descriptor`. Only plain 1D/2D/3D allocations are + supported in this initial version; layered/cubemap/sparse variants will + follow once their shape semantics are settled. + """ + + def close(self): + """Release this object's reference to the underlying ``CUarray``. + + Destruction (``cuArrayDestroy``) happens via the handle's deleter when + the last reference is dropped; for a non-owning handle (graphics interop + or a mipmap-level view) nothing is destroyed. Idempotent: a second call + (or destruction after ``close()``) is a no-op. + """ + + def __init__(self, *args, **kwargs): + ... + + @classmethod + def from_descriptor(cls, *, shape, format, num_channels, is_surface_load_store=False): + """Allocate a new CUDA array. + + Parameters + ---------- + shape : tuple of int + ``(width,)``, ``(width, height)``, or ``(width, height, depth)`` + in elements. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + is_surface_load_store : bool + If True, allocate with ``CUDA_ARRAY3D_SURFACE_LDST`` so the array + can be bound as a :class:`SurfaceObject` for kernel-side writes. + Default False. + + Returns + ------- + CUDAArray + """ + + @classmethod + def _from_handle(cls, handle: int, owning: bool, *, device_id=None): + """Wrap an externally-allocated ``CUarray``. + + Intended for graphics interop (``cuGraphicsSubResourceGetMappedArray``) + where the array is owned by the graphics API. With ``owning=False`` the + underlying ``CUarray`` is never destroyed by this object. Shape, format, + and channel count are queried from the driver. + """ + + @property + def handle(self): + """The underlying ``CUarray`` as an integer.""" + + @property + def shape(self): + """Allocation shape, in elements.""" + + @property + def format(self): + """The element :class:`ArrayFormat`.""" + + @property + def num_channels(self): + """Channels per element (1, 2, or 4).""" + + @property + def element_size(self): + """Bytes per element (format size * channels).""" + + @property + def device(self): + """The :class:`Device` this array was allocated on.""" + + @property + def is_surface_load_store(self): + """True if this array was created with ``CUDA_ARRAY3D_SURFACE_LDST`` + and can be bound as a :class:`SurfaceObject`.""" + + def _extent_bytes(self): + """Return (width_bytes, height, depth) for cuMemcpy3D, with height/depth + normalized to >=1 for lower-rank arrays.""" + + def copy_from(self, src, *, stream) -> None: + """Copy a full-array's worth of data into this array. + + Parameters + ---------- + src : Buffer or buffer-protocol object + Source data. Must contain at least ``self.size_bytes`` bytes + of contiguous data. + stream : Stream or GraphBuilder + Stream to issue the copy on. A :class:`~cuda.core.graph.GraphBuilder` + is accepted so the copy can be captured into a graph. + """ + + def copy_to(self, dst, *, stream): + """Copy a full-array's worth of data out of this array. + + Parameters + ---------- + dst : Buffer or writable buffer-protocol object + Destination. Must have at least ``self.size_bytes`` bytes of + writable, contiguous space. + stream : Stream or GraphBuilder + Stream to issue the copy on. A :class:`~cuda.core.graph.GraphBuilder` + is accepted so the copy can be captured into a graph. + + Returns + ------- + The ``dst`` object, for parity with :meth:`Buffer.copy_to`. + """ + + @property + def size_bytes(self): + """Total bytes of array storage (``prod(shape) * element_size``).""" + + def __enter__(self): + ... + + def __exit__(self, exc_type, exc, tb): + ... + + def __repr__(self): + ... +_FORMAT_ELEM_SIZE = {int(ArrayFormat.UINT8): 1, int(ArrayFormat.INT8): 1, int(ArrayFormat.UINT16): 2, int(ArrayFormat.INT16): 2, int(ArrayFormat.FLOAT16): 2, int(ArrayFormat.UINT32): 4, int(ArrayFormat.INT32): 4, int(ArrayFormat.FLOAT32): 4} + +def _validate_format_channels(format, num_channels): + """Validate the ``(format, num_channels)`` pair shared by the array, + mipmap, and texture factories. Raises on an invalid combination.""" + +def _validate_array_shape(shape): + """Coerce ``shape`` to a tuple of ints and validate rank (1-3) and that + every extent is >= 1. Returns the normalized tuple.""" \ No newline at end of file diff --git a/cuda_core/cuda/core/_array.pyx b/cuda_core/cuda/core/_array.pyx new file mode 100644 index 00000000000..7b65e1494f6 --- /dev/null +++ b/cuda_core/cuda/core/_array.pyx @@ -0,0 +1,472 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +cimport cpython +from libc.stdint cimport intptr_t +from libc.string cimport memset + +from cuda.bindings cimport cydriver +from cuda.core._memory._buffer cimport Buffer +from cuda.core._resource_handles cimport ( + ArrayHandle, + as_cu, + as_intptr, + create_array_handle, + create_array_handle_owning, + create_array_handle_ref, + get_last_error, +) +from cuda.core._stream cimport Stream, Stream_accept +from cuda.core._utils.cuda_utils cimport ( + HANDLE_RETURN, + _get_current_device_id, +) + +from enum import IntEnum + + +class ArrayFormat(IntEnum): + """Element format for a :class:`CUDAArray` allocation. + + Mirrors ``CUarray_format`` from the CUDA driver API. + """ + UINT8 = cydriver.CU_AD_FORMAT_UNSIGNED_INT8 + UINT16 = cydriver.CU_AD_FORMAT_UNSIGNED_INT16 + UINT32 = cydriver.CU_AD_FORMAT_UNSIGNED_INT32 + INT8 = cydriver.CU_AD_FORMAT_SIGNED_INT8 + INT16 = cydriver.CU_AD_FORMAT_SIGNED_INT16 + INT32 = cydriver.CU_AD_FORMAT_SIGNED_INT32 + FLOAT16 = cydriver.CU_AD_FORMAT_HALF + FLOAT32 = cydriver.CU_AD_FORMAT_FLOAT + + +# Bytes per element (single channel) for each format. +_FORMAT_ELEM_SIZE = { + int(ArrayFormat.UINT8): 1, + int(ArrayFormat.INT8): 1, + int(ArrayFormat.UINT16): 2, + int(ArrayFormat.INT16): 2, + int(ArrayFormat.FLOAT16): 2, + int(ArrayFormat.UINT32): 4, + int(ArrayFormat.INT32): 4, + int(ArrayFormat.FLOAT32): 4, +} + + +def _validate_format_channels(format, num_channels): + """Validate the ``(format, num_channels)`` pair shared by the array, + mipmap, and texture factories. Raises on an invalid combination.""" + if not isinstance(format, ArrayFormat): + raise TypeError(f"format must be an ArrayFormat, got {type(format).__name__}") + if isinstance(num_channels, bool) or num_channels not in (1, 2, 4): + raise ValueError(f"num_channels must be 1, 2, or 4, got {num_channels!r}") + + +def _validate_array_shape(shape): + """Coerce ``shape`` to a tuple of ints and validate rank (1-3) and that + every extent is >= 1. Returns the normalized tuple.""" + try: + shape_t = tuple(int(s) for s in shape) + except TypeError as e: + raise TypeError(f"shape must be a tuple of ints, got {type(shape).__name__}") from e + if not 1 <= len(shape_t) <= 3: + raise ValueError(f"shape rank must be 1, 2, or 3, got {len(shape_t)}") + for i, dim in enumerate(shape_t): + if dim < 1: + raise ValueError(f"shape[{i}] must be >= 1, got {dim}") + return shape_t + + +cdef void _fill_array_endpoint( + cydriver.CUDA_MEMCPY3D* p, CUDAArray arr, bint is_src +) noexcept: + """Populate the src or dst array fields of a CUDA_MEMCPY3D struct.""" + if is_src: + p.srcMemoryType = cydriver.CU_MEMORYTYPE_ARRAY + p.srcArray = as_cu(arr._handle) + p.srcXInBytes = 0 + p.srcY = 0 + p.srcZ = 0 + else: + p.dstMemoryType = cydriver.CU_MEMORYTYPE_ARRAY + p.dstArray = as_cu(arr._handle) + p.dstXInBytes = 0 + p.dstY = 0 + p.dstZ = 0 + + +cdef int _fill_host_endpoint( + cydriver.CUDA_MEMCPY3D* p, + object obj, + bint is_src, + size_t width_bytes, + size_t height, + size_t required, + cpython.Py_buffer* pybuf_out, +) except -1: + """Populate src/dst host fields from a buffer-protocol ``obj``. + + Acquires a Py_buffer view; the caller is responsible for releasing it + (this function always returns with the view held when it returns 1). + """ + cdef int flags = cpython.PyBUF_SIMPLE + if not is_src: + flags |= cpython.PyBUF_WRITABLE + if cpython.PyObject_GetBuffer(obj, pybuf_out, flags) != 0: + raise TypeError( + f"Source/destination must be a Buffer or a contiguous " + f"buffer-protocol object, got {type(obj).__name__}" + ) + if pybuf_out.len < required: + cpython.PyBuffer_Release(pybuf_out) + raise ValueError( + f"Host buffer has {pybuf_out.len} bytes, smaller than the array " + f"extent ({required} bytes)" + ) + if is_src: + p.srcMemoryType = cydriver.CU_MEMORYTYPE_HOST + p.srcHost = pybuf_out.buf + p.srcPitch = width_bytes + p.srcHeight = height + p.srcXInBytes = 0 + p.srcY = 0 + p.srcZ = 0 + else: + p.dstMemoryType = cydriver.CU_MEMORYTYPE_HOST + p.dstHost = pybuf_out.buf + p.dstPitch = width_bytes + p.dstHeight = height + p.dstXInBytes = 0 + p.dstY = 0 + p.dstZ = 0 + return 1 + + +cdef int _fill_linear_endpoint( + cydriver.CUDA_MEMCPY3D* p, + object obj, + bint is_src, + size_t width_bytes, + size_t height, + size_t depth, + cpython.Py_buffer* pybuf_out, +) except -1: + """Populate the src or dst linear fields. Returns 1 if pybuf_out was + filled (caller must release it), 0 otherwise. + """ + cdef intptr_t ptr + cdef size_t required = width_bytes * height * depth + if isinstance(obj, Buffer): + if (obj).size < required: + raise ValueError( + f"Buffer size ({(obj).size} bytes) is smaller than " + f"the array extent ({required} bytes)" + ) + ptr = int((obj).handle) + if is_src: + p.srcMemoryType = cydriver.CU_MEMORYTYPE_DEVICE + p.srcDevice = ptr + p.srcPitch = width_bytes + p.srcHeight = height + p.srcXInBytes = 0 + p.srcY = 0 + p.srcZ = 0 + else: + p.dstMemoryType = cydriver.CU_MEMORYTYPE_DEVICE + p.dstDevice = ptr + p.dstPitch = width_bytes + p.dstHeight = height + p.dstXInBytes = 0 + p.dstY = 0 + p.dstZ = 0 + return 0 + return _fill_host_endpoint( + p, obj, is_src, width_bytes, height, required, pybuf_out + ) + + +cdef _copy3d(CUDAArray arr, object other, Stream stream, bint to_array): + """Issue a full-array async 3D memcpy between ``arr`` and ``other``. + + Direction is determined by ``to_array``: True copies *into* arr, False + copies *out of* arr. ``stream`` must already be a concrete :class:`Stream` + (callers coerce via :func:`Stream_accept`). + """ + cdef cydriver.CUDA_MEMCPY3D params + cdef cpython.Py_buffer pybuf + cdef int got_buffer = 0 + cdef intptr_t stream_handle + cdef cydriver.CUstream c_stream + + memset(¶ms, 0, sizeof(params)) + width_bytes, height, depth = arr._extent_bytes() + params.WidthInBytes = width_bytes + params.Height = height + params.Depth = depth + + try: + if to_array: + got_buffer = _fill_linear_endpoint( + ¶ms, other, True, width_bytes, height, depth, &pybuf + ) + _fill_array_endpoint(¶ms, arr, False) + else: + _fill_array_endpoint(¶ms, arr, True) + got_buffer = _fill_linear_endpoint( + ¶ms, other, False, width_bytes, height, depth, &pybuf + ) + + stream_handle = int((stream).handle) + c_stream = stream_handle + with nogil: + HANDLE_RETURN(cydriver.cuMemcpy3DAsync(¶ms, c_stream)) + finally: + if got_buffer: + cpython.PyBuffer_Release(&pybuf) + + +cdef class CUDAArray: + """An opaque, hardware-laid-out GPU allocation for texture/surface access. + + Distinct from :class:`Buffer`: a ``CUarray`` has no exposed device pointer + and can only be accessed from kernels through a :class:`TextureObject` or + :class:`SurfaceObject`. Its memory layout is chosen by the driver for 2D/3D + spatial locality. + + **Copy-only interop.** Because the layout is opaque and there is no linear + device pointer, a ``CUDAArray`` cannot expose ``__cuda_array_interface__`` / + DLPack and cannot be shared zero-copy with NumPy, CuPy, numba-cuda, or + PyTorch. Moving data in or out is therefore always a copy: use + :meth:`copy_from` / :meth:`copy_to` against a linear :class:`Buffer` or a + host buffer-protocol object. There is no allocation helper — allocate the + linear :class:`Buffer` yourself (e.g. ``mr.allocate(arr.size_bytes, + stream=s)``) and copy. + + Construct via :meth:`from_descriptor`. Only plain 1D/2D/3D allocations are + supported in this initial version; layered/cubemap/sparse variants will + follow once their shape semantics are settled. + """ + + def __init__(self, *args, **kwargs): + raise RuntimeError( + "CUDAArray cannot be instantiated directly. Use CUDAArray.from_descriptor()." + ) + + @classmethod + def from_descriptor(cls, *, shape, format, num_channels, is_surface_load_store=False): + """Allocate a new CUDA array. + + Parameters + ---------- + shape : tuple of int + ``(width,)``, ``(width, height)``, or ``(width, height, depth)`` + in elements. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + is_surface_load_store : bool + If True, allocate with ``CUDA_ARRAY3D_SURFACE_LDST`` so the array + can be bound as a :class:`SurfaceObject` for kernel-side writes. + Default False. + + Returns + ------- + CUDAArray + """ + _validate_format_channels(format, num_channels) + shape_t = _validate_array_shape(shape) + + cdef cydriver.CUarray_format c_format = format + cdef cydriver.CUDA_ARRAY3D_DESCRIPTOR desc3d + cdef int rank = len(shape_t) + cdef unsigned int flags = ( + cydriver.CUDA_ARRAY3D_SURFACE_LDST if is_surface_load_store else 0 + ) + + # cuArray3DCreate handles 1D/2D/3D uniformly (Height/Depth 0 sentinels), + # so a single descriptor + create_array_handle covers every shape. + memset(&desc3d, 0, sizeof(desc3d)) + desc3d.Width = shape_t[0] + desc3d.Height = (shape_t[1] if rank >= 2 else 0) + desc3d.Depth = (shape_t[2] if rank >= 3 else 0) + desc3d.Format = c_format + desc3d.NumChannels = num_channels + desc3d.Flags = flags + + cdef ArrayHandle h = create_array_handle(desc3d) + if not h: + HANDLE_RETURN(get_last_error()) + + cdef CUDAArray self = cls.__new__(cls) + self._handle = h + self._shape = shape_t + self._format = c_format + self._num_channels = num_channels + self._surface_load_store = bool(is_surface_load_store) + self._device_id = _get_current_device_id() + return self + + @classmethod + def _from_handle(cls, intptr_t handle, bint owning, *, device_id=None): + """Wrap an externally-allocated ``CUarray``. + + Intended for graphics interop (``cuGraphicsSubResourceGetMappedArray``) + where the array is owned by the graphics API. With ``owning=False`` the + underlying ``CUarray`` is never destroyed by this object. Shape, format, + and channel count are queried from the driver. + """ + cdef cydriver.CUarray raw = handle + cdef ArrayHandle h + if owning: + h = create_array_handle_owning(raw) + else: + h = create_array_handle_ref(raw) + cdef int dev = _get_current_device_id() if device_id is None else int(device_id) + return _array_from_handle(h, dev) + + @property + def handle(self): + """The underlying ``CUarray`` as an integer.""" + return as_intptr(self._handle) + + @property + def shape(self): + """Allocation shape, in elements.""" + return self._shape + + @property + def format(self): + """The element :class:`ArrayFormat`.""" + return ArrayFormat(self._format) + + @property + def num_channels(self): + """Channels per element (1, 2, or 4).""" + return self._num_channels + + @property + def element_size(self): + """Bytes per element (format size * channels).""" + return _FORMAT_ELEM_SIZE[self._format] * self._num_channels + + @property + def device(self): + """The :class:`Device` this array was allocated on.""" + from cuda.core._device import Device + return Device(self._device_id) + + @property + def is_surface_load_store(self): + """True if this array was created with ``CUDA_ARRAY3D_SURFACE_LDST`` + and can be bound as a :class:`SurfaceObject`.""" + return self._surface_load_store + + def _extent_bytes(self): + """Return (width_bytes, height, depth) for cuMemcpy3D, with height/depth + normalized to >=1 for lower-rank arrays.""" + cdef int rank = len(self._shape) + cdef size_t w = self._shape[0] * ( + _FORMAT_ELEM_SIZE[self._format] * self._num_channels + ) + cdef size_t h = (self._shape[1] if rank >= 2 else 1) + cdef size_t d = (self._shape[2] if rank >= 3 else 1) + return w, h, d + + def copy_from(self, src, *, stream) -> None: + """Copy a full-array's worth of data into this array. + + Parameters + ---------- + src : Buffer or buffer-protocol object + Source data. Must contain at least ``self.size_bytes`` bytes + of contiguous data. + stream : Stream or GraphBuilder + Stream to issue the copy on. A :class:`~cuda.core.graph.GraphBuilder` + is accepted so the copy can be captured into a graph. + """ + _copy3d(self, src, Stream_accept(stream), to_array=True) + + def copy_to(self, dst, *, stream): + """Copy a full-array's worth of data out of this array. + + Parameters + ---------- + dst : Buffer or writable buffer-protocol object + Destination. Must have at least ``self.size_bytes`` bytes of + writable, contiguous space. + stream : Stream or GraphBuilder + Stream to issue the copy on. A :class:`~cuda.core.graph.GraphBuilder` + is accepted so the copy can be captured into a graph. + + Returns + ------- + The ``dst`` object, for parity with :meth:`Buffer.copy_to`. + """ + _copy3d(self, dst, Stream_accept(stream), to_array=False) + return dst + + @property + def size_bytes(self): + """Total bytes of array storage (``prod(shape) * element_size``).""" + cdef size_t n = 1 + for s in self._shape: + n *= s + return n * (_FORMAT_ELEM_SIZE[self._format] * self._num_channels) + + cpdef close(self): + """Release this object's reference to the underlying ``CUarray``. + + Destruction (``cuArrayDestroy``) happens via the handle's deleter when + the last reference is dropped; for a non-owning handle (graphics interop + or a mipmap-level view) nothing is destroyed. Idempotent: a second call + (or destruction after ``close()``) is a no-op. + """ + self._handle.reset() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + self.close() + + def __repr__(self): + return ( + f"CUDAArray(shape={self._shape}, " + f"format={ArrayFormat(self._format).name}, " + f"num_channels={self._num_channels})" + ) + + +cdef CUDAArray _array_from_handle(ArrayHandle h, int device_id): + """Wrap an existing ArrayHandle as a CUDAArray, querying the driver for the + array's shape/format/channels/surface-flag metadata. + + Any owning/non-owning semantics and parent (mipmap) dependency are already + captured structurally inside ``h``'s C++ box. + """ + if not h: + HANDLE_RETURN(get_last_error()) + + cdef CUDAArray self = CUDAArray.__new__(CUDAArray) + self._handle = h + self._device_id = device_id + + cdef cydriver.CUDA_ARRAY3D_DESCRIPTOR desc + cdef cydriver.CUarray raw = as_cu(h) + with nogil: + HANDLE_RETURN(cydriver.cuArray3DGetDescriptor(&desc, raw)) + + if desc.Depth > 0: + self._shape = (int(desc.Width), int(desc.Height), int(desc.Depth)) + elif desc.Height > 0: + self._shape = (int(desc.Width), int(desc.Height)) + else: + self._shape = (int(desc.Width),) + self._format = desc.Format + self._num_channels = desc.NumChannels + self._surface_load_store = bool(desc.Flags & cydriver.CUDA_ARRAY3D_SURFACE_LDST) + return self diff --git a/cuda_core/cuda/core/_cpp/resource_handles.cpp b/cuda_core/cuda/core/_cpp/resource_handles.cpp index 6e82d734e35..156878ab97c 100644 --- a/cuda_core/cuda/core/_cpp/resource_handles.cpp +++ b/cuda_core/cuda/core/_cpp/resource_handles.cpp @@ -77,6 +77,16 @@ decltype(&cuLinkDestroy) p_cuLinkDestroy = nullptr; decltype(&cuGraphicsUnmapResources) p_cuGraphicsUnmapResources = nullptr; decltype(&cuGraphicsUnregisterResource) p_cuGraphicsUnregisterResource = nullptr; +decltype(&cuArray3DCreate) p_cuArray3DCreate = nullptr; +decltype(&cuArrayDestroy) p_cuArrayDestroy = nullptr; +decltype(&cuMipmappedArrayCreate) p_cuMipmappedArrayCreate = nullptr; +decltype(&cuMipmappedArrayDestroy) p_cuMipmappedArrayDestroy = nullptr; +decltype(&cuMipmappedArrayGetLevel) p_cuMipmappedArrayGetLevel = nullptr; +decltype(&cuTexObjectCreate) p_cuTexObjectCreate = nullptr; +decltype(&cuTexObjectDestroy) p_cuTexObjectDestroy = nullptr; +decltype(&cuSurfObjectCreate) p_cuSurfObjectCreate = nullptr; +decltype(&cuSurfObjectDestroy) p_cuSurfObjectDestroy = nullptr; + // SM resource split (13.1+ — may be null on older drivers/bindings) #if CUDA_VERSION >= 13010 decltype(&cuDevSmResourceSplit) p_cuDevSmResourceSplit = nullptr; @@ -1337,6 +1347,168 @@ FileDescriptorHandle create_fd_handle_ref(int fd) { #endif } +// ============================================================================ +// Array / mipmapped-array / texture / surface handles (PR #467) +// ============================================================================ + +namespace { +struct ArrayBox { + CUarray resource; + // Non-null only for a mipmap-level view: keeps the parent mipmap (the real + // owner of the level's storage) alive for as long as the level is held. + MipmappedArrayHandle h_parent; +}; + +struct MipmappedArrayBox { + CUmipmappedArray resource; +}; + +struct TexObjectBox { + // Tagged so TexObjectHandle is a distinct C++ type from DevicePtrHandle / + // SurfObjectHandle (all wrap `unsigned long long`). + TexObjectValue resource; + // Type-erased backing dependency (ArrayHandle / MipmappedArrayHandle / + // DevicePtrHandle). The texture's resource is a union; we only need to keep + // whichever backing it was built from alive, never to dereference it. + std::shared_ptr h_backing; +}; + +struct SurfObjectBox { + SurfObjectValue resource; + ArrayHandle h_array; // surfaces are always array-backed +}; +} // namespace + +ArrayHandle create_array_handle(const CUDA_ARRAY3D_DESCRIPTOR& desc) { + GILReleaseGuard gil; + CUarray arr; + if (CUDA_SUCCESS != (err = p_cuArray3DCreate(&arr, &desc))) { + return {}; + } + auto box = std::shared_ptr( + new ArrayBox{arr, {}}, + [](const ArrayBox* b) { + GILReleaseGuard gil; + p_cuArrayDestroy(b->resource); + delete b; + } + ); + return ArrayHandle(box, &box->resource); +} + +ArrayHandle create_array_handle_ref(CUarray arr) { + if (!arr) { + return {}; + } + auto box = std::make_shared(ArrayBox{arr, {}}); + return ArrayHandle(box, &box->resource); +} + +ArrayHandle create_array_handle_owning(CUarray arr) { + if (!arr) { + return {}; + } + auto box = std::shared_ptr( + new ArrayBox{arr, {}}, + [](const ArrayBox* b) { + GILReleaseGuard gil; + p_cuArrayDestroy(b->resource); + delete b; + } + ); + return ArrayHandle(box, &box->resource); +} + +ArrayHandle create_array_level_handle(const MipmappedArrayHandle& h_mip, unsigned int level) { + GILReleaseGuard gil; + CUarray arr; + if (CUDA_SUCCESS != (err = p_cuMipmappedArrayGetLevel(&arr, as_cu(h_mip), level))) { + return {}; + } + // Non-owning level view: storage belongs to the mipmap. Embed the mipmap + // handle so the parent outlives this level; the deleter does not destroy. + auto box = std::shared_ptr( + new ArrayBox{arr, h_mip}, + [](const ArrayBox* b) { delete b; } + ); + return ArrayHandle(box, &box->resource); +} + +MipmappedArrayHandle create_mipmapped_array_handle(const CUDA_ARRAY3D_DESCRIPTOR& desc, + unsigned int num_levels) { + GILReleaseGuard gil; + CUmipmappedArray mip; + if (CUDA_SUCCESS != (err = p_cuMipmappedArrayCreate(&mip, &desc, num_levels))) { + return {}; + } + auto box = std::shared_ptr( + new MipmappedArrayBox{mip}, + [](const MipmappedArrayBox* b) { + GILReleaseGuard gil; + p_cuMipmappedArrayDestroy(b->resource); + delete b; + } + ); + return MipmappedArrayHandle(box, &box->resource); +} + +namespace { +TexObjectHandle make_tex_object_handle(const CUDA_RESOURCE_DESC& res, + const CUDA_TEXTURE_DESC& tex, + std::shared_ptr h_backing) { + GILReleaseGuard gil; + CUtexObject obj; + if (CUDA_SUCCESS != (err = p_cuTexObjectCreate(&obj, &res, &tex, nullptr))) { + return {}; + } + auto box = std::shared_ptr( + new TexObjectBox{TexObjectValue{obj}, std::move(h_backing)}, + [](const TexObjectBox* b) { + GILReleaseGuard gil; + p_cuTexObjectDestroy(b->resource.raw); + delete b; + } + ); + return TexObjectHandle(box, &box->resource); +} +} // namespace + +TexObjectHandle create_tex_object_handle_array(const CUDA_RESOURCE_DESC& res, + const CUDA_TEXTURE_DESC& tex, + const ArrayHandle& h_backing) { + return make_tex_object_handle(res, tex, h_backing); +} + +TexObjectHandle create_tex_object_handle_mipmap(const CUDA_RESOURCE_DESC& res, + const CUDA_TEXTURE_DESC& tex, + const MipmappedArrayHandle& h_backing) { + return make_tex_object_handle(res, tex, h_backing); +} + +TexObjectHandle create_tex_object_handle_linear(const CUDA_RESOURCE_DESC& res, + const CUDA_TEXTURE_DESC& tex, + const DevicePtrHandle& h_backing) { + return make_tex_object_handle(res, tex, h_backing); +} + +SurfObjectHandle create_surf_object_handle(const CUDA_RESOURCE_DESC& res, + const ArrayHandle& h_backing) { + GILReleaseGuard gil; + CUsurfObject obj; + if (CUDA_SUCCESS != (err = p_cuSurfObjectCreate(&obj, &res))) { + return {}; + } + auto box = std::shared_ptr( + new SurfObjectBox{SurfObjectValue{obj}, h_backing}, + [](const SurfObjectBox* b) { + GILReleaseGuard gil; + p_cuSurfObjectDestroy(b->resource.raw); + delete b; + } + ); + return SurfObjectHandle(box, &box->resource); +} + // ============================================================================ // SM resource split wrapper // ============================================================================ diff --git a/cuda_core/cuda/core/_cpp/resource_handles.hpp b/cuda_core/cuda/core/_cpp/resource_handles.hpp index 32a88f0b3cd..08a8aeac056 100644 --- a/cuda_core/cuda/core/_cpp/resource_handles.hpp +++ b/cuda_core/cuda/core/_cpp/resource_handles.hpp @@ -36,6 +36,14 @@ struct TaggedHandle { using NvvmProgramValue = TaggedHandle; using NvJitLinkValue = TaggedHandle; +// CUtexObject, CUsurfObject and CUdeviceptr are all `unsigned long long`, so +// shared_ptr et al. would be the *same* C++ type as +// DevicePtrHandle (and each other), collapsing the as_cu/as_intptr/as_py +// overload sets. Tag them to keep each handle type distinct, exactly as the +// NVVM / nvJitLink handles above do. +using TexObjectValue = TaggedHandle; +using SurfObjectValue = TaggedHandle; + // ============================================================================ // Thread-local error handling // ============================================================================ @@ -108,6 +116,17 @@ extern decltype(&cuLinkDestroy) p_cuLinkDestroy; extern decltype(&cuGraphicsUnmapResources) p_cuGraphicsUnmapResources; extern decltype(&cuGraphicsUnregisterResource) p_cuGraphicsUnregisterResource; +// Texture / surface / array (PR #467) +extern decltype(&cuArray3DCreate) p_cuArray3DCreate; +extern decltype(&cuArrayDestroy) p_cuArrayDestroy; +extern decltype(&cuMipmappedArrayCreate) p_cuMipmappedArrayCreate; +extern decltype(&cuMipmappedArrayDestroy) p_cuMipmappedArrayDestroy; +extern decltype(&cuMipmappedArrayGetLevel) p_cuMipmappedArrayGetLevel; +extern decltype(&cuTexObjectCreate) p_cuTexObjectCreate; +extern decltype(&cuTexObjectDestroy) p_cuTexObjectDestroy; +extern decltype(&cuSurfObjectCreate) p_cuSurfObjectCreate; +extern decltype(&cuSurfObjectDestroy) p_cuSurfObjectDestroy; + // SM resource split (13.1+ — may be null on older drivers/bindings) #if CUDA_VERSION >= 13010 extern decltype(&cuDevSmResourceSplit) p_cuDevSmResourceSplit; @@ -171,6 +190,10 @@ using NvvmProgramHandle = std::shared_ptr; using NvJitLinkHandle = std::shared_ptr; using CuLinkHandle = std::shared_ptr; using FileDescriptorHandle = std::shared_ptr; +using ArrayHandle = std::shared_ptr; +using MipmappedArrayHandle = std::shared_ptr; +using TexObjectHandle = std::shared_ptr; +using SurfObjectHandle = std::shared_ptr; // ============================================================================ @@ -530,6 +553,61 @@ FileDescriptorHandle create_fd_handle(int fd); // Create a non-owning file descriptor handle (caller manages the fd). FileDescriptorHandle create_fd_handle_ref(int fd); +// ============================================================================ +// Array / mipmapped-array / texture / surface handle functions (PR #467) +// +// These resources are managed exactly like every other cuda.core resource: +// the owning handle's deleter calls the matching cu*Destroy with the GIL +// released, structural dependencies are embedded in the box (so a backing +// resource always outlives a texture/surface/level built on it), and +// creation returns an empty handle + thread-local error on failure. +// ============================================================================ + +// Create an owning CUDA array via cuArray3DCreate. +// When the last reference is released, cuArrayDestroy is called automatically. +// Returns empty handle on error (caller must check). +ArrayHandle create_array_handle(const CUDA_ARRAY3D_DESCRIPTOR& desc); + +// Create a non-owning array handle (references an existing CUarray). +// Use for arrays owned elsewhere (e.g. graphics interop). Never destroyed here. +ArrayHandle create_array_handle_ref(CUarray arr); + +// Create an owning array handle adopting an existing CUarray. +// When the last reference is released, cuArrayDestroy is called automatically. +ArrayHandle create_array_handle_owning(CUarray arr); + +// Create a non-owning handle to a mipmap level via cuMipmappedArrayGetLevel. +// The level CUarray is owned by the mipmap; the parent MipmappedArrayHandle is +// embedded in the box so it outlives the level view. No destroy in the deleter. +// Returns empty handle on error (caller must check). +ArrayHandle create_array_level_handle(const MipmappedArrayHandle& h_mip, unsigned int level); + +// Create an owning mipmapped array via cuMipmappedArrayCreate. +// When the last reference is released, cuMipmappedArrayDestroy is called. +// Returns empty handle on error (caller must check). +MipmappedArrayHandle create_mipmapped_array_handle(const CUDA_ARRAY3D_DESCRIPTOR& desc, + unsigned int num_levels); + +// Create an owning texture object via cuTexObjectCreate, embedding the backing +// resource handle (array / mipmapped array / linear-or-pitch2d device pointer) +// so the backing always outlives the texture. cuTexObjectDestroy runs in the +// deleter. Returns empty handle on error (caller must check). +TexObjectHandle create_tex_object_handle_array(const CUDA_RESOURCE_DESC& res, + const CUDA_TEXTURE_DESC& tex, + const ArrayHandle& h_backing); +TexObjectHandle create_tex_object_handle_mipmap(const CUDA_RESOURCE_DESC& res, + const CUDA_TEXTURE_DESC& tex, + const MipmappedArrayHandle& h_backing); +TexObjectHandle create_tex_object_handle_linear(const CUDA_RESOURCE_DESC& res, + const CUDA_TEXTURE_DESC& tex, + const DevicePtrHandle& h_backing); + +// Create an owning surface object via cuSurfObjectCreate, embedding the backing +// array handle so it outlives the surface. cuSurfObjectDestroy runs in the +// deleter. Returns empty handle on error (caller must check). +SurfObjectHandle create_surf_object_handle(const CUDA_RESOURCE_DESC& res, + const ArrayHandle& h_backing); + // ============================================================================ // Overloaded helper functions to extract raw resources from handles // ============================================================================ @@ -595,6 +673,24 @@ inline CUlinkState as_cu(const CuLinkHandle& h) noexcept { return h ? *h : nullptr; } +inline CUarray as_cu(const ArrayHandle& h) noexcept { + return h ? *h : nullptr; +} + +inline CUmipmappedArray as_cu(const MipmappedArrayHandle& h) noexcept { + return h ? *h : nullptr; +} + +// CUtexObject / CUsurfObject are integer-valued (like CUdeviceptr); null is 0. +// The raw value lives in the tagged wrapper's `raw` field. +inline CUtexObject as_cu(const TexObjectHandle& h) noexcept { + return h ? h->raw : 0; +} + +inline CUsurfObject as_cu(const SurfObjectHandle& h) noexcept { + return h ? h->raw : 0; +} + // as_intptr() - extract handle as intptr_t for Python interop // Using signed intptr_t per C standard convention and issue #1342 inline std::intptr_t as_intptr(const ContextHandle& h) noexcept { @@ -661,6 +757,22 @@ inline std::intptr_t as_intptr(const FileDescriptorHandle& h) noexcept { return h ? static_cast(*h) : -1; } +inline std::intptr_t as_intptr(const ArrayHandle& h) noexcept { + return reinterpret_cast(as_cu(h)); +} + +inline std::intptr_t as_intptr(const MipmappedArrayHandle& h) noexcept { + return reinterpret_cast(as_cu(h)); +} + +inline std::intptr_t as_intptr(const TexObjectHandle& h) noexcept { + return static_cast(as_cu(h)); +} + +inline std::intptr_t as_intptr(const SurfObjectHandle& h) noexcept { + return static_cast(as_cu(h)); +} + // as_py() - convert handle to Python wrapper object (returns new reference) #if PY_VERSION_HEX < 0x030D0000 extern "C" int _Py_IsFinalizing(void); @@ -776,6 +888,22 @@ inline PyObject* as_py(const FileDescriptorHandle& h) noexcept { return PyLong_FromSsize_t(as_intptr(h)); } +inline PyObject* as_py(const ArrayHandle& h) noexcept { + return detail::make_py("cuda.bindings.driver", "CUarray", as_intptr(h)); +} + +inline PyObject* as_py(const MipmappedArrayHandle& h) noexcept { + return detail::make_py("cuda.bindings.driver", "CUmipmappedArray", as_intptr(h)); +} + +inline PyObject* as_py(const TexObjectHandle& h) noexcept { + return detail::make_py("cuda.bindings.driver", "CUtexObject", as_intptr(h)); +} + +inline PyObject* as_py(const SurfObjectHandle& h) noexcept { + return detail::make_py("cuda.bindings.driver", "CUsurfObject", as_intptr(h)); +} + // ============================================================================ // SM resource split wrapper (13.1+) // diff --git a/cuda_core/cuda/core/_mipmapped_array.pxd b/cuda_core/cuda/core/_mipmapped_array.pxd new file mode 100644 index 00000000000..be0d8f00966 --- /dev/null +++ b/cuda_core/cuda/core/_mipmapped_array.pxd @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from cuda.bindings cimport cydriver +from cuda.core._resource_handles cimport MipmappedArrayHandle + + +cdef class MipmappedArray: + + cdef: + MipmappedArrayHandle _handle + tuple _shape # (w,), (w, h), or (w, h, d) + cydriver.CUarray_format _format + unsigned int _num_channels # 1, 2, or 4 + unsigned int _num_levels + int _device_id + bint _surface_load_store + + cpdef close(self) diff --git a/cuda_core/cuda/core/_mipmapped_array.pyi b/cuda_core/cuda/core/_mipmapped_array.pyi new file mode 100644 index 00000000000..63799b86161 --- /dev/null +++ b/cuda_core/cuda/core/_mipmapped_array.pyi @@ -0,0 +1,111 @@ +# This file was generated by stubgen-pyx v0.2.6 from cuda_core/cuda/core/_mipmapped_array.pyx + +from __future__ import annotations + + +class MipmappedArray: + """A mipmapped CUDA array for texture/surface access across levels. + + Wraps ``CUmipmappedArray``. Each mip level is a distinct, hardware-laid-out + allocation accessible only via a :class:`TextureObject` (or by retrieving + the level's :class:`CUDAArray` and binding it as a :class:`SurfaceObject`). + Destroying the :class:`MipmappedArray` destroys all level arrays + implicitly, so the :class:`CUDAArray` instances returned by :meth:`get_level` + are non-owning and hold a strong reference back to their parent. + + Construct via :meth:`from_descriptor`. + """ + + def close(self): + """Release this object's reference to the underlying ``CUmipmappedArray``. + + Destruction (``cuMipmappedArrayDestroy``) happens via the handle's + deleter when the last reference is dropped. A level :class:`CUDAArray` + from :meth:`get_level` holds its own reference to this mipmap's storage, + so it stays valid until both it and this object are released. Idempotent. + """ + + def __init__(self, *args, **kwargs): + ... + + @classmethod + def from_descriptor(cls, *, shape, format, num_channels, num_levels, is_surface_load_store=False): + """Allocate a new mipmapped CUDA array. + + Parameters + ---------- + shape : tuple of int + ``(width,)``, ``(width, height)``, or ``(width, height, depth)`` + in elements, for the base (level 0) mip. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + num_levels : int + Number of mip levels to allocate; must be >= 1. The driver caps + this at the log2 of the largest dimension; passing a larger value + yields a driver error. + is_surface_load_store : bool + If True, allocate with ``CUDA_ARRAY3D_SURFACE_LDST`` so individual + levels (obtained via :meth:`get_level`) can be bound as + :class:`SurfaceObject` for kernel-side writes. Default False. + + Returns + ------- + MipmappedArray + """ + + def get_level(self, level): + """Return a non-owning :class:`CUDAArray` view of the given mip level. + + Parameters + ---------- + level : int + Mip level index in ``[0, num_levels)``. + + Returns + ------- + CUDAArray + A non-owning :class:`CUDAArray` wrapping the level's ``CUarray``. + The :class:`MipmappedArray` is kept alive for the lifetime of the + returned :class:`CUDAArray`; the underlying storage is released only + when this :class:`MipmappedArray` is destroyed. + """ + + @property + def handle(self): + """The underlying ``CUmipmappedArray`` as an integer.""" + + @property + def shape(self): + """Base-level (level 0) allocation shape, in elements.""" + + @property + def format(self): + """The element :class:`ArrayFormat`.""" + + @property + def num_channels(self): + """Channels per element (1, 2, or 4).""" + + @property + def num_levels(self): + """Number of mip levels.""" + + @property + def is_surface_load_store(self): + """True if this mipmap (and each of its levels) was created with + ``CUDA_ARRAY3D_SURFACE_LDST`` and can back a :class:`SurfaceObject`.""" + + @property + def device(self): + """The :class:`Device` this mipmap was allocated on.""" + + def __enter__(self): + ... + + def __exit__(self, exc_type, exc, tb): + ... + + def __repr__(self): + ... \ No newline at end of file diff --git a/cuda_core/cuda/core/_mipmapped_array.pyx b/cuda_core/cuda/core/_mipmapped_array.pyx new file mode 100644 index 00000000000..2abffe64ca0 --- /dev/null +++ b/cuda_core/cuda/core/_mipmapped_array.pyx @@ -0,0 +1,203 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from libc.string cimport memset + +from cuda.bindings cimport cydriver +from cuda.core._array cimport _array_from_handle +from cuda.core._array import ArrayFormat, _validate_array_shape, _validate_format_channels +from cuda.core._resource_handles cimport ( + ArrayHandle, + MipmappedArrayHandle, + as_intptr, + create_array_level_handle, + create_mipmapped_array_handle, + get_last_error, +) +from cuda.core._utils.cuda_utils cimport ( + HANDLE_RETURN, + _get_current_device_id, +) + + +cdef class MipmappedArray: + """A mipmapped CUDA array for texture/surface access across levels. + + Wraps ``CUmipmappedArray``. Each mip level is a distinct, hardware-laid-out + allocation accessible only via a :class:`TextureObject` (or by retrieving + the level's :class:`CUDAArray` and binding it as a :class:`SurfaceObject`). + Destroying the :class:`MipmappedArray` destroys all level arrays + implicitly, so the :class:`CUDAArray` instances returned by :meth:`get_level` + are non-owning and hold a strong reference back to their parent. + + Construct via :meth:`from_descriptor`. + """ + + def __init__(self, *args, **kwargs): + raise RuntimeError( + "MipmappedArray cannot be instantiated directly. " + "Use MipmappedArray.from_descriptor()." + ) + + @classmethod + def from_descriptor( + cls, *, shape, format, num_channels, num_levels, is_surface_load_store=False + ): + """Allocate a new mipmapped CUDA array. + + Parameters + ---------- + shape : tuple of int + ``(width,)``, ``(width, height)``, or ``(width, height, depth)`` + in elements, for the base (level 0) mip. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + num_levels : int + Number of mip levels to allocate; must be >= 1. The driver caps + this at the log2 of the largest dimension; passing a larger value + yields a driver error. + is_surface_load_store : bool + If True, allocate with ``CUDA_ARRAY3D_SURFACE_LDST`` so individual + levels (obtained via :meth:`get_level`) can be bound as + :class:`SurfaceObject` for kernel-side writes. Default False. + + Returns + ------- + MipmappedArray + """ + _validate_format_channels(format, num_channels) + shape_t = _validate_array_shape(shape) + + levels = int(num_levels) + if levels < 1: + raise ValueError(f"num_levels must be >= 1, got {levels}") + + cdef cydriver.CUarray_format c_format = format + cdef cydriver.CUDA_ARRAY3D_DESCRIPTOR desc3d + cdef int rank = len(shape_t) + cdef unsigned int flags = ( + cydriver.CUDA_ARRAY3D_SURFACE_LDST if is_surface_load_store else 0 + ) + cdef unsigned int c_levels = levels + + # Mipmap creation uses the 3D descriptor regardless of rank; lower-rank + # shapes use Height=0/Depth=0 sentinels, matching cuArray3DCreate. + memset(&desc3d, 0, sizeof(desc3d)) + desc3d.Width = shape_t[0] + desc3d.Height = (shape_t[1] if rank >= 2 else 0) + desc3d.Depth = (shape_t[2] if rank >= 3 else 0) + desc3d.Format = c_format + desc3d.NumChannels = num_channels + desc3d.Flags = flags + + cdef MipmappedArrayHandle h = create_mipmapped_array_handle(desc3d, c_levels) + if not h: + HANDLE_RETURN(get_last_error()) + + cdef MipmappedArray self = cls.__new__(cls) + self._handle = h + self._shape = shape_t + self._format = c_format + self._num_channels = num_channels + self._num_levels = levels + self._surface_load_store = bool(is_surface_load_store) + self._device_id = _get_current_device_id() + return self + + def get_level(self, level): + """Return a non-owning :class:`CUDAArray` view of the given mip level. + + Parameters + ---------- + level : int + Mip level index in ``[0, num_levels)``. + + Returns + ------- + CUDAArray + A non-owning :class:`CUDAArray` wrapping the level's ``CUarray``. + The :class:`MipmappedArray` is kept alive for the lifetime of the + returned :class:`CUDAArray`; the underlying storage is released only + when this :class:`MipmappedArray` is destroyed. + """ + lvl = int(level) + if lvl < 0: + raise ValueError(f"level must be >= 0, got {lvl}") + if lvl >= self._num_levels: + raise ValueError( + f"level ({lvl}) must be < num_levels ({self._num_levels})" + ) + + cdef ArrayHandle h_level = create_array_level_handle(self._handle, lvl) + if not h_level: + HANDLE_RETURN(get_last_error()) + # The returned CUDAArray is non-owning; its C++ box embeds this mipmap's + # handle, so the parent's storage structurally outlives the level view + # (no Python parent reference needed). + return _array_from_handle(h_level, self._device_id) + + @property + def handle(self): + """The underlying ``CUmipmappedArray`` as an integer.""" + return as_intptr(self._handle) + + @property + def shape(self): + """Base-level (level 0) allocation shape, in elements.""" + return self._shape + + @property + def format(self): + """The element :class:`ArrayFormat`.""" + return ArrayFormat(self._format) + + @property + def num_channels(self): + """Channels per element (1, 2, or 4).""" + return self._num_channels + + @property + def num_levels(self): + """Number of mip levels.""" + return int(self._num_levels) + + @property + def is_surface_load_store(self): + """True if this mipmap (and each of its levels) was created with + ``CUDA_ARRAY3D_SURFACE_LDST`` and can back a :class:`SurfaceObject`.""" + return self._surface_load_store + + @property + def device(self): + """The :class:`Device` this mipmap was allocated on.""" + from cuda.core._device import Device + return Device(self._device_id) + + cpdef close(self): + """Release this object's reference to the underlying ``CUmipmappedArray``. + + Destruction (``cuMipmappedArrayDestroy``) happens via the handle's + deleter when the last reference is dropped. A level :class:`CUDAArray` + from :meth:`get_level` holds its own reference to this mipmap's storage, + so it stays valid until both it and this object are released. Idempotent. + """ + self._handle.reset() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + self.close() + + def __repr__(self): + return ( + f"MipmappedArray(shape={self._shape}, " + f"format={ArrayFormat(self._format).name}, " + f"num_channels={self._num_channels}, " + f"num_levels={self._num_levels})" + ) diff --git a/cuda_core/cuda/core/_resource_handles.pxd b/cuda_core/cuda/core/_resource_handles.pxd index 0ed3d6e5942..88d6e8c4762 100644 --- a/cuda_core/cuda/core/_resource_handles.pxd +++ b/cuda_core/cuda/core/_resource_handles.pxd @@ -43,6 +43,18 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core": ctypedef shared_ptr[const cydriver.CUlinkState] CuLinkHandle ctypedef shared_ptr[const int] FileDescriptorHandle + ctypedef shared_ptr[const cydriver.CUarray] ArrayHandle + ctypedef shared_ptr[const cydriver.CUmipmappedArray] MipmappedArrayHandle + + # CUtexObject / CUsurfObject are both `unsigned long long` (as is CUdeviceptr), + # so they are wrapped in distinct tagged value types to keep each handle's + # as_cu/as_intptr/as_py overloads distinct. + cppclass TexObjectValue "cuda_core::TexObjectValue": + pass + cppclass SurfObjectValue "cuda_core::SurfObjectValue": + pass + ctypedef shared_ptr[const TexObjectValue] TexObjectHandle + ctypedef shared_ptr[const SurfObjectValue] SurfObjectHandle # as_cu() - extract the raw CUDA handle (inline C++) cydriver.CUcontext as_cu(ContextHandle h) noexcept nogil @@ -60,6 +72,10 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core": cynvvm.nvvmProgram as_cu(NvvmProgramHandle h) noexcept nogil cynvjitlink.nvJitLinkHandle as_cu(NvJitLinkHandle h) noexcept nogil cydriver.CUlinkState as_cu(CuLinkHandle h) noexcept nogil + cydriver.CUarray as_cu(ArrayHandle h) noexcept nogil + cydriver.CUmipmappedArray as_cu(MipmappedArrayHandle h) noexcept nogil + cydriver.CUtexObject as_cu(TexObjectHandle h) noexcept nogil + cydriver.CUsurfObject as_cu(SurfObjectHandle h) noexcept nogil # as_intptr() - extract handle as intptr_t for Python interop (inline C++) intptr_t as_intptr(ContextHandle h) noexcept nogil @@ -78,6 +94,10 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core": intptr_t as_intptr(NvJitLinkHandle h) noexcept nogil intptr_t as_intptr(CuLinkHandle h) noexcept nogil intptr_t as_intptr(FileDescriptorHandle h) noexcept nogil + intptr_t as_intptr(ArrayHandle h) noexcept nogil + intptr_t as_intptr(MipmappedArrayHandle h) noexcept nogil + intptr_t as_intptr(TexObjectHandle h) noexcept nogil + intptr_t as_intptr(SurfObjectHandle h) noexcept nogil # as_py() - convert handle to Python wrapper object (inline C++; requires GIL) object as_py(ContextHandle h) @@ -96,6 +116,10 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core": object as_py(NvJitLinkHandle h) object as_py(CuLinkHandle h) object as_py(FileDescriptorHandle h) + object as_py(ArrayHandle h) + object as_py(MipmappedArrayHandle h) + object as_py(TexObjectHandle h) + object as_py(SurfObjectHandle h) # ============================================================================= @@ -224,6 +248,25 @@ cdef CuLinkHandle create_culink_handle_ref(cydriver.CUlinkState state) except+ n cdef FileDescriptorHandle create_fd_handle(int fd) except+ nogil cdef FileDescriptorHandle create_fd_handle_ref(int fd) except+ nogil +# Array / mipmapped-array / texture / surface handles (PR #467) +cdef ArrayHandle create_array_handle(const cydriver.CUDA_ARRAY3D_DESCRIPTOR& desc) except+ nogil +cdef ArrayHandle create_array_handle_ref(cydriver.CUarray arr) except+ nogil +cdef ArrayHandle create_array_handle_owning(cydriver.CUarray arr) except+ nogil +cdef ArrayHandle create_array_level_handle(const MipmappedArrayHandle& h_mip, unsigned int level) except+ nogil +cdef MipmappedArrayHandle create_mipmapped_array_handle( + const cydriver.CUDA_ARRAY3D_DESCRIPTOR& desc, unsigned int num_levels) except+ nogil +cdef TexObjectHandle create_tex_object_handle_array( + const cydriver.CUDA_RESOURCE_DESC& res, const cydriver.CUDA_TEXTURE_DESC& tex, + const ArrayHandle& h_backing) except+ nogil +cdef TexObjectHandle create_tex_object_handle_mipmap( + const cydriver.CUDA_RESOURCE_DESC& res, const cydriver.CUDA_TEXTURE_DESC& tex, + const MipmappedArrayHandle& h_backing) except+ nogil +cdef TexObjectHandle create_tex_object_handle_linear( + const cydriver.CUDA_RESOURCE_DESC& res, const cydriver.CUDA_TEXTURE_DESC& tex, + const DevicePtrHandle& h_backing) except+ nogil +cdef SurfObjectHandle create_surf_object_handle( + const cydriver.CUDA_RESOURCE_DESC& res, const ArrayHandle& h_backing) except+ nogil + # SM resource split (13.1+ — calls through function pointer, safe on older bindings) # groupParams is void* here to avoid referencing CU_DEV_SM_RESOURCE_GROUP_PARAMS # (which doesn't exist in cuda-bindings 13.0 .pxd). The C++ side casts it. diff --git a/cuda_core/cuda/core/_resource_handles.pyi b/cuda_core/cuda/core/_resource_handles.pyi index 490073c9fd1..c6d1652f4ba 100644 --- a/cuda_core/cuda/core/_resource_handles.pyi +++ b/cuda_core/cuda/core/_resource_handles.pyi @@ -19,4 +19,8 @@ NvrtcProgramHandle = shared_ptr NvvmProgramHandle = shared_ptr NvJitLinkHandle = shared_ptr CuLinkHandle = shared_ptr -FileDescriptorHandle = shared_ptr \ No newline at end of file +FileDescriptorHandle = shared_ptr +ArrayHandle = shared_ptr +MipmappedArrayHandle = shared_ptr +TexObjectHandle = shared_ptr +SurfObjectHandle = shared_ptr \ No newline at end of file diff --git a/cuda_core/cuda/core/_resource_handles.pyx b/cuda_core/cuda/core/_resource_handles.pyx index c87956f0c68..b874fba7d5c 100644 --- a/cuda_core/cuda/core/_resource_handles.pyx +++ b/cuda_core/cuda/core/_resource_handles.pyx @@ -202,6 +202,29 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core": unsigned int flags, void* groupParams) nogil bint has_sm_resource_split "cuda_core::has_sm_resource_split" () noexcept nogil + # Array / mipmapped-array / texture / surface handles (PR #467) + ArrayHandle create_array_handle "cuda_core::create_array_handle" ( + const cydriver.CUDA_ARRAY3D_DESCRIPTOR& desc) except+ nogil + ArrayHandle create_array_handle_ref "cuda_core::create_array_handle_ref" ( + cydriver.CUarray arr) except+ nogil + ArrayHandle create_array_handle_owning "cuda_core::create_array_handle_owning" ( + cydriver.CUarray arr) except+ nogil + ArrayHandle create_array_level_handle "cuda_core::create_array_level_handle" ( + const MipmappedArrayHandle& h_mip, unsigned int level) except+ nogil + MipmappedArrayHandle create_mipmapped_array_handle "cuda_core::create_mipmapped_array_handle" ( + const cydriver.CUDA_ARRAY3D_DESCRIPTOR& desc, unsigned int num_levels) except+ nogil + TexObjectHandle create_tex_object_handle_array "cuda_core::create_tex_object_handle_array" ( + const cydriver.CUDA_RESOURCE_DESC& res, const cydriver.CUDA_TEXTURE_DESC& tex, + const ArrayHandle& h_backing) except+ nogil + TexObjectHandle create_tex_object_handle_mipmap "cuda_core::create_tex_object_handle_mipmap" ( + const cydriver.CUDA_RESOURCE_DESC& res, const cydriver.CUDA_TEXTURE_DESC& tex, + const MipmappedArrayHandle& h_backing) except+ nogil + TexObjectHandle create_tex_object_handle_linear "cuda_core::create_tex_object_handle_linear" ( + const cydriver.CUDA_RESOURCE_DESC& res, const cydriver.CUDA_TEXTURE_DESC& tex, + const DevicePtrHandle& h_backing) except+ nogil + SurfObjectHandle create_surf_object_handle "cuda_core::create_surf_object_handle" ( + const cydriver.CUDA_RESOURCE_DESC& res, const ArrayHandle& h_backing) except+ nogil + # ============================================================================= # CUDA Driver API capsule @@ -284,6 +307,17 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core": void* p_cuGraphicsUnmapResources "reinterpret_cast(cuda_core::p_cuGraphicsUnmapResources)" void* p_cuGraphicsUnregisterResource "reinterpret_cast(cuda_core::p_cuGraphicsUnregisterResource)" + # Texture / surface / array (PR #467) + void* p_cuArray3DCreate "reinterpret_cast(cuda_core::p_cuArray3DCreate)" + void* p_cuArrayDestroy "reinterpret_cast(cuda_core::p_cuArrayDestroy)" + void* p_cuMipmappedArrayCreate "reinterpret_cast(cuda_core::p_cuMipmappedArrayCreate)" + void* p_cuMipmappedArrayDestroy "reinterpret_cast(cuda_core::p_cuMipmappedArrayDestroy)" + void* p_cuMipmappedArrayGetLevel "reinterpret_cast(cuda_core::p_cuMipmappedArrayGetLevel)" + void* p_cuTexObjectCreate "reinterpret_cast(cuda_core::p_cuTexObjectCreate)" + void* p_cuTexObjectDestroy "reinterpret_cast(cuda_core::p_cuTexObjectDestroy)" + void* p_cuSurfObjectCreate "reinterpret_cast(cuda_core::p_cuSurfObjectCreate)" + void* p_cuSurfObjectDestroy "reinterpret_cast(cuda_core::p_cuSurfObjectDestroy)" + # SM resource split (13.1+) void* p_cuDevSmResourceSplit "reinterpret_cast(cuda_core::p_cuDevSmResourceSplit)" @@ -328,6 +362,10 @@ cdef void _init_driver_fn_pointers() noexcept: global p_cuLinkDestroy global p_cuGraphicsUnmapResources, p_cuGraphicsUnregisterResource global p_cuDevSmResourceSplit + global p_cuArray3DCreate, p_cuArrayDestroy + global p_cuMipmappedArrayCreate, p_cuMipmappedArrayDestroy, p_cuMipmappedArrayGetLevel + global p_cuTexObjectCreate, p_cuTexObjectDestroy + global p_cuSurfObjectCreate, p_cuSurfObjectDestroy # Context p_cuDevicePrimaryCtxRetain = _get_driver_fn("cuDevicePrimaryCtxRetain") @@ -388,6 +426,17 @@ cdef void _init_driver_fn_pointers() noexcept: p_cuGraphicsUnmapResources = _get_driver_fn("cuGraphicsUnmapResources") p_cuGraphicsUnregisterResource = _get_driver_fn("cuGraphicsUnregisterResource") + # Texture / surface / array (PR #467) + p_cuArray3DCreate = _get_driver_fn("cuArray3DCreate") + p_cuArrayDestroy = _get_driver_fn("cuArrayDestroy") + p_cuMipmappedArrayCreate = _get_driver_fn("cuMipmappedArrayCreate") + p_cuMipmappedArrayDestroy = _get_driver_fn("cuMipmappedArrayDestroy") + p_cuMipmappedArrayGetLevel = _get_driver_fn("cuMipmappedArrayGetLevel") + p_cuTexObjectCreate = _get_driver_fn("cuTexObjectCreate") + p_cuTexObjectDestroy = _get_driver_fn("cuTexObjectDestroy") + p_cuSurfObjectCreate = _get_driver_fn("cuSurfObjectCreate") + p_cuSurfObjectDestroy = _get_driver_fn("cuSurfObjectDestroy") + # SM resource split (13.1+ — may not exist in older cuda-bindings) p_cuDevSmResourceSplit = _get_optional_driver_fn("cuDevSmResourceSplit") diff --git a/cuda_core/cuda/core/_surface.pxd b/cuda_core/cuda/core/_surface.pxd new file mode 100644 index 00000000000..a96e9de4836 --- /dev/null +++ b/cuda_core/cuda/core/_surface.pxd @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from cuda.bindings cimport cydriver +from cuda.core._resource_handles cimport SurfObjectHandle + + +cdef class SurfaceObject: + + cdef: + # The backing CUDAArray is kept alive structurally by the C++ box behind + # this handle, not by _source_ref. + SurfObjectHandle _handle + object _source_ref # ResourceDescriptor, retained for introspection + int _device_id + + cpdef close(self) diff --git a/cuda_core/cuda/core/_surface.pyi b/cuda_core/cuda/core/_surface.pyi new file mode 100644 index 00000000000..e22e81c2e9c --- /dev/null +++ b/cuda_core/cuda/core/_surface.pyi @@ -0,0 +1,70 @@ +# This file was generated by stubgen-pyx v0.2.6 from cuda_core/cuda/core/_surface.pyx + +from __future__ import annotations + + +class SurfaceObject: + """A bindless surface handle for kernel-side typed load/store. + + Wraps ``cuSurfObjectCreate``. Unlike a :class:`TextureObject`, a surface + has no sampling state (no filtering, no addressing modes, no normalization); + kernels read and write through it using integer pixel coordinates. + + The backing :class:`CUDAArray` must have been created with + ``is_surface_load_store=True`` and is kept alive for the lifetime of this + object to prevent dangling handles. + + Construct via :meth:`from_array` or :meth:`from_descriptor`. Passes to + kernels as a 64-bit handle (via the ``handle`` property). + """ + + def close(self): + """Release this object's reference to the underlying ``CUsurfObject``. + + Destruction (``cuSurfObjectDestroy``) and release of the backing array + happen via the handle's deleter when the last reference is dropped. + Idempotent. + """ + + def __init__(self, *args, **kwargs): + ... + + @classmethod + def from_array(cls, array): + """Create a surface object directly from an :class:`CUDAArray`. + + The array must have been created with ``is_surface_load_store=True``. + """ + + @classmethod + def from_descriptor(cls, *, resource): + """Create a surface object from a :class:`ResourceDescriptor`. + + Parameters + ---------- + resource : ResourceDescriptor + Must wrap an :class:`CUDAArray` allocated with + ``is_surface_load_store=True``. Linear/pitch2d resources are not + valid surface backings. + """ + + @property + def handle(self): + """The underlying ``CUsurfObject`` as an integer (64-bit kernel arg).""" + + @property + def resource(self): + """The :class:`ResourceDescriptor` this surface was built from.""" + + @property + def device(self): + ... + + def __enter__(self): + ... + + def __exit__(self, exc_type, exc, tb): + ... + + def __repr__(self): + ... \ No newline at end of file diff --git a/cuda_core/cuda/core/_surface.pyx b/cuda_core/cuda/core/_surface.pyx new file mode 100644 index 00000000000..10a01a31aad --- /dev/null +++ b/cuda_core/cuda/core/_surface.pyx @@ -0,0 +1,132 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from libc.string cimport memset + +from cuda.bindings cimport cydriver +from cuda.core._array cimport CUDAArray +from cuda.core._resource_handles cimport ( + SurfObjectHandle, + as_cu, + as_intptr, + create_surf_object_handle, + get_last_error, +) +from cuda.core._texture import ResourceDescriptor +from cuda.core._utils.cuda_utils cimport ( + HANDLE_RETURN, + _get_current_device_id, +) + + +cdef class SurfaceObject: + """A bindless surface handle for kernel-side typed load/store. + + Wraps ``cuSurfObjectCreate``. Unlike a :class:`TextureObject`, a surface + has no sampling state (no filtering, no addressing modes, no normalization); + kernels read and write through it using integer pixel coordinates. + + The backing :class:`CUDAArray` must have been created with + ``is_surface_load_store=True`` and is kept alive for the lifetime of this + object to prevent dangling handles. + + Construct via :meth:`from_array` or :meth:`from_descriptor`. Passes to + kernels as a 64-bit handle (via the ``handle`` property). + """ + + def __init__(self, *args, **kwargs): + raise RuntimeError( + "SurfaceObject cannot be instantiated directly. " + "Use SurfaceObject.from_array() or SurfaceObject.from_descriptor()." + ) + + @classmethod + def from_array(cls, array): + """Create a surface object directly from an :class:`CUDAArray`. + + The array must have been created with ``is_surface_load_store=True``. + """ + if not isinstance(array, CUDAArray): + raise TypeError(f"array must be an CUDAArray, got {type(array).__name__}") + return cls.from_descriptor(resource=ResourceDescriptor.from_array(array)) + + @classmethod + def from_descriptor(cls, *, resource): + """Create a surface object from a :class:`ResourceDescriptor`. + + Parameters + ---------- + resource : ResourceDescriptor + Must wrap an :class:`CUDAArray` allocated with + ``is_surface_load_store=True``. Linear/pitch2d resources are not + valid surface backings. + """ + if not isinstance(resource, ResourceDescriptor): + raise TypeError( + f"resource must be a ResourceDescriptor, got " + f"{type(resource).__name__}" + ) + if resource.kind != "array": + raise ValueError( + f"SurfaceObject requires an array-backed ResourceDescriptor, " + f"got kind={resource.kind!r}" + ) + + cdef CUDAArray arr = resource.source + if not arr.is_surface_load_store: + raise ValueError( + "CUDAArray must be created with is_surface_load_store=True to be " + "bound as a SurfaceObject" + ) + + cdef cydriver.CUDA_RESOURCE_DESC res_desc + memset(&res_desc, 0, sizeof(res_desc)) + res_desc.resType = cydriver.CU_RESOURCE_TYPE_ARRAY + res_desc.res.array.hArray = as_cu(arr._handle) + + cdef SurfObjectHandle h = create_surf_object_handle(res_desc, arr._handle) + if not h: + HANDLE_RETURN(get_last_error()) + + cdef SurfaceObject self = cls.__new__(cls) + self._handle = h + self._source_ref = resource + self._device_id = _get_current_device_id() + return self + + @property + def handle(self): + """The underlying ``CUsurfObject`` as an integer (64-bit kernel arg).""" + return as_intptr(self._handle) + + @property + def resource(self): + """The :class:`ResourceDescriptor` this surface was built from.""" + return self._source_ref + + @property + def device(self): + from cuda.core._device import Device + return Device(self._device_id) + + cpdef close(self): + """Release this object's reference to the underlying ``CUsurfObject``. + + Destruction (``cuSurfObjectDestroy``) and release of the backing array + happen via the handle's deleter when the last reference is dropped. + Idempotent. + """ + self._handle.reset() + self._source_ref = None + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + self.close() + + def __repr__(self): + return f"SurfaceObject(handle=0x{as_intptr(self._handle):x})" diff --git a/cuda_core/cuda/core/_texture.pxd b/cuda_core/cuda/core/_texture.pxd new file mode 100644 index 00000000000..f8532a4dad5 --- /dev/null +++ b/cuda_core/cuda/core/_texture.pxd @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from cuda.bindings cimport cydriver +from cuda.core._resource_handles cimport TexObjectHandle + + +cdef class TextureObject: + + cdef: + # The backing resource (array / mipmap / device pointer) is kept alive + # structurally by the C++ box behind this handle, not by _source_ref. + TexObjectHandle _handle + object _source_ref # ResourceDescriptor, retained for introspection + object _texture_desc # original TextureDescriptor for introspection + int _device_id + + cpdef close(self) diff --git a/cuda_core/cuda/core/_texture.pyi b/cuda_core/cuda/core/_texture.pyi new file mode 100644 index 00000000000..26cd237bc5d --- /dev/null +++ b/cuda_core/cuda/core/_texture.pyi @@ -0,0 +1,263 @@ +# This file was generated by stubgen-pyx v0.2.6 from cuda_core/cuda/core/_texture.pyx + +from __future__ import annotations + +from dataclasses import dataclass +from enum import IntEnum + +from cuda.bindings import cydriver + + +class AddressMode(IntEnum): + """Boundary behavior for out-of-range texture coordinates.""" + WRAP = cydriver.CU_TR_ADDRESS_MODE_WRAP + CLAMP = cydriver.CU_TR_ADDRESS_MODE_CLAMP + MIRROR = cydriver.CU_TR_ADDRESS_MODE_MIRROR + BORDER = cydriver.CU_TR_ADDRESS_MODE_BORDER + +class FilterMode(IntEnum): + """Texel sampling mode.""" + POINT = cydriver.CU_TR_FILTER_MODE_POINT + LINEAR = cydriver.CU_TR_FILTER_MODE_LINEAR + +class ReadMode(IntEnum): + """How sampled values are returned to the kernel. + + - ``ELEMENT_TYPE``: return the raw element value (integer formats stay + integer, float stays float). + - ``NORMALIZED_FLOAT``: integer formats are promoted to a normalized + ``float`` in ``[0, 1]`` (unsigned) or ``[-1, 1]`` (signed). + Float formats are unaffected. + """ + ELEMENT_TYPE = 0 + NORMALIZED_FLOAT = 1 + +class ResourceDescriptor: + """Describes the memory backing a :class:`TextureObject`. + + Construct via the ``from_*`` classmethods: + + - :meth:`from_array` wraps a :class:`CUDAArray` (works for both + :class:`TextureObject` and :class:`SurfaceObject`). + - :meth:`from_mipmapped_array` wraps a :class:`MipmappedArray` for mipmapped + sampling (texture only, not surface). + - :meth:`from_linear` wraps a :class:`Buffer` as a typed 1D fetch. Texture + objects built from a linear resource do not support filtering, + normalized coordinates, or addressing modes. + - :meth:`from_pitch2d` wraps a :class:`Buffer` as a row-pitched 2D image. + Supports filtering and 2D addressing, but only 2D access. + + Linear and pitch2D resources cannot back a :class:`SurfaceObject` — those + require an :class:`CUDAArray` allocated with ``is_surface_load_store=True``. + """ + __slots__ = ('_kind', '_source', '_format', '_num_channels', '_size_bytes', '_width', '_height', '_pitch_bytes') + + def __init__(self): + ... + + @classmethod + def from_array(cls, array): + """Build a resource descriptor backed by a :class:`CUDAArray`.""" + + @classmethod + def from_mipmapped_array(cls, mipmapped_array): + """Build a resource descriptor backed by a :class:`MipmappedArray`. + + Suitable for binding to a :class:`TextureObject` for mipmapped + sampling. Not valid as a :class:`SurfaceObject` backing: surfaces + require a single :class:`CUDAArray` level (obtain via + :meth:`MipmappedArray.get_level`). + """ + + @classmethod + def from_linear(cls, buffer, *, format, num_channels, size_bytes=None): + """Build a resource descriptor for a linear (typed 1D) texture fetch. + + Parameters + ---------- + buffer : Buffer + Device-memory backing. Must remain alive for the lifetime of any + :class:`TextureObject` built from this descriptor. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + size_bytes : int, optional + Bytes of ``buffer`` to bind. Defaults to ``buffer.size``. Must not + exceed it. + + Notes + ----- + Texture objects built from a linear resource ignore the + :class:`TextureDescriptor` addressing/filtering fields — kernels read + through a typed 1D fetch with bounds checking only. + """ + + @classmethod + def from_pitch2d(cls, buffer, *, format, num_channels, width, height, pitch_bytes): + """Build a resource descriptor for a row-pitched 2D image. + + Parameters + ---------- + buffer : Buffer + Device-memory backing. Must remain alive for the lifetime of any + :class:`TextureObject` built from this descriptor. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + width : int + Image width, in elements. + height : int + Image height, in rows. + pitch_bytes : int + Distance between consecutive rows, in bytes. Must be at least + ``width * format_size * num_channels`` and meet the driver's + ``CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT``. + """ + + @property + def kind(self): + ... + + @property + def source(self): + ... + + @property + def format(self): + """The element :class:`ArrayFormat` (``None`` for array-backed).""" + + @property + def num_channels(self): + """Channels per element (``None`` for array-backed).""" + + @property + def size_bytes(self): + """Bytes bound for a linear resource (``None`` for other kinds).""" + + @property + def width(self): + """Pitch2D image width, in elements (``None`` for other kinds).""" + + @property + def height(self): + """Pitch2D image height, in rows (``None`` for other kinds).""" + + @property + def pitch_bytes(self): + """Pitch2D row pitch, in bytes (``None`` for other kinds).""" + + def __repr__(self): + ... + +@dataclass +class TextureDescriptor: + """Sampling state for a :class:`TextureObject` (mirrors ``CUDA_TEXTURE_DESC``). + + Attributes + ---------- + address_mode : tuple of AddressMode + Boundary behavior per axis. May be a single :class:`AddressMode` (applied + to all axes) or a tuple of 1-3 entries (one per dimension). + filter_mode : FilterMode + Texel sampling mode. Default ``POINT``. + read_mode : ReadMode + How sampled integer values are returned. Default ``ELEMENT_TYPE``. + normalized_coords : bool + If True, coordinates are in ``[0, 1]`` instead of pixel indices. + srgb : bool + If True, perform sRGB → linear conversion on read (8-bit formats only). + disable_trilinear_optimization : bool + If True, request exact trilinear filtering. + seamless_cubemap : bool + If True, enable seamless cubemap edge filtering. + max_anisotropy : int + Maximum anisotropy; 0 disables anisotropic filtering. + mipmap_filter_mode : FilterMode + Filtering between mipmap levels. Default ``POINT``. + mipmap_level_bias : float + min_mipmap_level_clamp : float + max_mipmap_level_clamp : float + border_color : tuple of float or None + 4-tuple used when ``address_mode`` includes ``BORDER``; ``None`` means + zero. + """ + address_mode: AddressMode | tuple[AddressMode, ...] = AddressMode.CLAMP + filter_mode: FilterMode = FilterMode.POINT + read_mode: ReadMode = ReadMode.ELEMENT_TYPE + normalized_coords: bool = False + srgb: bool = False + disable_trilinear_optimization: bool = False + seamless_cubemap: bool = False + max_anisotropy: int = 0 + mipmap_filter_mode: FilterMode = FilterMode.POINT + mipmap_level_bias: float = 0.0 + min_mipmap_level_clamp: float = 0.0 + max_mipmap_level_clamp: float = 0.0 + border_color: tuple[float, ...] | None = None + +class TextureObject: + """A bindless texture handle for kernel-side sampled reads. + + Wraps ``cuTexObjectCreate``. The underlying memory resource (e.g. the + :class:`CUDAArray` referenced by the descriptor) is kept alive for the + lifetime of this object to prevent dangling handles. + + Construct via :meth:`from_descriptor`. Passes to kernels as a 64-bit + handle (via the ``handle`` property). + """ + + def close(self): + """Release this object's reference to the underlying ``CUtexObject``. + + Destruction (``cuTexObjectDestroy``) and release of the backing resource + happen via the handle's deleter when the last reference is dropped. + Idempotent. + """ + + def __init__(self, *args, **kwargs): + ... + + @classmethod + def from_descriptor(cls, *, resource, texture_descriptor): + """Create a texture object from a resource + sampling descriptor. + + Parameters + ---------- + resource : ResourceDescriptor + texture_descriptor : TextureDescriptor + """ + + @property + def handle(self): + """The underlying ``CUtexObject`` as an integer (64-bit kernel arg).""" + + @property + def resource(self): + """The :class:`ResourceDescriptor` this texture was built from.""" + + @property + def texture_descriptor(self): + """The :class:`TextureDescriptor` this texture was built from.""" + + @property + def device(self): + ... + + def __enter__(self): + ... + + def __exit__(self, exc_type, exc, tb): + ... + + def __repr__(self): + ... +_TRSF_READ_AS_INTEGER = 1 +_TRSF_NORMALIZED_COORDINATES = 2 +_TRSF_SRGB = 16 +_TRSF_DISABLE_TRILINEAR_OPTIMIZATION = 32 +_TRSF_SEAMLESS_CUBEMAP = 64 + +def _normalize_address_modes(address_mode): + """Return a 3-tuple of AddressMode values from a scalar or 1-3 tuple.""" \ No newline at end of file diff --git a/cuda_core/cuda/core/_texture.pyx b/cuda_core/cuda/core/_texture.pyx new file mode 100644 index 00000000000..ad43024f1ec --- /dev/null +++ b/cuda_core/cuda/core/_texture.pyx @@ -0,0 +1,576 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from libc.stdint cimport intptr_t +from libc.string cimport memset + +from cuda.bindings cimport cydriver +from cuda.core._array cimport CUDAArray +from cuda.core._array import ArrayFormat, _FORMAT_ELEM_SIZE, _validate_format_channels +from cuda.core._memory._buffer cimport Buffer +from cuda.core._mipmapped_array cimport MipmappedArray +from cuda.core._mipmapped_array import MipmappedArray as _PyMipmappedArray +from cuda.core._resource_handles cimport ( + TexObjectHandle, + as_cu, + as_intptr, + create_tex_object_handle_array, + create_tex_object_handle_linear, + create_tex_object_handle_mipmap, + get_last_error, +) +from cuda.core._utils.cuda_utils cimport ( + HANDLE_RETURN, + _get_current_device_id, +) + +from dataclasses import dataclass +from enum import IntEnum + + +# Driver texture-descriptor flag bits (CU_TRSF_*). +_TRSF_READ_AS_INTEGER = 0x01 +_TRSF_NORMALIZED_COORDINATES = 0x02 +_TRSF_SRGB = 0x10 +_TRSF_DISABLE_TRILINEAR_OPTIMIZATION = 0x20 +_TRSF_SEAMLESS_CUBEMAP = 0x40 + + +class AddressMode(IntEnum): + """Boundary behavior for out-of-range texture coordinates.""" + WRAP = cydriver.CU_TR_ADDRESS_MODE_WRAP + CLAMP = cydriver.CU_TR_ADDRESS_MODE_CLAMP + MIRROR = cydriver.CU_TR_ADDRESS_MODE_MIRROR + BORDER = cydriver.CU_TR_ADDRESS_MODE_BORDER + + +class FilterMode(IntEnum): + """Texel sampling mode.""" + POINT = cydriver.CU_TR_FILTER_MODE_POINT + LINEAR = cydriver.CU_TR_FILTER_MODE_LINEAR + + +class ReadMode(IntEnum): + """How sampled values are returned to the kernel. + + - ``ELEMENT_TYPE``: return the raw element value (integer formats stay + integer, float stays float). + - ``NORMALIZED_FLOAT``: integer formats are promoted to a normalized + ``float`` in ``[0, 1]`` (unsigned) or ``[-1, 1]`` (signed). + Float formats are unaffected. + """ + ELEMENT_TYPE = 0 + NORMALIZED_FLOAT = 1 + + +class ResourceDescriptor: + """Describes the memory backing a :class:`TextureObject`. + + Construct via the ``from_*`` classmethods: + + - :meth:`from_array` wraps a :class:`CUDAArray` (works for both + :class:`TextureObject` and :class:`SurfaceObject`). + - :meth:`from_mipmapped_array` wraps a :class:`MipmappedArray` for mipmapped + sampling (texture only, not surface). + - :meth:`from_linear` wraps a :class:`Buffer` as a typed 1D fetch. Texture + objects built from a linear resource do not support filtering, + normalized coordinates, or addressing modes. + - :meth:`from_pitch2d` wraps a :class:`Buffer` as a row-pitched 2D image. + Supports filtering and 2D addressing, but only 2D access. + + Linear and pitch2D resources cannot back a :class:`SurfaceObject` — those + require an :class:`CUDAArray` allocated with ``is_surface_load_store=True``. + """ + + __slots__ = ( + "_kind", "_source", + "_format", "_num_channels", + "_size_bytes", + "_width", "_height", "_pitch_bytes", + ) + + def __init__(self): + raise RuntimeError( + "ResourceDescriptor cannot be instantiated directly. " + "Use ResourceDescriptor.from_* factories." + ) + + @classmethod + def from_array(cls, array): + """Build a resource descriptor backed by a :class:`CUDAArray`.""" + if not isinstance(array, CUDAArray): + raise TypeError(f"array must be an CUDAArray, got {type(array).__name__}") + self = cls.__new__(cls) + self._kind = "array" + self._source = array + self._format = None + self._num_channels = None + self._size_bytes = None + self._width = None + self._height = None + self._pitch_bytes = None + return self + + @classmethod + def from_mipmapped_array(cls, mipmapped_array): + """Build a resource descriptor backed by a :class:`MipmappedArray`. + + Suitable for binding to a :class:`TextureObject` for mipmapped + sampling. Not valid as a :class:`SurfaceObject` backing: surfaces + require a single :class:`CUDAArray` level (obtain via + :meth:`MipmappedArray.get_level`). + """ + if not isinstance(mipmapped_array, _PyMipmappedArray): + raise TypeError( + f"mipmapped_array must be a MipmappedArray, got " + f"{type(mipmapped_array).__name__}" + ) + self = cls.__new__(cls) + self._kind = "mipmapped_array" + self._source = mipmapped_array + self._format = None + self._num_channels = None + self._size_bytes = None + self._width = None + self._height = None + self._pitch_bytes = None + return self + + @classmethod + def from_linear(cls, buffer, *, format, num_channels, size_bytes=None): + """Build a resource descriptor for a linear (typed 1D) texture fetch. + + Parameters + ---------- + buffer : Buffer + Device-memory backing. Must remain alive for the lifetime of any + :class:`TextureObject` built from this descriptor. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + size_bytes : int, optional + Bytes of ``buffer`` to bind. Defaults to ``buffer.size``. Must not + exceed it. + + Notes + ----- + Texture objects built from a linear resource ignore the + :class:`TextureDescriptor` addressing/filtering fields — kernels read + through a typed 1D fetch with bounds checking only. + """ + if not isinstance(buffer, Buffer): + raise TypeError(f"buffer must be a Buffer, got {type(buffer).__name__}") + _validate_format_channels(format, num_channels) + + buf_size = int(buffer.size) + elem = _FORMAT_ELEM_SIZE[int(format)] * int(num_channels) + if size_bytes is None: + size = buf_size + else: + size = int(size_bytes) + if size > buf_size: + raise ValueError( + f"size_bytes ({size}) exceeds buffer.size ({buf_size})" + ) + if size < elem: + raise ValueError( + f"size_bytes ({size}) must be at least one element ({elem} bytes)" + ) + if size % elem != 0: + raise ValueError( + f"size_bytes ({size}) must be a multiple of element size " + f"({elem} bytes for {format.name} x {num_channels})" + ) + + self = cls.__new__(cls) + self._kind = "linear" + self._source = buffer + self._format = int(format) + self._num_channels = int(num_channels) + self._size_bytes = size + self._width = None + self._height = None + self._pitch_bytes = None + return self + + @classmethod + def from_pitch2d( + cls, buffer, *, format, num_channels, width, height, pitch_bytes + ): + """Build a resource descriptor for a row-pitched 2D image. + + Parameters + ---------- + buffer : Buffer + Device-memory backing. Must remain alive for the lifetime of any + :class:`TextureObject` built from this descriptor. + format : ArrayFormat + Element format. + num_channels : int + Channels per element. Must be 1, 2, or 4. + width : int + Image width, in elements. + height : int + Image height, in rows. + pitch_bytes : int + Distance between consecutive rows, in bytes. Must be at least + ``width * format_size * num_channels`` and meet the driver's + ``CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT``. + """ + if not isinstance(buffer, Buffer): + raise TypeError(f"buffer must be a Buffer, got {type(buffer).__name__}") + _validate_format_channels(format, num_channels) + + w = int(width) + h = int(height) + p = int(pitch_bytes) + if w < 1: + raise ValueError(f"width must be >= 1, got {w}") + if h < 1: + raise ValueError(f"height must be >= 1, got {h}") + elem = _FORMAT_ELEM_SIZE[int(format)] * int(num_channels) + min_pitch = w * elem + if p < min_pitch: + raise ValueError( + f"pitch_bytes ({p}) must be >= width * element_size ({min_pitch})" + ) + if p * h > int(buffer.size): + raise ValueError( + f"pitch_bytes * height ({p * h}) exceeds buffer.size ({int(buffer.size)})" + ) + + self = cls.__new__(cls) + self._kind = "pitch2d" + self._source = buffer + self._format = int(format) + self._num_channels = int(num_channels) + self._size_bytes = None + self._width = w + self._height = h + self._pitch_bytes = p + return self + + @property + def kind(self): + return self._kind + + @property + def source(self): + return self._source + + @property + def format(self): + """The element :class:`ArrayFormat` (``None`` for array-backed).""" + return None if self._format is None else ArrayFormat(self._format) + + @property + def num_channels(self): + """Channels per element (``None`` for array-backed).""" + return self._num_channels + + @property + def size_bytes(self): + """Bytes bound for a linear resource (``None`` for other kinds).""" + return self._size_bytes + + @property + def width(self): + """Pitch2D image width, in elements (``None`` for other kinds).""" + return self._width + + @property + def height(self): + """Pitch2D image height, in rows (``None`` for other kinds).""" + return self._height + + @property + def pitch_bytes(self): + """Pitch2D row pitch, in bytes (``None`` for other kinds).""" + return self._pitch_bytes + + def __repr__(self): + if self._kind == "linear": + return ( + f"ResourceDescriptor(kind='linear', format={self.format.name}, " + f"num_channels={self._num_channels}, size_bytes={self._size_bytes})" + ) + if self._kind == "pitch2d": + return ( + f"ResourceDescriptor(kind='pitch2d', format={self.format.name}, " + f"num_channels={self._num_channels}, " + f"width={self._width}, height={self._height}, " + f"pitch_bytes={self._pitch_bytes})" + ) + return f"ResourceDescriptor(kind={self._kind!r})" + + +@dataclass +class TextureDescriptor: + """Sampling state for a :class:`TextureObject` (mirrors ``CUDA_TEXTURE_DESC``). + + Attributes + ---------- + address_mode : tuple of AddressMode + Boundary behavior per axis. May be a single :class:`AddressMode` (applied + to all axes) or a tuple of 1-3 entries (one per dimension). + filter_mode : FilterMode + Texel sampling mode. Default ``POINT``. + read_mode : ReadMode + How sampled integer values are returned. Default ``ELEMENT_TYPE``. + normalized_coords : bool + If True, coordinates are in ``[0, 1]`` instead of pixel indices. + srgb : bool + If True, perform sRGB → linear conversion on read (8-bit formats only). + disable_trilinear_optimization : bool + If True, request exact trilinear filtering. + seamless_cubemap : bool + If True, enable seamless cubemap edge filtering. + max_anisotropy : int + Maximum anisotropy; 0 disables anisotropic filtering. + mipmap_filter_mode : FilterMode + Filtering between mipmap levels. Default ``POINT``. + mipmap_level_bias : float + min_mipmap_level_clamp : float + max_mipmap_level_clamp : float + border_color : tuple of float or None + 4-tuple used when ``address_mode`` includes ``BORDER``; ``None`` means + zero. + """ + + address_mode: AddressMode | tuple[AddressMode, ...] = AddressMode.CLAMP + filter_mode: FilterMode = FilterMode.POINT + read_mode: ReadMode = ReadMode.ELEMENT_TYPE + normalized_coords: bool = False + srgb: bool = False + disable_trilinear_optimization: bool = False + seamless_cubemap: bool = False + max_anisotropy: int = 0 + mipmap_filter_mode: FilterMode = FilterMode.POINT + mipmap_level_bias: float = 0.0 + min_mipmap_level_clamp: float = 0.0 + max_mipmap_level_clamp: float = 0.0 + border_color: tuple[float, ...] | None = None + + +def _normalize_address_modes(address_mode): + """Return a 3-tuple of AddressMode values from a scalar or 1-3 tuple.""" + if isinstance(address_mode, AddressMode): + return (address_mode, address_mode, address_mode) + try: + modes = tuple(address_mode) + except TypeError as e: + raise TypeError( + "address_mode must be an AddressMode or a tuple of AddressMode" + ) from e + if not 1 <= len(modes) <= 3: + raise ValueError( + f"address_mode tuple must have 1-3 entries, got {len(modes)}" + ) + for i, m in enumerate(modes): + if not isinstance(m, AddressMode): + raise TypeError( + f"address_mode[{i}] must be an AddressMode, got {type(m).__name__}" + ) + # Pad to 3 entries by repeating the last one. + padded = list(modes) + [modes[-1]] * (3 - len(modes)) + return tuple(padded) + + +cdef class TextureObject: + """A bindless texture handle for kernel-side sampled reads. + + Wraps ``cuTexObjectCreate``. The underlying memory resource (e.g. the + :class:`CUDAArray` referenced by the descriptor) is kept alive for the + lifetime of this object to prevent dangling handles. + + Construct via :meth:`from_descriptor`. Passes to kernels as a 64-bit + handle (via the ``handle`` property). + """ + + def __init__(self, *args, **kwargs): + raise RuntimeError( + "TextureObject cannot be instantiated directly. " + "Use TextureObject.from_descriptor()." + ) + + @classmethod + def from_descriptor(cls, *, resource, texture_descriptor): + """Create a texture object from a resource + sampling descriptor. + + Parameters + ---------- + resource : ResourceDescriptor + texture_descriptor : TextureDescriptor + """ + if not isinstance(resource, ResourceDescriptor): + raise TypeError( + f"resource must be a ResourceDescriptor, got " + f"{type(resource).__name__}" + ) + if not isinstance(texture_descriptor, TextureDescriptor): + raise TypeError( + f"texture_descriptor must be a TextureDescriptor, got " + f"{type(texture_descriptor).__name__}" + ) + + cdef cydriver.CUDA_RESOURCE_DESC res_desc + cdef cydriver.CUDA_TEXTURE_DESC tex_desc + memset(&res_desc, 0, sizeof(res_desc)) + memset(&tex_desc, 0, sizeof(tex_desc)) + + # --- Resource descriptor --- + cdef CUDAArray arr + cdef MipmappedArray mip + cdef Buffer buf + cdef intptr_t devptr + if resource.kind == "array": + arr = resource.source + res_desc.resType = cydriver.CU_RESOURCE_TYPE_ARRAY + res_desc.res.array.hArray = as_cu(arr._handle) + elif resource.kind == "mipmapped_array": + mip = resource.source + res_desc.resType = cydriver.CU_RESOURCE_TYPE_MIPMAPPED_ARRAY + res_desc.res.mipmap.hMipmappedArray = as_cu(mip._handle) + elif resource.kind == "linear": + buf = resource.source + devptr = int(buf.handle) + res_desc.resType = cydriver.CU_RESOURCE_TYPE_LINEAR + res_desc.res.linear.devPtr = devptr + res_desc.res.linear.format = resource._format + res_desc.res.linear.numChannels = resource._num_channels + res_desc.res.linear.sizeInBytes = resource._size_bytes + elif resource.kind == "pitch2d": + buf = resource.source + devptr = int(buf.handle) + res_desc.resType = cydriver.CU_RESOURCE_TYPE_PITCH2D + res_desc.res.pitch2D.devPtr = devptr + res_desc.res.pitch2D.format = resource._format + res_desc.res.pitch2D.numChannels = resource._num_channels + res_desc.res.pitch2D.width = resource._width + res_desc.res.pitch2D.height = resource._height + res_desc.res.pitch2D.pitchInBytes = resource._pitch_bytes + else: + raise NotImplementedError( + f"ResourceDescriptor kind {resource.kind!r} is not yet supported" + ) + + # --- Texture descriptor --- + modes = _normalize_address_modes(texture_descriptor.address_mode) + tex_desc.addressMode[0] = modes[0] + tex_desc.addressMode[1] = modes[1] + tex_desc.addressMode[2] = modes[2] + + if not isinstance(texture_descriptor.filter_mode, FilterMode): + raise TypeError( + f"filter_mode must be a FilterMode, got " + f"{type(texture_descriptor.filter_mode).__name__}" + ) + tex_desc.filterMode = texture_descriptor.filter_mode + + if not isinstance(texture_descriptor.read_mode, ReadMode): + raise TypeError( + f"read_mode must be a ReadMode, got " + f"{type(texture_descriptor.read_mode).__name__}" + ) + + cdef unsigned int flags = 0 + # CU_TRSF_READ_AS_INTEGER suppresses normalization, so it maps to + # ReadMode.ELEMENT_TYPE. + if texture_descriptor.read_mode == ReadMode.ELEMENT_TYPE: + flags |= _TRSF_READ_AS_INTEGER + if texture_descriptor.normalized_coords: + flags |= _TRSF_NORMALIZED_COORDINATES + if texture_descriptor.srgb: + flags |= _TRSF_SRGB + if texture_descriptor.disable_trilinear_optimization: + flags |= _TRSF_DISABLE_TRILINEAR_OPTIMIZATION + if texture_descriptor.seamless_cubemap: + flags |= _TRSF_SEAMLESS_CUBEMAP + tex_desc.flags = flags + + if texture_descriptor.max_anisotropy < 0: + raise ValueError("max_anisotropy must be >= 0") + tex_desc.maxAnisotropy = texture_descriptor.max_anisotropy + + if not isinstance(texture_descriptor.mipmap_filter_mode, FilterMode): + raise TypeError( + f"mipmap_filter_mode must be a FilterMode, got " + f"{type(texture_descriptor.mipmap_filter_mode).__name__}" + ) + tex_desc.mipmapFilterMode = texture_descriptor.mipmap_filter_mode + tex_desc.mipmapLevelBias = texture_descriptor.mipmap_level_bias + tex_desc.minMipmapLevelClamp = texture_descriptor.min_mipmap_level_clamp + tex_desc.maxMipmapLevelClamp = texture_descriptor.max_mipmap_level_clamp + + cdef int i + if texture_descriptor.border_color is None: + for i in range(4): + tex_desc.borderColor[i] = 0.0 + else: + bc = tuple(texture_descriptor.border_color) + if len(bc) != 4: + raise ValueError( + f"border_color must have 4 elements, got {len(bc)}" + ) + for i in range(4): + tex_desc.borderColor[i] = bc[i] + + cdef TexObjectHandle h + if resource.kind == "array": + h = create_tex_object_handle_array(res_desc, tex_desc, arr._handle) + elif resource.kind == "mipmapped_array": + h = create_tex_object_handle_mipmap(res_desc, tex_desc, mip._handle) + else: # linear or pitch2d — both backed by a device Buffer + h = create_tex_object_handle_linear(res_desc, tex_desc, buf._h_ptr) + if not h: + HANDLE_RETURN(get_last_error()) + + cdef TextureObject self = cls.__new__(cls) + self._handle = h + self._source_ref = resource + self._texture_desc = texture_descriptor + self._device_id = _get_current_device_id() + return self + + @property + def handle(self): + """The underlying ``CUtexObject`` as an integer (64-bit kernel arg).""" + return as_intptr(self._handle) + + @property + def resource(self): + """The :class:`ResourceDescriptor` this texture was built from.""" + return self._source_ref + + @property + def texture_descriptor(self): + """The :class:`TextureDescriptor` this texture was built from.""" + return self._texture_desc + + @property + def device(self): + from cuda.core._device import Device + return Device(self._device_id) + + cpdef close(self): + """Release this object's reference to the underlying ``CUtexObject``. + + Destruction (``cuTexObjectDestroy``) and release of the backing resource + happen via the handle's deleter when the last reference is dropped. + Idempotent. + """ + self._handle.reset() + self._source_ref = None + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + self.close() + + def __repr__(self): + return f"TextureObject(handle=0x{as_intptr(self._handle):x})" diff --git a/cuda_core/cuda/core/_utils/cuda_utils.pxd b/cuda_core/cuda/core/_utils/cuda_utils.pxd index 4562cd71355..11e464e6381 100644 --- a/cuda_core/cuda/core/_utils/cuda_utils.pxd +++ b/cuda_core/cuda/core/_utils/cuda_utils.pxd @@ -25,6 +25,11 @@ cdef int HANDLE_RETURN_NVJITLINK( cynvjitlink.nvJitLinkHandle handle, cynvjitlink.nvJitLinkResult err) except?-1 nogil +# Helper for retrieving the current CUDA device. Raises if no active context +# is bound to the calling thread. +cdef int _get_current_device_id() except? -1 + + # TODO: stop exposing these within the codebase? cpdef int _check_driver_error(cydriver.CUresult error) except?-1 nogil cpdef int _check_runtime_error(error) except?-1 diff --git a/cuda_core/cuda/core/_utils/cuda_utils.pyx b/cuda_core/cuda/core/_utils/cuda_utils.pyx index 4e20f689b5a..318d4466bee 100644 --- a/cuda_core/cuda/core/_utils/cuda_utils.pyx +++ b/cuda_core/cuda/core/_utils/cuda_utils.pyx @@ -69,6 +69,14 @@ cdef int HANDLE_RETURN(cydriver.CUresult err) except?-1 nogil: return 0 +cdef int _get_current_device_id() except? -1: + """Return the current thread's bound CUdevice ordinal.""" + cdef cydriver.CUdevice dev + with nogil: + HANDLE_RETURN(cydriver.cuCtxGetDevice(&dev)) + return dev + + cdef int HANDLE_RETURN_NVRTC(cynvrtc.nvrtcProgram prog, cynvrtc.nvrtcResult err) except?-1 nogil: """Handle NVRTC result codes, raising NVRTCError with program log on failure.""" if err == cynvrtc.nvrtcResult.NVRTC_SUCCESS: diff --git a/cuda_core/cuda/core/textures.py b/cuda_core/cuda/core/textures.py new file mode 100644 index 00000000000..0a8b0127861 --- /dev/null +++ b/cuda_core/cuda/core/textures.py @@ -0,0 +1,39 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +"""Texture and surface APIs for ``cuda.core``. + +This subpackage groups the CUDA "Texture and Surface" object model — opaque +array storage and the bindless texture/surface handles built on it — under a +single namespace, mirroring how the CUDA driver documentation organizes them. + +Import these types from here, e.g.:: + + from cuda.core.textures import CUDAArray, TextureObject, TextureDescriptor +""" + +from cuda.core._array import ArrayFormat, CUDAArray +from cuda.core._mipmapped_array import MipmappedArray +from cuda.core._surface import SurfaceObject +from cuda.core._texture import ( + AddressMode, + FilterMode, + ReadMode, + ResourceDescriptor, + TextureDescriptor, + TextureObject, +) + +__all__ = [ + "AddressMode", + "ArrayFormat", + "CUDAArray", + "FilterMode", + "MipmappedArray", + "ReadMode", + "ResourceDescriptor", + "SurfaceObject", + "TextureDescriptor", + "TextureObject", +] diff --git a/cuda_core/docs/source/api.rst b/cuda_core/docs/source/api.rst index b1498b57da3..2418f0578e1 100644 --- a/cuda_core/docs/source/api.rst +++ b/cuda_core/docs/source/api.rst @@ -161,6 +161,49 @@ Tensor Memory Accelerator (TMA) TensorMapDescriptorOptions +Textures and surfaces +--------------------- + +CUDA arrays back bindless texture and surface objects for kernel-side sampled +reads and typed load/store. These types live in the :mod:`cuda.core.textures` +namespace. :class:`CUDAArray` is allocated through +:meth:`CUDAArray.from_descriptor` and bound through a :class:`ResourceDescriptor` +factory; linear (1D) and row-pitched 2D :class:`Buffer` views as well as +mipmapped allocations (:class:`MipmappedArray`) are also supported as texture +backings. + +A :class:`CUDAArray` has an opaque, hardware-defined layout with no linear +device pointer, so it cannot participate in ``__cuda_array_interface__`` / +DLPack zero-copy interop. Data is moved in and out only by copying — use +:meth:`CUDAArray.copy_from` / :meth:`CUDAArray.copy_to` against a linear +:class:`Buffer` or a host buffer-protocol object. + +.. currentmodule:: cuda.core.textures + +.. autosummary:: + :toctree: generated/ + + :template: autosummary/cyclass.rst + + CUDAArray + MipmappedArray + ResourceDescriptor + TextureObject + SurfaceObject + + :template: dataclass.rst + + TextureDescriptor + +.. autosummary:: + :toctree: generated/ + + ArrayFormat + AddressMode + FilterMode + ReadMode + + CUDA compilation toolchain -------------------------- diff --git a/cuda_core/examples/gl_interop_fluid.py b/cuda_core/examples/gl_interop_fluid.py new file mode 100644 index 00000000000..38b92315ef1 --- /dev/null +++ b/cuda_core/examples/gl_interop_fluid.py @@ -0,0 +1,1253 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +# ################################################################################ +# +# This example demonstrates cuda.core.CUDAArray, TextureObject, and SurfaceObject +# in combination with GraphicsResource for CUDA/OpenGL interop. It runs a +# real-time Stable Fluids (Jos Stam) smoke/ink solver entirely on the GPU: +# velocity, pressure, and dye fields live in ping-ponged CUDA arrays, are read +# through TextureObjects with free hardware bilinear filtering (the heart of +# semi-Lagrangian advection), and written back through SurfaceObjects. The dye +# is colorized straight into an OpenGL PBO. Drag the mouse to inject swirling +# ink. Requires pyglet. +# +# ################################################################################ + +# What this example teaches +# ========================= +# - How semi-Lagrangian advection uses tex2D LINEAR sampling: trace each cell +# backward along the velocity field and read the old quantity with free +# hardware bilinear interpolation (no manual lerp, no neighbor gather). +# - How to drive several distinct kernels (advect, divergence, Jacobi pressure +# solve, gradient subtraction, dye advect, colorize) over a shared set of +# pre-created TextureObject/SurfaceObject handles, ping-ponging multiple +# fields without recreating handles per frame. +# - How to fold live mouse input into a GPU simulation: capture the mouse delta +# and splat velocity + dye into the field via a SurfaceObject (in-place +# read-modify-write, one thread per cell -> no race). +# +# How it works +# ============ +# Stam's "Stable Fluids" solves the incompressible Navier-Stokes equations on a +# regular grid by splitting each step into stages that are each individually +# stable: +# +# 1. ADVECT VELOCITY - move the velocity field along itself. For each cell we +# back-trace its center one timestep against the local velocity and read +# the old velocity there with tex2D LINEAR (bilinear). This is the +# unconditionally-stable semi-Lagrangian scheme. +# 2. SPLAT (input) - add the mouse-drag velocity and a dab of dye in a soft +# radial brush around the cursor (in-place on the velocity/dye surfaces). +# 3. DIVERGENCE - compute div(velocity), the amount each cell is a +# source/sink. An incompressible fluid must have zero divergence. +# 4. PRESSURE SOLVE - Jacobi-iterate the Poisson equation lap(p) = div, +# ping-ponging two pressure buffers for ~30 iterations. +# 5. SUBTRACT GRADIENT- v <- v - grad(p). This projects the velocity onto its +# divergence-free part, enforcing incompressibility. +# 6. ADVECT DYE - move the ink along the (now divergence-free) velocity, +# again with tex2D LINEAR back-tracing. +# 7. COLORIZE - map dye density through a vivid gradient into the PBO. +# +# PING-PONG (read one array, write the other, then swap) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +-----------+ tex2D LINEAR +-------------+ surf2Dwrite +-----------+ +# | vel_a | -----------------------> | advect / | --------------> | vel_b | +# | (vx, vy) | | jacobi / | | (vx, vy) | +# +-----------+ | advect_dye | +-----------+ +# ^ +-------------+ | +# +-------------------------------- (swap) ------------------------------+ +# +# Why LINEAR + CLAMP + normalized coords? +# --------------------------------------- +# Semi-Lagrangian advection traces a cell's center back to an arbitrary +# fractional position and needs the interpolated field value there. LINEAR +# filtering gives that bilinear interpolation for free in hardware. We use a +# bounded box (CLAMP) rather than a torus so ink piles up against the walls +# instead of wrapping. CLAMP, like all addressing modes, behaves cleanly with +# normalized coordinates, and we sample at texel centers `(i + 0.5) / N` so a +# zero-velocity cell reads back exactly its own value. +# +# Channel byte width in surf2Dwrite +# --------------------------------- +# `surf2Dwrite` takes the x coordinate in BYTES, not in elements. Velocity is a +# `float2` (8 bytes) so its x offset is `x * sizeof(float2)`; pressure and +# divergence are `float` (4 bytes, `x * sizeof(float)`); the dye is a `float4` +# RGBA color (16 bytes, `x * sizeof(float4)`). Getting this wrong silently +# corrupts every other column. +# +# What you should see +# =================== +# Big blobs of saturated color are dropped into the fluid every fraction of a +# second and immediately billow, swirl, and mix into turbulent ribbons that +# fill the window -- "ink dropped in water." Drag the mouse to paint your own +# rainbow ink. Press R to clear, Escape to exit. The window title shows the +# current FPS, pressure-iteration count, and live texture/surface config. +# + +# /// script +# dependencies = ["cuda_bindings", "cuda_core>0.6.0", "pyglet"] +# /// + +import colorsys +import ctypes +import math +import random +import sys +import time + +import numpy as np + +from cuda.core import ( + Device, + GraphicsResource, + LaunchConfig, + Program, + ProgramOptions, + launch, +) +from cuda.core.textures import ( + AddressMode, + ArrayFormat, + CUDAArray, + FilterMode, + ReadMode, + ResourceDescriptor, + SurfaceObject, + TextureDescriptor, + TextureObject, +) + +# --------------------------------------------------------------------------- +# Simulation parameters (feel free to change these) +# --------------------------------------------------------------------------- +WIDTH = 512 +HEIGHT = 512 +DT = 1.0 # simulation timestep +PRESSURE_ITERS = 30 # Jacobi iterations for the pressure solve per frame +VELOCITY_DISSIPATION = 0.999 # per-step velocity decay (1.0 = no decay) +DYE_DISSIPATION = 0.994 # per-step dye decay; ink lingers and builds, then fades +SPLAT_RADIUS = 24.0 # brush radius in cells for mouse injection +SPLAT_FORCE = 6.0 # how strongly a mouse delta becomes velocity +SPLAT_DYE = 1.0 # mouse ink intensity (color * this is deposited) +CURL_SEED = 2.5 # strength of the ambient curl seeded on reset +# Vorticity confinement pushes velocity back toward regions of high |curl|, +# sharpening the swirls that numerical diffusion would otherwise smear out. +# This is the single extra kernel that turns soft blobs into crisp curling +# plumes. Tunable: ~0.1-0.3 reads well at DT=1.0; higher gets turbulent. +VORTICITY = 0.28 # confinement strength (0.0 disables it) + +# Auto-bursts keep the simulation alive and colorful without any input: when +# the mouse is idle we periodically drop a big blob of a random bright color +# with a random velocity impulse at a random spot -- the classic "ink dropped +# in water" look that quickly fills the frame with billowing, swirling color. +# Grab the cursor and drag to paint your own ink. +AUTO_EMIT = True +BURST_INTERVAL = 0.45 # seconds between automatic colored bursts +BURSTS_PER_EVENT = 2 # blobs dropped each burst event +BURST_RADIUS = 42.0 # blob radius in cells (big, soft) +BURST_FORCE = 18.0 # velocity impulse magnitude per blob +BURST_DYE = 1.2 # ink intensity per blob (random color * this) + +# This solver advances one step per displayed frame, so its per-step rates +# (dissipation, advection distance) would otherwise depend on the frame rate -- +# on a fast GPU the dye would dissipate away almost instantly between bursts. +# We make it frame-rate INDEPENDENT instead: every frame, the real elapsed time +# is expressed in units of a REF_FPS reference step and the dissipation and +# advection distance are scaled by it, so the ink evolves at the same wall-clock +# rate (and looks the same) whether the loop runs at 60 or 2000 FPS. Running +# faster just means more, smaller, smoother substeps. +REF_FPS = 60.0 + + +# ============================= Helper functions ============================= +# +# The functions below set up CUDA and OpenGL. If you're here to learn about +# CUDAArray/TextureObject/SurfaceObject, skip ahead to main() -- the interesting +# part is there. These helpers exist so that main() reads like a short story +# instead of a wall of boilerplate. +# ============================================================================ + + +def setup_cuda(): + """Compile the CUDA kernels and return (device, stream, kernels, configs). + + Returns a dict of kernels keyed by name and a shared LaunchConfig (every + kernel is pixel-parallel over the same WIDTH x HEIGHT grid). + """ + dev = Device(0) + dev.set_current() + + # SurfaceObject requires surface load/store, which has existed since SM 2.0, + # but bindless surface objects (cuSurfObjectCreate) require SM 3.0+. + cc = dev.compute_capability + if cc.major < 3: + print( + "This example requires a GPU with compute capability >= 3.0 for " + f"bindless surface objects. Found sm_{cc.major}{cc.minor}.", + file=sys.stderr, + ) + sys.exit(1) + + stream = dev.create_stream() + + # Compile as C++ so the templated tex2D overload resolves. + program_options = ProgramOptions(std="c++17", arch=f"sm_{dev.arch}") + prog = Program(KERNEL_SOURCE, code_type="c++", options=program_options) + mod = prog.compile( + "cubin", + name_expressions=( + "seed_field", + "splat", + "advect_velocity", + "vorticity_confinement", + "divergence", + "pressure_jacobi", + "subtract_gradient", + "advect_dye", + "colorize", + ), + ) + + kernels = { + "seed": mod.get_kernel("seed_field"), + "splat": mod.get_kernel("splat"), + "advect_vel": mod.get_kernel("advect_velocity"), + "vorticity": mod.get_kernel("vorticity_confinement"), + "divergence": mod.get_kernel("divergence"), + "jacobi": mod.get_kernel("pressure_jacobi"), + "subtract": mod.get_kernel("subtract_gradient"), + "advect_dye": mod.get_kernel("advect_dye"), + "colorize": mod.get_kernel("colorize"), + } + + block = (16, 16, 1) + grid = ( + (WIDTH + block[0] - 1) // block[0], + (HEIGHT + block[1] - 1) // block[1], + 1, + ) + config = LaunchConfig(grid=grid, block=block) + + return dev, stream, kernels, config + + +def create_window(): + """Open a pyglet window and return (window, gl_module, pyglet).""" + try: + import pyglet + from pyglet.gl import gl as _gl + except ImportError: + print( + "This example requires pyglet >= 2.0.\nInstall it with: pip install pyglet", + file=sys.stderr, + ) + sys.exit(1) + + window = pyglet.window.Window( + WIDTH, + HEIGHT, + caption="cuda.core CUDAArray/Texture/Surface - Stable Fluids", + vsync=False, + ) + return window, _gl, pyglet + + +def create_display_resources(gl, width, height): + """Create the GL objects needed to show a texture on screen. + + This sets up a shader program, a fullscreen quad, and an empty texture. + None of this is CUDA-specific -- it's standard OpenGL boilerplate for + rendering a textured quad. + + Returns (shader_program, vertex_array_id, texture_id). The shader_program + is a pyglet ShaderProgram object (must be kept alive). + """ + from pyglet.graphics.shader import Shader, ShaderProgram + + # Shader program -- just passes texture coordinates through + vert = Shader(VERTEX_SHADER_SOURCE, "vertex") + frag = Shader(FRAGMENT_SHADER_SOURCE, "fragment") + shader_prog = ShaderProgram(vert, frag) + + # Fullscreen quad (two triangles covering the entire window) + quad_verts = np.array( + [ + # x, y, s, t (position + texture coordinate) + -1, + -1, + 0, + 0, + 1, + -1, + 1, + 0, + 1, + 1, + 1, + 1, + -1, + -1, + 0, + 0, + 1, + 1, + 1, + 1, + -1, + 1, + 0, + 1, + ], + dtype=np.float32, + ) + + vao = ctypes.c_uint(0) + gl.glGenVertexArrays(1, ctypes.byref(vao)) + gl.glBindVertexArray(vao.value) + + vbo = ctypes.c_uint(0) + gl.glGenBuffers(1, ctypes.byref(vbo)) + gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo.value) + gl.glBufferData( + gl.GL_ARRAY_BUFFER, + quad_verts.nbytes, + quad_verts.ctypes.data_as(ctypes.c_void_p), + gl.GL_STATIC_DRAW, + ) + + stride = 4 * 4 # 4 floats * 4 bytes each = 16 bytes per vertex + pos_loc = gl.glGetAttribLocation(shader_prog.id, b"position") + gl.glEnableVertexAttribArray(pos_loc) + gl.glVertexAttribPointer(pos_loc, 2, gl.GL_FLOAT, gl.GL_FALSE, stride, ctypes.c_void_p(0)) + + tc_loc = gl.glGetAttribLocation(shader_prog.id, b"texcoord") + gl.glEnableVertexAttribArray(tc_loc) + gl.glVertexAttribPointer(tc_loc, 2, gl.GL_FLOAT, gl.GL_FALSE, stride, ctypes.c_void_p(8)) + + gl.glBindVertexArray(0) + + # Empty texture (will be filled each frame from the PBO) + tex = ctypes.c_uint(0) + gl.glGenTextures(1, ctypes.byref(tex)) + gl.glBindTexture(gl.GL_TEXTURE_2D, tex.value) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) + gl.glTexImage2D( + gl.GL_TEXTURE_2D, + 0, + gl.GL_RGBA8, + width, + height, + 0, + gl.GL_RGBA, + gl.GL_UNSIGNED_BYTE, + None, + ) + + return shader_prog, vao.value, tex.value + + +def create_pixel_buffer(gl, width, height): + """Create a Pixel Buffer Object (PBO) -- the bridge between CUDA and OpenGL. + + A PBO is a GPU-side buffer that OpenGL can read from when uploading pixels + to a texture. By registering this same buffer with CUDA, the CUDA kernel + can write directly into it. + + Returns (pbo_gl_name, size_in_bytes). + """ + pbo = ctypes.c_uint(0) + gl.glGenBuffers(1, ctypes.byref(pbo)) + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, pbo.value) + nbytes = width * height * 4 # RGBA, 1 byte per channel + gl.glBufferData(gl.GL_PIXEL_UNPACK_BUFFER, nbytes, None, gl.GL_DYNAMIC_DRAW) + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0) + return pbo.value, nbytes + + +def copy_pbo_to_texture(gl, pbo_id, tex_id, width, height): + """Copy pixel data from the PBO into the GL texture (GPU-to-GPU).""" + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, pbo_id) + gl.glBindTexture(gl.GL_TEXTURE_2D, tex_id) + gl.glTexSubImage2D( + gl.GL_TEXTURE_2D, + 0, + 0, + 0, + width, + height, + gl.GL_RGBA, + gl.GL_UNSIGNED_BYTE, + None, # None = read from the currently bound PBO, not from CPU + ) + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0) + + +def draw_fullscreen_quad(gl, shader_prog, vao_id, tex_id): + """Draw the texture to the screen using the fullscreen quad.""" + gl.glUseProgram(shader_prog.id) + gl.glBindTexture(gl.GL_TEXTURE_2D, tex_id) + gl.glBindVertexArray(vao_id) + gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) + gl.glBindVertexArray(0) + gl.glUseProgram(0) + + +# ============================ API MAP (cuda.core) =========================== +# +# The three helpers below are where every CUDAArray / ResourceDescriptor / +# TextureDescriptor / TextureObject / SurfaceObject knob in this example is set. +# Each visible setting maps to a concrete piece of cuda.core / CUDA behavior: +# +# CUDAArray.from_descriptor(...) -> allocates a CUDA *array* (opaque, tiled +# layout optimized for 2D texture fetches), +# not linear device memory. +# ArrayFormat.FLOAT32 -> each channel is a 32-bit float texel. +# num_channels=2 / num_channels=1 -> float2 (vx, vy) vs scalar (pressure / +# divergence / dye); also fixes the +# surf2Dwrite byte offset per element. +# is_surface_load_store=True -> the SAME array can be bound both as a +# TextureObject (cached, filtered READS) +# and as a SurfaceObject (raw WRITES). This +# is what lets each field be sampled and +# then written back in the ping-pong. +# +# ResourceDescriptor.from_array(arr) -> wraps the CUDAArray as the resource a +# TextureObject reads from. +# FilterMode.LINEAR -> free HARDWARE bilinear interpolation; +# this is what makes semi-Lagrangian +# advection a single tex2D fetch at a +# fractional back-traced position (no +# manual lerp, no neighbor gather). +# AddressMode.CLAMP -> bounded box boundary: out-of-range traces +# read the edge texel (ink piles up at the +# walls instead of wrapping like a torus). +# ReadMode.ELEMENT_TYPE -> return the stored float value as-is (no +# integer->[0,1] normalization of texels). +# normalized_coords=True -> sample in [0, 1) so CLAMP is well-defined +# and texel centers are (i + 0.5) / N. +# +# SurfaceObject.from_array(arr) -> binds the array for surf2Dread/surf2Dwrite. +# The x coordinate is in BYTES, so it is +# x * sizeof(elem): sizeof(float2)=8 for +# velocity, sizeof(float)=4 for the scalars. +# ============================================================================ + + +def make_velocity_array(): + """Allocate a `float2` velocity CUDA array (channel 0 = vx, channel 1 = vy).""" + return CUDAArray.from_descriptor( + shape=(WIDTH, HEIGHT), + format=ArrayFormat.FLOAT32, + num_channels=2, + is_surface_load_store=True, + ) + + +def make_scalar_array(): + """Allocate a single-channel `float` CUDA array (pressure / divergence / dye).""" + return CUDAArray.from_descriptor( + shape=(WIDTH, HEIGHT), + format=ArrayFormat.FLOAT32, + num_channels=1, + is_surface_load_store=True, + ) + + +def make_color_array(): + """Allocate a `float4` RGBA dye CUDA array. + + The dye carries a full color per cell (not just a density), so different + bursts inject different hues that advect and mix. Same LINEAR sampling and + surface-write machinery as the scalar fields -- only the channel count + (and the surf2Dwrite byte stride, sizeof(float4) = 16) differ. + """ + return CUDAArray.from_descriptor( + shape=(WIDTH, HEIGHT), + format=ArrayFormat.FLOAT32, + num_channels=4, + is_surface_load_store=True, + ) + + +def make_texture(arr): + """Bind `arr` as a TextureObject configured for LINEAR + CLAMP + normalized. + + One descriptor serves every read in this example: semi-Lagrangian advection + needs the bilinear interpolation, and the stencil reads (divergence, Jacobi, + gradient) sample exactly at texel centers so LINEAR returns the exact value. + """ + res_desc = ResourceDescriptor.from_array(arr) + tex_desc = TextureDescriptor( + address_mode=AddressMode.CLAMP, + filter_mode=FilterMode.LINEAR, + read_mode=ReadMode.ELEMENT_TYPE, + # Normalized coordinates keep CLAMP addressing well-defined and let us + # sample at texel centers as (i + 0.5) / N. + normalized_coords=True, + ) + return TextureObject.from_descriptor(resource=res_desc, texture_descriptor=tex_desc) + + +def seed_field(stream, kernels, config, vel_surf, dye_surf, prs_surf, seed_value): + """Reset the field: gentle ambient curl in velocity, zero pressure/dye. + + Takes long-lived SurfaceObjects (not freshly created ones): `launch` is + async, so a SurfaceObject created inside a `with` block that closes right + after `launch` returns would destroy the handle before the kernel runs. + """ + launch( + stream, + config, + kernels["seed"], + np.uint64(vel_surf.handle), + np.uint64(dye_surf.handle), + np.uint64(prs_surf.handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.float32(CURL_SEED), + np.uint32(seed_value), + ) + + +# ================================== main() ================================== + + +def main(): + # --- Step 1: Set up CUDA (compile kernels, create stream) --- + dev, stream, kernels, config = setup_cuda() + + # --- Step 2: Open a window --- + window, gl, pyglet = create_window() + + # --- Step 3: Create GL resources for drawing a texture to screen --- + # (Standard OpenGL boilerplate -- not CUDA-specific.) + shader_prog, quad_vao, tex_id = create_display_resources(gl, WIDTH, HEIGHT) + + # --- Step 4: Create the Pixel Buffer Object (PBO) --- + # The PBO is GPU memory owned by OpenGL. It's the bridge between the + # two worlds: CUDA writes into it, OpenGL reads from it. + pbo_id, _ = create_pixel_buffer(gl, WIDTH, HEIGHT) + + # --- Step 5: Register the PBO with CUDA --- + resource = GraphicsResource.from_gl_buffer(pbo_id, flags="write_discard") + + # --- Step 6: Allocate the simulation fields --- + # velocity (float2) and dye (float) ping-pong; pressure (float) + # ping-pongs across Jacobi iterations; divergence (float) is a single + # scratch target written once per frame. + vel_a = make_velocity_array() + vel_b = make_velocity_array() + prs_a = make_scalar_array() + prs_b = make_scalar_array() + div = make_scalar_array() + dye_a = make_color_array() + dye_b = make_color_array() + + # --- Step 7: Pre-create every bindless handle ONCE --- + # Creating texture/surface objects is comparatively expensive, and they + # must outlive the async launches that reference them, so we build them + # up front and keep them alive for the whole run. + # API MAP: make_texture binds an array as a read-only TextureObject + # (LINEAR + CLAMP + normalized; see the API MAP block above), while + # SurfaceObject.from_array binds the SAME array for raw surf2Dwrite + # writes -- the read/write halves of one ping-pong buffer. + vel_tex_a = make_texture(vel_a) + vel_tex_b = make_texture(vel_b) + vel_surf_a = SurfaceObject.from_array(vel_a) + vel_surf_b = SurfaceObject.from_array(vel_b) + + prs_tex_a = make_texture(prs_a) + prs_tex_b = make_texture(prs_b) + prs_surf_a = SurfaceObject.from_array(prs_a) + prs_surf_b = SurfaceObject.from_array(prs_b) + + div_tex = make_texture(div) + div_surf = SurfaceObject.from_array(div) + + dye_tex_a = make_texture(dye_a) + dye_tex_b = make_texture(dye_b) + dye_surf_a = SurfaceObject.from_array(dye_a) + dye_surf_b = SurfaceObject.from_array(dye_b) + + # --- Step 8: Seed the initial field (curl into vel_a, zero pressure/dye) --- + seed_field(stream, kernels, config, vel_surf_a, dye_surf_a, prs_surf_a, seed_value=0) + stream.sync() + + # `vel` / `dye` track which ping-pong array currently holds the live state. + state = {"vel": "a", "dye": "a", "seed": 0, "next_burst": 0.0} + + # Mouse state shared with the event handlers. Coordinates are in SIMULATION + # space (y = 0 at top); the framebuffer has y = 0 at the bottom, so we flip. + mouse = {"down": False, "x": 0.0, "y": 0.0, "dx": 0.0, "dy": 0.0} + + def vel_pair(): + # Read live velocity, write the other buffer; returns (read_tex, write_surf, next). + if state["vel"] == "a": + return vel_tex_a, vel_surf_b, "b" + return vel_tex_b, vel_surf_a, "a" + + def vel_live_tex(): + return vel_tex_a if state["vel"] == "a" else vel_tex_b + + def vel_live_surf(): + return vel_surf_a if state["vel"] == "a" else vel_surf_b + + def dye_pair(): + if state["dye"] == "a": + return dye_tex_a, dye_surf_b, "b" + return dye_tex_b, dye_surf_a, "a" + + def dye_live_tex(): + return dye_tex_a if state["dye"] == "a" else dye_tex_b + + def dye_live_surf(): + return dye_surf_a if state["dye"] == "a" else dye_surf_b + + # --- Step 9: Render loop --- + start_time = time.monotonic() + frame_count = 0 + fps_time = start_time + clock = {"last": start_time} # wall-clock time of the previous frame + + def _window_to_sim(x, y): + # Window: y = 0 at bottom. Simulation: y = 0 at top. Flip vertically. + sx = float(x) + sy = float(HEIGHT - 1 - y) + return sx, sy + + @window.event + def on_key_press(symbol, _modifiers): + key = pyglet.window.key + if symbol == key.ESCAPE: + window.close() + return + if symbol == key.R: + state["seed"] += 1 + seed_field( + stream, + kernels, + config, + vel_surf_a, + dye_surf_a, + prs_surf_a, + seed_value=state["seed"], + ) + state["vel"] = "a" + state["dye"] = "a" + return + + @window.event + def on_mouse_press(x, y, _button, _modifiers): + mouse["down"] = True + mouse["x"], mouse["y"] = _window_to_sim(x, y) + mouse["dx"] = 0.0 + mouse["dy"] = 0.0 + + @window.event + def on_mouse_release(_x, _y, _button, _modifiers): + mouse["down"] = False + mouse["dx"] = 0.0 + mouse["dy"] = 0.0 + + @window.event + def on_mouse_drag(x, y, dx, dy, _buttons, _modifiers): + # The mouse delta IS the injected velocity. Framebuffer dy is up-positive + # while simulation y is down-positive, so the sim-space delta is -dy. + mouse["down"] = True + mouse["x"], mouse["y"] = _window_to_sim(x, y) + mouse["dx"] = float(dx) + mouse["dy"] = float(-dy) + + @window.event + def on_draw(): + nonlocal frame_count, fps_time + + window.clear() + now_t = time.monotonic() + elapsed = now_t - start_time + + # Frame-rate independence: express this frame's real duration in units of + # a REF_FPS reference step. `step` scales the advection distance, and the + # per-step dissipations are raised to `step` so their per-SECOND rate is + # constant no matter how fast the loop runs. Clamp to absorb the first + # frame and any hitch without launching a giant (unstable-looking) step. + dt_real = now_t - clock["last"] + clock["last"] = now_t + step = min(max(dt_real * REF_FPS, 0.0), 3.0) + dt_adv = DT * step + vel_diss = VELOCITY_DISSIPATION**step + dye_diss = DYE_DISSIPATION**step + + # (a) Advect velocity along itself (semi-Lagrangian, tex2D LINEAR). + vel_read, vel_write, vel_next = vel_pair() + launch( + stream, + config, + kernels["advect_vel"], + np.uint64(vel_read.handle), + np.uint64(vel_write.handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.float32(dt_adv), + np.float32(vel_diss), + ) + state["vel"] = vel_next + + # (b) Splat mouse-drag velocity and colored dye into the live fields. + # The injected color cycles through hues over time so dragging + # paints a rainbow ribbon of ink. + inject = 1 if mouse["down"] else 0 + mr, mg, mb = colorsys.hsv_to_rgb((elapsed * 0.15) % 1.0, 0.85, 1.0) + launch( + stream, + config, + kernels["splat"], + np.uint64(vel_live_surf().handle), + np.uint64(dye_live_surf().handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.float32(mouse["x"]), + np.float32(mouse["y"]), + np.float32(mouse["dx"] * SPLAT_FORCE), + np.float32(mouse["dy"] * SPLAT_FORCE), + np.float32(SPLAT_RADIUS), + np.float32(mr * SPLAT_DYE), + np.float32(mg * SPLAT_DYE), + np.float32(mb * SPLAT_DYE), + np.int32(inject), + ) + + # (b2) When the user is not dragging, periodically drop big blobs of a + # random bright color with a random velocity impulse at random + # spots -- the classic "ink in water" look. Reuses the same `splat` + # kernel as the mouse, just with a color argument. + if AUTO_EMIT and not mouse["down"] and elapsed >= state["next_burst"]: + state["next_burst"] = elapsed + BURST_INTERVAL + for _ in range(BURSTS_PER_EVENT): + bx = random.uniform(0.12, 0.88) * WIDTH + by = random.uniform(0.12, 0.88) * HEIGHT + ang = random.uniform(0.0, 2.0 * math.pi) + bfx = math.cos(ang) * BURST_FORCE + bfy = math.sin(ang) * BURST_FORCE + br, bg, bb = colorsys.hsv_to_rgb(random.random(), 0.9, 1.0) + launch( + stream, + config, + kernels["splat"], + np.uint64(vel_live_surf().handle), + np.uint64(dye_live_surf().handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.float32(bx), + np.float32(by), + np.float32(bfx), + np.float32(bfy), + np.float32(BURST_RADIUS), + np.float32(br * BURST_DYE), + np.float32(bg * BURST_DYE), + np.float32(bb * BURST_DYE), + np.int32(1), + ) + + # (b3) Vorticity confinement: read the live velocity through its + # TextureObject, compute curl + grad|curl|, and add a force that + # pushes velocity back toward high-vorticity regions -- this is the + # one extra kernel that sharpens the curling plumes. Like + # advect_velocity, it reads neighbor velocities, so it MUST + # ping-pong (read old buffer, write the other) -- aliasing a + # texture read with a surface write of the same array in one launch + # is undefined. + if VORTICITY > 0.0: + vort_read, vort_write, vort_next = vel_pair() + launch( + stream, + config, + kernels["vorticity"], + np.uint64(vort_read.handle), + np.uint64(vort_write.handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.float32(dt_adv), + np.float32(VORTICITY), + ) + state["vel"] = vort_next + + # (c) Compute divergence of the live velocity field. + launch( + stream, + config, + kernels["divergence"], + np.uint64(vel_live_tex().handle), + np.uint64(div_surf.handle), + np.int32(WIDTH), + np.int32(HEIGHT), + ) + + # (d) Pressure solve: Jacobi-iterate lap(p) = div, ping-ponging pressure. + # Start from a cleared pressure field (prs_a) each frame. + launch( + stream, + config, + kernels["jacobi"], + np.uint64(prs_tex_a.handle), # ignored on the first pass via clear flag + np.uint64(div_tex.handle), + np.uint64(prs_surf_b.handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.int32(1), # clear: treat the previous pressure as zero + ) + # After the clearing pass the result lives in prs_b. Continue iterating. + prs_cur = "b" + for _ in range(PRESSURE_ITERS - 1): + if prs_cur == "b": + read_tex, write_surf, prs_cur = prs_tex_b, prs_surf_a, "a" + else: + read_tex, write_surf, prs_cur = prs_tex_a, prs_surf_b, "b" + launch( + stream, + config, + kernels["jacobi"], + np.uint64(read_tex.handle), + np.uint64(div_tex.handle), + np.uint64(write_surf.handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.int32(0), # do not clear: read the previous pressure + ) + # `prs_cur` now names the buffer holding the converged pressure. + prs_final_tex = prs_tex_a if prs_cur == "a" else prs_tex_b + + # (e) Subtract pressure gradient from the live velocity (in-place). + launch( + stream, + config, + kernels["subtract"], + np.uint64(prs_final_tex.handle), + np.uint64(vel_live_surf().handle), + np.int32(WIDTH), + np.int32(HEIGHT), + ) + + # (f) Advect the dye along the (now divergence-free) velocity field. + dye_read, dye_write, dye_next = dye_pair() + launch( + stream, + config, + kernels["advect_dye"], + np.uint64(dye_read.handle), + np.uint64(vel_live_tex().handle), + np.uint64(dye_write.handle), + np.int32(WIDTH), + np.int32(HEIGHT), + np.float32(dt_adv), + np.float32(dye_diss), + ) + state["dye"] = dye_next + + # (g) Colorize the latest dye into the OpenGL PBO. + with resource.map(stream=stream) as buf: + launch( + stream, + config, + kernels["colorize"], + np.uint64(dye_live_tex().handle), + buf.handle, + np.int32(WIDTH), + np.int32(HEIGHT), + ) + # Unmap happens automatically when the `with` block exits. + + # (h) Tell OpenGL to copy the PBO contents into our texture. + copy_pbo_to_texture(gl, pbo_id, tex_id, WIDTH, HEIGHT) + + # (i) Draw the texture to the screen. + draw_fullscreen_quad(gl, shader_prog, quad_vao, tex_id) + + # Reset the per-frame mouse delta so a held-still cursor stops pushing. + mouse["dx"] = 0.0 + mouse["dy"] = 0.0 + + # FPS counter (shown in window title) + frame_count += 1 + now = time.monotonic() + if now - fps_time >= 1.0: + fps = frame_count / (now - fps_time) + window.set_caption( + "cuda.core CUDAArray/Texture/Surface - Stable Fluids" + f" ({WIDTH}x{HEIGHT}, {fps:.0f} FPS," + f" {PRESSURE_ITERS} pressure iters)" + " | TextureObject[LINEAR|CLAMP|norm|float2]" + " + SurfaceObject writes + GraphicsResource(PBO)" + ) + frame_count = 0 + fps_time = now + + @window.event + def on_close(): + # Release everything we opened, in reverse order. Each of these is a + # context manager too, but pyglet owns the event loop here so we + # release explicitly to be deterministic about ordering. + resource.close() + dye_tex_a.close() + dye_tex_b.close() + dye_surf_a.close() + dye_surf_b.close() + div_tex.close() + div_surf.close() + prs_tex_a.close() + prs_tex_b.close() + prs_surf_a.close() + prs_surf_b.close() + vel_tex_a.close() + vel_tex_b.close() + vel_surf_a.close() + vel_surf_b.close() + dye_a.close() + dye_b.close() + div.close() + prs_a.close() + prs_b.close() + vel_a.close() + vel_b.close() + stream.close() + + # Render as fast as the GPU allows; the per-step rates are scaled by real + # elapsed time (see REF_FPS) so the look is frame-rate independent. + pyglet.app.run(interval=0) + + +# ======================== GPU code (CUDA + GLSL) ============================ +# +# These source strings are kept at the bottom of the file so they don't +# distract from the Python logic above. The important things to know: +# +# - KERNEL_SOURCE contains the eight CUDA C++ kernels of the Stable Fluids +# pipeline. Reads go through cudaTextureObject_t (LINEAR + CLAMP + +# normalized coords); writes go through cudaSurfaceObject_t with the x +# offset in BYTES. A small helper converts pixel coords to normalized +# texel-center coords. +# +# - VERTEX_SHADER_SOURCE / FRAGMENT_SHADER_SOURCE are GLSL. They draw a +# texture onto a rectangle covering the entire window. Nothing interesting. +# +# ============================================================================ + +KERNEL_SOURCE = r""" +// Sample a float2 (velocity) field at pixel center (px, py) with bilinear +// filtering. CLAMP addressing keeps out-of-range traces at the border. +__device__ __forceinline__ +float2 sample_vec(cudaTextureObject_t tex, float px, float py, + int width, int height) { + float u = (px + 0.5f) / (float)width; + float v = (py + 0.5f) / (float)height; + return tex2D(tex, u, v); +} + +// Sample a scalar (float) field at pixel center (px, py) with bilinear filtering. +__device__ __forceinline__ +float sample_scalar(cudaTextureObject_t tex, float px, float py, + int width, int height) { + float u = (px + 0.5f) / (float)width; + float v = (py + 0.5f) / (float)height; + return tex2D(tex, u, v); +} + +// Sample a float4 (RGBA dye) field at pixel center with bilinear filtering. +__device__ __forceinline__ +float4 sample_color(cudaTextureObject_t tex, float px, float py, + int width, int height) { + float u = (px + 0.5f) / (float)width; + float v = (py + 0.5f) / (float)height; + return tex2D(tex, u, v); +} + +extern "C" +__global__ +void seed_field(cudaSurfaceObject_t vel_surf, + cudaSurfaceObject_t dye_surf, + cudaSurfaceObject_t prs_surf, + int width, int height, + float curl, unsigned int seed) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + // Seed a gentle global rotation: velocity perpendicular to the radius from + // the center gives a curl, so even with no mouse input there is motion. + float cx = width * 0.5f; + float cy = height * 0.5f; + float rx = (x - cx) / cx; // ~[-1, 1] + float ry = (y - cy) / cy; + float2 vel = make_float2(-ry * curl, rx * curl); + + // A touch of deterministic noise so successive resets look a little + // different and to break perfect symmetry. + unsigned int h = (unsigned int)x * 374761393u + + (unsigned int)y * 668265263u + seed * 2246822519u; + h = (h ^ (h >> 13)) * 1274126177u; + h = h ^ (h >> 16); + float noise = ((h & 0xffffu) / 65535.0f) - 0.5f; // [-0.5, 0.5] + vel.x += noise * 0.2f; + vel.y += noise * 0.2f; + + // Dye starts black; the colored bursts (or the mouse) paint the ink, so + // there is nothing to seed here beyond clearing to zero. + surf2Dwrite(vel, vel_surf, x * (int)sizeof(float2), y); + surf2Dwrite(make_float4(0.0f, 0.0f, 0.0f, 0.0f), dye_surf, + x * (int)sizeof(float4), y); + surf2Dwrite(0.0f, prs_surf, x * (int)sizeof(float), y); +} + +// Inject mouse-drag velocity and dye into a soft radial brush around the +// cursor. In-place read-modify-write: each thread owns its own cell, no race. +extern "C" +__global__ +void splat(cudaSurfaceObject_t vel_surf, + cudaSurfaceObject_t dye_surf, + int width, int height, + float mx, float my, + float fx, float fy, + float radius, float dr, float dg, float db, + int inject) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + if (!inject) return; + + float dx = (float)x - mx; + float dy = (float)y - my; + float d2 = dx * dx + dy * dy; + float falloff = expf(-d2 / (radius * radius)); + if (falloff < 1e-3f) return; + + float2 vel; + surf2Dread(&vel, vel_surf, x * (int)sizeof(float2), y); + vel.x += fx * falloff; + vel.y += fy * falloff; + surf2Dwrite(vel, vel_surf, x * (int)sizeof(float2), y); + + // Additive colored ink. float4 surface element is 16 bytes. + float4 dye; + surf2Dread(&dye, dye_surf, x * (int)sizeof(float4), y); + dye.x += dr * falloff; + dye.y += dg * falloff; + dye.z += db * falloff; + dye.w = 1.0f; + surf2Dwrite(dye, dye_surf, x * (int)sizeof(float4), y); +} + +// Semi-Lagrangian advection of the velocity field along itself. +extern "C" +__global__ +void advect_velocity(cudaTextureObject_t vel_tex, + cudaSurfaceObject_t vel_out, + int width, int height, + float dt, float dissipation) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float2 v = sample_vec(vel_tex, (float)x, (float)y, width, height); + // Trace this cell's center backward along the velocity field. + float px = (float)x - dt * v.x; + float py = (float)y - dt * v.y; + float2 advected = sample_vec(vel_tex, px, py, width, height); + advected.x *= dissipation; + advected.y *= dissipation; + surf2Dwrite(advected, vel_out, x * (int)sizeof(float2), y); +} + +// Vorticity confinement. Curl of a 2D velocity field is the scalar +// w = dVy/dx - dVx/dy. Where |w| has a gradient we add a force that pushes +// velocity along the swirl, reinjecting the small-scale rotation that +// numerical diffusion smears away -- the result is crisper, longer-lived +// curls. Reads neighbor velocities through the TextureObject and writes the +// updated velocity to a SEPARATE ping-pong buffer (no read/write aliasing). +__device__ __forceinline__ +float curl_at(cudaTextureObject_t vel_tex, float px, float py, + int width, int height) { + float2 l = sample_vec(vel_tex, px - 1.0f, py, width, height); + float2 r = sample_vec(vel_tex, px + 1.0f, py, width, height); + float2 d = sample_vec(vel_tex, px, py - 1.0f, width, height); + float2 u = sample_vec(vel_tex, px, py + 1.0f, width, height); + return 0.5f * ((r.y - l.y) - (u.x - d.x)); +} + +extern "C" +__global__ +void vorticity_confinement(cudaTextureObject_t vel_tex, + cudaSurfaceObject_t vel_out, + int width, int height, + float dt, float eps) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float fx = (float)x; + float fy = (float)y; + + // Curl at this cell and at the 4 neighbors (for grad|curl|). + float w = curl_at(vel_tex, fx, fy, width, height); + float wl = curl_at(vel_tex, fx - 1.0f, fy, width, height); + float wr = curl_at(vel_tex, fx + 1.0f, fy, width, height); + float wd = curl_at(vel_tex, fx, fy - 1.0f, width, height); + float wu = curl_at(vel_tex, fx, fy + 1.0f, width, height); + + // Gradient of |curl|, normalized to a unit direction N. + float gx = 0.5f * (fabsf(wr) - fabsf(wl)); + float gy = 0.5f * (fabsf(wu) - fabsf(wd)); + float len = sqrtf(gx * gx + gy * gy) + 1e-5f; + float nx = gx / len; + float ny = gy / len; + + // Confinement force = eps * (N x w_hat). In 2D: (N_y * w, -N_x * w). + float2 v = sample_vec(vel_tex, fx, fy, width, height); + v.x += eps * dt * (ny * w); + v.y += eps * dt * (-nx * w); + surf2Dwrite(v, vel_out, x * (int)sizeof(float2), y); +} + +// Divergence of the velocity field (central differences), written as a scalar. +extern "C" +__global__ +void divergence(cudaTextureObject_t vel_tex, + cudaSurfaceObject_t div_out, + int width, int height) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float2 l = sample_vec(vel_tex, (float)x - 1.0f, (float)y, width, height); + float2 r = sample_vec(vel_tex, (float)x + 1.0f, (float)y, width, height); + float2 d = sample_vec(vel_tex, (float)x, (float)y - 1.0f, width, height); + float2 u = sample_vec(vel_tex, (float)x, (float)y + 1.0f, width, height); + + float div = 0.5f * ((r.x - l.x) + (u.y - d.y)); + surf2Dwrite(div, div_out, x * (int)sizeof(float), y); +} + +// One Jacobi iteration of lap(p) = div. With unit grid spacing the update is +// p = (p_left + p_right + p_down + p_up - div) / 4. When `clear` is set the +// previous pressure is treated as zero so the first pass starts clean. +extern "C" +__global__ +void pressure_jacobi(cudaTextureObject_t prs_tex, + cudaTextureObject_t div_tex, + cudaSurfaceObject_t prs_out, + int width, int height, + int clear) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float pl = 0.0f, pr = 0.0f, pd = 0.0f, pu = 0.0f; + if (!clear) { + pl = sample_scalar(prs_tex, (float)x - 1.0f, (float)y, width, height); + pr = sample_scalar(prs_tex, (float)x + 1.0f, (float)y, width, height); + pd = sample_scalar(prs_tex, (float)x, (float)y - 1.0f, width, height); + pu = sample_scalar(prs_tex, (float)x, (float)y + 1.0f, width, height); + } + float div = sample_scalar(div_tex, (float)x, (float)y, width, height); + float p = (pl + pr + pd + pu - div) * 0.25f; + surf2Dwrite(p, prs_out, x * (int)sizeof(float), y); +} + +// v <- v - grad(p): project the velocity onto its divergence-free part. +extern "C" +__global__ +void subtract_gradient(cudaTextureObject_t prs_tex, + cudaSurfaceObject_t vel_surf, + int width, int height) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float pl = sample_scalar(prs_tex, (float)x - 1.0f, (float)y, width, height); + float pr = sample_scalar(prs_tex, (float)x + 1.0f, (float)y, width, height); + float pd = sample_scalar(prs_tex, (float)x, (float)y - 1.0f, width, height); + float pu = sample_scalar(prs_tex, (float)x, (float)y + 1.0f, width, height); + + float2 v; + surf2Dread(&v, vel_surf, x * (int)sizeof(float2), y); + v.x -= 0.5f * (pr - pl); + v.y -= 0.5f * (pu - pd); + surf2Dwrite(v, vel_surf, x * (int)sizeof(float2), y); +} + +// Semi-Lagrangian advection of the dye along the velocity field. +extern "C" +__global__ +void advect_dye(cudaTextureObject_t dye_tex, + cudaTextureObject_t vel_tex, + cudaSurfaceObject_t dye_out, + int width, int height, + float dt, float dissipation) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float2 v = sample_vec(vel_tex, (float)x, (float)y, width, height); + float px = (float)x - dt * v.x; + float py = (float)y - dt * v.y; + float4 d = sample_color(dye_tex, px, py, width, height); + d.x *= dissipation; + d.y *= dissipation; + d.z *= dissipation; + d.w *= dissipation; + surf2Dwrite(d, dye_out, x * (int)sizeof(float4), y); +} + +// Tonemap the accumulated float4 dye color into the PBO. The ink color is +// whatever the bursts/mouse injected and advection mixed; we apply a filmic +// 1 - exp(-c) curve so dense ink stays vivid without harshly clipping. +extern "C" +__global__ +void colorize(cudaTextureObject_t dye_tex, + unsigned char* output, + int width, int height) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float4 c = sample_color(dye_tex, (float)x, (float)y, width, height); + const float gain = 1.3f; + float r = 1.0f - expf(-fmaxf(c.x, 0.0f) * gain); + float g = 1.0f - expf(-fmaxf(c.y, 0.0f) * gain); + float b = 1.0f - expf(-fmaxf(c.z, 0.0f) * gain); + + int idx = (y * width + x) * 4; + output[idx + 0] = (unsigned char)(r * 255.0f); + output[idx + 1] = (unsigned char)(g * 255.0f); + output[idx + 2] = (unsigned char)(b * 255.0f); + output[idx + 3] = 255; +} +""" + +# GLSL shaders -- these just display a texture on a fullscreen rectangle. +# Nothing CUDA-specific here. + +VERTEX_SHADER_SOURCE = """#version 330 core +in vec2 position; +in vec2 texcoord; +out vec2 v_texcoord; +void main() { + gl_Position = vec4(position, 0.0, 1.0); + v_texcoord = texcoord; +} +""" + +FRAGMENT_SHADER_SOURCE = """#version 330 core +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; +void main() { + fragColor = texture(tex, v_texcoord); +} +""" + + +if __name__ == "__main__": + main() diff --git a/cuda_core/examples/gl_interop_fluid_numba_cuda_mlir.py b/cuda_core/examples/gl_interop_fluid_numba_cuda_mlir.py new file mode 100644 index 00000000000..712929f04bf --- /dev/null +++ b/cuda_core/examples/gl_interop_fluid_numba_cuda_mlir.py @@ -0,0 +1,631 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +# ################################################################################ +# +# A numba-cuda port of gl_interop_fluid.py (Jos Stam "Stable Fluids"). +# +# The original example is a cuda.core showcase: each field is a `cudaArray` +# bound both as a TextureObject (cached, hardware-filtered READS) and a +# SurfaceObject (raw WRITES), and semi-Lagrangian advection is a single +# `tex2D` LINEAR fetch at a fractional back-traced coordinate. +# +# numba-cuda has NO texture or surface support (no tex2D, no surf2Dwrite, no +# cudaArray binding). So this port shows what the SAME solver looks like when +# every field is an ordinary linear device array and the hardware bilinear +# filter is written by hand (see `sample_*` below). The physics is identical; +# only the memory model and the read path change. +# +# What changes vs. the cuda.core version +# ======================================= +# cuda.core / CUDA C++ -> numba-cuda (this file) +# -------------------------------------- ----------------------------------- +# CUDAArray(num_channels=2) as texture -> cuda.device_array((H, W, 2), f32) +# tex2D(tex, u, v) [HW LINEAR] -> sample_vec(arr, px, py) [manual lerp] +# AddressMode.CLAMP -> index clamp inside sample_*() +# surf2Dwrite(v, surf, x*8, y) -> arr[y, x, 0] = v.x; arr[y, x, 1] = v.y +# TextureObject + SurfaceObject pair -> one device array; ping-pong by swap +# GraphicsResource PBO (zero-copy) -> copy_to_host + glTexSubImage2D +# +# This file is intentionally self-contained: numba-cuda + pyglet + numpy only. +# It does not import cuda.core. Run it next to gl_interop_fluid.py to compare. +# +# /// script +# dependencies = ["numba-cuda-mlir", "pyglet", "numpy"] +# /// + +import colorsys +import ctypes +import math +import random +import sys +import time + +import numpy as np + +# This port targets the MLIR-based numba-cuda backend (`numba-cuda-mlir`), which +# tracks the current cuda.bindings / cuda.core API. It exposes the same +# `cuda.jit` / `cuda.grid` / device-array surface as stock `numba.cuda`, so the +# kernels below are unchanged. Fall back to stock `numba.cuda` for environments +# that only ship the classic backend. +try: + from numba_cuda_mlir import cuda +except ImportError: + from numba import cuda + +# --------------------------------------------------------------------------- # +# Simulation parameters (same values as gl_interop_fluid.py) +# --------------------------------------------------------------------------- # +WIDTH = 512 +HEIGHT = 512 +DT = 1.0 +PRESSURE_ITERS = 30 +VELOCITY_DISSIPATION = 0.999 +DYE_DISSIPATION = 0.994 +SPLAT_RADIUS = 24.0 +SPLAT_FORCE = 6.0 +SPLAT_DYE = 1.0 +CURL_SEED = 2.5 +VORTICITY = 0.28 + +AUTO_EMIT = True +BURST_INTERVAL = 0.45 +BURSTS_PER_EVENT = 2 +BURST_RADIUS = 42.0 +BURST_FORCE = 18.0 +BURST_DYE = 1.2 + +REF_FPS = 60.0 + +# =============================== Device helpers ============================= # +# +# These replace the texture unit. A cudaArray bound LINEAR + CLAMP + normalized +# turns one `tex2D` call into a hardware bilinear read with edge clamping. With +# linear device memory we do the same arithmetic explicitly: locate the four +# texel centers around the (fractional) sample point, clamp each to the edge, +# and blend. Sampling at an integer pixel center returns the stored value +# exactly, which is why the stencil kernels (divergence/jacobi/gradient) can use +# the same sampler the advection kernels use. + + +@cuda.jit(device=True, inline=True) +def _clampi(i, n): + # AddressMode.CLAMP: out-of-range coordinates read the border texel. + if i < 0: + return 0 + if i > n - 1: + return n - 1 + return i + + +@cuda.jit(device=True, inline=True) +def _bilinear_setup(px, py, w, h): + # Shared front half of every sampler: pixel-center coords -> (corner + # indices, fractional weights). px/py are in pixel space where an integer + # value addresses a texel center, matching the (i + 0.5)/N convention the + # C++ version feeds to tex2D. + # Keep the explicit int(): stock numba.cuda's math.floor returns a float + # (unlike CPython), and a float can't index an array. RUF046 only sees the + # CPython return type, so it is a false positive here. + x0 = int(math.floor(px)) # noqa: RUF046 + y0 = int(math.floor(py)) # noqa: RUF046 + fx = px - x0 + fy = py - y0 + x0c = _clampi(x0, w) + x1c = _clampi(x0 + 1, w) + y0c = _clampi(y0, h) + y1c = _clampi(y0 + 1, h) + return x0c, x1c, y0c, y1c, fx, fy + + +@cuda.jit(device=True, inline=True) +def sample_scalar(fld, px, py, w, h): + # Equivalent of tex2D(tex, u, v) with LINEAR + CLAMP. + x0c, x1c, y0c, y1c, fx, fy = _bilinear_setup(px, py, w, h) + top = fld[y0c, x0c] * (1.0 - fx) + fld[y0c, x1c] * fx + bot = fld[y1c, x0c] * (1.0 - fx) + fld[y1c, x1c] * fx + return top * (1.0 - fy) + bot * fy + + +@cuda.jit(device=True, inline=True) +def sample_vec(fld, px, py, w, h): + # Equivalent of tex2D(tex, u, v). Returns (vx, vy) as a tuple -- + # numba device functions can return tuples, so this reads almost like the + # float2 the C++ version returns. + x0c, x1c, y0c, y1c, fx, fy = _bilinear_setup(px, py, w, h) + g = 1.0 - fx + h0 = 1.0 - fy + vx = (fld[y0c, x0c, 0] * g + fld[y0c, x1c, 0] * fx) * h0 + (fld[y1c, x0c, 0] * g + fld[y1c, x1c, 0] * fx) * fy + vy = (fld[y0c, x0c, 1] * g + fld[y0c, x1c, 1] * fx) * h0 + (fld[y1c, x0c, 1] * g + fld[y1c, x1c, 1] * fx) * fy + return vx, vy + + +@cuda.jit(device=True, inline=True) +def sample_color(fld, px, py, w, h): + # Equivalent of tex2D(tex, u, v). Returns (r, g, b, a). + x0c, x1c, y0c, y1c, fx, fy = _bilinear_setup(px, py, w, h) + g = 1.0 - fx + h0 = 1.0 - fy + out0 = (fld[y0c, x0c, 0] * g + fld[y0c, x1c, 0] * fx) * h0 + (fld[y1c, x0c, 0] * g + fld[y1c, x1c, 0] * fx) * fy + out1 = (fld[y0c, x0c, 1] * g + fld[y0c, x1c, 1] * fx) * h0 + (fld[y1c, x0c, 1] * g + fld[y1c, x1c, 1] * fx) * fy + out2 = (fld[y0c, x0c, 2] * g + fld[y0c, x1c, 2] * fx) * h0 + (fld[y1c, x0c, 2] * g + fld[y1c, x1c, 2] * fx) * fy + out3 = (fld[y0c, x0c, 3] * g + fld[y0c, x1c, 3] * fx) * h0 + (fld[y1c, x0c, 3] * g + fld[y1c, x1c, 3] * fx) * fy + return out0, out1, out2, out3 + + +@cuda.jit(device=True, inline=True) +def curl_at(vel, px, py, w, h): + # Scalar 2D curl w = dVy/dx - dVx/dy via central differences. + lx, ly = sample_vec(vel, px - 1.0, py, w, h) + rx, ry = sample_vec(vel, px + 1.0, py, w, h) + dx_, dy_ = sample_vec(vel, px, py - 1.0, w, h) + ux, uy = sample_vec(vel, px, py + 1.0, w, h) + return 0.5 * ((ry - ly) - (ux - dx_)) + + +# ================================= Kernels ================================== # +# +# One thread per cell. cuda.grid(2) returns (x, y) with x fastest, matching the +# blockIdx.x*blockDim.x+threadIdx.x layout of the C++ kernels. Arrays are +# indexed [y, x] (row-major), so writes go to fld[y, x]. + + +@cuda.jit +def seed_field(vel, dye, prs, w, h, curl, seed): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + + cx = w * 0.5 + cy = h * 0.5 + rx = (x - cx) / cx + ry = (y - cy) / cy + vx = -ry * curl + vy = rx * curl + + # Same integer hash as the C++ version; mask to 32 bits to emulate uint32. + hsh = (x * 374761393 + y * 668265263 + seed * 2246822519) & 0xFFFFFFFF + hsh = ((hsh ^ (hsh >> 13)) * 1274126177) & 0xFFFFFFFF + hsh = (hsh ^ (hsh >> 16)) & 0xFFFFFFFF + noise = ((hsh & 0xFFFF) / 65535.0) - 0.5 + + vel[y, x, 0] = vx + noise * 0.2 + vel[y, x, 1] = vy + noise * 0.2 + dye[y, x, 0] = 0.0 + dye[y, x, 1] = 0.0 + dye[y, x, 2] = 0.0 + dye[y, x, 3] = 0.0 + prs[y, x] = 0.0 + + +@cuda.jit +def splat(vel, dye, w, h, mx, my, fx, fy, radius, dr, dg, db, inject): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + if inject == 0: + return + + dx = x - mx + dy = y - my + falloff = math.exp(-(dx * dx + dy * dy) / (radius * radius)) + if falloff < 1e-3: + return + + # In-place read-modify-write; each thread owns its own cell, so no race. + vel[y, x, 0] += fx * falloff + vel[y, x, 1] += fy * falloff + dye[y, x, 0] += dr * falloff + dye[y, x, 1] += dg * falloff + dye[y, x, 2] += db * falloff + dye[y, x, 3] = 1.0 + + +@cuda.jit +def advect_velocity(vel_in, vel_out, w, h, dt, diss): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + vx, vy = sample_vec(vel_in, float(x), float(y), w, h) + # Back-trace the cell center one timestep against the local velocity. + px = x - dt * vx + py = y - dt * vy + ax, ay = sample_vec(vel_in, px, py, w, h) + vel_out[y, x, 0] = ax * diss + vel_out[y, x, 1] = ay * diss + + +@cuda.jit +def vorticity_confinement(vel_in, vel_out, w, h, dt, eps): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + fx = float(x) + fy = float(y) + + wc = curl_at(vel_in, fx, fy, w, h) + wl = curl_at(vel_in, fx - 1.0, fy, w, h) + wr = curl_at(vel_in, fx + 1.0, fy, w, h) + wd = curl_at(vel_in, fx, fy - 1.0, w, h) + wu = curl_at(vel_in, fx, fy + 1.0, w, h) + + gx = 0.5 * (abs(wr) - abs(wl)) + gy = 0.5 * (abs(wu) - abs(wd)) + length = math.sqrt(gx * gx + gy * gy) + 1e-5 + nx = gx / length + ny = gy / length + + vx, vy = sample_vec(vel_in, fx, fy, w, h) + vel_out[y, x, 0] = vx + eps * dt * (ny * wc) + vel_out[y, x, 1] = vy + eps * dt * (-nx * wc) + + +@cuda.jit +def divergence(vel, div_out, w, h): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + lx, ly = sample_vec(vel, x - 1.0, float(y), w, h) + rx, ry = sample_vec(vel, x + 1.0, float(y), w, h) + dx_, dy_ = sample_vec(vel, float(x), y - 1.0, w, h) + ux, uy = sample_vec(vel, float(x), y + 1.0, w, h) + div_out[y, x] = 0.5 * ((rx - lx) + (uy - dy_)) + + +@cuda.jit +def pressure_jacobi(prs_in, div, prs_out, w, h, clear): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + pl = 0.0 + pr = 0.0 + pd = 0.0 + pu = 0.0 + if clear == 0: + pl = sample_scalar(prs_in, x - 1.0, float(y), w, h) + pr = sample_scalar(prs_in, x + 1.0, float(y), w, h) + pd = sample_scalar(prs_in, float(x), y - 1.0, w, h) + pu = sample_scalar(prs_in, float(x), y + 1.0, w, h) + d = sample_scalar(div, float(x), float(y), w, h) + prs_out[y, x] = (pl + pr + pd + pu - d) * 0.25 + + +@cuda.jit +def subtract_gradient(prs, vel, w, h): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + pl = sample_scalar(prs, x - 1.0, float(y), w, h) + pr = sample_scalar(prs, x + 1.0, float(y), w, h) + pd = sample_scalar(prs, float(x), y - 1.0, w, h) + pu = sample_scalar(prs, float(x), y + 1.0, w, h) + vel[y, x, 0] -= 0.5 * (pr - pl) + vel[y, x, 1] -= 0.5 * (pu - pd) + + +@cuda.jit +def advect_dye(dye_in, vel, dye_out, w, h, dt, diss): + x, y = cuda.grid(2) + if x >= w or y >= h: + return + vx, vy = sample_vec(vel, float(x), float(y), w, h) + px = x - dt * vx + py = y - dt * vy + r, g, b, a = sample_color(dye_in, px, py, w, h) + dye_out[y, x, 0] = r * diss + dye_out[y, x, 1] = g * diss + dye_out[y, x, 2] = b * diss + dye_out[y, x, 3] = a * diss + + +@cuda.jit +def colorize(dye, out, w, h): + # Filmic 1 - exp(-c) tonemap into an RGBA8 buffer (flat, row-major). + x, y = cuda.grid(2) + if x >= w or y >= h: + return + r, g, b, a = sample_color(dye, float(x), float(y), w, h) + gain = 1.3 + rr = 1.0 - math.exp(-max(r, 0.0) * gain) + gg = 1.0 - math.exp(-max(g, 0.0) * gain) + bb = 1.0 - math.exp(-max(b, 0.0) * gain) + idx = (y * w + x) * 4 + out[idx + 0] = np.uint8(rr * 255.0) + out[idx + 1] = np.uint8(gg * 255.0) + out[idx + 2] = np.uint8(bb * 255.0) + out[idx + 3] = np.uint8(255) + + +# ============================== Display (GL) ================================ # +# +# Pure OpenGL boilerplate, unchanged in spirit from gl_interop_fluid.py. The +# only difference: instead of a CUDA-registered PBO, the colorized frame is +# copied to host and uploaded with glTexSubImage2D. For a 512x512 demo that is +# ~1 MB/frame and not the bottleneck; see the note at the bottom of the file +# for the zero-copy upgrade. + +VERTEX_SHADER_SOURCE = """#version 330 core +in vec2 position; +in vec2 texcoord; +out vec2 v_texcoord; +void main() { + gl_Position = vec4(position, 0.0, 1.0); + v_texcoord = texcoord; +} +""" + +FRAGMENT_SHADER_SOURCE = """#version 330 core +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; +void main() { fragColor = texture(tex, v_texcoord); } +""" + + +def create_window(): + try: + import pyglet + from pyglet.gl import gl as _gl + except ImportError: + print("This example requires pyglet >= 2.0: pip install pyglet", file=sys.stderr) + sys.exit(1) + window = pyglet.window.Window(WIDTH, HEIGHT, caption="numba-cuda - Stable Fluids", vsync=False) + return window, _gl, pyglet + + +def create_display_resources(gl): + from pyglet.graphics.shader import Shader, ShaderProgram + + shader_prog = ShaderProgram(Shader(VERTEX_SHADER_SOURCE, "vertex"), Shader(FRAGMENT_SHADER_SOURCE, "fragment")) + quad = np.array( + [-1, -1, 0, 0, 1, -1, 1, 0, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, 1, 1, -1, 1, 0, 1], + dtype=np.float32, + ) + vao = ctypes.c_uint(0) + gl.glGenVertexArrays(1, ctypes.byref(vao)) + gl.glBindVertexArray(vao.value) + vbo = ctypes.c_uint(0) + gl.glGenBuffers(1, ctypes.byref(vbo)) + gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo.value) + gl.glBufferData(gl.GL_ARRAY_BUFFER, quad.nbytes, quad.ctypes.data_as(ctypes.c_void_p), gl.GL_STATIC_DRAW) + stride = 16 + pos = gl.glGetAttribLocation(shader_prog.id, b"position") + gl.glEnableVertexAttribArray(pos) + gl.glVertexAttribPointer(pos, 2, gl.GL_FLOAT, gl.GL_FALSE, stride, ctypes.c_void_p(0)) + tc = gl.glGetAttribLocation(shader_prog.id, b"texcoord") + gl.glEnableVertexAttribArray(tc) + gl.glVertexAttribPointer(tc, 2, gl.GL_FLOAT, gl.GL_FALSE, stride, ctypes.c_void_p(8)) + gl.glBindVertexArray(0) + + tex = ctypes.c_uint(0) + gl.glGenTextures(1, ctypes.byref(tex)) + gl.glBindTexture(gl.GL_TEXTURE_2D, tex.value) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) + gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA8, WIDTH, HEIGHT, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, None) + return shader_prog, vao.value, tex.value + + +def upload_and_draw(gl, shader_prog, vao_id, tex_id, host_rgba): + gl.glBindTexture(gl.GL_TEXTURE_2D, tex_id) + gl.glTexSubImage2D( + gl.GL_TEXTURE_2D, + 0, + 0, + 0, + WIDTH, + HEIGHT, + gl.GL_RGBA, + gl.GL_UNSIGNED_BYTE, + host_rgba.ctypes.data_as(ctypes.c_void_p), + ) + gl.glUseProgram(shader_prog.id) + gl.glBindVertexArray(vao_id) + gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) + gl.glBindVertexArray(0) + gl.glUseProgram(0) + + +# ================================== main() ================================== # + + +def main(): + if not cuda.is_available(): + print("No CUDA GPU available to numba.", file=sys.stderr) + sys.exit(1) + + window, gl, pyglet = create_window() + shader_prog, quad_vao, tex_id = create_display_resources(gl) + + stream = cuda.stream() + block = (16, 16) + grid = ((WIDTH + 15) // 16, (HEIGHT + 15) // 16) + + # Fields as linear device arrays. velocity = (H, W, 2), dye = (H, W, 4), + # pressure/divergence = (H, W). The a/b pairs ping-pong; we swap references. + f32 = np.float32 + vel_a = cuda.device_array((HEIGHT, WIDTH, 2), f32) + vel_b = cuda.device_array((HEIGHT, WIDTH, 2), f32) + prs_a = cuda.device_array((HEIGHT, WIDTH), f32) + prs_b = cuda.device_array((HEIGHT, WIDTH), f32) + div = cuda.device_array((HEIGHT, WIDTH), f32) + dye_a = cuda.device_array((HEIGHT, WIDTH, 4), f32) + dye_b = cuda.device_array((HEIGHT, WIDTH, 4), f32) + + # Colorized frame: device buffer + a pinned host buffer for fast copyback. + rgba_dev = cuda.device_array(WIDTH * HEIGHT * 4, np.uint8) + rgba_host = cuda.pinned_array(WIDTH * HEIGHT * 4, np.uint8) + + fields = {"vel": [vel_a, vel_b], "prs": [prs_a, prs_b], "dye": [dye_a, dye_b]} + + seed_field[grid, block, stream](vel_a, dye_a, prs_a, WIDTH, HEIGHT, CURL_SEED, 0) + stream.synchronize() + + mouse = {"down": False, "x": 0.0, "y": 0.0, "dx": 0.0, "dy": 0.0} + state = {"seed": 0, "next_burst": 0.0} + start_time = time.monotonic() + clock = {"last": start_time} + frame = {"n": 0, "t": start_time} + + def w2s(x, y): + return float(x), float(HEIGHT - 1 - y) + + @window.event + def on_key_press(symbol, _mods): + key = pyglet.window.key + if symbol == key.ESCAPE: + window.close() + elif symbol == key.R: + state["seed"] += 1 + seed_field[grid, block, stream]( + fields["vel"][0], fields["dye"][0], fields["prs"][0], WIDTH, HEIGHT, CURL_SEED, state["seed"] + ) + + @window.event + def on_mouse_press(x, y, *_): + mouse["down"] = True + mouse["x"], mouse["y"] = w2s(x, y) + mouse["dx"] = mouse["dy"] = 0.0 + + @window.event + def on_mouse_release(*_): + mouse["down"] = False + mouse["dx"] = mouse["dy"] = 0.0 + + @window.event + def on_mouse_drag(x, y, dx, dy, *_): + mouse["down"] = True + mouse["x"], mouse["y"] = w2s(x, y) + mouse["dx"] = float(dx) + mouse["dy"] = float(-dy) + + @window.event + def on_draw(): + window.clear() + now_t = time.monotonic() + elapsed = now_t - start_time + dt_real = now_t - clock["last"] + clock["last"] = now_t + step = min(max(dt_real * REF_FPS, 0.0), 3.0) + dt_adv = DT * step + vel_diss = VELOCITY_DISSIPATION**step + dye_diss = DYE_DISSIPATION**step + + vel, dye, prs = fields["vel"], fields["dye"], fields["prs"] + + # (a) advect velocity along itself + advect_velocity[grid, block, stream](vel[0], vel[1], WIDTH, HEIGHT, dt_adv, vel_diss) + vel.reverse() + + # (b) splat mouse velocity + colored dye (in-place on live buffers) + inject = 1 if mouse["down"] else 0 + mr, mg, mb = colorsys.hsv_to_rgb((elapsed * 0.15) % 1.0, 0.85, 1.0) + splat[grid, block, stream]( + vel[0], + dye[0], + WIDTH, + HEIGHT, + mouse["x"], + mouse["y"], + mouse["dx"] * SPLAT_FORCE, + mouse["dy"] * SPLAT_FORCE, + SPLAT_RADIUS, + mr * SPLAT_DYE, + mg * SPLAT_DYE, + mb * SPLAT_DYE, + inject, + ) + + # (b2) auto-bursts when idle + if AUTO_EMIT and not mouse["down"] and elapsed >= state["next_burst"]: + state["next_burst"] = elapsed + BURST_INTERVAL + for _ in range(BURSTS_PER_EVENT): + bx = random.uniform(0.12, 0.88) * WIDTH + by = random.uniform(0.12, 0.88) * HEIGHT + ang = random.uniform(0.0, 2.0 * math.pi) + br, bg, bb = colorsys.hsv_to_rgb(random.random(), 0.9, 1.0) + splat[grid, block, stream]( + vel[0], + dye[0], + WIDTH, + HEIGHT, + bx, + by, + math.cos(ang) * BURST_FORCE, + math.sin(ang) * BURST_FORCE, + BURST_RADIUS, + br * BURST_DYE, + bg * BURST_DYE, + bb * BURST_DYE, + 1, + ) + + # (b3) vorticity confinement (ping-pong: reads neighbors) + if VORTICITY > 0.0: + vorticity_confinement[grid, block, stream](vel[0], vel[1], WIDTH, HEIGHT, dt_adv, VORTICITY) + vel.reverse() + + # (c) divergence of the live velocity + divergence[grid, block, stream](vel[0], div, WIDTH, HEIGHT) + + # (d) pressure solve: first pass clears, then Jacobi-iterate + pressure_jacobi[grid, block, stream](prs[0], div, prs[1], WIDTH, HEIGHT, 1) + prs.reverse() + for _ in range(PRESSURE_ITERS - 1): + pressure_jacobi[grid, block, stream](prs[0], div, prs[1], WIDTH, HEIGHT, 0) + prs.reverse() + + # (e) subtract pressure gradient (in-place on live velocity) + subtract_gradient[grid, block, stream](prs[0], vel[0], WIDTH, HEIGHT) + + # (f) advect dye along the divergence-free velocity + advect_dye[grid, block, stream](dye[0], vel[0], dye[1], WIDTH, HEIGHT, dt_adv, dye_diss) + dye.reverse() + + # (g) colorize -> (h) copy to host -> (i) upload + draw + colorize[grid, block, stream](dye[0], rgba_dev, WIDTH, HEIGHT) + rgba_dev.copy_to_host(rgba_host, stream=stream) + stream.synchronize() + upload_and_draw(gl, shader_prog, quad_vao, tex_id, rgba_host) + + mouse["dx"] = mouse["dy"] = 0.0 + + frame["n"] += 1 + now = time.monotonic() + if now - frame["t"] >= 1.0: + fps = frame["n"] / (now - frame["t"]) + window.set_caption( + f"numba-cuda - Stable Fluids ({WIDTH}x{HEIGHT}, {fps:.0f} FPS, " + f"{PRESSURE_ITERS} pressure iters) | manual bilinear, linear device arrays" + ) + frame["n"] = 0 + frame["t"] = now + + pyglet.app.run(interval=0) + + +if __name__ == "__main__": + main() + +# ============================ Notes / next steps ============================ # +# +# Zero-copy display (optional upgrade) +# ------------------------------------ +# This sketch copies each frame host-side. To match the original's zero-copy +# CUDA->GL path you would register the GL PBO with CUDA and write the colorize +# kernel straight into the mapped device pointer. numba does not wrap GL interop +# itself, so you would call cuda.bindings driver functions +# (cuGraphicsGLRegisterBuffer / cuGraphicsMapResources / +# cuGraphicsResourceGetMappedPointer) and wrap the returned pointer as a numba +# DeviceNDArray via numba.cuda.cudadrv.driver.MemoryPointer. At that point +# reusing cuda.core's GraphicsResource (bridged with cuda.external_stream) is +# usually less code than reimplementing it. +# +# What is genuinely lost vs. the cuda.core/C++ version +# ---------------------------------------------------- +# - Hardware bilinear filtering: sample_*() does it in software (more FLOPs). +# - The texture cache's 2D-locality optimization for the gather-heavy advection +# and stencil reads. Linear global memory still caches via L1/L2, but the +# texture path is purpose-built for this access pattern. +# These cost some throughput; for a 512x512 interactive demo it is unnoticeable. diff --git a/cuda_core/examples/gl_interop_mipmap_lod.py b/cuda_core/examples/gl_interop_mipmap_lod.py new file mode 100644 index 00000000000..29bfa798755 --- /dev/null +++ b/cuda_core/examples/gl_interop_mipmap_lod.py @@ -0,0 +1,732 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +# ################################################################################ +# +# This example demonstrates the new cuda.core texture/surface stack: +# MipmappedArray, SurfaceObject, and a TextureObject that does trilinear +# (LINEAR mipmap + LINEAR filter) sampling with user-controlled LOD bias. +# Requires pyglet. +# +# ################################################################################ + +# What this example teaches +# ========================= +# How to allocate a mipmap pyramid as a single MipmappedArray, populate each +# level from a CUDA kernel by binding it as a SurfaceObject, and then sample +# the whole pyramid from a TextureObject with manual LOD bias. +# +# How it works +# ============ +# A mipmap pyramid is a stack of progressively-halved images of the same +# texture. The base level (level 0) holds the highest-resolution version; each +# subsequent level is a 2x2 box-filtered downsample of the level below it: +# +# level 0: 512 x 512 <- highest detail +# level 1: 256 x 256 +# level 2: 128 x 128 +# ... +# level 9: 1 x 1 <- a single average color +# +# At sample time, the GPU picks the mip level that best matches the on-screen +# size of the texel, optionally blending between adjacent levels (trilinear). +# Selecting a coarser level than the "right" one is called a positive LOD bias +# and produces a softer/blurrier image; a negative bias selects finer levels +# (sharper but more aliased when undersampled). +# +# +----------------------+ +-----------------------+ +# | MipmappedArray | | TextureObject | +# | (single allocation, | <--- | (samples the whole | +# | 10 mip levels) | | pyramid w/ trilinear | +# +----------------------+ | filtering) | +# ^ ^ +-----------------------+ +# | | +# | +---- one SurfaceObject per level, used at BUILD time only +# | to let a kernel write pixels into that level. +# | +# +----------- get_level(L) returns a NON-OWNING CUDAArray view of level L; +# the storage belongs to the parent MipmappedArray. +# +# STARTUP -- one-time mipmap build +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# 1. Allocate MipmappedArray (10 levels, float4 RGBA, is_surface_load_store=True). +# 2. Level 0: launch `seed_base` kernel -> SurfaceObject -> high-frequency +# procedural pattern. +# 3. For L = 1..num_levels-1: launch `downsample` kernel: +# - reads level L-1 through a TextureObject (POINT-filtered) +# - writes level L through a SurfaceObject +# - 4-sample box average of the parent's 2x2 footprint. +# +# PER FRAME (render loop) +# ~~~~~~~~~~~~~~~~~~~~~~~ +# The display TextureObject samples the whole pyramid with `tex2DLod`, +# where the LOD is computed per-pixel as `log2(zoom) + lod_bias`. The result +# is written to a GL PBO via GraphicsResource, then drawn as a textured quad. +# +# What you should see +# =================== +# A 512x512 procedural pattern (concentric rings + diagonal grid) shown +# stretched across the window. Use the mouse wheel to zoom in/out (this +# implicitly changes the LOD), and use the bracket keys `[` / `]` to add a +# manual LOD bias on top of that. Press `R` to reset. +# +# Mouse wheel zoom in / out +# [ LOD bias -= 0.25 (sharper, more aliased) +# ] LOD bias += 0.25 (blurrier, samples a coarser level) +# R reset zoom + bias +# Escape / close quit +# +# The window title shows the current zoom, manual bias, and effective LOD. +# Close the window or press Escape to exit. +# + +# /// script +# dependencies = ["cuda_bindings", "cuda_core>0.6.0", "pyglet"] +# /// + +import ctypes +import math +import sys +import time + +import numpy as np + +from cuda.core import ( + Device, + GraphicsResource, + LaunchConfig, + Program, + ProgramOptions, + launch, +) +from cuda.core.textures import ( + AddressMode, + ArrayFormat, + FilterMode, + MipmappedArray, + ReadMode, + ResourceDescriptor, + SurfaceObject, + TextureDescriptor, + TextureObject, +) + +# --------------------------------------------------------------------------- +# Configuration (feel free to change these) +# --------------------------------------------------------------------------- +WIDTH = 800 +HEIGHT = 600 +BASE_SIZE = 512 # Texture base-level edge length (must be a power of two). +LOD_BIAS_STEP = 0.25 + + +# ============================= Helper functions ============================= +# +# The functions below set up CUDA, OpenGL, and the mipmap pyramid. If you're +# here to learn about MipmappedArray / SurfaceObject / mipmapped TextureObject, +# you can skip straight to main() -- the interesting part is there. These +# helpers exist so that main() reads like a short story. +# ============================================================================ + + +def _check_compute_capability(dev): + """Surface load/store + mipmapped arrays require sm_30+.""" + cc = dev.compute_capability + if cc.major < 3: + print( + f"This example requires compute capability >= 3.0, got sm_{cc.major}{cc.minor}.", + file=sys.stderr, + ) + sys.exit(1) + + +def setup_cuda(): + """Compile the three kernels and return everything we need to drive them. + + Returns + ------- + (dev, stream, kernels, arch_str) + kernels is a dict with keys "seed_base", "downsample", "display". + """ + dev = Device(0) + dev.set_current() + _check_compute_capability(dev) + stream = dev.create_stream() + + program_options = ProgramOptions(std="c++17", arch=f"sm_{dev.arch}") + prog = Program(KERNEL_SOURCE, code_type="c++", options=program_options) + mod = prog.compile( + "cubin", + name_expressions=("seed_base", "downsample", "display"), + ) + kernels = { + "seed_base": mod.get_kernel("seed_base"), + "downsample": mod.get_kernel("downsample"), + "display": mod.get_kernel("display"), + } + return dev, stream, kernels, f"sm_{dev.arch}" + + +def build_mipmap_pyramid(mip, num_levels, stream, kernels): + """Populate every level of `mip` using SurfaceObject writes. + + Strategy + -------- + * Level 0 is filled directly by `seed_base`, which writes a procedural + pattern through a SurfaceObject bound to level 0. + * Each subsequent level L is filled by `downsample`, which reads level L-1 + through a POINT-filtered TextureObject and box-averages a 2x2 footprint + into level L through a SurfaceObject. + * All operations are issued on a single stream, so they serialize + implicitly -- no per-level sync is needed. + """ + # ---- Level 0: seed the base image ------------------------------------- + base_arr = mip.get_level(0) # non-owning view; do NOT use a `with` block + with SurfaceObject.from_array(base_arr) as base_surf: + block = (16, 16, 1) + grid = ( + (BASE_SIZE + block[0] - 1) // block[0], + (BASE_SIZE + block[1] - 1) // block[1], + 1, + ) + launch( + stream, + LaunchConfig(grid=grid, block=block), + kernels["seed_base"], + np.uint64(base_surf.handle), + np.int32(BASE_SIZE), + np.int32(BASE_SIZE), + ) + # base_arr (non-owning) is allowed to fall out of scope here; the parent + # MipmappedArray keeps the underlying storage alive. + + # ---- Levels 1..N-1: box-filter downsample ------------------------------ + # Each iteration reads level (L-1) through a temporary TextureObject and + # writes level L through a temporary SurfaceObject. Both close cleanly + # at the end of their `with` blocks. + src_tex_desc = TextureDescriptor( + address_mode=AddressMode.CLAMP, + filter_mode=FilterMode.POINT, # explicit per-texel reads + read_mode=ReadMode.ELEMENT_TYPE, + normalized_coords=False, # integer pixel coordinates + ) + for level in range(1, num_levels): + parent_size = BASE_SIZE >> (level - 1) + level_size = BASE_SIZE >> level + if level_size < 1: + break + + src_arr = mip.get_level(level - 1) + dst_arr = mip.get_level(level) + src_res = ResourceDescriptor.from_array(src_arr) + with ( + TextureObject.from_descriptor(resource=src_res, texture_descriptor=src_tex_desc) as src_tex, + SurfaceObject.from_array(dst_arr) as dst_surf, + ): + block = (16, 16, 1) + grid = ( + (level_size + block[0] - 1) // block[0], + (level_size + block[1] - 1) // block[1], + 1, + ) + launch( + stream, + LaunchConfig(grid=grid, block=block), + kernels["downsample"], + np.uint64(src_tex.handle), + np.uint64(dst_surf.handle), + np.int32(parent_size), + np.int32(level_size), + ) + # src_arr, dst_arr (non-owning) fall out of scope; storage stays + # alive via the parent MipmappedArray. + + # One sync at the end is enough -- the whole build chain ran on this + # stream and serialized naturally. + stream.sync() + + +def create_window(): + """Open a pyglet window and return (window, gl_module, pyglet).""" + try: + import pyglet + from pyglet.gl import gl as _gl + except ImportError: + print( + "This example requires pyglet >= 2.0.\nInstall it with: pip install pyglet", + file=sys.stderr, + ) + sys.exit(1) + + window = pyglet.window.Window( + WIDTH, + HEIGHT, + caption="MipmappedArray Example - Mipmap LOD viewer", + vsync=False, + ) + return window, _gl, pyglet + + +def create_display_resources(gl, width, height): + """Standard GL boilerplate: a shader program, a fullscreen quad, and an + empty texture that we'll repeatedly fill from a PBO. Not CUDA-specific. + + Returns (shader_program, vertex_array_id, texture_id). + """ + from pyglet.graphics.shader import Shader, ShaderProgram + + vert = Shader(VERTEX_SHADER_SOURCE, "vertex") + frag = Shader(FRAGMENT_SHADER_SOURCE, "fragment") + shader_prog = ShaderProgram(vert, frag) + + quad_verts = np.array( + [ + # x, y, s, t (position + texture coordinate) + -1, + -1, + 0, + 0, + 1, + -1, + 1, + 0, + 1, + 1, + 1, + 1, + -1, + -1, + 0, + 0, + 1, + 1, + 1, + 1, + -1, + 1, + 0, + 1, + ], + dtype=np.float32, + ) + + vao = ctypes.c_uint(0) + gl.glGenVertexArrays(1, ctypes.byref(vao)) + gl.glBindVertexArray(vao.value) + + vbo = ctypes.c_uint(0) + gl.glGenBuffers(1, ctypes.byref(vbo)) + gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo.value) + gl.glBufferData( + gl.GL_ARRAY_BUFFER, + quad_verts.nbytes, + quad_verts.ctypes.data_as(ctypes.c_void_p), + gl.GL_STATIC_DRAW, + ) + + stride = 4 * 4 # 4 floats * 4 bytes each + pos_loc = gl.glGetAttribLocation(shader_prog.id, b"position") + gl.glEnableVertexAttribArray(pos_loc) + gl.glVertexAttribPointer(pos_loc, 2, gl.GL_FLOAT, gl.GL_FALSE, stride, ctypes.c_void_p(0)) + + tc_loc = gl.glGetAttribLocation(shader_prog.id, b"texcoord") + gl.glEnableVertexAttribArray(tc_loc) + gl.glVertexAttribPointer(tc_loc, 2, gl.GL_FLOAT, gl.GL_FALSE, stride, ctypes.c_void_p(8)) + + gl.glBindVertexArray(0) + + tex = ctypes.c_uint(0) + gl.glGenTextures(1, ctypes.byref(tex)) + gl.glBindTexture(gl.GL_TEXTURE_2D, tex.value) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) + gl.glTexImage2D( + gl.GL_TEXTURE_2D, + 0, + gl.GL_RGBA8, + width, + height, + 0, + gl.GL_RGBA, + gl.GL_UNSIGNED_BYTE, + None, + ) + + return shader_prog, vao.value, tex.value + + +def create_pixel_buffer(gl, width, height): + """Create a Pixel Buffer Object (PBO) -- the CUDA/GL bridge. + + Returns (pbo_gl_name, size_in_bytes). + """ + pbo = ctypes.c_uint(0) + gl.glGenBuffers(1, ctypes.byref(pbo)) + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, pbo.value) + nbytes = width * height * 4 # RGBA8 + gl.glBufferData(gl.GL_PIXEL_UNPACK_BUFFER, nbytes, None, gl.GL_DYNAMIC_DRAW) + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0) + return pbo.value, nbytes + + +def copy_pbo_to_texture(gl, pbo_id, tex_id, width, height): + """Copy pixel data from the PBO into the GL texture (GPU-to-GPU).""" + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, pbo_id) + gl.glBindTexture(gl.GL_TEXTURE_2D, tex_id) + gl.glTexSubImage2D( + gl.GL_TEXTURE_2D, + 0, + 0, + 0, + width, + height, + gl.GL_RGBA, + gl.GL_UNSIGNED_BYTE, + None, + ) + gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0) + + +def draw_fullscreen_quad(gl, shader_prog, vao_id, tex_id): + """Draw the texture to the screen using the fullscreen quad.""" + gl.glUseProgram(shader_prog.id) + gl.glBindTexture(gl.GL_TEXTURE_2D, tex_id) + gl.glBindVertexArray(vao_id) + gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) + gl.glBindVertexArray(0) + gl.glUseProgram(0) + + +# ================================== main() ================================== + + +def main(): + # --- Step 1: Set up CUDA (compile kernels, create stream) --- + dev, stream, kernels, _arch = setup_cuda() + + # --- Step 2: Allocate the mipmap pyramid and build every level --- + # is_surface_load_store=True is required for kernel-side writes. + num_levels = int(math.log2(BASE_SIZE)) + 1 + mip = MipmappedArray.from_descriptor( + shape=(BASE_SIZE, BASE_SIZE), + format=ArrayFormat.FLOAT32, + num_channels=4, + num_levels=num_levels, + is_surface_load_store=True, + ) + build_mipmap_pyramid(mip, num_levels, stream, kernels) + + # --- Step 3: Bind the WHOLE pyramid as a trilinear-filtered texture --- + # Normalized coordinates (0..1) make zoom-by-uv simple. The texture + # descriptor's mipmap_level_bias stays 0.0; the display kernel + # receives the user-controlled bias as a kernel argument and folds + # it into the tex2DLod call (avoids rebuilding the TextureObject + # whenever the user changes the bias). + display_tex_desc = TextureDescriptor( + address_mode=AddressMode.WRAP, + filter_mode=FilterMode.LINEAR, + read_mode=ReadMode.ELEMENT_TYPE, + normalized_coords=True, + mipmap_filter_mode=FilterMode.LINEAR, # trilinear + mipmap_level_bias=0.0, + min_mipmap_level_clamp=0.0, + max_mipmap_level_clamp=float(num_levels - 1), + ) + display_tex = TextureObject.from_descriptor( + resource=ResourceDescriptor.from_mipmapped_array(mip), + texture_descriptor=display_tex_desc, + ) + + # --- Step 4: Open a window and set up the GL/CUDA bridge --- + window, gl, pyglet = create_window() + shader_prog, quad_vao, tex_id = create_display_resources(gl, WIDTH, HEIGHT) + pbo_id, _ = create_pixel_buffer(gl, WIDTH, HEIGHT) + resource = GraphicsResource.from_gl_buffer(pbo_id, flags="write_discard") + + # --- Step 5: Render loop state --- + # `zoom` controls how big a texel is on screen: zoom > 1 stretches the + # texture and selects coarser mip levels (positive LOD); zoom < 1 shrinks + # the texture and selects finer levels. `lod_bias` is a manual offset + # added on top. + state = {"zoom": 1.0, "lod_bias": 0.0} + start_time = time.monotonic() + frame_count = [0] + fps_time = [start_time] + + block = (16, 16, 1) + grid = ( + (WIDTH + block[0] - 1) // block[0], + (HEIGHT + block[1] - 1) // block[1], + 1, + ) + config = LaunchConfig(grid=grid, block=block) + + def effective_lod(): + # Same formula the display kernel uses, clamped to the legal range so + # the window title matches what the GPU actually sees. + raw = math.log2(max(state["zoom"], 1e-6)) + state["lod_bias"] + return max(0.0, min(float(num_levels - 1), raw)) + + @window.event + def on_draw(): + window.clear() + + # (a) Map the PBO so CUDA can write into it. + with resource.map(stream=stream) as buf: + # (b) Launch the display kernel -- samples the mipmap and writes RGBA. + launch( + stream, + config, + kernels["display"], + buf.handle, + np.int32(WIDTH), + np.int32(HEIGHT), + np.uint64(display_tex.handle), + np.float32(state["zoom"]), + np.float32(state["lod_bias"]), + np.float32(float(num_levels - 1)), + ) + # (c) Unmap happens automatically; cuGraphicsUnmapResources serializes + # the CUDA work against subsequent OpenGL use. + + copy_pbo_to_texture(gl, pbo_id, tex_id, WIDTH, HEIGHT) + draw_fullscreen_quad(gl, shader_prog, quad_vao, tex_id) + + frame_count[0] += 1 + now = time.monotonic() + if now - fps_time[0] >= 1.0: + fps = frame_count[0] / (now - fps_time[0]) + window.set_caption( + f"MipmappedArray LOD viewer " + f"({WIDTH}x{HEIGHT}, {fps:.0f} FPS) -- " + f"zoom={state['zoom']:.2f}, " + f"bias={state['lod_bias']:+.2f}, " + f"LOD={effective_lod():.2f}" + ) + frame_count[0] = 0 + fps_time[0] = now + + @window.event + def on_mouse_scroll(_x, _y, _scroll_x, scroll_y): + # One wheel step changes zoom by ~12.5%. Clamped to keep LOD in range. + if scroll_y == 0: + return + factor = 1.125**scroll_y + state["zoom"] = max(1.0 / 64.0, min(64.0, state["zoom"] * factor)) + + @window.event + def on_key_press(symbol, _modifiers): + key = pyglet.window.key + if symbol == key.BRACKETLEFT: + state["lod_bias"] = max(-float(num_levels), state["lod_bias"] - LOD_BIAS_STEP) + elif symbol == key.BRACKETRIGHT: + state["lod_bias"] = min(float(num_levels), state["lod_bias"] + LOD_BIAS_STEP) + elif symbol == key.R: + state["zoom"] = 1.0 + state["lod_bias"] = 0.0 + + @window.event + def on_close(): + # Release CUDA-side resources in reverse construction order. GL + # objects clean up via pyglet on window close. + resource.close() + display_tex.close() + mip.close() + stream.close() + + pyglet.app.run(interval=0) + + +# ======================== GPU code (CUDA + GLSL) ============================ +# +# Three CUDA kernels are concatenated into one program string so they share a +# single NVRTC compile. All three operate on float4 RGBA pixels. +# +# seed_base -- writes a high-frequency procedural pattern to level 0 via a +# SurfaceObject. NOTE: surf2Dwrite's x-coordinate is in BYTES, +# not in elements, so we multiply by sizeof(float4) every time. +# +# downsample -- reads level L-1 through a POINT-filtered TextureObject and +# writes the 2x2 box average to level L through a SurfaceObject. +# tex2D with non-normalized coords needs the +0.5 half-texel +# offset to hit exact texel centers. +# +# display -- samples the WHOLE mipmap pyramid with tex2DLod, where the +# per-thread LOD is `clamp(log2(zoom) + lod_bias, 0, maxLod)`. +# Writes 8-bit RGBA into the PBO. +# +# GLSL shaders at the very bottom just draw a textured quad. Nothing CUDA- +# specific there. +# +# ============================================================================ + +KERNEL_SOURCE = r""" +// -------------------------------------------------------------------------- +// Helper: clamp a float to [a, b]. +// -------------------------------------------------------------------------- +__device__ __forceinline__ float clampf(float v, float a, float b) { + return fminf(fmaxf(v, a), b); +} + +// CUDA does not ship a builtin "fract" so we provide one (used by seed_base). +__device__ __forceinline__ float fracf(float v) { + return v - floorf(v); +} + +// -------------------------------------------------------------------------- +// seed_base: write a procedural high-frequency pattern to level 0. +// +// surf is a SurfaceObject bound to the level-0 CUDAArray (float4 RGBA). The +// pattern is a colorful blend of concentric rings, a diagonal grid, and a +// radial sweep, designed to have plenty of fine detail so the difference +// between mip levels is visually obvious. +// -------------------------------------------------------------------------- +extern "C" __global__ +void seed_base(cudaSurfaceObject_t surf, int width, int height) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + float u = ((float)x + 0.5f) / (float)width; + float v = ((float)y + 0.5f) / (float)height; + + // Concentric rings centered on the image. + float cx = u - 0.5f; + float cy = v - 0.5f; + float r = sqrtf(cx * cx + cy * cy); + float rings = 0.5f + 0.5f * sinf(r * 80.0f); + + // Diagonal grid -- thin lines about every 1/16 of the image. + float gx = fabsf(fracf(u * 16.0f) - 0.5f); + float gy = fabsf(fracf(v * 16.0f) - 0.5f); + float grid = (gx < 0.05f || gy < 0.05f) ? 1.0f : 0.0f; + + // Angular sweep gives the rings some color variation. + float theta = atan2f(cy, cx); + float sweep = 0.5f + 0.5f * sinf(theta * 6.0f); + + // Combine into an RGBA color. Keep values in [0, 1]. + float red = clampf(rings * (0.4f + 0.6f * sweep) + 0.3f * grid, 0.0f, 1.0f); + float green = clampf(rings * (0.6f - 0.4f * sweep) + 0.3f * grid, 0.0f, 1.0f); + float blue = clampf(0.4f + 0.4f * sweep + 0.5f * grid, 0.0f, 1.0f); + float alpha = 1.0f; + + float4 px = make_float4(red, green, blue, alpha); + + // Surface writes index x in BYTES (this is the classic gotcha). + surf2Dwrite(px, surf, x * (int)sizeof(float4), y); +} + +// -------------------------------------------------------------------------- +// downsample: box-filter a 2x2 footprint of the parent level into one texel. +// +// src is a POINT-filtered TextureObject bound to level (L-1). +// dst is a SurfaceObject bound to level L. +// (dst_w, dst_h) is the size of level L. +// (src_w = 2 * dst_w, src_h = 2 * dst_h is implicit and unused; we pass it +// only for the bounds check.) +// +// Texture coordinates: tex2D with non-normalized coords returns texel (i, j) +// when sampled at (i + 0.5, j + 0.5). So for output texel (x, y) the four +// parent texels live at parent-coords (2x + 0.5, 2y + 0.5), (2x + 1.5, ...). +// -------------------------------------------------------------------------- +extern "C" __global__ +void downsample(cudaTextureObject_t src, + cudaSurfaceObject_t dst, + int src_size, + int dst_size) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= dst_size || y >= dst_size) return; + + float fx = 2.0f * (float)x; + float fy = 2.0f * (float)y; + + float4 a = tex2D(src, fx + 0.5f, fy + 0.5f); + float4 b = tex2D(src, fx + 1.5f, fy + 0.5f); + float4 c = tex2D(src, fx + 0.5f, fy + 1.5f); + float4 d = tex2D(src, fx + 1.5f, fy + 1.5f); + + float4 px; + px.x = 0.25f * (a.x + b.x + c.x + d.x); + px.y = 0.25f * (a.y + b.y + c.y + d.y); + px.z = 0.25f * (a.z + b.z + c.z + d.z); + px.w = 0.25f * (a.w + b.w + c.w + d.w); + + // Silence unused-variable warning for the convenience parameter. + (void)src_size; + + surf2Dwrite(px, dst, x * (int)sizeof(float4), y); +} + +// -------------------------------------------------------------------------- +// display: per-pixel mipmap sample with manual LOD bias. +// +// tex is a TextureObject built from the whole MipmappedArray (LINEAR + +// LINEAR mipmap filter, normalized coords). For each output pixel we compute +// a single per-thread LOD from `zoom` and `lod_bias`, then sample with +// tex2DLod. Output is written as RGBA8 into a linear byte buffer. +// -------------------------------------------------------------------------- +extern "C" __global__ +void display(unsigned char *output, + int width, + int height, + cudaTextureObject_t tex, + float zoom, + float lod_bias, + float max_lod) { + int x = blockIdx.x * blockDim.x + threadIdx.x; + int y = blockIdx.y * blockDim.y + threadIdx.y; + if (x >= width || y >= height) return; + + // Normalized window coords in [0, 1]. + float u = ((float)x + 0.5f) / (float)width; + float v = ((float)y + 0.5f) / (float)height; + + // Zoom around the window center so the user sees the effect symmetrically. + u = (u - 0.5f) * zoom + 0.5f; + v = (v - 0.5f) * zoom + 0.5f; + + // LOD: zoom > 1 means the texture is being stretched (each texel covers + // more screen area), which intuitively corresponds to selecting a coarser + // (higher) mip level. log2(zoom) yields exactly that. lod_bias is added + // on top, and the final value is clamped to the legal range. + float lod = log2f(fmaxf(zoom, 1e-6f)) + lod_bias; + lod = clampf(lod, 0.0f, max_lod); + + float4 c = tex2DLod(tex, u, v, lod); + + int idx = (y * width + x) * 4; + output[idx + 0] = (unsigned char)(clampf(c.x, 0.0f, 1.0f) * 255.0f); + output[idx + 1] = (unsigned char)(clampf(c.y, 0.0f, 1.0f) * 255.0f); + output[idx + 2] = (unsigned char)(clampf(c.z, 0.0f, 1.0f) * 255.0f); + output[idx + 3] = 255; +} +""" + +# GLSL shaders -- these just display a texture on a fullscreen rectangle. +# Nothing CUDA-specific here. + +VERTEX_SHADER_SOURCE = """#version 330 core +in vec2 position; +in vec2 texcoord; +out vec2 v_texcoord; +void main() { + gl_Position = vec4(position, 0.0, 1.0); + v_texcoord = texcoord; +} +""" + +FRAGMENT_SHADER_SOURCE = """#version 330 core +in vec2 v_texcoord; +out vec4 fragColor; +uniform sampler2D tex; +void main() { + fragColor = texture(tex, v_texcoord); +} +""" + + +if __name__ == "__main__": + main() diff --git a/cuda_core/examples/texture_sample.py b/cuda_core/examples/texture_sample.py new file mode 100644 index 00000000000..57c055d07c4 --- /dev/null +++ b/cuda_core/examples/texture_sample.py @@ -0,0 +1,216 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +# ################################################################################ +# +# This example demonstrates building a 2D CUDA CUDAArray, binding it as a +# bindless TextureObject, and sampling it from a kernel with both POINT-exact +# and LINEAR-interpolated coordinates. +# +# Texture coordinate convention (non-normalized): each texel (i, j) is centered +# at (i + 0.5, j + 0.5). So tex2D(tex, 0.5, 0.5) returns texel (0, 0) exactly, +# while tex2D(tex, 1.0, 0.5) returns the linear blend of texels (0, 0) and (1, 0). +# All test coordinates below are chosen with that half-pixel offset in mind. +# +# ################################################################################ + +# /// script +# dependencies = ["cuda_bindings", "cuda_core", "nvidia-cuda-nvrtc"] +# /// + +import numpy as np + +from cuda.core import ( + Device, + LaunchConfig, + LegacyPinnedMemoryResource, + Program, + ProgramOptions, + launch, +) +from cuda.core.textures import ( + AddressMode, + ArrayFormat, + CUDAArray, + FilterMode, + ReadMode, + ResourceDescriptor, + TextureDescriptor, + TextureObject, +) + +# Kernel reads N (x, y) coordinates from `coords` (interleaved float pairs) and +# writes tex2D(tex, x, y) to out[i]. Compiled as C++ so the templated +# tex2D overload resolves. +code = r""" +extern "C" __global__ +void sample_texture(cudaTextureObject_t tex, + float *out, + const float *coords, + int n) { + int i = blockIdx.x * blockDim.x + threadIdx.x; + if (i >= n) return; + float x = coords[2 * i + 0]; + float y = coords[2 * i + 1]; + out[i] = tex2D(tex, x, y); +} +""" + + +def main(): + dev = Device() + dev.set_current() + stream = dev.create_stream() + + pinned_mr = LegacyPinnedMemoryResource() + try: + # Allocate a 2D CUDAArray: shape=(W, H), single-channel float32. + # Note: CUDAArray.from_descriptor takes shape=(width, height), so the host + # buffer fed into copy_from must be laid out as H rows of W elements + # (row-major), i.e. host_pattern.shape == (H, W). + width, height = 16, 16 + with CUDAArray.from_descriptor( + shape=(width, height), + format=ArrayFormat.FLOAT32, + num_channels=1, + ) as arr: + # Plant a known pattern: pattern[y, x] = x + 100*y. + # Cast to float32 so the byte count matches the array's storage. + ys, xs = np.meshgrid( + np.arange(height, dtype=np.float32), + np.arange(width, dtype=np.float32), + indexing="ij", + ) + pattern = (xs + 100.0 * ys).astype(np.float32) + assert pattern.shape == (height, width) + arr.copy_from(pattern, stream=stream) + + # Build a linear-filtering, clamped, non-normalized texture. + res_desc = ResourceDescriptor.from_array(arr) + tex_desc = TextureDescriptor( + address_mode=AddressMode.CLAMP, + filter_mode=FilterMode.LINEAR, + read_mode=ReadMode.ELEMENT_TYPE, + normalized_coords=False, + ) + with TextureObject.from_descriptor(resource=res_desc, texture_descriptor=tex_desc) as tex: + _run_kernel_and_verify(dev, stream, tex, pattern, width, height, pinned_mr) + finally: + stream.close() + + +def _run_kernel_and_verify(dev, stream, tex, pattern, width, height, pinned_mr): + """Kernel launch + correctness check, isolated so the with-blocks in main() + stay readable. Owns its own pinned-buffer cleanup.""" + coords_buf = None + out_buf = None + try: + # Build the test coordinate list: + # - Texel-center samples should return the exact planted value. + # - Half-integer samples land between texels and exercise LINEAR + # filtering -- they should equal the average of the surrounding + # texels. + center_samples = [ + (0.5, 0.5), # -> pattern[0, 0] = 0 + (3.5, 0.5), # -> pattern[0, 3] = 3 + (0.5, 4.5), # -> pattern[4, 0] = 400 + (7.5, 9.5), # -> pattern[9, 7] = 907 + (15.5, 15.5), # -> pattern[15, 15] = 1515 + ] + half_samples = [ + # (1.0, 0.5): blend of texels (0, 0) and (1, 0) -> 0.5 + (1.0, 0.5), + # (0.5, 1.0): blend of texels (0, 0) and (0, 1) -> 50.0 + (0.5, 1.0), + # (1.0, 1.0): blend of the 2x2 block at (0..1, 0..1) -> 50.5 + (1.0, 1.0), + # (4.0, 5.0): blend of the 2x2 block at (3..4, 4..5) -> 453.5 + (4.0, 5.0), + ] + coords = np.array(center_samples + half_samples, dtype=np.float32) + n = coords.shape[0] + coords_flat = coords.reshape(-1) + coords_nbytes = int(coords_flat.nbytes) + out_nbytes = n * np.dtype(np.float32).itemsize + + # Use pinned host memory for inputs and outputs. Pinned allocations are + # GPU-accessible (zero-copy), so the kernel can read coords directly + # and we can read results without a separate device->host copy. + coords_buf = pinned_mr.allocate(coords_nbytes) + out_buf = pinned_mr.allocate(out_nbytes) + coords_view = np.from_dlpack(coords_buf).view(dtype=np.float32) + out_view = np.from_dlpack(out_buf).view(dtype=np.float32) + coords_view[:] = coords_flat + out_view[:] = 0.0 + + # Compile the kernel as C++ (templated tex2D requires this). + program_options = ProgramOptions(std="c++17", arch=f"sm_{dev.arch}") + prog = Program(code, code_type="c++", options=program_options) + mod = prog.compile("cubin", name_expressions=("sample_texture",)) + kernel = mod.get_kernel("sample_texture") + + block = 64 + grid = (n + block - 1) // block + config = LaunchConfig(grid=grid, block=block) + # cudaTextureObject_t is a 64-bit handle; pass it as uint64 to be + # unambiguous (a bare Python int would also work since intptr_t is + # 8 bytes on 64-bit platforms). + launch( + stream, + config, + kernel, + np.uint64(tex.handle), + out_buf, + coords_buf, + np.int32(n), + ) + stream.sync() + results = np.asarray(out_view) + + # Verify texel-center samples (POINT-exact regardless of filter mode). + n_center = len(center_samples) + for i, (x, y) in enumerate(center_samples): + expected = (x - 0.5) + 100.0 * (y - 0.5) + got = float(results[i]) + assert np.isclose(got, expected, atol=1e-4), ( + f"center sample {i} at ({x}, {y}): expected {expected}, got {got}" + ) + + # Verify half-integer samples against the analytic mean of the 4 + # surrounding texels. Allow a small tolerance for the 1/256 fixed-point + # weight quantization that hardware filtering performs. + for j, (x, y) in enumerate(half_samples): + idx = n_center + j + # Surrounding integer texel coordinates: (xi, yi), (xi+1, yi), + # (xi, yi+1), (xi+1, yi+1). With x = xi + 1, y = yi + 1 (e.g. + # (1.0, 1.0)) the four neighbors are (0,0)..(1,1). + xi = int(np.floor(x - 0.5)) + yi = int(np.floor(y - 0.5)) + tx = (x - 0.5) - xi + ty = (y - 0.5) - yi + corners = [] + for dy in (0, 1): + for dx in (0, 1): + xv = min(max(xi + dx, 0), width - 1) + yv = min(max(yi + dy, 0), height - 1) + corners.append(pattern[yv, xv]) + v00, v10, v01, v11 = corners + expected = (1 - tx) * (1 - ty) * v00 + tx * (1 - ty) * v10 + (1 - tx) * ty * v01 + tx * ty * v11 + got = float(results[idx]) + assert np.isclose(got, expected, atol=1e-2), ( + f"half sample {j} at ({x}, {y}): expected {expected}, got {got}" + ) + + print("Texture sampling example completed successfully.") + print(f" texel-center samples verified: {n_center}") + print(f" half-integer samples verified: {len(half_samples)}") + finally: + if coords_buf is not None: + coords_buf.close() + if out_buf is not None: + out_buf.close() + + +if __name__ == "__main__": + main() diff --git a/cuda_core/pixi.lock b/cuda_core/pixi.lock index b53c44c0ef9..6530b72fa3f 100644 --- a/cuda_core/pixi.lock +++ b/cuda_core/pixi.lock @@ -2804,6 +2804,429 @@ environments: - conda: ../cuda_bindings build: py314hd7f1909_0 - conda: ../cuda_pathfinder + numba-mlir: + channels: + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.16.1-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.14.1-pl5321h039972f_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-8.1.1-gpl_h6d6c1bd_904.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.18.1-h27c8c51_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.44.6-h2b0a6b4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glslang-16.3.0-h96af755_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.15-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.1-h6083320_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/intel-gmmlib-22.10.0-hb700be7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/intel-media-driver-26.1.6-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/level-zero-1.29.0-hb700be7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libass-0.17.4-h96ad9f0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-8_h4a7cf45_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcap-2.78-hd0affe5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-8_h0358290_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdovi-3.3.2-ha23c83e_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.127-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.13.0-default_he001693_1000.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.4.0-h10be129_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-h174a0a3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-8_h47877c9_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.33-pthreads_h94d23a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2026.2.0-hb56ce9e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2026.2.0-hd85de46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2026.2.0-hd85de46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2026.2.0-hd41364c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2026.2.0-hb56ce9e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2026.2.0-hb56ce9e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-npu-plugin-2026.2.0-hb56ce9e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2026.2.0-hd41364c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2026.2.0-h7a07914_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2026.2.0-h7a07914_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2026.2.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2026.2.0-h78e8023_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2026.2.0-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.19-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libplacebo-7.360.1-h9eeb4b2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h6eeba95_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.62.3-h4c96295_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-h084b8d7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libudev1-257.13-h084b8d7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libunwind-1.8.3-h65a8314_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liburing-2.14-hb700be7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libusb-1.0.29-h73b1eb8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libva-2.23.0-he1eb515_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpl-2.16.0-h54a6638_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.15.2-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.2-hca5e8e5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.6-py314h2b28147_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ocl-icd-2.3.4-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/opencl-headers-2025.06.13-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openh264-2.6.0-hc22cd8d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pugixml-1.15-h3f63f65_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyglet-2.1.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/sdl2-2.32.56-h54a6638_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/sdl3-3.4.10-hdeec2a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/shaderc-2026.2-h718be3e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/spirv-tools-2026.2-hb700be7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.1-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-hab88423_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wayland-protocols-1.49-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/x264-1!164.3095-h166bdaf_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-h280c20c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.3-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxscrnsaver-1.2.4-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2025.1-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/d4/e0/c8a1f0c8f9ffdea4f5fe6dbab89b326cef4d85caf489dad39e209da89416/cuda_bindings-13.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/51/08/1aeffc9a529a7f94c9cee9bfd3a991743398b5f90aab30f06f2a4bc8205e/cuda_core-1.0.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/11/c8/26f2e4aae92f11522a96043892ba39a90eac610d5242523aa863212bc1c7/cuda_pathfinder-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/8c/29b52f76ee4b4f94d5f1ef05797a83ae48ba8b6d5fcd5691dafb570a5f65/cuda_toolkit-13.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/52/f6/620a144d38e5496a6e8842b837d48885fb532594752194a01f81701d8b91/numba_cuda_mlir-0.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fe/fb/195d50d25ab68a76b817ffc68c45b1fb828598ce35a8e5c1736060628dab/nvidia_cuda_cccl-13.3.3.3.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8d/a7/998af901511d5efdc6e42fc597d32a69f34eecf86f1591a9d230ab3ab951/nvidia_cuda_crt-13.3.33-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/3f/af/e1b107f034f7c133255c162b922bbad3da5be20ebf76df17662ae4bd31f6/nvidia_cuda_nvcc-13.3.33-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/8b/2c/86916c8a34dcdb0c3ddd1c0e30545041bd781184e437b9cb76fcda70560b/nvidia_cuda_nvrtc-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/97/be/5699b6e642b372f7d24c59c2f41383e2696825e20bab85f7399c7c6a56f7/nvidia_cuda_runtime-13.3.29-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f0/ee/580ca6f29dcab0221db8706badca1bbbb084f1975c4d4e83329c3a7e31f0/nvidia_nvjitlink-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/01/8a/f767031dcd0d24c2bbab4b696dbcf004da4f3284e5e4649fc47bc0e2bb78/nvidia_nvvm-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl + linux-aarch64: + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.16.1-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/aom-3.14.1-pl5321h8fffa31_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/dav1d-1.2.1-h31becfc_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ffmpeg-8.1.1-gpl_hef17b83_904.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.18.1-hba86a56_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.3-h8af1aa0_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fribidi-1.0.16-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gdk-pixbuf-2.44.6-h90308e0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/glslang-16.3.0-h124e036_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gmp-6.3.0-h0a1ffab_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.15-hfae3067_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-14.2.1-h1134a53_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lame-3.100-h4e544f5_1003.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.19.1-h9d5b58d_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libabseil-20260107.1-cxx17_h6983b43_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libass-0.17.4-hcfe818d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-8_haddc8a3_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcap-2.78-hf9559e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-8_hd72aa62_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdovi-3.3.2-hf71c8f5_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.127-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.8.1-hfae3067_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libflac-1.5.0-he9c94f4_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-devel-1.7.0-hd24410f_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.88.1-h96a7f82_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-devel-1.7.0-hd24410f_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwloc-2.13.0-default_ha95e27d_1000.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwy-1.4.0-h0626a34_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjxl-0.11.2-hbae46ee_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-8_h88aeb00_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libogg-1.3.5-h86ecc28_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.33-pthreads_h9d3fd7e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-2026.2.0-h1915271_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-arm-cpu-plugin-2026.2.0-h1915271_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-auto-batch-plugin-2026.2.0-h3d5001d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-auto-plugin-2026.2.0-h3d5001d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-hetero-plugin-2026.2.0-he07c6df_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-ir-frontend-2026.2.0-he07c6df_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-onnx-frontend-2026.2.0-h558496d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-paddle-frontend-2026.2.0-h558496d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-pytorch-frontend-2026.2.0-hfae3067_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-tensorflow-frontend-2026.2.0-h2cb6e3c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-tensorflow-lite-frontend-2026.2.0-hfae3067_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopus-1.6.1-h80f16a2_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.19-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libplacebo-7.360.1-h07e46df_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libprotobuf-6.33.5-h306233d_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/librsvg-2.62.3-hf685517_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsndfile-1.2.2-h30591a0_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.2-h10b116e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsystemd0-257.13-hfcc8634_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libudev1-257.13-hfcc8634_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libunwind-1.8.3-h6470e1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liburing-2.14-hfefdfc9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libusb-1.0.29-h06eaf92_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42.1-h1022ec0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libvorbis-1.3.7-h7ac5ae9_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libvpx-1.15.2-hfae3067_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.2-h3c6a4c8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.3-h79dcc73_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.3-h869d058_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mpg123-1.32.9-h65af167_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-hf8d1292_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.6-py314h314fbd6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openh264-2.6.0-h0564a2a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.3-h546c87b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pango-1.56.4-h8547ced_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.4-h7ac5ae9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pugixml-1.15-h6ef32b0_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pulseaudio-client-17.0-hcf98165_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyglet-2.1.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.6-h1c24c05_0_cp314t.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sdl2-2.32.56-h7ac5ae9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sdl3-3.4.10-had2c13b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/shaderc-2026.2-hfeb5c2c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/snappy-1.2.2-he774c54_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spirv-tools-2026.2-hfefdfc9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/svt-av1-4.0.1-hfae3067_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tbb-2023.0.0-h57272ed_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.25.0-h4f8a99f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/x264-1!164.3095-h4e544f5_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/x265-3.5-hdd96247_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.47-h80f16a2_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcursor-1.2.3-h86ecc28_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.3-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxscrnsaver-1.2.4-h86ecc28_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-xorgproto-2025.1-he30d5cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda + - pypi: https://files.pythonhosted.org/packages/52/b8/83b1f563925b290f2d11a01a77a84013ba56052fe3653a5bef3ccfbb43d6/cuda_bindings-13.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/e3/ab/db09228d5a8c124a93514726d2e18f31824f66d3a6769ee4e51721dd64cf/cuda_core-1.0.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/11/c8/26f2e4aae92f11522a96043892ba39a90eac610d5242523aa863212bc1c7/cuda_pathfinder-1.5.5-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/9a/8c/29b52f76ee4b4f94d5f1ef05797a83ae48ba8b6d5fcd5691dafb570a5f65/cuda_toolkit-13.3.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/90/16712f7566d35bb86964ca3a29858e6ca2d9e6c75d5f869e56dc6f700001/numba_cuda_mlir-0.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/5f/7a/9cb8a7fb87a85b11e8753548ae1422be847c5dddf3ca9ff5b080b309e271/nvidia_cuda_cccl-13.3.3.3.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/d1/32/5ea57f8cd6ad5df2173d175ac5db4e06edde40028b1b1f6c539ea4c10290/nvidia_cuda_crt-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/be/b6/bb07a3a63b5b7b55516366747892abbf3ee62d616684c40bb51e6cbfe956/nvidia_cuda_nvcc-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/e7/b6/60a3641111d39ebfcfcd8b8bfd0290d7623c4b8b5f90952c2d84776f8ca4/nvidia_cuda_nvrtc-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/5f/e5/c1a221c8e6fecd071b80ea44c20fc253ae24f56e15e3f77cfbc3fb76e724/nvidia_cuda_runtime-13.3.29-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/69/30/45414e35ff2eee7db3da037e5707037ccf9d2b5218ffbdb055ea4d5aa98a/nvidia_nvjitlink-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + - pypi: https://files.pythonhosted.org/packages/83/36/ce0d42d3a4465c858c379932f0080d29d22f04383ab79119c7c4f4cdd5ef/nvidia_nvvm-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.14.1-pl5321h06fc181_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-8.1.1-gpl_h6d5d71d_904.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.1-hd47e2ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gdk-pixbuf-2.44.6-h1f5b9c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glslang-16.3.0-h294ba9c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.2.1-h5a1b470_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lame-3.100-hcfcfb64_1003.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-8_h8455456_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-8_h2a3cdd5_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.1-h7ce1215_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwy-1.4.0-h172a326_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.4.1-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjxl-0.11.2-h932607e_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-8_hf9ab0e9_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.5-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libopus-1.6.1-h6a83c73_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-h7351971_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/librsvg-2.62.3-h15cfe45_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.2-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libusb-1.0.29-h1839187_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libvorbis-1.3.7-h5112557_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.7-h4fa8253_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.0.0-hac47afa_908.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.6-py314h02f10f6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/onemkl-license-2026.0.0-h57928b3_908.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.6.0-hb17fa0b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.3-hf411b9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.56.4-h13911b6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyglet-2.1.14-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.6-h4b44e0e_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/sdl2-2.32.56-h5112557_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/sdl3-3.4.10-h5112557_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/shaderc-2026.2-h8fa7867_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/spirv-tools-2026.2-h49e36cd_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.0.1-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-h1b7c187_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.51.36231-h84cd919_39.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda build_number: 20 @@ -2910,6 +3333,17 @@ packages: license_family: GPL size: 584660 timestamp: 1768327524772 +- conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.16.1-hb03c661_0.conda + sha256: cf93ca0f1f107e95a35969a4622684e08fcb8cf37f8cf4a1e9e424828386c921 + md5: 8904e09bda369377b3dd07e2ac828c5d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-or-later + license_family: LGPL + purls: [] + size: 592377 + timestamp: 1781521980743 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda sha256: ea2233e2db9908c2e5f29d3ca420a546b4583253f4f70abb5494cdd676866d42 md5: 4a98cbc4ade694520227402ff8880630 @@ -2919,6 +3353,28 @@ packages: license_family: GPL size: 615729 timestamp: 1768327548407 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.16.1-he30d5cf_0.conda + sha256: 105e4c19cfa770affcb9a64b9d2451f406914cd09a67664009910869fa01a639 + md5: 5427b5dcb268bddf1a69c16d1cb77a47 + depends: + - libgcc >=14 + license: LGPL-2.1-or-later + license_family: LGPL + purls: [] + size: 621865 + timestamp: 1781522013595 +- conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.14.1-pl5321h039972f_1.conda + sha256: b1d972a9b949a88babee681437535550b3ca5dbca6a23a40dffeb7900fec19fd + md5: 5a78a69eb3b50f24b379e9d2a93163ae + depends: + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 3103347 + timestamp: 1780752473089 - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda sha256: b08ef033817b5f9f76ce62dfcac7694e7b6b4006420372de22494503decac855 md5: 346722a0be40f6edc53f12640d301338 @@ -2929,6 +3385,17 @@ packages: license_family: BSD size: 2706396 timestamp: 1718551242397 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/aom-3.14.1-pl5321h8fffa31_1.conda + sha256: a228f46f68fa3e2e50a09b5a4cefd1ee2c1ce868bfa2a288867b3d44b6e77427 + md5: a3c86229b531656c2bce99e8a6c6de4a + depends: + - libstdcxx >=14 + - libgcc >=14 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 4091040 + timestamp: 1780752489693 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/aom-3.9.1-hcccb83c_0.conda sha256: ac438ce5d3d3673a9188b535fc7cda413b479f0d52536aeeac1bd82faa656ea0 md5: cc744ac4efe5bcaa8cca51ff5b850df0 @@ -2939,6 +3406,18 @@ packages: license_family: BSD size: 3250813 timestamp: 1718551360260 +- conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.14.1-pl5321h06fc181_1.conda + sha256: 3033fa8953f7f0c1bb5b89b5af77253badc14a89ba94d743dde3c9159e10fd5e + md5: 7a8ace8100a48355a34d87386012c57b + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 2214571 + timestamp: 1780752497150 - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.1-he0c23c2_0.conda sha256: 0524d0c0b61dacd0c22ac7a8067f977b1d52380210933b04141f5099c5b6fec7 md5: 3d7c14285d3eb3239a76ff79063f27a5 @@ -3227,6 +3706,24 @@ packages: purls: [] size: 147413 timestamp: 1772006283803 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-h4c7d964_0.conda + sha256: 86981d764e4ea1883409d30447ff9da46127426d31a63df08315aaded768e652 + md5: c9b86eece2f944541b86441c94117ab3 + depends: + - __win + license: ISC + purls: [] + size: 130182 + timestamp: 1779289939595 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda + sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b + md5: 489b8e97e666c93f68fdb35c3c9b957f + depends: + - __unix + license: ISC + purls: [] + size: 129868 + timestamp: 1779289852439 - conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.3-pyha770c72_0.conda sha256: ec791bb6f1ef504411f87b28946a7ae63ed1f3681cefc462cf1dfdaf0790b6a9 md5: 241ef6e3db47a143ac34c21bfba510f1 @@ -3264,6 +3761,7 @@ packages: - xorg-libxext >=1.3.6,<2.0a0 - xorg-libxrender >=0.9.12,<0.10.0a0 license: LGPL-2.1-only or MPL-1.1 + purls: [] size: 989514 timestamp: 1766415934926 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda @@ -3289,6 +3787,7 @@ packages: - xorg-libxext >=1.3.6,<2.0a0 - xorg-libxrender >=0.9.12,<0.10.0a0 license: LGPL-2.1-only or MPL-1.1 + purls: [] size: 927045 timestamp: 1766416003626 - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda @@ -3309,6 +3808,7 @@ packages: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 license: LGPL-2.1-only or MPL-1.1 + purls: [] size: 1537783 timestamp: 1766416059188 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda @@ -3483,6 +3983,28 @@ packages: - pkg:pypi/cssutils?source=hash-mapping size: 284664 timestamp: 1747322864144 +- pypi: https://files.pythonhosted.org/packages/52/b8/83b1f563925b290f2d11a01a77a84013ba56052fe3653a5bef3ccfbb43d6/cuda_bindings-13.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl + name: cuda-bindings + version: 13.3.1 + sha256: c3c772dfff49681541d59630c90f858e173ac926b9c593a2b7123f2a1043cc76 + requires_dist: + - cuda-pathfinder>=1.4.2 + - cuda-toolkit[nvfatbin,nvjitlink,nvrtc,nvvm]==13.* ; extra == 'all' + - cuda-toolkit[cufile]==13.* ; sys_platform == 'linux' and extra == 'all' + - cuda-toolkit==13.* ; extra == 'all' + - nvidia-cudla==13.* ; platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/d4/e0/c8a1f0c8f9ffdea4f5fe6dbab89b326cef4d85caf489dad39e209da89416/cuda_bindings-13.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: cuda-bindings + version: 13.3.1 + sha256: efd4c814d311ec08c981f6dded1dbe7d4b371067ee4f6c14cccec4bde9590f80 + requires_dist: + - cuda-pathfinder>=1.4.2 + - cuda-toolkit[nvfatbin,nvjitlink,nvrtc,nvvm]==13.* ; extra == 'all' + - cuda-toolkit[cufile]==13.* ; sys_platform == 'linux' and extra == 'all' + - cuda-toolkit==13.* ; extra == 'all' + - nvidia-cudla==13.* ; platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all' + requires_python: '>=3.10' - conda: ../cuda_bindings name: cuda-bindings version: 13.2.0 @@ -3679,6 +4201,28 @@ packages: license: LicenseRef-NVIDIA-End-User-License-Agreement size: 1462453 timestamp: 1779895589763 +- pypi: https://files.pythonhosted.org/packages/51/08/1aeffc9a529a7f94c9cee9bfd3a991743398b5f90aab30f06f2a4bc8205e/cuda_core-1.0.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + name: cuda-core + version: 1.0.1 + sha256: af2db9e50e81d73e4f0b72ad279d0a9c789372393938fe75c17236b9ed974d7d + requires_dist: + - cuda-pathfinder>=1.4.2 + - numpy + - backports-strenum ; python_full_version < '3.11' + - cuda-bindings[all]==12.* ; extra == 'cu12' + - cuda-bindings[all]==13.* ; extra == 'cu13' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/e3/ab/db09228d5a8c124a93514726d2e18f31824f66d3a6769ee4e51721dd64cf/cuda_core-1.0.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl + name: cuda-core + version: 1.0.1 + sha256: 4410bf1ef15c2ec23dccc302da76893c9354b530dee422e3277b116231bf5fe1 + requires_dist: + - cuda-pathfinder>=1.4.2 + - numpy + - backports-strenum ; python_full_version < '3.11' + - cuda-bindings[all]==12.* ; extra == 'cu12' + - cuda-bindings[all]==13.* ; extra == 'cu13' + requires_python: '>=3.10' - conda: . name: cuda-core version: 0.7.0 @@ -4899,6 +5443,11 @@ packages: purls: [] size: 45453672 timestamp: 1779905194696 +- pypi: https://files.pythonhosted.org/packages/11/c8/26f2e4aae92f11522a96043892ba39a90eac610d5242523aa863212bc1c7/cuda_pathfinder-1.5.5-py3-none-any.whl + name: cuda-pathfinder + version: 1.5.5 + sha256: 0228c023f95d1480f143ef5c8922d27a2ab052087a942e81dc289c9eb8f91689 + requires_python: '>=3.10' - conda: ../cuda_pathfinder name: cuda-pathfinder version: 1.3.4a0 @@ -4961,6 +5510,81 @@ packages: license: LicenseRef-NVIDIA-End-User-License-Agreement size: 25101 timestamp: 1779913642980 +- pypi: https://files.pythonhosted.org/packages/9a/8c/29b52f76ee4b4f94d5f1ef05797a83ae48ba8b6d5fcd5691dafb570a5f65/cuda_toolkit-13.3.0-py2.py3-none-any.whl + name: cuda-toolkit + version: 13.3.0 + sha256: 6e50798a0cc6e94f3044be58ca7b6628852c017ccec1220af88e60d266fe8f2c + requires_dist: + - nvidia-cublas==13.5.1.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-cccl==13.3.3.3.1.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-crt==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-culibos==13.3.33.* ; (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-cuobjdump==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-cupti==13.3.35.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-cuxxfilt==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-nvcc==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-nvdisasm==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-nvrtc==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-opencl==13.3.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-profiler-api==13.3.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-runtime==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-sanitizer-api==13.3.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-tileiras==13.3.36.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cudla==13.3.29.* ; platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all' + - nvidia-cufft==12.3.0.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cufile==1.18.0.66.* ; (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-curand==10.4.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cusolver==12.2.2.18.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cusparse==12.8.1.7.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-npp==13.1.2.48.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-nvfatbin==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-nvjitlink>=13.3.33,<14 ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-nvjpeg==13.2.0.21.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-nvml-dev==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-nvptxcompiler==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-nvtx==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-nvvm==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'all') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'all') + - nvidia-cuda-cccl==13.3.3.3.1.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cccl') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cccl') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cccl') + - nvidia-cuda-crt==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'crt') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'crt') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'crt') + - nvidia-cublas==13.5.1.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cublas') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cublas') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cublas') + - nvidia-cuda-nvrtc==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cublas') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cublas') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cublas') + - nvidia-cuda-runtime==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cudart') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cudart') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cudart') + - nvidia-cudla==13.3.29.* ; platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cudla' + - nvidia-cufft==12.3.0.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cufft') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cufft') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cufft') + - nvidia-nvjitlink>=13.3.33,<14 ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cufft') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cufft') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cufft') + - nvidia-cufile==1.18.0.66.* ; (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cufile') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cufile') + - nvidia-cuda-culibos==13.3.33.* ; (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'culibos') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'culibos') + - nvidia-cuda-cuobjdump==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cuobjdump') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cuobjdump') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cuobjdump') + - nvidia-cuda-cupti==13.3.35.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cupti') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cupti') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cupti') + - nvidia-curand==10.4.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'curand') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'curand') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'curand') + - nvidia-cublas==13.5.1.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cusolver') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cusolver') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cusolver') + - nvidia-cusolver==12.2.2.18.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cusolver') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cusolver') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cusolver') + - nvidia-cusparse==12.8.1.7.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cusolver') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cusolver') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cusolver') + - nvidia-nvjitlink>=13.3.33,<14 ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cusolver') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cusolver') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cusolver') + - nvidia-cusparse==12.8.1.7.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cusparse') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cusparse') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cusparse') + - nvidia-nvjitlink>=13.3.33,<14 ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cusparse') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cusparse') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cusparse') + - nvidia-cuda-cuxxfilt==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'cuxxfilt') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'cuxxfilt') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'cuxxfilt') + - nvidia-npp==13.1.2.48.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'npp') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'npp') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'npp') + - nvidia-cuda-crt==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvcc') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvcc') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvcc') + - nvidia-cuda-nvcc==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvcc') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvcc') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvcc') + - nvidia-cuda-runtime==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvcc') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvcc') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvcc') + - nvidia-nvvm==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvcc') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvcc') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvcc') + - nvidia-cuda-nvdisasm==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvdisasm') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvdisasm') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvdisasm') + - nvidia-nvfatbin==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvfatbin') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvfatbin') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvfatbin') + - nvidia-nvjitlink>=13.3.33,<14 ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvjitlink') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvjitlink') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvjitlink') + - nvidia-nvjpeg==13.2.0.21.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvjpeg') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvjpeg') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvjpeg') + - nvidia-nvml-dev==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvml') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvml') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvml') + - nvidia-nvptxcompiler==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvptxcompiler') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvptxcompiler') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvptxcompiler') + - nvidia-cuda-nvrtc==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvrtc') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvrtc') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvrtc') + - nvidia-nvtx==13.3.29.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvtx') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvtx') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvtx') + - nvidia-nvvm==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'nvvm') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'nvvm') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'nvvm') + - nvidia-cuda-opencl==13.3.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'opencl') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'opencl') + - nvidia-cuda-profiler-api==13.3.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'profiler') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'profiler') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'profiler') + - nvidia-cuda-sanitizer-api==13.3.27.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'sanitizer') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'sanitizer') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'sanitizer') + - nvidia-cuda-nvcc==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'tileiras') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'tileiras') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'tileiras') + - nvidia-cuda-tileiras==13.3.36.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'tileiras') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'tileiras') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'tileiras') + - nvidia-nvjitlink>=13.3.33,<14 ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'tileiras') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'tileiras') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'tileiras') + - nvidia-nvvm==13.3.33.* ; (platform_machine == 'AMD64' and sys_platform == 'win32' and extra == 'tileiras') or (platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'tileiras') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'tileiras') - conda: https://conda.anaconda.org/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda sha256: 5f5f428031933f117ff9f7fcc650e6ea1b3fef5936cf84aa24af79167513b656 md5: b6d5d7f1c171cbd228ea06b556cfa859 @@ -5131,6 +5755,7 @@ packages: - libgcc-ng >=12 license: BSD-2-Clause license_family: BSD + purls: [] size: 760229 timestamp: 1685695754230 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/dav1d-1.2.1-h31becfc_0.conda @@ -5140,6 +5765,7 @@ packages: - libgcc-ng >=12 license: BSD-2-Clause license_family: BSD + purls: [] size: 347363 timestamp: 1685696690003 - conda: https://conda.anaconda.org/conda-forge/win-64/dav1d-1.2.1-hcfcfb64_0.conda @@ -5151,6 +5777,7 @@ packages: - vc14_runtime >=14.29.30139 license: BSD-2-Clause license_family: BSD + purls: [] size: 618643 timestamp: 1685696352968 - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda @@ -5164,6 +5791,7 @@ packages: - libglib >=2.86.2,<3.0a0 - libexpat >=2.7.3,<3.0a0 license: AFL-2.1 OR GPL-2.0-or-later + purls: [] size: 447649 timestamp: 1764536047944 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda @@ -5176,6 +5804,7 @@ packages: - libzlib >=1.3.1,<2.0a0 - libexpat >=2.7.3,<3.0a0 license: AFL-2.1 OR GPL-2.0-or-later + purls: [] size: 480416 timestamp: 1764536098891 - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.20-py314h42812f9_0.conda @@ -5373,6 +6002,71 @@ packages: license_family: GPL size: 12485347 timestamp: 1773008832077 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-8.1.1-gpl_h6d6c1bd_904.conda + sha256: d9064d5f8575e4f7b6a2c73718f4d4b8986808d8a92eabc5f6b50d5a2fbb18ec + md5: 5acc906a0f5f8f56d28665ac6b840f8e + depends: + - __glibc >=2.17,<3.0.a0 + - alsa-lib >=1.2.16,<1.3.0a0 + - aom >=3.14.1,<3.15.0a0 + - bzip2 >=1.0.8,<2.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - fontconfig >=2.18.1,<3.0a0 + - fonts-conda-ecosystem + - gmp >=6.3.0,<7.0a0 + - harfbuzz >=14.2.1 + - lame >=3.100,<3.101.0a0 + - libass >=0.17.4,<0.17.5.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - libjxl >=0.11,<1.0a0 + - liblzma >=5.8.3,<6.0a0 + - libopenvino >=2026.2.0,<2026.2.1.0a0 + - libopenvino-auto-batch-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-auto-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-hetero-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-intel-cpu-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-intel-gpu-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-intel-npu-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-ir-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-onnx-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-paddle-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-pytorch-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-tensorflow-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-tensorflow-lite-frontend >=2026.2.0,<2026.2.1.0a0 + - libopus >=1.6.1,<2.0a0 + - libplacebo >=7.360.1,<7.361.0a0 + - librsvg >=2.62.3,<3.0a0 + - libstdcxx >=14 + - libva >=2.23.0,<3.0a0 + - libvorbis >=1.3.7,<1.4.0a0 + - libvpl >=2.16.0,<2.17.0a0 + - libvpx >=1.15.2,<1.16.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.2,<2.0a0 + - openh264 >=2.6.0,<2.6.1.0a0 + - openssl >=3.5.6,<4.0a0 + - pulseaudio-client >=17.0,<17.1.0a0 + - sdl2 >=2.32.56,<3.0a0 + - shaderc >=2026.2,<2026.3.0a0 + - svt-av1 >=4.0.1,<4.0.2.0a0 + - x264 >=1!164.3095,<1!165 + - x265 >=3.5,<3.6.0a0 + - xorg-libx11 >=1.8.13,<2.0a0 + constrains: + - __cuda >=12.8 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 12996053 + timestamp: 1780667981113 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ffmpeg-8.0.1-gpl_h62efc85_914.conda sha256: a2816bcef9d7b072597192fcb15b851eaee1ef358c0a3890ab255070d41b64cb md5: e9f109db13b0fad0c1f2f92d9770c8c3 @@ -5431,6 +6125,66 @@ packages: license_family: GPL size: 12035194 timestamp: 1773008913159 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ffmpeg-8.1.1-gpl_hef17b83_904.conda + sha256: 5d50fac41e33f43144fccc32fadf84eff748b7397cf7fb2bebbce54413448762 + md5: df73a6f7d9a40e7eec63a39e53e38ca6 + depends: + - alsa-lib >=1.2.16,<1.3.0a0 + - aom >=3.14.1,<3.15.0a0 + - bzip2 >=1.0.8,<2.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - fontconfig >=2.18.1,<3.0a0 + - fonts-conda-ecosystem + - gmp >=6.3.0,<7.0a0 + - harfbuzz >=14.2.1 + - lame >=3.100,<3.101.0a0 + - libass >=0.17.4,<0.17.5.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - libjxl >=0.11,<1.0a0 + - liblzma >=5.8.3,<6.0a0 + - libopenvino >=2026.2.0,<2026.2.1.0a0 + - libopenvino-arm-cpu-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-auto-batch-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-auto-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-hetero-plugin >=2026.2.0,<2026.2.1.0a0 + - libopenvino-ir-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-onnx-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-paddle-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-pytorch-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-tensorflow-frontend >=2026.2.0,<2026.2.1.0a0 + - libopenvino-tensorflow-lite-frontend >=2026.2.0,<2026.2.1.0a0 + - libopus >=1.6.1,<2.0a0 + - libplacebo >=7.360.1,<7.361.0a0 + - librsvg >=2.62.3,<3.0a0 + - libstdcxx >=14 + - libvorbis >=1.3.7,<1.4.0a0 + - libvpx >=1.15.2,<1.16.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.2,<2.0a0 + - openh264 >=2.6.0,<2.6.1.0a0 + - openssl >=3.5.6,<4.0a0 + - pulseaudio-client >=17.0,<17.1.0a0 + - sdl2 >=2.32.56,<3.0a0 + - shaderc >=2026.2,<2026.3.0a0 + - svt-av1 >=4.0.1,<4.0.2.0a0 + - x264 >=1!164.3095,<1!165 + - x265 >=3.5,<3.6.0a0 + - xorg-libx11 >=1.8.13,<2.0a0 + constrains: + - __cuda >=12.8 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 12619638 + timestamp: 1780668065925 - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-8.0.1-gpl_hb2d76f6_914.conda sha256: fbe7916ed95bdc9650c9906865ab21cc04fb337548fdffec94f64a547ba3644d md5: 7cffff39ee349bddb81e1de24c780f34 @@ -5472,6 +6226,48 @@ packages: license_family: GPL size: 10417843 timestamp: 1773010275486 +- conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-8.1.1-gpl_h6d5d71d_904.conda + sha256: 6931df70697ae0d74ea9680695facd1a5e1e0163bf0e4a5618a086bef7a6f220 + md5: 8d45d61991af969cd4641f678e741996 + depends: + - aom >=3.14.1,<3.15.0a0 + - bzip2 >=1.0.8,<2.0a0 + - dav1d >=1.2.1,<1.2.2.0a0 + - fontconfig >=2.18.1,<3.0a0 + - fonts-conda-ecosystem + - harfbuzz >=14.2.1 + - lame >=3.100,<3.101.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libiconv >=1.18,<2.0a0 + - libjxl >=0.11,<1.0a0 + - liblzma >=5.8.3,<6.0a0 + - libopus >=1.6.1,<2.0a0 + - librsvg >=2.62.3,<3.0a0 + - libvorbis >=1.3.7,<1.4.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - libzlib >=1.3.2,<2.0a0 + - openh264 >=2.6.0,<2.6.1.0a0 + - openssl >=3.5.6,<4.0a0 + - sdl2 >=2.32.56,<3.0a0 + - shaderc >=2026.2,<2026.3.0a0 + - svt-av1 >=4.0.1,<4.0.2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - x264 >=1!164.3095,<1!165 + - x265 >=3.5,<3.6.0a0 + constrains: + - __cuda >=12.8 + license: GPL-2.0-or-later + license_family: GPL + purls: [] + size: 10974250 + timestamp: 1780670037652 - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda sha256: dddea9ec53d5e179de82c24569d41198f98db93314f0adae6b15195085d5567f md5: f58064cec97b12a7136ebb8a6f8a129b @@ -5508,6 +6304,7 @@ packages: md5: 0c96522c6bdaed4b1566d11387caaf45 license: BSD-3-Clause license_family: BSD + purls: [] size: 397370 timestamp: 1566932522327 - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 @@ -5515,6 +6312,7 @@ packages: md5: 34893075a5c9e55cdafac56607368fc6 license: OFL-1.1 license_family: Other + purls: [] size: 96530 timestamp: 1620479909603 - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 @@ -5522,6 +6320,7 @@ packages: md5: 4d59c254e01d9cde7957100457e2d5fb license: OFL-1.1 license_family: Other + purls: [] size: 700814 timestamp: 1620479612257 - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda @@ -5529,6 +6328,7 @@ packages: md5: 49023d73832ef61042f6a237cb2687e7 license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 license_family: Other + purls: [] size: 1620504 timestamp: 1727511233259 - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda @@ -5546,6 +6346,22 @@ packages: license_family: MIT size: 270705 timestamp: 1771382710863 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.18.1-h27c8c51_0.conda + sha256: 2e50bdcebdf70a865b81f2456bbc586386451ec601c60f2b6cd22b8c40a2d384 + md5: e0e050cfa9fa85fe39632ab11cb7f3e0 + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libgcc >=14 + - libuuid >=2.42.1,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 281880 + timestamp: 1780450077431 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda sha256: 835aff8615dd8d8fff377679710ce81b8a2c47b6404e21a92fb349fda193a15c md5: 0fed1ff55f4938a65907f3ecf62609db @@ -5560,6 +6376,21 @@ packages: license_family: MIT size: 279044 timestamp: 1771382728182 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.18.1-hba86a56_0.conda + sha256: 2ccfd118269d363a5506161c4a0d96da46d2f01beecc74e0540a54b4737d0e45 + md5: f4d29a0cd77104a683607319a542ac7e + depends: + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libgcc >=14 + - libuuid >=2.42.1,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 290522 + timestamp: 1780450108132 - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda sha256: ff2db9d305711854de430f946dc59bd40167940a1de38db29c5a78659f219d9c md5: a0b1b87e871011ca3b783bbf410bc39f @@ -5576,6 +6407,24 @@ packages: license_family: MIT size: 195332 timestamp: 1771382820659 +- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.18.1-hd47e2ca_0.conda + sha256: 9217184c4a8e82101b0e512b059ae3ff67e3913133b9031edad89ab5341284e4 + md5: abd79bad98c99c1a116154d6de74ea89 + depends: + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libiconv >=1.18,<2.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 202630 + timestamp: 1780450217840 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 md5: fee5683a3f04bd15cbd8318b096a27ab @@ -5583,6 +6432,7 @@ packages: - fonts-conda-forge license: BSD-3-Clause license_family: BSD + purls: [] size: 3667 timestamp: 1566974674465 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda @@ -5595,6 +6445,7 @@ packages: - font-ttf-source-code-pro license: BSD-3-Clause license_family: BSD + purls: [] size: 4059 timestamp: 1762351264405 - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda @@ -5606,6 +6457,16 @@ packages: license: GPL-2.0-only OR FTL size: 174292 timestamp: 1772757205296 +- conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda + sha256: c934c385889c7836f034039b43b05ccfa98f53c900db03d8411189892ced090b + md5: 8462b5322567212beeb025f3519fb3e2 + depends: + - libfreetype 2.14.3 ha770c72_0 + - libfreetype6 2.14.3 h73754d4_0 + license: GPL-2.0-only OR FTL + purls: [] + size: 173839 + timestamp: 1774298173462 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.2-h8af1aa0_0.conda sha256: ecbe6e811574fba5194b29ac3a2badea5eaa060bd9fe7f5bd48a70d16ef38e5a md5: 9cb47d7bbb36646c44d7cf1cb8047887 @@ -5615,6 +6476,16 @@ packages: license: GPL-2.0-only OR FTL size: 173437 timestamp: 1772756019067 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.3-h8af1aa0_1.conda + sha256: 1112c56bc19cbce233b30d9d31ce8eb6fcc100c9baa5145315aaa1e3a25b5178 + md5: 5e8e88bfb3fbb0df0f9f8bb890721e07 + depends: + - libfreetype 2.14.3 h8af1aa0_1 + - libfreetype6 2.14.3 hdae7a39_1 + license: GPL-2.0-only OR FTL + purls: [] + size: 174060 + timestamp: 1780933507786 - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.2-h57928b3_0.conda sha256: 6dd4bb3862ea3d07015331059504cf3b6af1a11a6909e7a9b6e04a20e253da28 md5: c360b467564b875a9f5dc481b8726cee @@ -5624,6 +6495,17 @@ packages: license: GPL-2.0-only OR FTL size: 185633 timestamp: 1772756186241 +- conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_1.conda + sha256: a0e419e96146159f12344c870dca608d11bca36841f228092b986ffc2e1e0f02 + md5: e77293b32225b136a8be300f93d0e89f + depends: + - libfreetype 2.14.3 h57928b3_1 + - libfreetype6 2.14.3 hdbac1cb_1 + - zlib + license: GPL-2.0-only OR FTL + purls: [] + size: 185584 + timestamp: 1780934817461 - conda: https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda sha256: 858283ff33d4c033f4971bf440cebff217d5552a5222ba994c49be990dacd40d md5: f9f81ea472684d75b9dd8d0b328cf655 @@ -5631,6 +6513,7 @@ packages: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: LGPL-2.1-or-later + purls: [] size: 61244 timestamp: 1757438574066 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fribidi-1.0.16-he30d5cf_0.conda @@ -5639,6 +6522,7 @@ packages: depends: - libgcc >=14 license: LGPL-2.1-or-later + purls: [] size: 62909 timestamp: 1757438620177 - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_0.conda @@ -5649,6 +6533,7 @@ packages: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 license: LGPL-2.1-or-later + purls: [] size: 64394 timestamp: 1757438741305 - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda @@ -5806,6 +6691,22 @@ packages: license_family: LGPL size: 575109 timestamp: 1771530561157 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.44.6-h2b0a6b4_0.conda + sha256: c5594497f0646e9079705b3199dbb2d5b13c48173cf110000fa1c8818e2b3e0c + md5: 7892f39a39ed39591a89a28eba03e987 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libpng >=1.6.56,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + license: LGPL-2.1-or-later + license_family: LGPL + purls: [] + size: 577414 + timestamp: 1774985848058 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gdk-pixbuf-2.44.5-h90308e0_1.conda sha256: aa95b37da0750fb93c5eeef79073b9b0d50976fa0dc02ed0301ff7bbbfc7ff36 md5: c75ae103325db056719dd51d6525e1cd @@ -5820,6 +6721,21 @@ packages: license_family: LGPL size: 584221 timestamp: 1771532437279 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gdk-pixbuf-2.44.6-h90308e0_0.conda + sha256: 53ac38045a8c0b6aa9cfaf784443a3744dc86ab4737c1479b44ae85c96926fe1 + md5: bdd860e72c5e10eb4ffa3d61f9b02ee0 + depends: + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libpng >=1.6.56,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + license: LGPL-2.1-or-later + license_family: LGPL + purls: [] + size: 583708 + timestamp: 1774987740322 - conda: https://conda.anaconda.org/conda-forge/win-64/gdk-pixbuf-2.44.5-h1f5b9c4_1.conda sha256: 82c725a67098c7c43dfc33ba292a48e68530135b94a8703f20566d90574acdfd md5: 4059b4975e2de5894286dbe6bd6728fb @@ -5837,6 +6753,24 @@ packages: license_family: LGPL size: 574950 timestamp: 1771530717329 +- conda: https://conda.anaconda.org/conda-forge/win-64/gdk-pixbuf-2.44.6-h1f5b9c4_0.conda + sha256: 3b8a4bdb183b3b9b70caa91498680add15fb70678ec2a21391e6860c5dfed3e7 + md5: e1ff1d17cb48f89d71f74b0c5eab3b47 + depends: + - libglib >=2.86.4,<3.0a0 + - libintl >=0.22.5,<1.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libpng >=1.6.56,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-or-later + license_family: LGPL + purls: [] + size: 576065 + timestamp: 1774986034812 - conda: https://conda.anaconda.org/conda-forge/linux-64/glslang-16.2.0-h96af755_1.conda sha256: 88a5ad3571948bde22957d08ab01328b8a7eb04fdee66268b3125cc322dbde8b md5: ba5b655d827f263090ad2dc514810328 @@ -5849,6 +6783,19 @@ packages: license_family: BSD size: 1353008 timestamp: 1770195199411 +- conda: https://conda.anaconda.org/conda-forge/linux-64/glslang-16.3.0-h96af755_0.conda + sha256: 3c9b6a90937a96ad27d160304cdbe5e9961db613aba2b84ff673429f0c61d48e + md5: d175cb2c14104728ada04883786a309d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - spirv-tools >=2026,<2027.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 1366082 + timestamp: 1777747028121 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/glslang-16.2.0-h124e036_1.conda sha256: a1c0db6c226b9d80e74bdd49f604eece637489c8c71e6ae63ada8db9e2359944 md5: 3ead7f968b529f76f972621558ed2f68 @@ -5860,6 +6807,18 @@ packages: license_family: BSD size: 1348415 timestamp: 1770195275881 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/glslang-16.3.0-h124e036_0.conda + sha256: bae4806f4076cf9f91089fbeae7c9357ce4348df3657c25b249ac4487beed230 + md5: c0045dffcc3660ecd1b9123df377796f + depends: + - libgcc >=14 + - libstdcxx >=14 + - spirv-tools >=2026,<2027.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 1359428 + timestamp: 1777747105441 - conda: https://conda.anaconda.org/conda-forge/win-64/glslang-16.2.0-h294ba9c_1.conda sha256: c46afa4a43b7709e07a69d0a2d70b10f59f22e96dbf9ec80e53a42cc6551111c md5: 4b5f576265df0a05d4e47e48c50bb4e6 @@ -5872,6 +6831,19 @@ packages: license_family: BSD size: 4929181 timestamp: 1770195251565 +- conda: https://conda.anaconda.org/conda-forge/win-64/glslang-16.3.0-h294ba9c_0.conda + sha256: d80276b89d8aeab6ff0d8d7d4b9af336b368fc0b8fa28ea8cde6f6f2aa07bacf + md5: 7d6fed8a6ebeeebd6362790e22e56bb3 + depends: + - spirv-tools >=2026,<2027.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 5074630 + timestamp: 1777747167205 - conda: https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda sha256: 309cf4f04fec0c31b6771a5809a1909b4b3154a2208f52351e1ada006f4c750c md5: c94a5994ef49749880a8139cf9afcbe1 @@ -5879,6 +6851,7 @@ packages: - libgcc-ng >=12 - libstdcxx-ng >=12 license: GPL-2.0-or-later OR LGPL-3.0-or-later + purls: [] size: 460055 timestamp: 1718980856608 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/gmp-6.3.0-h0a1ffab_2.conda @@ -5888,6 +6861,7 @@ packages: - libgcc-ng >=12 - libstdcxx-ng >=12 license: GPL-2.0-or-later OR LGPL-3.0-or-later + purls: [] size: 417323 timestamp: 1718980707330 - conda: https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda @@ -5931,6 +6905,18 @@ packages: license_family: LGPL size: 99596 timestamp: 1755102025473 +- conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.15-hecca717_0.conda + sha256: 885fa7d1d7e2ad9ed0a700ee0d81ceb49de278253082d517959b22d6336eecce + md5: cf09e9fc938518e91d0706572cadf17a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 100054 + timestamp: 1780454302233 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda sha256: c9b1781fe329e0b77c5addd741e58600f50bef39321cae75eba72f2f381374b7 md5: 4aa540e9541cc9d6581ab23ff2043f13 @@ -5941,6 +6927,17 @@ packages: license_family: LGPL size: 102400 timestamp: 1755102000043 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.15-hfae3067_0.conda + sha256: 3e529c517a76a1f4497c51eeedeeb927d33f732dcdb48055a020a83eb3e4e95c + md5: 4db044857ab1d09b2e8f0013c65387c1 + depends: + - libgcc >=14 + - libstdcxx >=14 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 103119 + timestamp: 1780455096710 - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda sha256: 5f1714b07252f885a62521b625898326ade6ca25fbc20727cfe9a88f68a54bfd md5: b785694dd3ec77a011ccf0c24725382b @@ -5952,6 +6949,18 @@ packages: license_family: LGPL size: 96336 timestamp: 1755102441729 +- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.15-hac47afa_0.conda + sha256: 88b6601f8edae59834b59b521e293ff3b58361dc1603240f5a8328c24e6936ad + md5: ff9a9bfe791f56b0227597a7651a6af0 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.0-or-later + license_family: LGPL + purls: [] + size: 97308 + timestamp: 1780454389458 - conda: https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.2-py314h42812f9_0.conda sha256: fdeec5dbb5f964b1709f3d6f697137f0e68650e09ffa80b9b1bee2afb2373da4 md5: 511748f9debe034ff88eef99bc215fd3 @@ -6140,6 +7149,26 @@ packages: license_family: MIT size: 2615630 timestamp: 1773217509651 +- conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.1-h6083320_0.conda + sha256: da9901aa1e20cbc2369fda212039b294dd02bce95f005539bab840b7310bf7d0 + md5: 21ee4640b7c2d94e584349fa12b29b9a + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.14,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libgcc >=14 + - libglib >=2.88.1,<3.0a0 + - libstdcxx >=14 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 2362258 + timestamp: 1780450503234 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.1.0-h1134a53_0.conda sha256: 49074457bdc624c0c0f39bb4b9b7689ec6334127ed7d5312484908f48e9a8e20 md5: 811bb5384d92870a3492fab4de4ff3f6 @@ -6158,6 +7187,25 @@ packages: license_family: MIT size: 2346492 timestamp: 1773222371375 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-14.2.1-h1134a53_0.conda + sha256: 17a671aa62e1f0a8750514353e3d6e9aab80598908d9b107fc7f3cf7972176b6 + md5: 5f3ec279ab7cc391b7dff69dc08298fa + depends: + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.14,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libgcc >=14 + - libglib >=2.88.1,<3.0a0 + - libstdcxx >=14 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 2786349 + timestamp: 1780454506157 - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.1.0-h5a1b470_0.conda sha256: 27acd845926048481a831b7321674b3f92accde49869fb95438f0a35ea89419b md5: b3a4ff5d1e21d58090cd87060eb54c2d @@ -6177,6 +7225,26 @@ packages: license_family: MIT size: 1285640 timestamp: 1773217788574 +- conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.2.1-h5a1b470_0.conda + sha256: 55d6d483e089afe68bdbb38a003d7b76002e65341665b80f38e6ce4b494beef6 + md5: 0bcbb7f911590beec914555c6b82050d + depends: + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.14,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.8.1,<3.0a0 + - libfreetype >=2.14.3 + - libfreetype6 >=2.14.3 + - libglib >=2.88.1,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: [] + size: 1304897 + timestamp: 1780450940279 - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba md5: 0a802cb9888dd14eeefc611f05c40b6e @@ -6267,6 +7335,18 @@ packages: license_family: MIT size: 13222158 timestamp: 1767970128854 +- conda: https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_0.conda + sha256: 1bda728d70a619731b278c859eda364146cb5b4b8c739a64da8128353d81d1c4 + md5: 0097b24800cb696915c3dbd1f5335d3f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 14954024 + timestamp: 1773822508646 - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda sha256: ae89d0299ada2a3162c2614a9d26557a92aa6a77120ce142f8e0109bbf0342b0 md5: 53abe63df7e10a6ba605dc5f9f961d36 @@ -6349,6 +7429,18 @@ packages: - pkg:pypi/iniconfig?source=hash-mapping size: 13387 timestamp: 1760831448842 +- conda: https://conda.anaconda.org/conda-forge/linux-64/intel-gmmlib-22.10.0-hb700be7_0.conda + sha256: bc231d69eb6663db0e09738fb916c5e5507147cf1ac60f364f964004e0b29bab + md5: 10909406c1b0e4b57f9f4f0eb0999af8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + purls: [] + size: 1013714 + timestamp: 1774422680665 - conda: https://conda.anaconda.org/conda-forge/linux-64/intel-gmmlib-22.9.0-hb700be7_0.conda sha256: edad668db79c6c4899d46e1cd4a331f5d008f9ed8f7d2e39e1dfe1a2d81acec0 md5: 26311c5112b5c713f472bdfbb5ec5aa3 @@ -6373,6 +7465,20 @@ packages: license_family: MIT size: 8783533 timestamp: 1773230300873 +- conda: https://conda.anaconda.org/conda-forge/linux-64/intel-media-driver-26.1.6-hecca717_0.conda + sha256: 7cbd7fda22db70c64af64c9173434a4ede58e4f220bda52a044e469aa94c65cb + md5: aaf7c3db8c7c4533deb5449d3ba1c51f + depends: + - __glibc >=2.17,<3.0.a0 + - intel-gmmlib >=22.10.0,<23.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libva >=2.23.0,<3.0a0 + license: MIT + license_family: MIT + purls: [] + size: 8782375 + timestamp: 1776080148587 - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-7.2.0-pyh6dadd2b_1.conda sha256: 9cdadaeef5abadca4113f92f5589db19f8b7df5e1b81cb0225f7024a3aedefa3 md5: b3a7d5842f857414d9ae831a799444dd @@ -6696,6 +7802,7 @@ packages: - libgcc-ng >=12 license: LGPL-2.0-only license_family: LGPL + purls: [] size: 508258 timestamp: 1664996250081 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lame-3.100-h4e544f5_1003.tar.bz2 @@ -6705,6 +7812,7 @@ packages: - libgcc-ng >=12 license: LGPL-2.0-only license_family: LGPL + purls: [] size: 604863 timestamp: 1664997611416 - conda: https://conda.anaconda.org/conda-forge/win-64/lame-3.100-hcfcfb64_1003.tar.bz2 @@ -6716,8 +7824,34 @@ packages: - vs2015_runtime >=14.29.30139 license: LGPL-2.0-only license_family: LGPL + purls: [] size: 570583 timestamp: 1664996824680 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_1.conda + sha256: 112b5b9462572d970f4abd2912f76a25ee7db158b1e7260163d91dd8a630db84 + md5: 8b3ce45e929cd8e8e5f4d18586b56d8b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - libtiff >=4.7.1,<4.8.0a0 + license: MIT + license_family: MIT + purls: [] + size: 251971 + timestamp: 1780211695895 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.19.1-h9d5b58d_1.conda + sha256: ed213207bbf11663181941e0931caa9ce748f0544688e8e0fbcf330bca279389 + md5: 9183fda4be2b4ee5760cdb8e540439c8 + depends: + - libgcc >=14 + - libjpeg-turbo >=3.1.4.1,<4.0a0 + - libtiff >=4.7.1,<4.8.0a0 + license: MIT + license_family: MIT + purls: [] + size: 296564 + timestamp: 1780211834883 - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda sha256: 565941ac1f8b0d2f2e8f02827cbca648f4d18cd461afc31f15604cd291b5c5f3 md5: 12bd9a3f089ee6c9266a37dab82afabd @@ -6786,6 +7920,7 @@ packages: - libstdcxx >=14 license: Apache-2.0 license_family: Apache + purls: [] size: 261513 timestamp: 1773113328888 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda @@ -6796,6 +7931,7 @@ packages: - libstdcxx >=14 license: Apache-2.0 license_family: Apache + purls: [] size: 240444 timestamp: 1773114901155 - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda @@ -6807,6 +7943,7 @@ packages: - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache + purls: [] size: 172395 timestamp: 1773113455582 - conda: https://conda.anaconda.org/conda-forge/linux-64/level-zero-1.28.2-hb700be7_0.conda @@ -6820,6 +7957,18 @@ packages: license_family: MIT size: 858387 timestamp: 1772045965844 +- conda: https://conda.anaconda.org/conda-forge/linux-64/level-zero-1.29.0-hb700be7_0.conda + sha256: d87cfc5eaa08eefff97d891ecb49faa958fcfc32a425767796269c4100d4e516 + md5: f3c3bc77c96af553f761af0e78bc8d9d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + purls: [] + size: 875773 + timestamp: 1780142086148 - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda sha256: a7a4481a4d217a3eadea0ec489826a69070fcc3153f00443aa491ed21527d239 md5: 6f7b4302263347698fd24565fbf11310 @@ -6832,6 +7981,7 @@ packages: - abseil-cpp =20260107.1 license: Apache-2.0 license_family: Apache + purls: [] size: 1384817 timestamp: 1770863194876 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libabseil-20260107.1-cxx17_h6983b43_0.conda @@ -6845,6 +7995,7 @@ packages: - libabseil-static =20260107.1=cxx17* license: Apache-2.0 license_family: Apache + purls: [] size: 1401836 timestamp: 1770863223557 - conda: https://conda.anaconda.org/conda-forge/linux-64/libass-0.17.4-h96ad9f0_0.conda @@ -6862,6 +8013,7 @@ packages: - fonts-conda-ecosystem - harfbuzz >=11.0.1 license: ISC + purls: [] size: 152179 timestamp: 1749328931930 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libass-0.17.4-hcfe818d_0.conda @@ -6878,6 +8030,7 @@ packages: - libfreetype6 >=2.13.3 - libzlib >=1.3.1,<2.0a0 license: ISC + purls: [] size: 171287 timestamp: 1749328949722 - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda @@ -6933,6 +8086,24 @@ packages: purls: [] size: 18621 timestamp: 1774503034895 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-8_h4a7cf45_openblas.conda + build_number: 8 + sha256: b2da6bfd72a1c9cb143ccf64bf5b28790cb4eb58bd1cb978f6537b2322f7d48b + md5: 00fc660ab1b2f5ca07e92b4900d10c79 + depends: + - libopenblas >=0.3.33,<0.3.34.0a0 + - libopenblas >=0.3.33,<1.0a0 + constrains: + - blas 2.308 openblas + - mkl <2027 + - libcblas 3.11.0 8*_openblas + - liblapack 3.11.0 8*_openblas + - liblapacke 3.11.0 8*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18804 + timestamp: 1779859100675 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda build_number: 5 sha256: 700f3c03d0fba8e687a345404a45fbabe781c1cf92242382f62cef2948745ec4 @@ -6968,6 +8139,24 @@ packages: purls: [] size: 18682 timestamp: 1774503047392 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-8_haddc8a3_openblas.conda + build_number: 8 + sha256: c897399c943168c646f659952f73a9154f9122d7e9b151649dbe075dfdcd484b + md5: 8b44dad125760faa2b3925f5a6e3112d + depends: + - libopenblas >=0.3.33,<0.3.34.0a0 + - libopenblas >=0.3.33,<1.0a0 + constrains: + - libcblas 3.11.0 8*_openblas + - liblapack 3.11.0 8*_openblas + - mkl <2027 + - blas 2.308 openblas + - liblapacke 3.11.0 8*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18843 + timestamp: 1779859042591 - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_hf2e6a31_mkl.conda build_number: 5 sha256: f0cb7b2697461a306341f7ff32d5b361bb84f3e94478464c1e27ee01fc8f276b @@ -6999,6 +8188,22 @@ packages: purls: [] size: 68082 timestamp: 1774503684284 +- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-8_h8455456_mkl.conda + build_number: 8 + sha256: 43a87b59e6d4c68d80b2e4de487b1b54d66fe1f9a06636909b5a5ab9eae27269 + md5: 4a0ce24b1a946ff77ae9eaa7ef015a33 + depends: + - mkl >=2026.0.0,<2027.0a0 + constrains: + - libcblas 3.11.0 8*_mkl + - liblapacke 3.11.0 8*_mkl + - blas 2.308 mkl + - liblapack 3.11.0 8*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 68103 + timestamp: 1779859688049 - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda sha256: 318f36bd49ca8ad85e6478bd8506c88d82454cc008c1ac1c6bf00a3c42fa610e md5: 72c8fd1af66bd67bf580645b426513ed @@ -7007,6 +8212,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 79965 timestamp: 1764017188531 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda @@ -7016,6 +8222,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 80030 timestamp: 1764017273715 - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda @@ -7027,6 +8234,7 @@ packages: - vc14_runtime >=14.44.35208 license: MIT license_family: MIT + purls: [] size: 82042 timestamp: 1764017799966 - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda @@ -7038,6 +8246,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 34632 timestamp: 1764017199083 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda @@ -7048,6 +8257,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 33166 timestamp: 1764017282936 - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda @@ -7060,6 +8270,7 @@ packages: - vc14_runtime >=14.44.35208 license: MIT license_family: MIT + purls: [] size: 34449 timestamp: 1764017851337 - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda @@ -7071,6 +8282,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 298378 timestamp: 1764017210931 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda @@ -7081,6 +8293,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 309304 timestamp: 1764017292044 - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda @@ -7093,6 +8306,7 @@ packages: - vc14_runtime >=14.44.35208 license: MIT license_family: MIT + purls: [] size: 252903 timestamp: 1764017901735 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda @@ -7117,6 +8331,17 @@ packages: purls: [] size: 124432 timestamp: 1774333989027 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcap-2.78-hd0affe5_0.conda + sha256: cc8c9fc6ddf0fbd3d1275b558ae9abad6cda23bced268732e2da21a87bb358cd + md5: f9f17eab7f3df1c6fd4b1a548a2f683a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 124335 + timestamp: 1775488792584 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcap-2.77-h68e9139_0.conda sha256: 154eefd8f94010d89ba76a057949b9b1f75c7379bd0d19d4657c952bedcf5904 md5: 10fe36ec0a9f7b1caae0331c9ba50f61 @@ -7137,6 +8362,16 @@ packages: purls: [] size: 109458 timestamp: 1774335293336 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcap-2.78-hf9559e3_0.conda + sha256: 14b6654d942be7a68496d4e52d6aa4e217cf82005a42c20d1880eb473e34eb3a + md5: 1503ce9f8a3df149a33ccd7c300ec1d2 + depends: + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 109192 + timestamp: 1775490102029 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda build_number: 5 sha256: 0cbdcc67901e02dc17f1d19e1f9170610bd828100dc207de4d5b6b8ad1ae7ad8 @@ -7182,6 +8417,21 @@ packages: purls: [] size: 18622 timestamp: 1774503050205 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-8_h0358290_openblas.conda + build_number: 8 + sha256: 1a2bc77bb26520255904a3d9b1f40e6bf0bf9d8d3405c7709dd162282820915a + md5: 33a413f1095f8325e5c30fde3b0d2445 + depends: + - libblas 3.11.0 8_h4a7cf45_openblas + constrains: + - blas 2.308 openblas + - liblapacke 3.11.0 8*_openblas + - liblapack 3.11.0 8*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18778 + timestamp: 1779859107964 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda build_number: 5 sha256: 3fad5c9de161dccb4e42c8b1ae8eccb33f4ed56bccbcced9cbb0956ae7869e61 @@ -7211,6 +8461,21 @@ packages: purls: [] size: 18689 timestamp: 1774503058069 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-8_hd72aa62_openblas.conda + build_number: 8 + sha256: 3ba039f0705022939d90e36c1ed2fcbafd7f5bb77563e3702202ae796b32f4d2 + md5: 76242b7ad6e43809afa8671dd609b4ed + depends: + - libblas 3.11.0 8_haddc8a3_openblas + constrains: + - liblapack 3.11.0 8*_openblas + - liblapacke 3.11.0 8*_openblas + - blas 2.308 openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18817 + timestamp: 1779859049133 - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a3cdd5_mkl.conda build_number: 5 sha256: 49dc59d8e58360920314b8d276dd80da7866a1484a9abae4ee2760bc68f3e68d @@ -7240,6 +8505,21 @@ packages: purls: [] size: 68221 timestamp: 1774503722413 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-8_h2a3cdd5_mkl.conda + build_number: 8 + sha256: 2a5b6555b481df4603e44cba49a6ef727584fd2f3c5235dd4bcb3028fffbdfb5 + md5: 09f1d8e4d2675d34ad2acb115211d10c + depends: + - libblas 3.11.0 8_h8455456_mkl + constrains: + - liblapacke 3.11.0 8*_mkl + - blas 2.308 mkl + - liblapack 3.11.0 8*_mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 68443 + timestamp: 1779859701498 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcublas-13.5.1.27-h676940d_0.conda sha256: 39a1183f64d4ebff942117f7be9c0883b772ddf5796dee18bdda1d52949a9627 md5: 7bd32031313d7dca6c8250429b94bd03 @@ -7503,6 +8783,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 73490 timestamp: 1761979956660 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda @@ -7512,6 +8793,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 71117 timestamp: 1761979776756 - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda @@ -7523,8 +8805,34 @@ packages: - vc14_runtime >=14.44.35208 license: MIT license_family: MIT + purls: [] size: 156818 timestamp: 1761979842440 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdovi-3.3.2-ha23c83e_4.conda + sha256: d15432f07f654583978712e034d308b103a8b4650f0fdec172b5031a8af2b6c9 + md5: b26a64dfb24fef32d3330e37ce5e4f44 + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: [] + size: 311420 + timestamp: 1777838991858 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdovi-3.3.2-hf71c8f5_4.conda + sha256: 4e41c61b67d6f077db7364bc2911c4d81e6c8080b86605e9d0adb97a5ed654b6 + md5: 530f83c19ee601cb9cda5b305ddf02fd + depends: + - libgcc >=14 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: [] + size: 316167 + timestamp: 1777838999692 - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda sha256: c076a213bd3676cc1ef22eeff91588826273513ccc6040d9bea68bccdc849501 md5: 9314bc5a1fe7d1044dc9dfd3ef400535 @@ -7536,6 +8844,18 @@ packages: license_family: MIT size: 310785 timestamp: 1757212153962 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.127-hb03c661_0.conda + sha256: 7d3187c11b7ae66c5595a8afd5a7ce352a490527fdf6614cab129bc7f2c16ba3 + md5: d8d16b9b32a3c5df7e5b3350e2cbe058 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libpciaccess >=0.19,<0.20.0a0 + license: MIT + license_family: MIT + purls: [] + size: 311505 + timestamp: 1778975798004 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda sha256: 4e6cdb5dd37db794b88bec714b4418a0435b04d14e9f7afc8cc32f2a3ced12f2 md5: 2079727b538f6dd16f3fa579d4c3c53f @@ -7546,6 +8866,17 @@ packages: license_family: MIT size: 344548 timestamp: 1757212128414 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.127-he30d5cf_0.conda + sha256: 2a941ffcd6b09380344c2cb5b198d2743ce4fc30ec9a5c8c83e53368d8015aef + md5: 987d35ad350bb552a30f3d314f6c7655 + depends: + - libgcc >=14 + - libpciaccess >=0.19,<0.20.0a0 + license: MIT + license_family: MIT + purls: [] + size: 345283 + timestamp: 1778975814771 - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 md5: c277e0a4d549b03ac1e9d6cbbe3d017b @@ -7580,6 +8911,16 @@ packages: license: LicenseRef-libglvnd size: 44840 timestamp: 1731330973553 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_3.conda + sha256: 9a25ea93e8272785405a21d30f84e620befb1d545f6dfaae18f06103b5df0443 + md5: 75e9f795be506c96dd43cb09c7c8d557 + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_3 + license: LicenseRef-libglvnd + purls: [] + size: 46500 + timestamp: 1779728188901 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda sha256: 8962abf38a58c235611ce356b9899f6caeb0352a8bce631b0bcc59352fda455e md5: cf105bce884e4ef8c8ccdca9fe6695e7 @@ -7588,6 +8929,15 @@ packages: license: LicenseRef-libglvnd size: 53551 timestamp: 1731330990477 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_3.conda + sha256: b987d3874edfcd9c7ddca86c003cb04ae51160a72c173a24cd46ab9eeb8886ab + md5: ec017f25e5d01ef9dd81e95ff73ff051 + depends: + - libglvnd 1.7.0 hd24410f_3 + license: LicenseRef-libglvnd + purls: [] + size: 54600 + timestamp: 1779728234591 - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda sha256: d78f1d3bea8c031d2f032b760f36676d87929b18146351c4464c66b0869df3f5 md5: e7f7ce06ec24cfcfb9e36d28cf82ba57 @@ -7613,6 +8963,19 @@ packages: purls: [] size: 76624 timestamp: 1774719175983 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda + sha256: 16feffd9ddbbe5b718515d38ee376c685ba95491cd901244e24671d20b952a77 + md5: b24d3c612f71e7aa74158d92106318b2 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + purls: [] + size: 77856 + timestamp: 1781203599810 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda sha256: 995ce3ad96d0f4b5ed6296b051a0d7b6377718f325bc0e792fbb96b0e369dad7 md5: 57f3b3da02a50a1be2a6fe847515417d @@ -7636,6 +8999,18 @@ packages: purls: [] size: 76523 timestamp: 1774719129371 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.8.1-hfae3067_1.conda + sha256: 20a5726bc8705d91437c9e6ef83b30da64a1719b869656d20a1ee818333ea5ac + md5: fac3b65a605cd253037fdf3daf2de8d9 + depends: + - libgcc >=14 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + purls: [] + size: 77649 + timestamp: 1781203572523 - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda sha256: b31f6fb629c4e17885aaf2082fb30384156d16b48b264e454de4a06a313b533d md5: 1c1ced969021592407f16ada4573586d @@ -7663,6 +9038,20 @@ packages: purls: [] size: 70609 timestamp: 1774719377850 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda + sha256: 1a54d874addda73b6f7164d5f3905821277a1831bcc05edd74b3085391688571 + md5: ccc490c81ffe14181861beac0e8f3169 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.8.1.* + license: MIT + license_family: MIT + purls: [] + size: 71631 + timestamp: 1781203724164 - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 md5: a360c33a5abe61c07959e449fa1453eb @@ -7707,6 +9096,7 @@ packages: - libstdcxx >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 424563 timestamp: 1764526740626 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libflac-1.5.0-he9c94f4_1.conda @@ -7719,6 +9109,7 @@ packages: - libstdcxx >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 397272 timestamp: 1764526699497 - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda @@ -7729,6 +9120,15 @@ packages: license: GPL-2.0-only OR FTL size: 8035 timestamp: 1772757210108 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda + sha256: 38f014a7129e644636e46064ecd6b1945e729c2140e21d75bb476af39e692db2 + md5: e289f3d17880e44b633ba911d57a321b + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 8049 + timestamp: 1774298163029 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.2-h8af1aa0_0.conda sha256: 23cdb94528bb4328b6f7550906dee5080952354445d8bd96241fa7d059c4af95 md5: 93bce8dee6a0a4906331db294ec250fe @@ -7737,6 +9137,15 @@ packages: license: GPL-2.0-only OR FTL size: 8108 timestamp: 1772756012710 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_1.conda + sha256: db75d0fc080992dc67db8e24d7bb2a2f2a0b25bfce8870fa45a82a4b5f6111a2 + md5: a13e600f9d18488b1fd1257344dbfdaa + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 8381 + timestamp: 1780933505754 - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.2-h57928b3_0.conda sha256: 427c3072b311e65bd3eae3fcb78f6847b15b2dbb173a8546424de56550b2abfb md5: 153d52fd0e4ba2a5bd5bb4f4afa41417 @@ -7745,6 +9154,15 @@ packages: license: GPL-2.0-only OR FTL size: 8404 timestamp: 1772756167212 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_1.conda + sha256: 035d0c67bf9f7a16f4a1764f420c120f1a995d071bb265fcc66ef688ef709d7b + md5: e45b52fb9a81c9e2708465a706e05952 + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 8711 + timestamp: 1780934891782 - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda sha256: aba65b94bdbed52de17ec3d0c6f2ebac2ef77071ad22d6900d1614d0dd702a0c md5: 8eaba3d1a4d7525c6814e861614457fd @@ -7758,6 +9176,20 @@ packages: license: GPL-2.0-only OR FTL size: 386316 timestamp: 1772757193822 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda + sha256: 16f020f96da79db1863fcdd8f2b8f4f7d52f177dd4c58601e38e9182e91adf1d + md5: fb16b4b69e3f1dcfe79d80db8fd0c55d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 384575 + timestamp: 1774298162622 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.2-hdae7a39_0.conda sha256: a2e9efb033f7519bbc0a54558d7c9bb96252adc22c6e09df2daee7615265fbb1 md5: 69d1cdfdabb66464cbde17890e8be3b9 @@ -7770,6 +9202,19 @@ packages: license: GPL-2.0-only OR FTL size: 423372 timestamp: 1772756012086 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_1.conda + sha256: 34fe8276befd6c42956c4acd969caeddbdc7ea8e6ed054b8388709b6c3e94ba4 + md5: 426cc33f8745ce11a73baf73db3954a7 + depends: + - libgcc >=14 + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 424236 + timestamp: 1780933505195 - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.2-hdbac1cb_0.conda sha256: 1e80e01e5662bd3a0c0e094fbeaec449dbb2288949ca55ca80345e7812904e67 md5: c21a474a38982cdb56b3454cf4f78389 @@ -7784,6 +9229,21 @@ packages: license: GPL-2.0-only OR FTL size: 340155 timestamp: 1772756166648 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_1.conda + sha256: 0bbd19c9f7c4d0232b31892e6a4d1f82b8d19d1b84d89725f1f491b336447758 + md5: 4e4d54f9f98383d977ba56ef39ebf46d + depends: + - libpng >=1.6.58,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + purls: [] + size: 340411 + timestamp: 1780934813224 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 md5: 0aa00f03f9e39fb9876085dee11a85d4 @@ -7798,6 +9258,20 @@ packages: purls: [] size: 1041788 timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda + sha256: 8e0a3b5e41272e5678499b5dfc4cddb673f9e935de01eb0767ce857001229f46 + md5: 57736f29cc2b0ec0b6c2952d3f101b6a + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_19 + - libgomp 15.2.0 he0feb66_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 1041084 + timestamp: 1778269013026 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda sha256: 43df385bedc1cab11993c4369e1f3b04b4ca5d0ea16cba6a0e7f18dbc129fcc9 md5: 552567ea2b61e3a3035759b2fdb3f9a6 @@ -7811,6 +9285,19 @@ packages: purls: [] size: 622900 timestamp: 1771378128706 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_19.conda + sha256: 4592b096e553f67799ae70d4b6167eeda3ec74587d68c7aecbf4e7b1df136681 + md5: f35b3f52d0a2ec4ffe3c89ba135cdb9a + depends: + - _openmp_mutex >=4.5 + constrains: + - libgomp 15.2.0 h8acb6b2_19 + - libgcc-ng ==15.2.0=*_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 622462 + timestamp: 1778268755949 - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda sha256: da2c96563c76b8c601746f03e03ac75d2b4640fa2ee017cb23d6c9fc31f1b2c6 md5: b085746891cca3bd2704a450a7b4b5ce @@ -7879,6 +9366,16 @@ packages: license_family: GPL size: 27526 timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda + sha256: 9dcf54adfaa5e861123c2da4f2f0451a685464ea7e5a41ad91cf67b31d658d98 + md5: 331ee9b72b9dff570d56b1302c5ab37d + depends: + - libgcc 15.2.0 he0feb66_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27694 + timestamp: 1778269016987 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda sha256: 83bb0415f59634dccfa8335d4163d1f6db00a27b36666736f9842b650b92cf2f md5: 4feebd0fbf61075a1a9c2e9b3936c257 @@ -7888,6 +9385,16 @@ packages: license_family: GPL size: 27568 timestamp: 1771378136019 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_19.conda + sha256: 1137f93f477f56199ded24117430045a0c02cbe8b10031beac3b9ad2138539d3 + md5: 770cf892e5530f43e63cadc673e85653 + depends: + - libgcc 15.2.0 h8acb6b2_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27738 + timestamp: 1778268759211 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda sha256: d2c9fad338fd85e4487424865da8e74006ab2e2475bd788f624d7a39b2a72aee md5: 9063115da5bc35fdc3e1002e69b9ef6e @@ -7900,6 +9407,18 @@ packages: purls: [] size: 27523 timestamp: 1771378269450 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda + sha256: 561a42758ef25b9ce308c4e2cf56daee4f06138385a17e29a492cd928e00be6f + md5: 42bf7eca1a951735fa06c0e3c0d5c8e6 + depends: + - libgfortran5 15.2.0 h68bc16d_19 + constrains: + - libgfortran-ng ==15.2.0=*_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27655 + timestamp: 1778269042954 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda sha256: 7dcd7dff2505d56fd5272a6e712ec912f50a46bf07dc6873a7e853694304e6e4 md5: 41f261f5e4e2e8cbd236c2f1f15dae1b @@ -7912,6 +9431,18 @@ packages: purls: [] size: 27587 timestamp: 1771378169244 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_19.conda + sha256: e5ad94be72634233510b33ba792a3339921bd468f0b8bc6961ea05eded251d9b + md5: c7a5b5decf969ead5ecada83654164cf + depends: + - libgfortran5 15.2.0 h1b7bec0_19 + constrains: + - libgfortran-ng ==15.2.0=*_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27728 + timestamp: 1778268784621 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda sha256: 539b57cf50ec85509a94ba9949b7e30717839e4d694bc94f30d41c9d34de2d12 md5: 646855f357199a12f02a87382d429b75 @@ -7925,6 +9456,19 @@ packages: purls: [] size: 2482475 timestamp: 1771378241063 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda + sha256: 057978bb69fea29ed715a9b98adf71015c31baecc4aeb2bfc20d4fd5d83579d4 + md5: 85072b0ad177c966294f129b7c04a2d5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 2483673 + timestamp: 1778269025089 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda sha256: 85347670dfb4a8d4c13cd7cae54138dcf2b1606b6bede42eef5507bf5f9660c6 md5: 574d88ce3348331e962cfa5ed451b247 @@ -7937,6 +9481,18 @@ packages: purls: [] size: 1486341 timestamp: 1771378148102 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_19.conda + sha256: af8e9bdcaa77f133a8ee4c1ef57ef564d9c45aa262abf9f5ef9b50eb99d96407 + md5: 779dbb494de6d3d6477cab52eb34285a + depends: + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 1487244 + timestamp: 1778268767295 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda sha256: dc2752241fa3d9e40ce552c1942d0a4b5eeb93740c9723873f6fcf8d39ef8d2d md5: 928b8be80851f5d8ffb016f9c81dae7a @@ -7947,6 +9503,17 @@ packages: license: LicenseRef-libglvnd size: 134712 timestamp: 1731330998354 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_3.conda + sha256: ec353b3076ed8e357ed961d0e9ff6997491cade0e603de5bd18a2e301ac78ebd + md5: f25206d7322c0e9648e8b83694d143ab + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_3 + - libglx 1.7.0 ha4b6fd6_3 + license: LicenseRef-libglvnd + purls: [] + size: 133469 + timestamp: 1779728207669 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda sha256: 3e954380f16255d1c8ae5da3bd3044d3576a0e1ac2e3c3ff2fe8f2f1ad2e467a md5: 0d00176464ebb25af83d40736a2cd3bb @@ -7956,6 +9523,16 @@ packages: license: LicenseRef-libglvnd size: 145442 timestamp: 1731331005019 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_3.conda + sha256: 05c75a2034bdbca29bab467d02ad770ed5e524e4f0670432258f2d8487c95348 + md5: 6e893c36f31502dd195d3d58f455fdbd + depends: + - libglvnd 1.7.0 hd24410f_3 + - libglx 1.7.0 hd24410f_3 + license: LicenseRef-libglvnd + purls: [] + size: 148112 + timestamp: 1779728248678 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda sha256: e281356c0975751f478c53e14f3efea6cd1e23c3069406d10708d6c409525260 md5: 53e7cbb2beb03d69a478631e23e340e9 @@ -7966,6 +9543,17 @@ packages: license: LicenseRef-libglvnd size: 113911 timestamp: 1731331012126 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_3.conda + sha256: 41d7d864ad1f199bdb06ff6cc3931455c8af62f1d2071a08c6fa08affbcb678f + md5: 63e43d278ee5084813fe3c2edf4834ce + depends: + - __glibc >=2.17,<3.0.a0 + - libgl 1.7.0 ha4b6fd6_3 + - libglx-devel 1.7.0 ha4b6fd6_3 + license: LicenseRef-libglvnd + purls: [] + size: 115664 + timestamp: 1779728218325 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-devel-1.7.0-hd24410f_2.conda sha256: ec5c3125b38295bad8acc80f793b8ee217ccb194338d73858be278db50ea82f1 md5: 5d8323dff6a93596fb6f985cf6e8521a @@ -7975,6 +9563,16 @@ packages: license: LicenseRef-libglvnd size: 113925 timestamp: 1731331014056 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-devel-1.7.0-hd24410f_3.conda + sha256: b7483884e5e8df362f113d7d7694f0a37ecf6409f1acaaa889f312688917c067 + md5: 3a0adce33b3b8a52c76389db1edfec1b + depends: + - libgl 1.7.0 hd24410f_3 + - libglx-devel 1.7.0 hd24410f_3 + license: LicenseRef-libglvnd + purls: [] + size: 116084 + timestamp: 1779728257534 - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda sha256: a27e44168a1240b15659888ce0d9b938ed4bdb49e9ea68a7c1ff27bcea8b55ce md5: bb26456332b07f68bf3b7622ed71c0da @@ -7990,6 +9588,22 @@ packages: license: LGPL-2.1-or-later size: 4398701 timestamp: 1771863239578 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_2.conda + sha256: 33eb5d5310a5c2c0a4707a0afa644801c2e08c8f70c45e1f62f354116dfe0970 + md5: 17d484ab9c8179c6a6e5b7dbb5065afc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libffi >=3.5.2,<3.6.0a0 + - pcre2 >=10.47,<10.48.0a0 + - libzlib >=1.3.2,<2.0a0 + - libiconv >=1.18,<2.0a0 + constrains: + - glib >2.66 + license: LGPL-2.1-or-later + purls: [] + size: 4754097 + timestamp: 1778508800134 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda sha256: afc503dbd04a5bf2709aa9d8318a03a8c4edb389f661ff280c3494bfef4341ec md5: 4ac4372fc4d7f20630a91314cdac8afd @@ -8004,6 +9618,21 @@ packages: license: LGPL-2.1-or-later size: 4512186 timestamp: 1771863220969 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.88.1-h96a7f82_2.conda + sha256: 050285afdb7bd98b1b8fb052af9da31fafde586a49d3b56dd33d5338b2d0e411 + md5: 16d72f76bf6fead4a29efb2fede0a06b + depends: + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + - libffi >=3.5.2,<3.6.0a0 + constrains: + - glib >2.66 + license: LGPL-2.1-or-later + purls: [] + size: 4946648 + timestamp: 1778508920982 - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda sha256: f035fb25f8858f201e0055c719ef91022e9465cd51fe803304b781863286fb10 md5: 0329a7e92c8c8b61fcaaf7ad44642a96 @@ -8021,20 +9650,54 @@ packages: license: LGPL-2.1-or-later size: 4095369 timestamp: 1771863229701 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda - sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 - md5: 434ca7e50e40f4918ab701e3facd59a0 +- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.1-h7ce1215_2.conda + sha256: f61277e224e9889c221bb2eac0f57d5aeeb82fc45d3dc326957d251c97444f7c + md5: 5fb838786a8317ebb38056bbe236d3ff depends: - - __glibc >=2.17,<3.0.a0 - license: LicenseRef-libglvnd - size: 132463 - timestamp: 1731330968309 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda - sha256: 57ec3898a923d4bcc064669e90e8abfc4d1d945a13639470ba5f3748bd3090da + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + - libintl >=0.22.5,<1.0a0 + - libffi >=3.5.2,<3.6.0a0 + constrains: + - glib >2.66 + license: LGPL-2.1-or-later + purls: [] + size: 4522891 + timestamp: 1778508851933 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 + md5: 434ca7e50e40f4918ab701e3facd59a0 + depends: + - __glibc >=2.17,<3.0.a0 + license: LicenseRef-libglvnd + size: 132463 + timestamp: 1731330968309 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_3.conda + sha256: e019ebe4e3f5cdf23e2f5e58ddf7ade27988c53820115b17b98f218ebcc87748 + md5: eb83f3f8cecc3e9bff9e250817fc69b6 + depends: + - __glibc >=2.17,<3.0.a0 + license: LicenseRef-libglvnd + purls: [] + size: 133586 + timestamp: 1779728183422 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda + sha256: 57ec3898a923d4bcc064669e90e8abfc4d1d945a13639470ba5f3748bd3090da md5: 9e115653741810778c9a915a2f8439e7 license: LicenseRef-libglvnd size: 152135 timestamp: 1731330986070 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_3.conda + sha256: ca124e53765a2b123e0ca6ce809c7caf188bb26e5fe125b69099378276d5e66f + md5: a2ad848c0aab2e326c6af08ea20502f4 + license: LicenseRef-libglvnd + purls: [] + size: 146645 + timestamp: 1779728228274 - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda sha256: 2d35a679624a93ce5b3e9dd301fff92343db609b79f0363e6d0ceb3a6478bfa7 md5: c8013e438185f33b13814c5c488acd5c @@ -8045,6 +9708,17 @@ packages: license: LicenseRef-libglvnd size: 75504 timestamp: 1731330988898 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_3.conda + sha256: 2f74713c9ca408ea84e88a30a9028153e7b553e8bb42e06139eac9a753c27da9 + md5: ec3c4350aa0261bf7f87b8ca15c8e80e + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_3 + - xorg-libx11 >=1.8.13,<2.0a0 + license: LicenseRef-libglvnd + purls: [] + size: 76586 + timestamp: 1779728199059 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda sha256: 6591af640cb05a399fab47646025f8b1e1a06a0d4bbb4d2e320d6629b47a1c61 md5: 1d4269e233636148696a67e2d30dad2a @@ -8054,6 +9728,16 @@ packages: license: LicenseRef-libglvnd size: 77736 timestamp: 1731330998960 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_3.conda + sha256: 2698b415b9f7b692cd64e34db623e1a6e54ed54e78b0b4e5d4ea6762791e9118 + md5: 338faf34b78d053841098c0528699e34 + depends: + - libglvnd 1.7.0 hd24410f_3 + - xorg-libx11 >=1.8.13,<2.0a0 + license: LicenseRef-libglvnd + purls: [] + size: 76704 + timestamp: 1779728242753 - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda sha256: 0a930e0148ab6e61089bbcdba25a2e17ee383e7de82e7af10cc5c12c82c580f3 md5: 27ac5ae872a21375d980bd4a6f99edf3 @@ -8065,6 +9749,18 @@ packages: license: LicenseRef-libglvnd size: 26388 timestamp: 1731331003255 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_3.conda + sha256: a17ae2d4cb2de04a20882ae14ec3cc1958e868a4dec81e3d7eca30115ee50e94 + md5: 16b6330783ce0d1ae8d22782173b32c9 + depends: + - __glibc >=2.17,<3.0.a0 + - libglx 1.7.0 ha4b6fd6_3 + - xorg-libx11 >=1.8.13,<2.0a0 + - xorg-xorgproto + license: LicenseRef-libglvnd + purls: [] + size: 27363 + timestamp: 1779728211402 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-devel-1.7.0-hd24410f_2.conda sha256: 4bc28ecc38f30ca1ac66a8fb6c5703f4d888381ec46d3938b7c3383210061ec5 md5: 1f9ddbb175a63401662d1c6222cef6ff @@ -8075,6 +9771,17 @@ packages: license: LicenseRef-libglvnd size: 26362 timestamp: 1731331008489 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-devel-1.7.0-hd24410f_3.conda + sha256: b30433c4f56bec0a7d9d288e0a456ed280183e32f3f4880ada2189fc12804a52 + md5: 3da9719866b95bddcad86c8aec6a8ba2 + depends: + - libglx 1.7.0 hd24410f_3 + - xorg-libx11 >=1.8.13,<2.0a0 + - xorg-xorgproto + license: LicenseRef-libglvnd + purls: [] + size: 27651 + timestamp: 1779728252006 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 md5: 239c5e9546c38a1e884d69effcf4c882 @@ -8085,6 +9792,16 @@ packages: purls: [] size: 603262 timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda + sha256: 5abe4ab9d93f6c9757d654f1969ae2267d4505315c1f2f8fe705fd60af084f1b + md5: faac990cb7aedc7f3a2224f2c9b0c26c + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 603817 + timestamp: 1778268942614 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda sha256: fc716f11a6a8525e27a5d332ef6a689210b0d2a4dd1133edc0f530659aa9faa6 md5: 4faa39bf919939602e594253bd673958 @@ -8093,6 +9810,14 @@ packages: purls: [] size: 588060 timestamp: 1771378040807 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_19.conda + sha256: 2370ef0ffcbae5bede3c4bf136add4abc257245eb91f724c99bb4a43116c5a83 + md5: c5e8a379c4a2ec2aea4ba22758c001d9 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 587387 + timestamp: 1778268674393 - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda sha256: 94981bc2e42374c737750895c6fdcfc43b7126c4fc788cad0ecc7281745931da md5: 939fb173e2a4d4e980ef689e99b35223 @@ -8117,6 +9842,20 @@ packages: license_family: BSD size: 2449916 timestamp: 1765103845133 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.13.0-default_he001693_1000.conda + sha256: 5041d295813dfb84652557839825880aae296222ab725972285c5abe3b6e4288 + md5: c197985b58bc813d26b42881f0021c82 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxml2 + - libxml2-16 >=2.14.6 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 2436378 + timestamp: 1770953868164 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwloc-2.12.2-default_ha470c98_1000.conda sha256: e87cf64d87c7706403507df7329f5b597c3b487f4c72ef53ef899e38983ea70e md5: c8b05c85ae962a993d9b7d6c9d10571e @@ -8129,6 +9868,19 @@ packages: license_family: BSD size: 2467105 timestamp: 1765103804193 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwloc-2.13.0-default_ha95e27d_1000.conda + sha256: 88888d99e81c93e7331f2eb0fec08b3c4a47a1bfa1c88b3e641f6568569b6261 + md5: 974183f6420938051e2f3208922d057f + depends: + - libgcc >=14 + - libstdcxx >=14 + - libxml2 + - libxml2-16 >=2.14.6 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 2453519 + timestamp: 1770953713701 - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.2-default_h4379cf1_1000.conda sha256: 8cdf11333a81085468d9aa536ebb155abd74adc293576f6013fc0c85a7a90da3 md5: 3b576f6860f838f950c570f4433b086e @@ -8144,6 +9896,21 @@ packages: purls: [] size: 2411241 timestamp: 1765104337762 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.13.0-default_h049141e_1000.conda + sha256: 2ee12e37223dfcd0acd050c80a91150c482b6e2899198521e1800dce66662467 + md5: 6a01c986e30292c715038d2788aa1385 + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - libxml2 + - libxml2-16 >=2.14.6 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 2396128 + timestamp: 1770954127918 - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda sha256: 2bdd1cdd677b119abc5e83069bec2e28fe6bfb21ebaea3cd07acee67f38ea274 md5: c2a0c1d0120520e979685034e0b79859 @@ -8154,6 +9921,17 @@ packages: license: Apache-2.0 OR BSD-3-Clause size: 1448617 timestamp: 1758894401402 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.4.0-h10be129_0.conda + sha256: 8b70955d5e9a49d08945d4f8e2eab855b2efa5fce9cb9bc5e75d86764e6f2f38 + md5: 3a9428b74c403c71048104d38437b48c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: Apache-2.0 OR BSD-3-Clause + purls: [] + size: 1435782 + timestamp: 1776989559668 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwy-1.3.0-h81d0cf9_1.conda sha256: a6a441692b27606f8ef64ee9e6a0c72c615c2e25b01c282ee080ee8f97861943 md5: d5b93534e24e7c15792b3f336c52af07 @@ -8163,6 +9941,16 @@ packages: license: Apache-2.0 OR BSD-3-Clause size: 1180000 timestamp: 1758894754411 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libhwy-1.4.0-h0626a34_0.conda + sha256: cff38f9a1df7bc3e5ac7856bc2e5c879151b54c07b55722ec0da1af49d869721 + md5: 61b4e7ef4624c692a3ebd07100795303 + depends: + - libgcc >=14 + - libstdcxx >=14 + license: Apache-2.0 OR BSD-3-Clause + purls: [] + size: 945401 + timestamp: 1776989517303 - conda: https://conda.anaconda.org/conda-forge/win-64/libhwy-1.3.0-ha71e874_1.conda sha256: c722a04f065656b988a46dee87303ff0bf037179c50e2e76704b693def7f9a96 md5: f4649d4b6bf40d616eda57d6255d2333 @@ -8173,6 +9961,17 @@ packages: license: Apache-2.0 OR BSD-3-Clause size: 536186 timestamp: 1758894243956 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwy-1.4.0-h172a326_0.conda + sha256: 4b45bf59ee46d3c746272c27651da9ce709fda4eee8536c7424acea60d0e2ad0 + md5: aeca1cb6665f19e560c1fbd20b5bcf34 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 OR BSD-3-Clause + purls: [] + size: 562583 + timestamp: 1776989522919 - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f md5: 915f5995e94f60e9a4826e0b0920ee88 @@ -8180,6 +9979,7 @@ packages: - __glibc >=2.17,<3.0.a0 - libgcc >=14 license: LGPL-2.1-only + purls: [] size: 790176 timestamp: 1754908768807 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda @@ -8188,6 +9988,7 @@ packages: depends: - libgcc >=14 license: LGPL-2.1-only + purls: [] size: 791226 timestamp: 1754910975665 - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda @@ -8207,6 +10008,7 @@ packages: depends: - libiconv >=1.17,<2.0a0 license: LGPL-2.1-or-later + purls: [] size: 95568 timestamp: 1723629479451 - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda @@ -8220,6 +10022,18 @@ packages: license: IJG AND BSD-3-Clause AND Zlib size: 633710 timestamp: 1762094827865 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda + sha256: 10056646c28115b174de81a44e23e3a0a3b95b5347d2e6c45cc6d49d35294256 + md5: 6178c6f2fb254558238ef4e6c56fb782 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + size: 633831 + timestamp: 1775962768273 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda sha256: 84064c7c53a64291a585d7215fe95ec42df74203a5bf7615d33d49a3b0f08bb6 md5: 5109d7f837a3dfdf5c60f60e311b041f @@ -8230,6 +10044,17 @@ packages: license: IJG AND BSD-3-Clause AND Zlib size: 691818 timestamp: 1762094728337 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda + sha256: e97ec2af5f09f8f6ea8ecd550055c95ae80fae22015fcfadaa94eafe025c9ccc + md5: a85ba48648f6868016f2741fd9170250 + depends: + - libgcc >=14 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + size: 693143 + timestamp: 1775962625956 - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda sha256: 795e2d4feb2f7fc4a2c6e921871575feb32b8082b5760726791f080d1e2c2597 md5: 56a686f92ac0273c0f6af58858a3f013 @@ -8242,6 +10067,34 @@ packages: license: IJG AND BSD-3-Clause AND Zlib size: 841783 timestamp: 1762094814336 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.4.1-hfd05255_0.conda + sha256: 698d57b5b90120270eaa401298319fcb25ea186ae95b340c2f4813ed9171083d + md5: 25a127bad5470852b30b239f030ec95b + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + purls: [] + size: 842806 + timestamp: 1775962811457 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-h174a0a3_1.conda + sha256: 0c8a78c6a42a6e4c6de3a5e82d692f60400d43f4cc80591745f28b37daad9c70 + md5: 850f48943d6b4589800a303f0de6a816 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libhwy >=1.4.0,<1.5.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 1846962 + timestamp: 1777065125966 - conda: https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda sha256: 0c2399cef02953b719afe6591223fb11d287d5a108ef8bb9a02dd509a0f738d7 md5: 1df8c1b1d6665642107883685db6cf37 @@ -8269,6 +10122,35 @@ packages: license_family: BSD size: 1489440 timestamp: 1770801995062 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjxl-0.11.2-hbae46ee_1.conda + sha256: 237bbfa18c4f245a24000c12924d61a9e54f7e6f689f405c0dc8e188a40de890 + md5: 532faebf82c7d2c10539518347cff460 + depends: + - libgcc >=14 + - libstdcxx >=14 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + - libhwy >=1.4.0,<1.5.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 1489188 + timestamp: 1777065125935 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjxl-0.11.2-h932607e_1.conda + sha256: 4715e22c602526c85da09f73865676add67e0995a944b821fbff84547a9db533 + md5: 327bce3eb1ef1875c7145e915d25bcd3 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libhwy >=1.4.0,<1.5.0a0 + - libbrotlienc >=1.2.0,<1.3.0a0 + - libbrotlidec >=1.2.0,<1.3.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 1194926 + timestamp: 1777065171989 - conda: https://conda.anaconda.org/conda-forge/win-64/libjxl-0.11.2-hf3f85d1_0.conda sha256: 525c5382eb32a43e7baf45b452079bf23daf8f8bf19fee7c8dafa8c731ada8bd md5: 869e71fcf2135212c51a96f7f7dbd00d @@ -8328,6 +10210,21 @@ packages: purls: [] size: 18624 timestamp: 1774503065378 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-8_h47877c9_openblas.conda + build_number: 8 + sha256: 168e327d737059553e15cc6ec36d76b9bbb3931c2a7721555fd68b4c9348b247 + md5: 809be8ba8712c77bc7d44c2d99390dc4 + depends: + - libblas 3.11.0 8_h4a7cf45_openblas + constrains: + - blas 2.308 openblas + - libcblas 3.11.0 8*_openblas + - liblapacke 3.11.0 8*_openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18790 + timestamp: 1779859115086 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda build_number: 5 sha256: 692222d186d3ffbc99eaf04b5b20181fd26aee1edec1106435a0a755c57cce86 @@ -8357,6 +10254,21 @@ packages: purls: [] size: 18702 timestamp: 1774503068721 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-8_h88aeb00_openblas.conda + build_number: 8 + sha256: d269a684afa0b2fdb44d6b60167f854f30410cdb5ee49a7275c026f6b10c8d05 + md5: 3af3f2aa755abc5e91351114ae214f55 + depends: + - libblas 3.11.0 8_haddc8a3_openblas + constrains: + - libcblas 3.11.0 8*_openblas + - liblapacke 3.11.0 8*_openblas + - blas 2.308 openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 18828 + timestamp: 1779859055749 - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hf9ab0e9_mkl.conda build_number: 5 sha256: a2d33f5cc2b8a9042f2af6981c6733ab1a661463823eaa56595a9c58c0ab77e1 @@ -8386,6 +10298,21 @@ packages: purls: [] size: 80571 timestamp: 1774503757128 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-8_hf9ab0e9_mkl.conda + build_number: 8 + sha256: 44999ed04bc0a56de44ee0ac8bd5b3702efd411a8b29491c0e3d3deb8619c94e + md5: d584799b920ecae9b75a2b70743a3de7 + depends: + - libblas 3.11.0 8_h8455456_mkl + constrains: + - libcblas 3.11.0 8*_mkl + - liblapacke 3.11.0 8*_mkl + - blas 2.308 mkl + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 81027 + timestamp: 1779859714698 - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb md5: c7c83eecbb72d88b940c249af56c8b17 @@ -8398,6 +10325,18 @@ packages: purls: [] size: 113207 timestamp: 1768752626120 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda + sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d + md5: b88d90cad08e6bc8ad540cb310a761fb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 113478 + timestamp: 1775825492909 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda sha256: 843c46e20519651a3e357a8928352b16c5b94f4cd3d5481acc48be2e93e8f6a3 md5: 96944e3c92386a12755b94619bae0b35 @@ -8409,6 +10348,17 @@ packages: purls: [] size: 125916 timestamp: 1768754941722 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda + sha256: d61962b9cd54c3554361550203c64d5b65b71e3058a285b66e4b04b9769f0a5c + md5: 76298a9e6d71ee6e832a8d0d7373b261 + depends: + - libgcc >=14 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 126102 + timestamp: 1775828008518 - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda sha256: f25bf293f550c8ed2e0c7145eb404324611cfccff37660869d97abf526eb957c md5: ba0bfd4c3cf73f299ffe46ff0eaeb8e3 @@ -8422,6 +10372,19 @@ packages: purls: [] size: 106169 timestamp: 1768752763559 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda + sha256: d636d1a25234063642f9c531a7bb58d84c1c496411280a36ea000bd122f078f1 + md5: 8f83619ab1588b98dd99c90b0bfc5c6d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.3.* + license: 0BSD + purls: [] + size: 106486 + timestamp: 1775825663227 - conda: https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-hd93470c_6.conda sha256: 5ea4675cb4a900795a5eb33519307cf985fd3787eb0cf33142e52ecc8eb8a7d4 md5: 886e83a08e0ad01d7fe868972bc729f3 @@ -8683,6 +10646,7 @@ packages: - __glibc >=2.17,<3.0.a0 license: BSD-3-Clause license_family: BSD + purls: [] size: 218500 timestamp: 1745825989535 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libogg-1.3.5-h86ecc28_1.conda @@ -8692,6 +10656,7 @@ packages: - libgcc >=13 license: BSD-3-Clause license_family: BSD + purls: [] size: 220653 timestamp: 1745826021156 - conda: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.5-h2466b09_1.conda @@ -8706,6 +10671,7 @@ packages: - ucrt >=10.0.20348.0 license: BSD-3-Clause license_family: BSD + purls: [] size: 35040 timestamp: 1745826086628 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda @@ -8737,6 +10703,21 @@ packages: purls: [] size: 5928890 timestamp: 1774471724897 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.33-pthreads_h94d23a6_0.conda + sha256: 3d9aa85648e5e18a6d66db98b8c4317cc426721ad7a220aa86330d1ccedc8903 + md5: 2d3278b721e40468295ca755c3b84070 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libgfortran + - libgfortran5 >=14.3.0 + constrains: + - openblas >=0.3.33,<0.3.34.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 5931919 + timestamp: 1776993658641 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-openmp_h1a8b088_4.conda sha256: 1892ceaefcf593dfd881ce3e88108875e60002b34a15b918d3e0b9129e5f631f md5: b1b27969f81db1b7068789d4bc6dadcf @@ -8782,6 +10763,20 @@ packages: purls: [] size: 5122134 timestamp: 1774471612323 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.33-pthreads_h9d3fd7e_0.conda + sha256: b018ecfb05e75a8eea3f21f6b5c5c2a54b5178bdcf19e2e2df2735740214a8c8 + md5: 58a66cd95e9692f08abe89f55a6f3f12 + depends: + - libgcc >=14 + - libgfortran + - libgfortran5 >=14.3.0 + constrains: + - openblas >=0.3.33,<0.3.34.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 5121336 + timestamp: 1776993423004 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2026.0.0-hb56ce9e_1.conda sha256: a396a2d1aa267f21c98717ac097138b32e41e4c40ae501729bded3801476eeb5 md5: 9f0596e995efe372c470ff45c93131cb @@ -8795,6 +10790,20 @@ packages: license_family: APACHE size: 6582302 timestamp: 1772727204779 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2026.2.0-hb56ce9e_0.conda + sha256: 1f2d5f0236eaf872c6c11891e59d9f4166913f3ab3b342352d12280b02b58185 + md5: db1296fbbd6fe992484e37f5ba9a6f27 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 6813018 + timestamp: 1780395324902 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-2026.0.0-h1915271_1.conda sha256: 6f8558cc4ee4d490db88640e71d3f79fa7552701d91c09ad6f1371dadb9bd3f1 md5: c8ff442d02723939711a726d9ff71eac @@ -8807,6 +10816,19 @@ packages: license_family: APACHE size: 5742222 timestamp: 1772721263739 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-2026.2.0-h1915271_0.conda + sha256: a382bdf384d0f4152a58331d024f890db83df9d133cd782d932169043e0ed590 + md5: 8921878e6366aec78dd3d966512bffe0 + depends: + - libgcc >=14 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 5928862 + timestamp: 1780392254655 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-arm-cpu-plugin-2026.0.0-h1915271_1.conda sha256: 8fff4375f324bdf8a3fe20c489710b692340007b7af2da1d14f6832990c24891 md5: ef26404d824453138bf0a12a8bb033df @@ -8820,6 +10842,20 @@ packages: license_family: APACHE size: 10237615 timestamp: 1772721303162 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-arm-cpu-plugin-2026.2.0-h1915271_0.conda + sha256: 68a0ac00e3c5d3e47cfcc509626acd4e4caf38b7426d642a44847e00183daa36 + md5: 0b4567fac6e30f52e6e833c4a7ed7ad2 + depends: + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 10263466 + timestamp: 1780392276062 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2026.0.0-hd85de46_1.conda sha256: 286de85805dc69ce0bd25367ae2a20c8096ddef35eb2483474eb246dacd5387e md5: ee41df976413676f794af2785b291b0c @@ -8833,6 +10869,20 @@ packages: license_family: APACHE size: 114431 timestamp: 1772727230331 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2026.2.0-hd85de46_0.conda + sha256: b926fd97763e5c8fc2f4f53eaa657818eca85eab6f7d3992d3ceef5bd86349ca + md5: 17ccdfee138a9369103983a5b8e30675 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 115526 + timestamp: 1780395345452 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-auto-batch-plugin-2026.0.0-h3d5001d_1.conda sha256: da7926f66318e539c9f20c2f5f3719a5ba663c6b9d5471e5223d290450219748 md5: 5e984d6405a8f8529d7429f28a7f285e @@ -8845,6 +10895,19 @@ packages: license_family: APACHE size: 111064 timestamp: 1772721336786 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-auto-batch-plugin-2026.2.0-h3d5001d_0.conda + sha256: fcdf66ab11ff3fa9ccf92ecf50fc5567f54dab6a16b05a683a6c3d30cfc6fbee + md5: aa9a66aa5729b2ee940968169cea7337 + depends: + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libstdcxx >=14 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 111823 + timestamp: 1780392306402 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2026.0.0-hd85de46_1.conda sha256: 9988ed6339a5eb044ae8d079e2b22f5a310c41e49a0cf716057f30b21ef9cec2 md5: ca025fa5c42ba94453636a2ae333de6b @@ -8858,6 +10921,20 @@ packages: license_family: APACHE size: 249056 timestamp: 1772727247597 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2026.2.0-hd85de46_0.conda + sha256: 0f386b1f58fbe63bd599855a08bd9d738615730cba86d9e64f2bba8d3872d24e + md5: 0453294b5631705c297c822fe963e7fc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 250550 + timestamp: 1780395355986 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-auto-plugin-2026.0.0-h3d5001d_1.conda sha256: 20f1958e160c64f3d207f1dbdb6960cc5642070a472bebffc0d587b2f6429033 md5: 573b3f5ec3963e0153501a2676660ee4 @@ -8870,6 +10947,19 @@ packages: license_family: APACHE size: 236010 timestamp: 1772721351244 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-auto-plugin-2026.2.0-h3d5001d_0.conda + sha256: a3f1b9b278bab50e8d2719f89555e982cefc15ac8675fc613e195fef7ffb4e2d + md5: af991ae91466db29164f151884d18ced + depends: + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libstdcxx >=14 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 236659 + timestamp: 1780392318802 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2026.0.0-hd41364c_1.conda sha256: c7db498aeda5b0f36b347f4211b93b66ba108faaf54157a08bae8fa3c3af5f81 md5: 07a23e96db38f63d9763f666b2db66aa @@ -8883,6 +10973,20 @@ packages: license_family: APACHE size: 211582 timestamp: 1772727264950 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2026.2.0-hd41364c_0.conda + sha256: dbb54fe5cbb27d9528797826c9aa80b0f742bc07e44652c09de2c79750719a5d + md5: 5542641915bccd4e95b15658062eb8f0 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 216023 + timestamp: 1780395366723 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-hetero-plugin-2026.0.0-he07c6df_1.conda sha256: 3778ea3887c9a9300761e3f39ce86976746a35aa1392a4b76e4e4d3ce9e095b4 md5: 74bd299545a1fe23439bf6e071ed9710 @@ -8895,6 +10999,19 @@ packages: license_family: APACHE size: 202574 timestamp: 1772721365749 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-hetero-plugin-2026.2.0-he07c6df_0.conda + sha256: 1854db417a938905bb962429ccad2342abe251c7d2df8ad5f65001c02bf121f2 + md5: d9fa12321fccac7fbbdfd4a33386f601 + depends: + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 207233 + timestamp: 1780392331535 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2026.0.0-hb56ce9e_1.conda sha256: 01a28c0bd1f205b3800e7759e30bc8e8a75836e0d5a73a745b4da42837bbb174 md5: b43b96578573ddbcc8d084ae6e44c964 @@ -8909,6 +11026,21 @@ packages: license_family: APACHE size: 13173323 timestamp: 1772727282718 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2026.2.0-hb56ce9e_0.conda + sha256: 87aa0a430b462c275a5f7b7ffb5f490d37d8ce97ccdc3d6e93b8bccb3d66f19f + md5: 930ac67c3e49a2ec1b45bcc2c2f701fd + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 13586589 + timestamp: 1780395378959 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2026.0.0-hb56ce9e_1.conda sha256: 720b87e1d5f1a10c577e040d4bf425072a978e925c6dfab8b1551bc848007c94 md5: 26e8e92c90d1a22af6eac8e9507d9b8f @@ -8924,6 +11056,22 @@ packages: license_family: APACHE size: 11402462 timestamp: 1772727323957 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2026.2.0-hb56ce9e_0.conda + sha256: 1efa48f137a3720a83276ee0b50201d540e1d41a92efe323118c43410ccf697b + md5: bc71ff82983c3d233928d3d89c141f82 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + - ocl-icd >=2.3.4,<3.0a0 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 12325490 + timestamp: 1780395417543 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-npu-plugin-2026.0.0-hb56ce9e_1.conda sha256: df7eb2b23a1af38f2cd2281353309f2e2a04da1374ecedc7c6745c2a67ba617c md5: 01ba8b179ac45b2b37fe2d4225dddcc7 @@ -8939,6 +11087,22 @@ packages: license_family: APACHE size: 1994640 timestamp: 1772727360780 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-npu-plugin-2026.2.0-hb56ce9e_0.conda + sha256: c300e263c51208457a320c98f94f1b18e713451577ed81ab425793e52e483d03 + md5: 30b2cabfd4d3e08af17e324260a0fb65 + depends: + - __glibc >=2.17,<3.0.a0 + - level-zero >=1.29.0,<2.0a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + - tbb >=2022.3.0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 2619772 + timestamp: 1780395452811 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2026.0.0-hd41364c_1.conda sha256: 8e7356b0b80b3f180615e264694d6811d388b210155d419553ff64e42f78ffa0 md5: aa002c4d343b01cdcc458c95cd071d1b @@ -8952,6 +11116,20 @@ packages: license_family: APACHE size: 192778 timestamp: 1772727380069 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2026.2.0-hd41364c_0.conda + sha256: 4e8e2c111820120d563d58e0863d239e0ff155f5bcbf5cf88fa3084b52fa0829 + md5: e63fab556e1ffa1ae56a6b4dace8b98c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 201661 + timestamp: 1780395466300 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-ir-frontend-2026.0.0-he07c6df_1.conda sha256: 5d191b9d29fb2bbaca95bcd7325fbc3329c1049eccda4b84cfd79c64d4b6dc83 md5: 0946447f9717222c95c24f958d73dba9 @@ -8964,6 +11142,19 @@ packages: license_family: APACHE size: 185648 timestamp: 1772721380070 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-ir-frontend-2026.2.0-he07c6df_0.conda + sha256: 55e59f52239653f65119a44b268cb84b95be825375413ddb302c37c0bee0c12c + md5: 6db219aa622d3c9ec09c7af4d72badb6 + depends: + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libstdcxx >=14 + - pugixml >=1.15,<1.16.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 195766 + timestamp: 1780392343931 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2026.0.0-h7a07914_1.conda sha256: 35a68214201e807bd9a31f94e618cb6a5385198e89eef46dde6c122cff77da58 md5: 218084544c2e7e78e4b8877ec37b8cdb @@ -8979,6 +11170,22 @@ packages: license_family: APACHE size: 1860687 timestamp: 1772727397981 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2026.2.0-h7a07914_0.conda + sha256: d34154e5dfdb43fce02ba15277d52e9b0a524d789826e6b1ea8289fd76a8ad75 + md5: 1fffc68405e92be38303bfdad42a25a6 + depends: + - __glibc >=2.17,<3.0.a0 + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libprotobuf >=6.33.5,<6.33.6.0a0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 1936193 + timestamp: 1780395477218 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-onnx-frontend-2026.0.0-h558496d_1.conda sha256: 9496ef9b24c3dcf3dda58a11360095fdd427d828d33705a1d9b90a4f1a5783c3 md5: 55e11d3e2f930299df66be96928e432d @@ -8993,6 +11200,21 @@ packages: license_family: APACHE size: 1665115 timestamp: 1772721394860 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-onnx-frontend-2026.2.0-h558496d_0.conda + sha256: dd3e35276ca74c6516225858adaf03ff0023bcae01aca405153aa23e0f9578e2 + md5: e84838a0406ca0441485ef2ae93cdc12 + depends: + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libprotobuf >=6.33.5,<6.33.6.0a0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 1734652 + timestamp: 1780392356739 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2026.0.0-h7a07914_1.conda sha256: cb37b717480207a66443a93d4342cf88210a74c0820fc0edd70e4fc791a64779 md5: 74915e5e271ef76a89f711eff5959a75 @@ -9008,6 +11230,22 @@ packages: license_family: APACHE size: 684224 timestamp: 1772727417276 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2026.2.0-h7a07914_0.conda + sha256: e0d2e852c4cf581efc6e5065b5ae48ab782bc4430d5dde358387c777eaaa9e95 + md5: 25841468f7fa47d4358f962b8b60b19a + depends: + - __glibc >=2.17,<3.0.a0 + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libprotobuf >=6.33.5,<6.33.6.0a0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 689792 + timestamp: 1780395490135 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-paddle-frontend-2026.0.0-h558496d_1.conda sha256: 9e04b6c6b370e46bee7306afc9bc76e725042e981102f4c7b6b697b061c7324a md5: d26f5d445e0545ce674b11f496dba1a0 @@ -9022,6 +11260,21 @@ packages: license_family: APACHE size: 631754 timestamp: 1772721411589 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-paddle-frontend-2026.2.0-h558496d_0.conda + sha256: e7fd3356db414ea71f9614f22ef3028ebcc3b42f41558ffa2b34875e8b250cfa + md5: 99c33a18de3d0eb45d4de33037740344 + depends: + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libprotobuf >=6.33.5,<6.33.6.0a0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 638732 + timestamp: 1780392373689 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2026.0.0-hecca717_1.conda sha256: 086469e5cd8bfde48975fe8641a7d6924e3da00d75dd06c99e03a78df03a0568 md5: 559ef86008749861a53025f669004f18 @@ -9034,6 +11287,19 @@ packages: license_family: APACHE size: 1185558 timestamp: 1772727435039 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2026.2.0-hecca717_0.conda + sha256: 712a3ca68db324a503cfe13223b992fbb90fced5e53d561941b4186c4714bb08 + md5: 4abf4fe404eabad43831c6d496d97747 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 1223721 + timestamp: 1780395502677 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-pytorch-frontend-2026.0.0-hfae3067_1.conda sha256: e62d016274d9aeae8033a37cd742162637ca37cd10a5d436934c2709c58240f2 md5: 0fd361e9e722e741146d818284feca74 @@ -9045,6 +11311,18 @@ packages: license_family: APACHE size: 1091266 timestamp: 1772721428223 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-pytorch-frontend-2026.2.0-hfae3067_0.conda + sha256: 098223bfba023f1a864582bdf5b672c6bf992834f5ed69e6666947e381643ec5 + md5: 1de433749949deb737840fc8916cb37b + depends: + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 1122814 + timestamp: 1780392386564 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2026.0.0-h78e8023_1.conda sha256: 3a9a404bc9fd39e7395d49f4bd8facb58a01a31aeceabe8723a9d4f8eb5cc381 md5: fb20f4234bc0e29af1baa13d35e36785 @@ -9061,6 +11339,23 @@ packages: license_family: APACHE size: 1257870 timestamp: 1772727453738 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2026.2.0-h78e8023_0.conda + sha256: 7df7413374e2e4e2c77960c0e4265d4a5871668f2766545253b91585c9bf50b7 + md5: cded5d117c53c5963fbab737a5333a33 + depends: + - __glibc >=2.17,<3.0.a0 + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libprotobuf >=6.33.5,<6.33.6.0a0 + - libstdcxx >=14 + - snappy >=1.2.2,<1.3.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 1281126 + timestamp: 1780395514787 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-tensorflow-frontend-2026.0.0-h2cb6e3c_1.conda sha256: f4ecfddd9583fa475e2e637ac9226b6ae20482abda53bf4339a29407e6c05cb3 md5: f2c28f19267bfcdf9ec9ed4406a89d0b @@ -9076,6 +11371,22 @@ packages: license_family: APACHE size: 1184078 timestamp: 1772721443833 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-tensorflow-frontend-2026.2.0-h2cb6e3c_0.conda + sha256: 01f0529aa2c012f153d6aeebfc4b7de6bd5e0a6811d5bd894fbcfcc825fed17a + md5: bce62d32b672e259d6014c02a3790be6 + depends: + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libprotobuf >=6.33.5,<6.33.6.0a0 + - libstdcxx >=14 + - snappy >=1.2.2,<1.3.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 1205286 + timestamp: 1780392400365 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2026.0.0-hecca717_1.conda sha256: e7cee37c92ed0b62c0458c13937b6ad66319f1879f236a31c3a67391a999f429 md5: 0f0281435478b981f672a44d0029018c @@ -9088,6 +11399,19 @@ packages: license_family: APACHE size: 456585 timestamp: 1772727473378 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2026.2.0-hecca717_0.conda + sha256: 72474e82f180fb15d8cf207b2ded6c12041871ebf9cae02c81c3a5c381b3f4c9 + md5: 37a1e17203f653196077d666365632fc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libopenvino 2026.2.0 hb56ce9e_0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 500837 + timestamp: 1780395526579 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-tensorflow-lite-frontend-2026.0.0-hfae3067_1.conda sha256: b0f32488fd11cd8ed563ad01934360df383f720a2adecf6d36aa3ea2565baab7 md5: 0a160f00a4050e3bf4749129750d0303 @@ -9099,6 +11423,18 @@ packages: license_family: APACHE size: 428895 timestamp: 1772721459028 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenvino-tensorflow-lite-frontend-2026.2.0-hfae3067_0.conda + sha256: 6613215bea89b3787cff16490227394f723dd793efcf9d1b4a35290a21cb8853 + md5: 778f93a0b0a0ad4a20155cc2d4ec0319 + depends: + - libgcc >=14 + - libopenvino 2026.2.0 h1915271_0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 466181 + timestamp: 1780392413800 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda sha256: f1061a26213b9653bbb8372bfa3f291787ca091a9a3060a10df4d5297aad74fd md5: 2446ac1fe030c2aa6141386c1f5a6aed @@ -9107,6 +11443,7 @@ packages: - libgcc >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 324993 timestamp: 1768497114401 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopus-1.6.1-h80f16a2_0.conda @@ -9116,6 +11453,7 @@ packages: - libgcc >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 383586 timestamp: 1768497303687 - conda: https://conda.anaconda.org/conda-forge/win-64/libopus-1.6.1-h6a83c73_0.conda @@ -9127,6 +11465,7 @@ packages: - ucrt >=10.0.20348.0 license: BSD-3-Clause license_family: BSD + purls: [] size: 307373 timestamp: 1768497136248 - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda @@ -9139,6 +11478,17 @@ packages: license_family: MIT size: 28424 timestamp: 1749901812541 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.19-hb03c661_0.conda + sha256: f41721636a7c2e51bc2c642e1127955ab9c81145470714fdaac44d4d09e4af41 + md5: 33082e13b4769b48cfeb648e15bfe3fc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 29147 + timestamp: 1773533027610 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda sha256: 7641dfdfe9bda7069ae94379e9924892f0b6604c1a016a3f76b230433bb280f2 md5: 5044e160c5306968d956c2a0a2a440d6 @@ -9148,6 +11498,45 @@ packages: license_family: MIT size: 29512 timestamp: 1749901899881 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.19-he30d5cf_0.conda + sha256: 5d26d751b7cc4b66e28ed1ae75900956600aaa5c5d874d5a8cf106d3aff834d3 + md5: 462239e256bc180c9c45dd049ba797ee + depends: + - libgcc >=14 + license: MIT + license_family: MIT + purls: [] + size: 30294 + timestamp: 1773533057559 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libplacebo-7.360.1-h9eeb4b2_0.conda + sha256: 26cbbd3d7b91801826c779c3f7e87d071856d5cbe3d55b22777ca0d984fb02ed + md5: e6324dfe6c02e0736bb9235f8ef3c8a6 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libdovi >=3.3.2,<4.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - lcms2 >=2.19,<3.0a0 + - shaderc >=2026.2,<2026.3.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 549348 + timestamp: 1777835950707 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libplacebo-7.360.1-h07e46df_0.conda + sha256: 3af9437023ec7fa8f9bf5e390b7f6ad3df403aa736b0305121d1734af2d0620e + md5: 1909ad87fcdfa8397e3568d01500dc8d + depends: + - libstdcxx >=14 + - libgcc >=14 + - lcms2 >=2.19,<3.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libdovi >=3.3.2,<4.0a0 + - shaderc >=2026.2,<2026.3.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 560813 + timestamp: 1777835957369 - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda sha256: 36ade759122cdf0f16e2a2562a19746d96cf9c863ffaa812f2f5071ebbe9c03c md5: 5f13ffc7d30ffec87864e678df9957b4 @@ -9158,6 +11547,17 @@ packages: license: zlib-acknowledgement size: 317669 timestamp: 1770691470744 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda + sha256: 377cfe037f3eeb3b1bf3ad333f724a64d32f315ee1958581fc671891d63d3f89 + md5: eba48a68a1a2b9d3c0d9511548db85db + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + purls: [] + size: 317729 + timestamp: 1776315175087 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda sha256: c7378c6b79de4d571d00ad1caf0a4c19d43c9c94077a761abb6ead44d891f907 md5: be4088903b94ea297975689b3c3aeb27 @@ -9167,6 +11567,16 @@ packages: license: zlib-acknowledgement size: 340156 timestamp: 1770691477245 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda + sha256: 483eaa53da40a6a3e558709d9f7b1ca388735364ae21a1ba58cf942514649c92 + md5: f51503ac45a4888bce71af9027a2ecc9 + depends: + - libgcc >=14 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + purls: [] + size: 341202 + timestamp: 1776315188425 - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda sha256: db23f281fa80597a0dc0445b18318346862602d7081ed76244df8cc4418d6d68 md5: 43f47a9151b9b8fc100aeefcf350d1a0 @@ -9178,6 +11588,18 @@ packages: license: zlib-acknowledgement size: 383155 timestamp: 1770691504832 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-h7351971_0.conda + sha256: 218913aeee391460bd0e341b834dbd9c6fa6ae0a4276c0c300266cc99a816a28 + md5: 52f1280563f3b48b5f75414cd2d15dd1 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + purls: [] + size: 385227 + timestamp: 1776315248638 - conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda sha256: afbf195443269ae10a940372c1d37cda749355d2bd96ef9587a962abd87f2429 md5: 11ac478fa72cf12c214199b8a96523f4 @@ -9192,6 +11614,21 @@ packages: license_family: BSD size: 3638698 timestamp: 1769749419271 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h6eeba95_1.conda + sha256: a59aa3f076d5710c618ca8fd12d9cd8211d8b738f6b0e0c98517c0162f23a5de + md5: 7a4b11f3dd7374f1991a4088390d07c1 + depends: + - __glibc >=2.17,<3.0.a0 + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.2,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 3675765 + timestamp: 1780003831209 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libprotobuf-6.33.5-h1f88751_0.conda sha256: f68780642c215b93f4991c43d88ab0af8a08e66826e68affc65b8905cc21d86b md5: 7f4a589ae616399b7e375053e82a3b12 @@ -9205,6 +11642,20 @@ packages: license_family: BSD size: 3465308 timestamp: 1769748410724 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libprotobuf-6.33.5-h306233d_1.conda + sha256: 6a2ccd92be6a7e0256c6eeb2e61328a72d40004f08923733274ca2129dc7f70d + md5: 97b7927d982dfc20f8f49ce5174d7466 + depends: + - libabseil * cxx17* + - libabseil >=20260107.1,<20260108.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.2,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 3502676 + timestamp: 1780003320814 - conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.60.2-h61e6d4b_0.conda sha256: 38b3189cf246f7265e06917f32d046ac375117c88834d045efe73ec48ceacc59 md5: d62da3d560992bfa2feb611d7be813b8 @@ -9221,6 +11672,26 @@ packages: license: LGPL-2.1-or-later size: 4011590 timestamp: 1771399906142 +- conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.62.3-h4c96295_0.conda + sha256: 5571bd8239d71961d4e3ce972f865b3ea95a91ce0b53d5749fe2dd24254ddbda + md5: 492c8d9b1c564c2e948b6cb4ba0f8261 + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.18.0,<3.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.6,<3.0a0 + - harfbuzz >=14.2.0 + - libgcc >=14 + - libglib >=2.88.1,<3.0a0 + - libxml2-16 >=2.14.6 + - pango >=1.56.4,<2.0a0 + constrains: + - __glibc >=2.17 + license: LGPL-2.1-or-later + purls: [] + size: 3476570 + timestamp: 1780450632624 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/librsvg-2.60.2-h8171147_0.conda sha256: d02d3b23aa58d7767b820289b5b50653e73d70ae32f6ee5b88f63c5c5d96c2de md5: 1d6f1aff501c8104f7292ab787d65f15 @@ -9236,6 +11707,25 @@ packages: license: LGPL-2.1-or-later size: 4016799 timestamp: 1771406266442 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/librsvg-2.62.3-hf685517_0.conda + sha256: c95ac70755863d8522c1115b54afca86148ea25366b616aa84c993c2ca54b9ce + md5: 38209cc04b3e3e5624c534bc703e6939 + depends: + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.18.0,<3.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.6,<3.0a0 + - harfbuzz >=14.2.0 + - libgcc >=14 + - libglib >=2.88.1,<3.0a0 + - libxml2-16 >=2.14.6 + - pango >=1.56.4,<2.0a0 + constrains: + - __glibc >=2.17 + license: LGPL-2.1-or-later + purls: [] + size: 3052373 + timestamp: 1780456154830 - conda: https://conda.anaconda.org/conda-forge/win-64/librsvg-2.60.0-hd5e4115_1.conda sha256: 3d06becb70212a7ed609eea07728b6545ddcff4889844290fed14a5d2fc18cd9 md5: a105938a4fae24539c89de6e7671d279 @@ -9251,6 +11741,23 @@ packages: license: LGPL-2.1-or-later size: 2877820 timestamp: 1771301866036 +- conda: https://conda.anaconda.org/conda-forge/win-64/librsvg-2.62.3-h15cfe45_0.conda + sha256: 6f678be6074b79fe754660d16857a6edba73dd197ad92086250dc38c11b179ab + md5: 3fffc63af7b943cde57aa72f5ffe6048 + depends: + - cairo >=1.18.4,<2.0a0 + - gdk-pixbuf >=2.44.6,<3.0a0 + - harfbuzz >=14.2.0 + - libglib >=2.88.1,<3.0a0 + - libxml2-16 >=2.14.6 + - pango >=1.56.4,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-or-later + purls: [] + size: 3361405 + timestamp: 1780451179155 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda sha256: e03ed186eefb46d7800224ad34bad1268c9d19ecb8f621380a50601c6221a4a7 md5: ad3a0e2dc4cce549b2860e2ef0e6d75b @@ -9308,6 +11815,7 @@ packages: - mpg123 >=1.32.9,<1.33.0a0 license: LGPL-2.1-or-later license_family: LGPL + purls: [] size: 355619 timestamp: 1765181778282 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsndfile-1.2.2-h30591a0_2.conda @@ -9324,6 +11832,7 @@ packages: - mpg123 >=1.32.9,<1.33.0a0 license: LGPL-2.1-or-later license_family: LGPL + purls: [] size: 406978 timestamp: 1765181892661 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda @@ -9368,6 +11877,17 @@ packages: purls: [] size: 951405 timestamp: 1772818874251 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda + sha256: 1ab603b6ec93933e76027e1f23b21b22b858ba1b56f1e1695ef6fe5e80cb7358 + md5: 062b0ac602fb0adf250e3dfa86f221c4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.2,<2.0a0 + license: blessing + purls: [] + size: 957849 + timestamp: 1780574429573 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda sha256: 1ddaf91b44fae83856276f4cb7ce544ffe41d4b55c1e346b504c6b45f19098d6 md5: 77891484f18eca74b8ad83694da9815e @@ -9379,6 +11899,17 @@ packages: purls: [] size: 952296 timestamp: 1772818881550 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.2-h10b116e_0.conda + sha256: 8d78a9e60ab6d43aa80add48d66aadaa1f2a35833e646d0bb253036f4079ade9 + md5: aec62a5e5f0892cc4cf80f266f3818ee + depends: + - icu >=78.3,<79.0a0 + - libgcc >=14 + - libzlib >=1.3.2,<2.0a0 + license: blessing + purls: [] + size: 962294 + timestamp: 1780574462426 - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda sha256: 5fccf1e4e4062f8b9a554abf4f9735a98e70f82e2865d0bfdb47b9de94887583 md5: 8830689d537fda55f990620680934bb1 @@ -9390,6 +11921,17 @@ packages: purls: [] size: 1297302 timestamp: 1772818899033 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.2-hf5d6505_0.conda + sha256: 4cd81319dcc58fb758da20a6d5595950c021adc2c18d7cffeadcfb590529629f + md5: df294e7f9f24a6063f0e226f4d028fda + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + size: 1313306 + timestamp: 1780574491977 - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e md5: 1b08cd684f34175e4514474793d44bcb @@ -9403,6 +11945,19 @@ packages: purls: [] size: 5852330 timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda + sha256: dff1058c76ec6b8759e41cefa2508162d00e4a5e6721aa68ec3fd10094e702dc + md5: 5794b3bdc38177caf969dabd3af08549 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_19 + constrains: + - libstdcxx-ng ==15.2.0=*_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 5852044 + timestamp: 1778269036376 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda sha256: 31fdb9ffafad106a213192d8319b9f810e05abca9c5436b60e507afb35a6bc40 md5: f56573d05e3b735cb03efeb64a15f388 @@ -9415,6 +11970,18 @@ packages: purls: [] size: 5541411 timestamp: 1771378162499 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_19.conda + sha256: 1dadc45e599f510dd5f97141dddcdbb9844d9f1430c1f3a38075cf1c58f87b4e + md5: 543fbc8d71f2a0baf04cf88ce96cb8bb + depends: + - libgcc 15.2.0 h8acb6b2_19 + constrains: + - libstdcxx-ng ==15.2.0=*_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 5546559 + timestamp: 1778268777463 - conda: https://conda.anaconda.org/conda-forge/win-64/libstdcxx-15.2.0-hae5796f_18.conda sha256: 7134b90a850f0e14f15bd0f0218fd728f19cd5c58420a90c2f561f58272b8519 md5: 7c09facd8f5aced6b4c146e1c4053e50 @@ -9481,6 +12048,16 @@ packages: license_family: GPL size: 27575 timestamp: 1771378314494 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_19.conda + sha256: 0672b6b6e1791c92e8eccad58081a99d614fcf82bca5841f9dfa3c3e658f83b9 + md5: e5ce228e579726c07255dbf90dc62101 + depends: + - libstdcxx 15.2.0 h934c35e_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27776 + timestamp: 1778269074600 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda sha256: 035a31cde134e706e30029a837a31f729ad32b7c5bca023271dfe91a8ba6c896 md5: 699d294376fe18d80b7ce7876c3a875d @@ -9490,6 +12067,16 @@ packages: license_family: GPL size: 27645 timestamp: 1771378204663 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_19.conda + sha256: 56b5ec297a988961486694f1c598889c3a697d77a0b42b8cea3faaa12e9bd360 + md5: c82ed61c3ec470c5ec624580e6ba16e4 + depends: + - libstdcxx 15.2.0 hef695bb_19 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 27803 + timestamp: 1778268813278 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda sha256: f0356bb344a684e7616fc84675cfca6401140320594e8686be30e8ac7547aed2 md5: 1d4c18d75c51ed9d00092a891a547a7d @@ -9500,6 +12087,17 @@ packages: license: LGPL-2.1-or-later size: 491953 timestamp: 1770738638119 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-h084b8d7_1.conda + sha256: 2293884d59cf0436c37fc0a4bad71011a8de2a6913610d1c701a7703377c1f75 + md5: ea0da9c20bbb221b530810c3c68bbe62 + depends: + - __glibc >=2.17,<3.0.a0 + - libcap >=2.78,<2.79.0a0 + - libgcc >=14 + license: LGPL-2.1-or-later + purls: [] + size: 493022 + timestamp: 1780084748140 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda sha256: c5008b602cb5c819f7b52d418b3ed17e1818cbbf6705b189e7ab36bb70cce3d8 md5: 8ee3cb7f64be0e8c4787f3a4dbe024e6 @@ -9530,6 +12128,16 @@ packages: purls: [] size: 516600 timestamp: 1773797150163 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsystemd0-257.13-hfcc8634_1.conda + sha256: 7938befc6a09d9f829663ea134b01bea78dabe08d928e9a7caa68e2d726e03c5 + md5: d8981d39a52ab992a033a68927da47e0 + depends: + - libcap >=2.78,<2.79.0a0 + - libgcc >=14 + license: LGPL-2.1-or-later + purls: [] + size: 515284 + timestamp: 1780084773602 - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda sha256: e5f8c38625aa6d567809733ae04bb71c161a42e44a9fa8227abe61fa5c60ebe0 md5: cd5a90476766d53e901500df9215e927 @@ -9545,6 +12153,7 @@ packages: - libzlib >=1.3.1,<2.0a0 - zstd >=1.5.7,<1.6.0a0 license: HPND + purls: [] size: 435273 timestamp: 1762022005702 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda @@ -9561,6 +12170,7 @@ packages: - libzlib >=1.3.1,<2.0a0 - zstd >=1.5.7,<1.6.0a0 license: HPND + purls: [] size: 488407 timestamp: 1762022048105 - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda @@ -9577,6 +12187,7 @@ packages: - vc14_runtime >=14.44.35208 - zstd >=1.5.7,<1.6.0a0 license: HPND + purls: [] size: 993166 timestamp: 1762022118895 - conda: https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda130_mkl_hb2e6204_303.conda @@ -9680,6 +12291,17 @@ packages: license: LGPL-2.1-or-later size: 144654 timestamp: 1770738650966 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libudev1-257.13-h084b8d7_1.conda + sha256: 287d05680e49eea51b8145fbf34bc213c0618b04f32e450e9da5d715e5134e38 + md5: 89e5671a076d99516a6acd72a35b1640 + depends: + - __glibc >=2.17,<3.0.a0 + - libcap >=2.78,<2.79.0a0 + - libgcc >=14 + license: LGPL-2.1-or-later + purls: [] + size: 145969 + timestamp: 1780084753104 - conda: https://conda.anaconda.org/conda-forge/linux-64/libudev1-257.13-hd0affe5_0.conda sha256: 1a1e367c04d66030aa93b4d33905f7f6fbb59cfc292e816fe3e9c1e8b3f4d1e2 md5: 2c2270f93d6f9073cbf72d821dfc7d72 @@ -9710,6 +12332,16 @@ packages: purls: [] size: 156357 timestamp: 1773797159424 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libudev1-257.13-hfcc8634_1.conda + sha256: 1963dbd5a5c08390db2321dd2fa5c9df45c0fe68701fce4f9c36141155b4de13 + md5: 67728797901490baae52b3ce8d738d34 + depends: + - libcap >=2.78,<2.79.0a0 + - libgcc >=14 + license: LGPL-2.1-or-later + purls: [] + size: 156922 + timestamp: 1780084778404 - conda: https://conda.anaconda.org/conda-forge/linux-64/libunwind-1.8.3-h65a8314_0.conda sha256: 71c8b9d5c72473752a0bb6e91b01dd209a03916cb71f36cc6a564e3a2a132d7a md5: e179a69edd30d75c0144d7a380b88f28 @@ -9719,6 +12351,7 @@ packages: - libstdcxx >=14 license: MIT license_family: MIT + purls: [] size: 75995 timestamp: 1757032240102 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libunwind-1.8.3-h6470e1d_0.conda @@ -9729,6 +12362,7 @@ packages: - libstdcxx >=14 license: MIT license_family: MIT + purls: [] size: 94555 timestamp: 1757032278900 - conda: https://conda.anaconda.org/conda-forge/linux-64/liburing-2.14-hb700be7_0.conda @@ -9740,6 +12374,7 @@ packages: - libstdcxx >=14 license: MIT license_family: MIT + purls: [] size: 154203 timestamp: 1770566529700 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liburing-2.14-hfefdfc9_0.conda @@ -9750,6 +12385,7 @@ packages: - libstdcxx >=14 license: MIT license_family: MIT + purls: [] size: 155011 timestamp: 1770567701524 - conda: https://conda.anaconda.org/conda-forge/linux-64/libusb-1.0.29-h73b1eb8_0.conda @@ -9760,6 +12396,7 @@ packages: - libgcc >=13 - libudev1 >=257.4 license: LGPL-2.1-or-later + purls: [] size: 89551 timestamp: 1748856210075 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libusb-1.0.29-h06eaf92_0.conda @@ -9769,6 +12406,7 @@ packages: - libgcc >=13 - libudev1 >=257.4 license: LGPL-2.1-or-later + purls: [] size: 93129 timestamp: 1748856228398 - conda: https://conda.anaconda.org/conda-forge/win-64/libusb-1.0.29-h1839187_0.conda @@ -9782,6 +12420,7 @@ packages: - vc14_runtime >=14.29.30139 - ucrt >=10.0.20348.0 license: LGPL-2.1-or-later + purls: [] size: 118204 timestamp: 1748856290542 - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda @@ -9805,6 +12444,17 @@ packages: purls: [] size: 40297 timestamp: 1775052476770 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda + sha256: 3f0edf1280e2f6684a986f821eaa3e123d2694a00b31b96ca0d4a4c12c129231 + md5: 7d0a66598195ef00b6efc55aefc7453b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 40163 + timestamp: 1779118517630 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda sha256: c37a8e89b700646f3252608f8368e7eb8e2a44886b92776e57ad7601fc402a11 md5: cf2861212053d05f27ec49c3784ff8bb @@ -9824,6 +12474,16 @@ packages: purls: [] size: 43567 timestamp: 1775052485727 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42.1-h1022ec0_0.conda + sha256: 1628839b062e98b2192857d4da8496ac9ac6b0dbb77aa040c34efc9192c440ee + md5: 0f42f9fedd2a32d798de95a7f65c456f + depends: + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 43453 + timestamp: 1779118526838 - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b md5: 0f03292cc56bf91a077a134ea8747118 @@ -9861,6 +12521,7 @@ packages: - xorg-libxfixes >=6.0.2,<7.0a0 license: MIT license_family: MIT + purls: [] size: 221308 timestamp: 1765652453244 - conda: https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda @@ -9875,6 +12536,7 @@ packages: - libogg >=1.3.5,<1.4.0a0 license: BSD-3-Clause license_family: BSD + purls: [] size: 285894 timestamp: 1753879378005 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libvorbis-1.3.7-h7ac5ae9_2.conda @@ -9887,6 +12549,7 @@ packages: - libogg >=1.3.5,<1.4.0a0 license: BSD-3-Clause license_family: BSD + purls: [] size: 289391 timestamp: 1753879417231 - conda: https://conda.anaconda.org/conda-forge/win-64/libvorbis-1.3.7-h5112557_2.conda @@ -9903,6 +12566,7 @@ packages: - libogg >=1.3.5,<1.4.0a0 license: BSD-3-Clause license_family: BSD + purls: [] size: 243401 timestamp: 1753879416570 - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpl-2.16.0-h54a6638_0.conda @@ -9916,6 +12580,7 @@ packages: - libva >=2.23.0,<3.0a0 license: MIT license_family: MIT + purls: [] size: 287992 timestamp: 1772980546550 - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.15.2-hecca717_0.conda @@ -9927,6 +12592,7 @@ packages: - libstdcxx >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 1070048 timestamp: 1762010217363 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libvpx-1.15.2-hfae3067_0.conda @@ -9937,6 +12603,7 @@ packages: - libstdcxx >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 1296382 timestamp: 1762012332100 - conda: https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda @@ -9952,6 +12619,7 @@ packages: - libvulkan-headers 1.4.341.0.* license: Apache-2.0 license_family: APACHE + purls: [] size: 199795 timestamp: 1770077125520 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda @@ -9966,6 +12634,7 @@ packages: - libvulkan-headers 1.4.341.0.* license: Apache-2.0 license_family: APACHE + purls: [] size: 217655 timestamp: 1770077141862 - conda: https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda @@ -9979,6 +12648,7 @@ packages: - libvulkan-headers 1.4.341.0.* license: Apache-2.0 license_family: APACHE + purls: [] size: 282251 timestamp: 1770077165680 - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda @@ -9991,6 +12661,7 @@ packages: - libwebp 1.6.0 license: BSD-3-Clause license_family: BSD + purls: [] size: 429011 timestamp: 1752159441324 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda @@ -10002,6 +12673,7 @@ packages: - libwebp 1.6.0 license: BSD-3-Clause license_family: BSD + purls: [] size: 359496 timestamp: 1752160685488 - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda @@ -10015,6 +12687,7 @@ packages: - libwebp 1.6.0 license: BSD-3-Clause license_family: BSD + purls: [] size: 279176 timestamp: 1752159543911 - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda @@ -10040,6 +12713,7 @@ packages: - xorg-libxdmcp license: MIT license_family: MIT + purls: [] size: 395888 timestamp: 1727278577118 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda @@ -10052,13 +12726,46 @@ packages: - xorg-libxdmcp license: MIT license_family: MIT + purls: [] size: 397493 timestamp: 1727280745441 - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda sha256: d2195b5fbcb0af1ff7b345efdf89290c279b8d1d74f325ae0ac98148c375863c md5: 2bca1fbb221d9c3c8e3a155784bbc2e9 depends: - - __glibc >=2.17,<3.0.a0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxcb >=1.17.0,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - xkeyboard-config + - xorg-libxau >=1.0.12,<2.0a0 + license: MIT/X11 Derivative + license_family: MIT + size: 837922 + timestamp: 1764794163823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.2-hca5e8e5_0.conda + sha256: 046f2ff4acebd8729fac03e99c8c307dfb48b6a32894ba8c11576e78f6e76e43 + md5: dc8b067e22b414172bedd8e3f03f3c95 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxcb >=1.17.0,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - xkeyboard-config + - xorg-libxau >=1.0.12,<2.0a0 + license: MIT/X11 Derivative + license_family: MIT + purls: [] + size: 851166 + timestamp: 1780213397575 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda + sha256: 37e4aa45b71c35095a01835bd42fa37c08218fec44eb2c6bf4b9e2826b0351d4 + md5: 22c1ce28d481e490f3635c1b6a2bb23f + depends: - libgcc >=14 - libstdcxx >=14 - libxcb >=1.17.0,<2.0a0 @@ -10068,11 +12775,11 @@ packages: - xorg-libxau >=1.0.12,<2.0a0 license: MIT/X11 Derivative license_family: MIT - size: 837922 - timestamp: 1764794163823 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda - sha256: 37e4aa45b71c35095a01835bd42fa37c08218fec44eb2c6bf4b9e2826b0351d4 - md5: 22c1ce28d481e490f3635c1b6a2bb23f + size: 863646 + timestamp: 1764794352540 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.2-h3c6a4c8_0.conda + sha256: 8f44670a714a12589bc82ea179e46ba4a19c4458d5cee765ddd4d5224eccd912 + md5: d6fc9ac66ea61eb662747959d0a68c57 depends: - libgcc >=14 - libstdcxx >=14 @@ -10083,8 +12790,9 @@ packages: - xorg-libxau >=1.0.12,<2.0a0 license: MIT/X11 Derivative license_family: MIT - size: 863646 - timestamp: 1764794352540 + purls: [] + size: 875994 + timestamp: 1780213408784 - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda sha256: 275c324f87bda1a3b67d2f4fcc3555eeff9e228a37655aa001284a7ceb6b0392 md5: e49238a1609f9a4a844b09d9926f2c3d @@ -10100,6 +12808,22 @@ packages: license_family: MIT size: 45968 timestamp: 1772704614539 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda + sha256: 3bc5551720c58591f6ea1146f7d1539c734ed1c40e7b9f5cb8cb7e900c509aba + md5: 995d8c8bad2a3cc8db14675a153dec2b + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.3,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libxml2-16 2.15.3 hca6bf5a_0 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 46810 + timestamp: 1776376751152 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda sha256: 3e51e1952cb60c8107094b6b78473d91ff49d428ad4bef6806124b383e8fe29c md5: 19de96909ee1198e2853acd8aba89f6c @@ -10114,6 +12838,21 @@ packages: license_family: MIT size: 47837 timestamp: 1772704681112 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.3-h869d058_0.conda + sha256: e3af6af9df73bd3c7a8e4e6c8cc38df3699e7f588b0705c257a8601e40acfbdf + md5: 2cffef27cb2eb9ed1e315a1e269d4335 + depends: + - icu >=78.3,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libxml2-16 2.15.3 h79dcc73_0 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 48101 + timestamp: 1776376766341 - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda sha256: f905eb7046987c336122121759e7f09144729f6898f48cd06df2a945b86998d8 md5: 1007e1bfe181a2aee214779ee7f13d30 @@ -10148,6 +12887,23 @@ packages: license_family: MIT size: 43866 timestamp: 1772704745691 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda + sha256: a4599c6bbbbdd7db570896e520c557eec8e66d94e839a59d17dc1f24a3d5f82b + md5: 95591ca5671d2213f5b2d5aa7818420d + depends: + - icu >=78.3,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libxml2-16 2.15.3 h3cfd58e_0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + purls: [] + size: 43684 + timestamp: 1776376992865 - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda sha256: 08d2b34b49bec9613784f868209bb7c3bb8840d6cf835ff692e036b09745188c md5: f3bc152cb4f86babe30f3a4bf0dbef69 @@ -10164,6 +12920,23 @@ packages: license_family: MIT size: 557492 timestamp: 1772704601644 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda + sha256: 3d44f737c5ae52d5af32682cc1530df433f401f8e58a7533926536244127572a + md5: e79d2c2f24b027aa8d5ab1b1ba3061e7 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.3,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - libxml2 2.15.3 + license: MIT + license_family: MIT + purls: [] + size: 559775 + timestamp: 1776376739004 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda sha256: da6b2ebbcecc158200d90be39514e4e902971628029b35b7f6ad57270659c5d9 md5: e3ec9079759d35b875097d6a9a69e744 @@ -10179,6 +12952,22 @@ packages: license_family: MIT size: 598438 timestamp: 1772704671710 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.3-h79dcc73_0.conda + sha256: ad048a9ca1bf2cdfedb2b0c231050da416c44ee1436a3d1a83b51d2e2deaa842 + md5: 68866231cfe8789e780347f2482df96d + depends: + - icu >=78.3,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - libxml2 2.15.3 + license: MIT + license_family: MIT + purls: [] + size: 601948 + timestamp: 1776376758674 - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h3cfd58e_0.conda sha256: d6d792f8f1d6786b9144adfa62c33a04aeec3d76682351b353ca1224fc1a74f3 md5: f6dd496a1f2b66951110a3a0817f699b @@ -10214,6 +13003,24 @@ packages: purls: [] size: 520078 timestamp: 1772704728534 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_0.conda + sha256: 3b61ee3caba702d2ff432fa3920835db963026e5c99c4e6fdca0c6114f59e7ce + md5: 9e8dd0d90ed830107b2c36801035b7db + depends: + - icu >=78.3,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.3,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libxml2 2.15.3 + license: MIT + license_family: MIT + purls: [] + size: 519871 + timestamp: 1776376969852 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -10337,6 +13144,21 @@ packages: purls: [] size: 348400 timestamp: 1774733045609 +- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.7-h4fa8253_0.conda + sha256: 70140a1fa5d7cb801c6be3273b0704b5f0e418e2fff6b12b8ce9db13067a1ed5 + md5: 0ca3373049a5be11689bc2f9b2f3a9d2 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - intel-openmp <0.0a0 + - openmp 22.1.7|22.1.7.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + purls: [] + size: 347536 + timestamp: 1780456277495 - conda: https://conda.anaconda.org/conda-forge/win-64/m2-conda-epoch-20250515-0_x86_64.conda build_number: 0 sha256: 51e9214548f177db9c3fe70424e3774c95bf19cd69e0e56e83abe2e393228ba1 @@ -10560,6 +13382,21 @@ packages: purls: [] size: 99997309 timestamp: 1774449747739 +- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2026.0.0-hac47afa_908.conda + sha256: f997bfc9bc4d4e14261cdcd1ad195d64a72ee44dca3145d24c1349f8d1311aa5 + md5: 36ea6e1292e9d5e89374201da79646ef + depends: + - llvm-openmp >=22.1.5 + - onemkl-license 2026.0.0 h57928b3_908 + - tbb >=2023.0.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 + license_family: Proprietary + purls: [] + size: 114354729 + timestamp: 1779293121860 - conda: https://conda.anaconda.org/conda-forge/linux-64/ml_dtypes-0.5.4-np2py314h6477eea_1.conda sha256: bf58f5b2d89958e8880cfde4e5e3d86f230485c5f5f1043fc47a56656f9655c6 md5: af93de29d470abbe21a6adc2ec58516e @@ -10664,6 +13501,7 @@ packages: - libstdcxx >=13 license: LGPL-2.1-only license_family: LGPL + purls: [] size: 491140 timestamp: 1730581373280 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mpg123-1.32.9-h65af167_0.conda @@ -10674,6 +13512,7 @@ packages: - libstdcxx >=13 license: LGPL-2.1-only license_family: LGPL + purls: [] size: 558708 timestamp: 1730581372400 - conda: https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda @@ -10857,6 +13696,16 @@ packages: purls: [] size: 891641 timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda + sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 + md5: fc21868a1a5aacc937e7a18747acb8a5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: X11 AND BSD-3-Clause + purls: [] + size: 918956 + timestamp: 1777422145199 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda sha256: 91cfb655a68b0353b2833521dc919188db3d8a7f4c64bea2c6a7557b24747468 md5: 182afabe009dc78d8b73100255ee6868 @@ -10866,6 +13715,15 @@ packages: purls: [] size: 926034 timestamp: 1738196018799 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-hf8d1292_0.conda + sha256: 369db85c5cd8d99dde364ce70725d76511d9c8199e5b820c740414091bf5bcca + md5: b2a43456aa56fe80c2477a5094899eff + depends: + - libgcc >=14 + license: X11 AND BSD-3-Clause + purls: [] + size: 960036 + timestamp: 1777422174534 - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_1.conda sha256: bb7b21d7fd0445ddc0631f64e66d91a179de4ba920b8381f29b9d006a42788c0 md5: 598fd7d4d0de2455fb74f56063969a97 @@ -10901,6 +13759,43 @@ packages: license_family: BSD size: 3843 timestamp: 1582593857545 +- pypi: https://files.pythonhosted.org/packages/52/f6/620a144d38e5496a6e8842b837d48885fb532594752194a01f81701d8b91/numba_cuda_mlir-0.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + name: numba-cuda-mlir + version: 0.4.0 + sha256: 2e67ed54324fdd9e3bd86872bc4949a1fe96c849cc5640939a7513da6f0f64b4 + requires_dist: + - numpy + - typing-extensions ; python_full_version < '3.12' + - cuda-bindings>=12.9.1,<14.0.0 + - cuda-core>=0.5.1,<2.0.0 + - cuda-bindings>=12.9.1,<13.0.0 ; extra == 'cu12' + - cuda-toolkit[cccl,cudart,nvcc,nvrtc]==12.* ; extra == 'cu12' + - nvidia-nvjitlink-cu12>=12.3.0,<13.0.0 ; extra == 'cu12' + - cuda-bindings==13.* ; extra == 'cu13' + - cuda-toolkit[cccl,cudart,nvcc,nvrtc]==13.* ; extra == 'cu13' + - nvidia-nvjitlink>=13.0.0,<14.0.0 ; extra == 'cu13' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/b1/90/16712f7566d35bb86964ca3a29858e6ca2d9e6c75d5f869e56dc6f700001/numba_cuda_mlir-0.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl + name: numba-cuda-mlir + version: 0.4.0 + sha256: d9c481dbe6a0bfc2f8d3bdb5b1ee6fce142667c88fffb970c26b2d7b33b6a541 + requires_dist: + - numpy + - typing-extensions ; python_full_version < '3.12' + - cuda-bindings>=12.9.1,<14.0.0 + - cuda-core>=0.5.1,<2.0.0 + - cuda-bindings>=12.9.1,<13.0.0 ; extra == 'cu12' + - cuda-toolkit[cccl,cudart,nvcc,nvrtc]==12.* ; extra == 'cu12' + - nvidia-nvjitlink-cu12>=12.3.0,<13.0.0 ; extra == 'cu12' + - cuda-bindings==13.* ; extra == 'cu13' + - cuda-toolkit[cccl,cudart,nvcc,nvrtc]==13.* ; extra == 'cu13' + - nvidia-nvjitlink>=13.0.0,<14.0.0 ; extra == 'cu13' + requires_python: '>=3.11' +- pypi: https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl + name: numpy + version: 2.4.6 + sha256: 9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 + requires_python: '>=3.11' - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda sha256: 1d8377c8001c15ed12c2713b723213474b435706ab9d34ede69795d64af9e94d md5: 4ea6b620fdf24a1a0bc4f1c7134dfafb @@ -10939,6 +13834,26 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 8927860 timestamp: 1773839233468 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.6-py314h2b28147_0.conda + sha256: bc61ae892973751a6b0e6ecea57ed6d7053224bddcb007165d6ceb1d7344ad47 + md5: f49b5f950379e0b97c35ca97682f7c6a + depends: + - python + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - liblapack >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=hash-mapping + size: 8928909 + timestamp: 1779169198391 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.2-py314haac167e_1.conda sha256: 1e1366e700156cbddc4daae0fec34a72b74105ba45f9c144f777120552924747 md5: 98ef547c85356475adb2197965c716b6 @@ -10977,6 +13892,24 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 8008045 timestamp: 1773839355275 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.6-py314h314fbd6_0.conda + sha256: 80bbd96ce7c023edbac9b4b2ae0f2d5b3f4da54801c53be91de1071c17dfde69 + md5: 7701250801c35f6a782287df118a486f + depends: + - python + - libgcc >=14 + - libstdcxx >=14 + - python_abi 3.14.* *_cp314t + - libblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 8084931 + timestamp: 1779169208044 - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.2-py314h06c3c77_1.conda sha256: 34fc25b81cfa987e1825586ddb1a4ac76a246fdef343c9171109017674ad6503 md5: 2fccd2c4e9feb4e4c2a90043015525d6 @@ -11015,6 +13948,26 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 7311362 timestamp: 1773839141373 +- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.6-py314h02f10f6_0.conda + sha256: de0eee21d902fb45a58454e3739e04ede7d02bf7575ca0ae9f959f20fa15c76b + md5: df95e6c7325bbae2571e5cef5f9c8096 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - libblas >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=hash-mapping + size: 7318163 + timestamp: 1779169232086 - conda: https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda sha256: 482d94fce136c4352b18c6397b9faf0a3149bfb12499ab1ffebad8db0cb6678f md5: 3aa4b625f20f55cf68e92df5e5bf3c39 @@ -11029,6 +13982,84 @@ packages: - pkg:pypi/numpydoc?source=hash-mapping size: 65801 timestamp: 1764715638266 +- pypi: https://files.pythonhosted.org/packages/5f/7a/9cb8a7fb87a85b11e8753548ae1422be847c5dddf3ca9ff5b080b309e271/nvidia_cuda_cccl-13.3.3.3.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + name: nvidia-cuda-cccl + version: 13.3.3.3.1 + sha256: 4dbc9dd84fbaeae267cbd80a9ed76d35171dba78639695dbdff0bae50e4503fa + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/fe/fb/195d50d25ab68a76b817ffc68c45b1fb828598ce35a8e5c1736060628dab/nvidia_cuda_cccl-13.3.3.3.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: nvidia-cuda-cccl + version: 13.3.3.3.1 + sha256: 40ba1fa0b2c694ddc06cc791ed5c8bdad4638e2735b784960d68ac3086399c97 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/8d/a7/998af901511d5efdc6e42fc597d32a69f34eecf86f1591a9d230ab3ab951/nvidia_cuda_crt-13.3.33-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: nvidia-cuda-crt + version: 13.3.33 + sha256: 01ff37600c7b880a14cab4ade763b4c10c0ff92f25cc9dca30f0881ce52693c4 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/d1/32/5ea57f8cd6ad5df2173d175ac5db4e06edde40028b1b1f6c539ea4c10290/nvidia_cuda_crt-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + name: nvidia-cuda-crt + version: 13.3.33 + sha256: c8c257393f9c9146a85d3644f352be8154843d760031f756e673222c768a4930 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/3f/af/e1b107f034f7c133255c162b922bbad3da5be20ebf76df17662ae4bd31f6/nvidia_cuda_nvcc-13.3.33-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: nvidia-cuda-nvcc + version: 13.3.33 + sha256: 53b5f1be1731574368b8be931b77b6313492266c464aef3dd3f431569ce90deb + requires_dist: + - nvidia-nvvm + - nvidia-cuda-runtime + - nvidia-cuda-crt + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/be/b6/bb07a3a63b5b7b55516366747892abbf3ee62d616684c40bb51e6cbfe956/nvidia_cuda_nvcc-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + name: nvidia-cuda-nvcc + version: 13.3.33 + sha256: 8c348623b1434aebd234da9ec1f81022587ae4995d65c3dc8a7743245cc441f7 + requires_dist: + - nvidia-nvvm + - nvidia-cuda-runtime + - nvidia-cuda-crt + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/8b/2c/86916c8a34dcdb0c3ddd1c0e30545041bd781184e437b9cb76fcda70560b/nvidia_cuda_nvrtc-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl + name: nvidia-cuda-nvrtc + version: 13.3.33 + sha256: 82530788b8c6164a54d3fd9ae8bcca8893d397c4aeb998861982a03bbe41e204 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/e7/b6/60a3641111d39ebfcfcd8b8bfd0290d7623c4b8b5f90952c2d84776f8ca4/nvidia_cuda_nvrtc-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + name: nvidia-cuda-nvrtc + version: 13.3.33 + sha256: 7b05ecda494c6dabc44231a608b060a71008a730d9dfda932cc508e6d29159e0 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/5f/e5/c1a221c8e6fecd071b80ea44c20fc253ae24f56e15e3f77cfbc3fb76e724/nvidia_cuda_runtime-13.3.29-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + name: nvidia-cuda-runtime + version: 13.3.29 + sha256: 73291e19c9dd919c140c91bda2f80b0eca487da5ee30a086ef7bc4918ecb90ea + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/97/be/5699b6e642b372f7d24c59c2f41383e2696825e20bab85f7399c7c6a56f7/nvidia_cuda_runtime-13.3.29-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + name: nvidia-cuda-runtime + version: 13.3.29 + sha256: e04420616e72f563167a7733272992d7e6df6dc5cb54b2f94f9f1520ea9e30c1 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/69/30/45414e35ff2eee7db3da037e5707037ccf9d2b5218ffbdb055ea4d5aa98a/nvidia_nvjitlink-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + name: nvidia-nvjitlink + version: 13.3.33 + sha256: ce48b37dfeb3cb1eae4cf85adacb47d7a6539ea2272870c9a3628ce275c2037e + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/f0/ee/580ca6f29dcab0221db8706badca1bbbb084f1975c4d4e83329c3a7e31f0/nvidia_nvjitlink-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl + name: nvidia-nvjitlink + version: 13.3.33 + sha256: 26a6de7fb4c8fdaa7703d3dad720d6d427ddfea5c48a528fd97c11733ad830e5 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/01/8a/f767031dcd0d24c2bbab4b696dbcf004da4f3284e5e4649fc47bc0e2bb78/nvidia_nvvm-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl + name: nvidia-nvvm + version: 13.3.33 + sha256: aafaf73246b6126bc88f521e5dab1d196395ee87739d9f5b7c39c9fee0ead9c7 + requires_python: '>=3' +- pypi: https://files.pythonhosted.org/packages/83/36/ce0d42d3a4465c858c379932f0080d29d22f04383ab79119c7c4f4cdd5ef/nvidia_nvvm-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl + name: nvidia-nvvm + version: 13.3.33 + sha256: fd74a1c5ef284ba04c1ba75f886404dff953c54731a3a9c7b45e9aedaf1a226b + requires_python: '>=3' - pypi: https://files.pythonhosted.org/packages/8c/79/017fab2f7167a9a9795665f894d04f77aafceca80821b51589bb4b23ff5c/nvidia_sphinx_theme-0.0.9.post1-py3-none-any.whl name: nvidia-sphinx-theme version: 0.0.9.post1 @@ -11048,6 +14079,26 @@ packages: license_family: BSD size: 106742 timestamp: 1743700382939 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ocl-icd-2.3.4-hb03c661_1.conda + sha256: 75f3bf733523a338f73d6c276c4a26634877cd970edb558f2769d9fa52b100a9 + md5: c2871ba95727fd1382c05db66048b64c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - opencl-headers >=2025.6.13 + license: BSD-2-Clause + license_family: BSD + purls: [] + size: 109598 + timestamp: 1780362789611 +- conda: https://conda.anaconda.org/conda-forge/win-64/onemkl-license-2026.0.0-h57928b3_908.conda + sha256: 42ad15cbb3bf31830efa04d4b86dd2d5c0dd590c86f98adcd3c8c1f75acf5dd5 + md5: 9c9303e08b50e09f5c23e1dac99d0936 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 + license_family: Proprietary + purls: [] + size: 41580 + timestamp: 1779292867015 - conda: https://conda.anaconda.org/conda-forge/linux-64/opencl-headers-2025.06.13-h5888daf_0.conda sha256: 2b6ce54174ec19110e1b3c37455f7cd138d0e228a75727a9bba443427da30a36 md5: 45c3d2c224002d6d0d7769142b29f986 @@ -11059,6 +14110,18 @@ packages: license_family: APACHE size: 55357 timestamp: 1749853464518 +- conda: https://conda.anaconda.org/conda-forge/linux-64/opencl-headers-2025.06.13-hecca717_0.conda + sha256: 8de2f0cd8a659b01abf86e7fbb8cea4f28ada62fd288429a2bbc040db1b98dd0 + md5: c930c8052d780caa41216af7de472226 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 55754 + timestamp: 1773844383536 - conda: https://conda.anaconda.org/conda-forge/linux-64/openh264-2.6.0-hc22cd8d_0.conda sha256: 3f231f2747a37a58471c82a9a8a80d92b7fece9f3fce10901a5ac888ce00b747 md5: b28cf020fd2dead0ca6d113608683842 @@ -11068,6 +14131,7 @@ packages: - libstdcxx >=13 license: BSD-2-Clause license_family: BSD + purls: [] size: 731471 timestamp: 1739400677213 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openh264-2.6.0-h0564a2a_0.conda @@ -11078,6 +14142,7 @@ packages: - libstdcxx >=13 license: BSD-2-Clause license_family: BSD + purls: [] size: 774512 timestamp: 1739400731652 - conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.6.0-hb17fa0b_0.conda @@ -11089,6 +14154,7 @@ packages: - vc14_runtime >=14.29.30139 license: BSD-2-Clause license_family: BSD + purls: [] size: 411269 timestamp: 1739401120354 - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda @@ -11103,6 +14169,18 @@ packages: purls: [] size: 3164551 timestamp: 1769555830639 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_0.conda + sha256: d48f5c22b9897c01e4dff3680f1f57ceb02711ab9c62f74339b080419dfad34b + md5: 79dd2074b5cd5c5c6b2930514a11e22d + depends: + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3159683 + timestamp: 1781069855778 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda sha256: 7f8048c0e75b2620254218d72b4ae7f14136f1981c5eb555ef61645a9344505f md5: 25f5885f11e8b1f075bccf4a2da91c60 @@ -11114,6 +14192,17 @@ packages: purls: [] size: 3692030 timestamp: 1769557678657 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.3-h546c87b_0.conda + sha256: da4a5df42614166b69c2f6d8602fc1425f7aaa699f77c3bafb5c7fe69b3d9fb7 + md5: fa6260b3e6eababf6ca85a7eb3336383 + depends: + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 3704664 + timestamp: 1781069675555 - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda sha256: 53a5ad2e5553b8157a91bb8aa375f78c5958f77cb80e9d2ce59471ea8e5c0bd6 md5: eb585509b815415bc964b2c7e11c7eb3 @@ -11127,6 +14216,19 @@ packages: purls: [] size: 9343023 timestamp: 1769557547888 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.3-hf411b9b_0.conda + sha256: cb6e7ba0d010ee0d3249ce9886de3d7613d26d9965d4c95666fa66b9c4c31001 + md5: e99f95734a326c0fd4d02bbd995150d4 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 9414790 + timestamp: 1781071745579 - conda: https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda sha256: 620379ebc27e1c43b9a8defdb167442a3413de949a464305443833db32ba7a83 md5: e13172f02effa3c9f07571ed0ddef44d @@ -11187,6 +14289,47 @@ packages: license: LGPL-2.1-or-later size: 455420 timestamp: 1751292466873 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda + sha256: 315b52bfa6d1a820f4806f6490d472581438a28e21df175290477caec18972b0 + md5: d53ffc0edc8eabf4253508008493c5bc + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.1 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 458036 + timestamp: 1774281947855 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pango-1.56.4-h8547ced_1.conda + sha256: d209c8b0d53c441ee0bc0d8fce0fcae8e7e05755e51b13b6b9da02c7aa032f98 + md5: 3fc7cc25bba3381e77b753578058e3b0 + depends: + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + license: LGPL-2.1-or-later + purls: [] + size: 470441 + timestamp: 1774284032397 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pango-1.56.4-he55ef5b_0.conda sha256: dd36cd5b6bc1c2988291a6db9fa4eb8acade9b487f6f1da4eaa65a1eebb0a12d md5: a22cc88bf6059c9bcc158c94c9aab5b8 @@ -11227,6 +14370,28 @@ packages: license: LGPL-2.1-or-later size: 454854 timestamp: 1751292618315 +- conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.56.4-h13911b6_1.conda + sha256: 3d4e6e541e633f6fd22fc2c1d79ad5ec39503dea3ba04fc3e01d5be904ec7cea + md5: 1f1cf3772ba7d4eef989e4679ddf97f7 + depends: + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.1 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.1-or-later + purls: [] + size: 454919 + timestamp: 1774282149607 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.6-pyhcf101f3_0.conda sha256: 42b2d77ccea60752f3aa929a6413a7835aaacdbbde679f2f5870a744fa836b94 md5: 97c1ce2fffa1209e7afb432810ec6e12 @@ -11249,6 +14414,7 @@ packages: - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD + purls: [] size: 1222481 timestamp: 1763655398280 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda @@ -11260,6 +14426,7 @@ packages: - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD + purls: [] size: 1166552 timestamp: 1763655534263 - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda @@ -11273,6 +14440,7 @@ packages: - vc14_runtime >=14.44.35208 license: BSD-3-Clause license_family: BSD + purls: [] size: 995992 timestamp: 1763655708300 - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda @@ -11307,6 +14475,7 @@ packages: - __glibc >=2.17,<3.0.a0 license: MIT license_family: MIT + purls: [] size: 450960 timestamp: 1754665235234 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.4-h7ac5ae9_1.conda @@ -11318,6 +14487,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 357913 timestamp: 1754665583353 - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda @@ -11332,6 +14502,7 @@ packages: - ucrt >=10.0.20348.0 license: MIT license_family: MIT + purls: [] size: 542795 timestamp: 1754665193489 - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda @@ -11423,6 +14594,7 @@ packages: - libgcc >=13 license: MIT license_family: MIT + purls: [] size: 8252 timestamp: 1726802366959 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda @@ -11432,6 +14604,7 @@ packages: - libgcc >=13 license: MIT license_family: MIT + purls: [] size: 8342 timestamp: 1726803319942 - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda @@ -11453,6 +14626,7 @@ packages: - libstdcxx >=13 license: MIT license_family: MIT + purls: [] size: 118488 timestamp: 1736601364156 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pugixml-1.15-h6ef32b0_0.conda @@ -11463,6 +14637,7 @@ packages: - libstdcxx >=13 license: MIT license_family: MIT + purls: [] size: 113424 timestamp: 1737355438448 - conda: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda @@ -11481,6 +14656,7 @@ packages: - pulseaudio 17.0 *_3 license: LGPL-2.1-or-later license_family: LGPL + purls: [] size: 750785 timestamp: 1763148198088 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pulseaudio-client-17.0-hcf98165_3.conda @@ -11498,6 +14674,7 @@ packages: - pulseaudio 17.0 *_3 license: LGPL-2.1-or-later license_family: LGPL + purls: [] size: 760306 timestamp: 1763148231117 - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda @@ -11605,6 +14782,19 @@ packages: license_family: BSD size: 725938 timestamp: 1770169149613 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyglet-2.1.14-pyhd8ed1ab_0.conda + sha256: 9436a5bdcf63c215a9b4c0bc7be4ba16dae43a714cd15c2133ca851c588279ac + md5: 85911d1b0c7ffe28189b6d461915ad9c + depends: + - ffmpeg >=4.0.0 + - freetype + - python >=3.10 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pyglet?source=hash-mapping + size: 728286 + timestamp: 1775384075243 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a md5: 6b6ece66ebcae2d5f326c77ef2c5a066 @@ -11754,6 +14944,34 @@ packages: size: 36702440 timestamp: 1770675584356 python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda + build_number: 100 + sha256: 6d28ac2b061179deb434d3d57afa98ffd20ec3c5d44ab8048a1ca33424b22d38 + md5: 0b9b2f83b5b600e1ac38becde8d0dd44 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.8.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.3,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.53.2,<4.0a0 + - libuuid >=2.42.1,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - openssl >=3.5.7,<4.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + purls: [] + size: 36717183 + timestamp: 1781255094700 + python_site_packages_path: lib/python3.14/site-packages - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.3-hb06a95a_101_cp314.conda build_number: 101 sha256: 87e9dff5646aba87cecfbc08789634c855871a7325169299d749040b0923a356 @@ -11781,6 +14999,34 @@ packages: size: 37305578 timestamp: 1770674395875 python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.6-h1c24c05_0_cp314t.conda + sha256: 7fc81ed776b89786c00b3bf9d67e5472e78b63f5c82e0bc66bd763f7d1df3d24 + md5: 3ccb01876bc484acb5ea03d3c3949cea + depends: + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-aarch64 >=2.36.1 + - libexpat >=2.8.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.3,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.53.2,<4.0a0 + - libuuid >=2.42.1,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.6,<7.0a0 + - openssl >=3.5.7,<4.0a0 + - python_abi 3.14.* *_cp314t + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + track_features: + - py_freethreading + license: Python-2.0 + purls: [] + size: 46058573 + timestamp: 1781254957859 + python_site_packages_path: lib/python3.14t/site-packages - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.3-h4b44e0e_101_cp314.conda build_number: 101 sha256: 3f99d83bfd95b9bdae64a42a1e4bf5131dc20b724be5ac8a9a7e1ac2c0f006d7 @@ -11806,6 +15052,31 @@ packages: size: 18273230 timestamp: 1770675442998 python_site_packages_path: Lib/site-packages +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.6-h4b44e0e_100_cp314.conda + build_number: 100 + sha256: f1acb89cb1a6bec9a94ae9f8e7411839de009cd64d3ac6a6aec4f3d8a481099a + md5: 8333e3ca6f8d1ebcd30b678dd53f0a25 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.8.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.3,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.53.2,<4.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.7,<4.0a0 + - python_abi 3.14.* *_cp314 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + purls: [] + size: 18481352 + timestamp: 1781256034828 + python_site_packages_path: Lib/site-packages - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda sha256: d6a17ece93bbd5139e02d2bd7dbfa80bee1a4261dced63f65f679121686bf664 md5: 5b8d21249ff20967101ffa321cab24e8 @@ -11852,6 +15123,17 @@ packages: purls: [] size: 6989 timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda + build_number: 8 + sha256: d9ed2538fba61265a330ee1b1afe99a4bb23ace706172b9464546c7e01259d63 + md5: 3251796e09870c978e0f69fa05e38fb6 + constrains: + - python 3.14.* *_cp314t + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 7020 + timestamp: 1752805919426 - conda: https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda130_mkl_py314_h382c374_303.conda sha256: d86f460bddc5b3c443b109e30a1c7f1f9b4044eabf6356c49f19dd660720e395 md5: 1a0371ac3f70358740c260541508f0f5 @@ -12373,6 +15655,7 @@ packages: - sdl3 >=3.2.22,<4.0a0 - libegl >=1.7.0,<2.0a0 license: Zlib + purls: [] size: 589145 timestamp: 1757842881 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sdl2-2.32.56-h7ac5ae9_0.conda @@ -12385,6 +15668,7 @@ packages: - libgl >=1.7.0,<2.0a0 - libegl >=1.7.0,<2.0a0 license: Zlib + purls: [] size: 597756 timestamp: 1757842928996 - conda: https://conda.anaconda.org/conda-forge/win-64/sdl2-2.32.56-h5112557_0.conda @@ -12399,8 +15683,39 @@ packages: - ucrt >=10.0.20348.0 - sdl3 >=3.2.22,<4.0a0 license: Zlib + purls: [] size: 572101 timestamp: 1757842925694 +- conda: https://conda.anaconda.org/conda-forge/linux-64/sdl3-3.4.10-hdeec2a5_0.conda + sha256: 04fa7dab2b8f688e3fc4b7ae4522fd3935fb0601e3329cda8b40d63c60d6cc05 + md5: 845c0b154836c034f361668bec2a4f20 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - xorg-libxcursor >=1.2.3,<2.0a0 + - libusb >=1.0.29,<2.0a0 + - libxkbcommon >=1.13.2,<2.0a0 + - xorg-libx11 >=1.8.13,<2.0a0 + - xorg-libxi >=1.8.3,<2.0a0 + - liburing >=2.14,<2.15.0a0 + - libunwind >=1.8.3,<1.9.0a0 + - xorg-libxtst >=1.2.5,<2.0a0 + - wayland >=1.25.0,<2.0a0 + - dbus >=1.16.2,<2.0a0 + - libgl >=1.7.0,<2.0a0 + - xorg-libxscrnsaver >=1.2.4,<2.0a0 + - xorg-libxext >=1.3.7,<2.0a0 + - libdrm >=2.4.127,<2.5.0a0 + - pulseaudio-client >=17.0,<17.1.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libegl >=1.7.0,<2.0a0 + - xorg-libxfixes >=6.0.2,<7.0a0 + - libudev1 >=257.13 + license: Zlib + purls: [] + size: 2148830 + timestamp: 1780262823658 - conda: https://conda.anaconda.org/conda-forge/linux-64/sdl3-3.4.2-hdeec2a5_0.conda sha256: 64b982664550e01c25f8f09333c0ee54d4764a80fe8636b8aaf881fe6e8a0dbe md5: 88a69db027a8ff59dab972a09d69a1ab @@ -12430,6 +15745,35 @@ packages: license: Zlib size: 2138749 timestamp: 1771668185803 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sdl3-3.4.10-had2c13b_0.conda + sha256: 8fe249e71c077a09f94f49256a8738a2ef22bb018f119194ece94361721dff65 + md5: 90e79fd7ec05af2fb5424cd84fd70d20 + depends: + - libstdcxx >=14 + - libgcc >=14 + - xorg-libxcursor >=1.2.3,<2.0a0 + - xorg-libxscrnsaver >=1.2.4,<2.0a0 + - pulseaudio-client >=17.0,<17.1.0a0 + - libusb >=1.0.29,<2.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + - libgl >=1.7.0,<2.0a0 + - libunwind >=1.8.3,<1.9.0a0 + - xorg-libxext >=1.3.7,<2.0a0 + - wayland >=1.25.0,<2.0a0 + - libdrm >=2.4.127,<2.5.0a0 + - libudev1 >=257.13 + - xorg-libxfixes >=6.0.2,<7.0a0 + - xorg-libxtst >=1.2.5,<2.0a0 + - libxkbcommon >=1.13.2,<2.0a0 + - libegl >=1.7.0,<2.0a0 + - liburing >=2.14,<2.15.0a0 + - xorg-libxi >=1.8.3,<2.0a0 + - xorg-libx11 >=1.8.13,<2.0a0 + - dbus >=1.16.2,<2.0a0 + license: Zlib + purls: [] + size: 2144308 + timestamp: 1780262838628 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sdl3-3.4.2-had2c13b_0.conda sha256: 17aad2e3439d6d778bf995134f37e442a8420adc740457f43d647d4dbf0b10fe md5: c667298eebd2296ace8cb07dbbba95c0 @@ -12458,6 +15802,19 @@ packages: license: Zlib size: 2136476 timestamp: 1771668207211 +- conda: https://conda.anaconda.org/conda-forge/win-64/sdl3-3.4.10-h5112557_0.conda + sha256: 0331417611907f1891c1c8b1c52fed48e337157a6e2d6a893ed352792f8f7ea0 + md5: 82adb3bed17cc9189d81ca90b41c77b9 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libusb >=1.0.29,<2.0a0 + - libvulkan-loader >=1.4.341.0,<2.0a0 + license: Zlib + purls: [] + size: 1677765 + timestamp: 1780262836463 - conda: https://conda.anaconda.org/conda-forge/win-64/sdl3-3.4.2-h5112557_0.conda sha256: a4677774a9d542c6f4bac8779a2d7105748d38d8b7d56c8d02f36d14fba471b9 md5: a0256884d35489e520360267e67ce3fc @@ -12492,6 +15849,20 @@ packages: license_family: Apache size: 113513 timestamp: 1770208767759 +- conda: https://conda.anaconda.org/conda-forge/linux-64/shaderc-2026.2-h718be3e_0.conda + sha256: c6e3280867e54c97996a4fedda0ab72c92d48d1d69258bddf910130df72c169d + md5: 6438976979721e2f60ec47327d8d38df + depends: + - __glibc >=2.17,<3.0.a0 + - glslang >=16,<17.0a0 + - libgcc >=14 + - libstdcxx >=14 + - spirv-tools >=2026,<2027.0a0 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 113684 + timestamp: 1777360595361 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/shaderc-2025.5-hfeb5c2c_1.conda sha256: bf3f47847832e33acbcb7a1aba948f3b574979ad2a91f2ebdc9fc685c09433db md5: 8268bdcd82d8f9abcb7f0fd6a9568ba4 @@ -12504,6 +15875,19 @@ packages: license_family: Apache size: 115498 timestamp: 1770208786806 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/shaderc-2026.2-hfeb5c2c_0.conda + sha256: 487c021f4f10ae963e9192c9bbc0d3bba8f11cb3a2bb91fd351e4ea3e1ebc109 + md5: 9a389f225e6d2a8cc1e425c128caffe8 + depends: + - glslang >=16,<17.0a0 + - libgcc >=14 + - libstdcxx >=14 + - spirv-tools >=2026,<2027.0a0 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 115991 + timestamp: 1777360628740 - conda: https://conda.anaconda.org/conda-forge/win-64/shaderc-2025.5-h8fa7867_1.conda sha256: b2f6e199df47ca314294ad393818d6b499fd544703abcede0f19007b8f8f10e4 md5: 04d62bc008ee442843e2f24f603ea1a6 @@ -12517,6 +15901,20 @@ packages: license_family: Apache size: 1558909 timestamp: 1770208850155 +- conda: https://conda.anaconda.org/conda-forge/win-64/shaderc-2026.2-h8fa7867_0.conda + sha256: 3a4edc274c947d34258af01886d9ca301098fe037dacd91ccd5f5291dda5ca0b + md5: dd6d0d119b1ca747af3ba964eaa3c565 + depends: + - glslang >=16,<17.0a0 + - spirv-tools >=2026,<2027.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 1559352 + timestamp: 1777360694042 - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda sha256: 458227f759d5e3fcec5d9b7acce54e10c9e1f4f4b7ec978f3bfd54ce4ee9853d md5: 3339e3b65d58accf4ca4fb8748ab16b3 @@ -12560,6 +15958,7 @@ packages: - libgcc >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 45829 timestamp: 1762948049098 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/snappy-1.2.2-he774c54_1.conda @@ -12571,6 +15970,7 @@ packages: - libgcc >=14 license: BSD-3-Clause license_family: BSD + purls: [] size: 47096 timestamp: 1762948094646 - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda @@ -12800,6 +16200,20 @@ packages: license_family: APACHE size: 2296977 timestamp: 1770089626195 +- conda: https://conda.anaconda.org/conda-forge/linux-64/spirv-tools-2026.2-hb700be7_0.conda + sha256: 309d1a3317e91a03611bc960fc807cf2c0c5baacbfddea0f5636438a76c52256 + md5: 0c2b1d811632f1f4aa923450a002ff4f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + constrains: + - spirv-headers >=1.4.350.0,<1.4.350.1.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 2392190 + timestamp: 1780139567779 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spirv-tools-2026.1-hfefdfc9_0.conda sha256: 841a7df4b73a13a148410e677b1bf07ed81bd181cc686278d64d65e033f4a06a md5: ad8208c6618a543687d754dc57876091 @@ -12812,6 +16226,19 @@ packages: license_family: APACHE size: 2255599 timestamp: 1770089690097 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/spirv-tools-2026.2-hfefdfc9_0.conda + sha256: fcd1bb3c246ffc0beee0c66d1f240610288c81286041190b42402435408b5cc5 + md5: c82bb7d70fffe04afe74d55542af1d41 + depends: + - libgcc >=14 + - libstdcxx >=14 + constrains: + - spirv-headers >=1.4.350.0,<1.4.350.1.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 2290233 + timestamp: 1780139661664 - conda: https://conda.anaconda.org/conda-forge/win-64/spirv-tools-2026.1-h49e36cd_0.conda sha256: 9976eeaf650d43833c110447ba264a72f470928d8a8fa5d1cfbadcd2a276184c md5: bf5a4eb05c8b38dbc4e32ce17ab36389 @@ -12825,6 +16252,20 @@ packages: license_family: APACHE size: 13881533 timestamp: 1770089875437 +- conda: https://conda.anaconda.org/conda-forge/win-64/spirv-tools-2026.2-h49e36cd_0.conda + sha256: 256818df74531014639af4cd0791a2a2d238bef74b593db92baeb3c881d89ef2 + md5: 64190192873306d90833d53a820311b8 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - spirv-headers >=1.4.350.0,<1.4.350.1.0a0 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 14305012 + timestamp: 1780140089597 - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlalchemy-2.0.49-py314h0f05182_0.conda sha256: 85b8d29abab6896abc18956a6e6cff3cba939b63440039be8471f5ca51096686 md5: 40330dd2ec87f319b1c4dffe0db4f4e7 @@ -12896,6 +16337,7 @@ packages: - libstdcxx >=14 license: BSD-2-Clause license_family: BSD + purls: [] size: 2619743 timestamp: 1769664536467 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/svt-av1-4.0.1-hfae3067_0.conda @@ -12906,6 +16348,7 @@ packages: - libstdcxx >=14 license: BSD-2-Clause license_family: BSD + purls: [] size: 2042800 timestamp: 1769668627820 - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-4.0.1-hac47afa_0.conda @@ -12917,6 +16360,7 @@ packages: - vc14_runtime >=14.44.35208 license: BSD-2-Clause license_family: BSD + purls: [] size: 1808810 timestamp: 1769664619287 - conda: https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda @@ -12978,6 +16422,19 @@ packages: license_family: APACHE size: 181329 timestamp: 1767886632911 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-hab88423_2.conda + sha256: 30cb9355c2fefc20ff1a3d6566b9714d5614086a2524c07721fc344eb20515ae + md5: 7073b15f9364ebc118998601ac6ca6a6 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libhwloc >=2.13.0,<2.13.1.0a0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 182331 + timestamp: 1778673758649 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tbb-2022.3.0-hfefdfc9_2.conda sha256: 2e875ba342c2cde6301b088cd6471f67e44d961bd292abcdfa6ba3fc32506935 md5: 4d424acd246a5ba42512c097139ed0a0 @@ -12989,6 +16446,18 @@ packages: license_family: APACHE size: 144746 timestamp: 1767888618836 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tbb-2023.0.0-h57272ed_2.conda + sha256: 7ed4e93fad3707aa1686c5be286604c63aad33c9765a0d53fab7adbd179510b3 + md5: 0bc302bd45e5f744a672eb4f4a930398 + depends: + - libgcc >=14 + - libhwloc >=2.13.0,<2.13.1.0a0 + - libstdcxx >=14 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 145425 + timestamp: 1778675412470 - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-h3155e25_2.conda sha256: abd9a489f059fba85c8ffa1abdaa4d515d6de6a3325238b8e81203b913cf65a9 md5: 0f9817ffbe25f9e69ceba5ea70c52606 @@ -13002,6 +16471,19 @@ packages: purls: [] size: 155869 timestamp: 1767886839029 +- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2023.0.0-hd3d4ead_2.conda + sha256: 8a4053839b8e997a5965e2dff7d6cf3c77be62d82c0e48c8a04a5ed2d2e73035 + md5: 8ee01a693aecff5432069eaaf1183c45 + depends: + - libhwloc >=2.13.0,<2.13.1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + purls: [] + size: 156515 + timestamp: 1778673901757 - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac md5: cffd3bdd58090148f4cfcd831f4b26ab @@ -13241,6 +16723,18 @@ packages: purls: [] size: 19356 timestamp: 1767320221521 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-h1b7c187_39.conda + sha256: 17693b60cb54f80c60275f003f3bfc1b128af56dbfd65c4fae37c64eeb755ce1 + md5: 2eacea63f545b97342da520df6854276 + depends: + - vc14_runtime >=14.51.36231 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 20362 + timestamp: 1781320968457 - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 md5: 37eb311485d2d8b2c419449582046a42 @@ -13254,6 +16748,19 @@ packages: purls: [] size: 683233 timestamp: 1767320219644 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36231-h1b9f54f_39.conda + sha256: 8153ed849c92e891eacac0f2f8d7ecb79f9b5fd7f7917fbb896f252a60a40390 + md5: 06a5bf5a1ca16cce0df6eaa91fc42bc2 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.51.36231 h1b9f54f_39 + constrains: + - vs2015_runtime 14.51.36231.* *_39 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 737434 + timestamp: 1781320964561 - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 md5: 242d9f25d2ae60c76b38a5e42858e51d @@ -13266,6 +16773,18 @@ packages: purls: [] size: 115235 timestamp: 1767320173250 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36231-h1b9f54f_39.conda + sha256: 07fb14713c4bc62e2533a2e23a363abfb0e65650681fba0ae4c840e2219350f3 + md5: 8b53a83fda40ec679e4d63fa32fae989 + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.51.36231.* *_39 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + purls: [] + size: 120684 + timestamp: 1781320948530 - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.44.35208-h38c0c73_34.conda sha256: 63ff4ec6e5833f768d402f5e95e03497ce211ded5b6f492e660e2bfc726ad24d md5: f276d1de4553e8fca1dfb6988551ebb4 @@ -13275,6 +16794,16 @@ packages: license_family: BSD size: 19347 timestamp: 1767320221943 +- conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.51.36231-h84cd919_39.conda + sha256: 6de6c2cf008fc2dce61060b583f2d8494c83883106952b201381b6b0505f03d7 + md5: 2ccc63d7b7d066a814ed9f99072832d7 + depends: + - vc14_runtime >=14.51.36231 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 20355 + timestamp: 1781320968804 - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda sha256: 3aa04ae8e9521d9b56b562376d944c3e52b69f9d2a0667f77b8953464822e125 md5: 035da2e4f5770f036ff704fa17aace24 @@ -13288,6 +16817,20 @@ packages: license_family: MIT size: 329779 timestamp: 1761174273487 +- conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda + sha256: ea374d57a8fcda281a0a89af0ee49a2c2e99cc4ac97cf2e2db7064e74e764bdb + md5: 996583ea9c796e5b915f7d7580b51ea6 + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + purls: [] + size: 334139 + timestamp: 1773959575393 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.24.0-h4f8a99f_1.conda sha256: d94af8f287db764327ac7b48f6c0cd5c40da6ea2606afd34ac30671b7c85d8ee md5: f6966cb1f000c230359ae98c29e37d87 @@ -13300,6 +16843,19 @@ packages: license_family: MIT size: 331480 timestamp: 1761174368396 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.25.0-h4f8a99f_0.conda + sha256: 3cc479df517b0ce110835a1256f91ca568581cb6dfe1c53a0786f0a226039a45 + md5: 0a7a9548726f98d5869fd4c43e110f0f + depends: + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + purls: [] + size: 335260 + timestamp: 1773959583826 - conda: https://conda.anaconda.org/conda-forge/noarch/wayland-protocols-1.47-hd8ed1ab_0.conda sha256: 9ab2c12053ea8984228dd573114ffc6d63df42c501d59fda3bf3aeb1eaa1d23e md5: 7da1571f560d4ba3343f7f4c48a79c76 @@ -13307,6 +16863,14 @@ packages: license_family: MIT size: 140476 timestamp: 1765821981856 +- conda: https://conda.anaconda.org/conda-forge/noarch/wayland-protocols-1.49-hd8ed1ab_0.conda + sha256: 04ce686cd187d379344f9b2be7b4da5f431b265dc0944a6b764fab9da9171948 + md5: 0839a3421140d4a9ba93fb988698fc00 + license: MIT + license_family: MIT + purls: [] + size: 147954 + timestamp: 1780946721169 - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.6.0-pyhd8ed1ab_0.conda sha256: e298b508b2473c4227206800dfb14c39e4b14fd79d4636132e9e1e4244cdf4aa md5: c3197f8c0d5b955c904616b716aca093 @@ -13347,6 +16911,7 @@ packages: - libgcc-ng >=12 license: GPL-2.0-or-later license_family: GPL + purls: [] size: 897548 timestamp: 1660323080555 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/x264-1!164.3095-h4e544f5_2.tar.bz2 @@ -13356,6 +16921,7 @@ packages: - libgcc-ng >=12 license: GPL-2.0-or-later license_family: GPL + purls: [] size: 1000661 timestamp: 1660324722559 - conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 @@ -13366,6 +16932,7 @@ packages: - vs2015_runtime >=14.16.27033 license: GPL-2.0-or-later license_family: GPL + purls: [] size: 1041889 timestamp: 1660323726084 - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 @@ -13376,6 +16943,7 @@ packages: - libstdcxx-ng >=10.3.0 license: GPL-2.0-or-later license_family: GPL + purls: [] size: 3357188 timestamp: 1646609687141 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/x265-3.5-hdd96247_3.tar.bz2 @@ -13386,6 +16954,7 @@ packages: - libstdcxx-ng >=10.3.0 license: GPL-2.0-or-later license_family: GPL + purls: [] size: 1018181 timestamp: 1646610147365 - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 @@ -13396,8 +16965,21 @@ packages: - vs2015_runtime >=14.16.27033 license: GPL-2.0-or-later license_family: GPL + purls: [] size: 5517425 timestamp: 1646611941216 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-h280c20c_1.conda + sha256: 2bd7452f68c39bfff954385b062aca9389262369e318739af270d23af47580a5 + md5: bb1e548a92b0efa12c3e2385ae2d4529 + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - xorg-libx11 >=1.8.13,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 440702 + timestamp: 1781482698093 - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda sha256: 19c2bb14bec84b0e995b56b752369775c75f1589314b43733948bb5f471a6915 md5: b56e0c8432b56decafae7e78c5f29ba5 @@ -13409,6 +16991,17 @@ packages: license_family: MIT size: 399291 timestamp: 1772021302485 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.47-h80f16a2_1.conda + sha256: 70070c1bd0c8f6af2640fa6302c06c29ad5740c80e290a6b287c8a6498290207 + md5: 81ae02fc22dcd8d56dc197851c95e2f8 + depends: + - libgcc >=14 + - xorg-libx11 >=1.8.13,<2.0a0 + license: MIT + license_family: MIT + purls: [] + size: 441739 + timestamp: 1781482715632 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.47-he30d5cf_0.conda sha256: ec7ff9dffbd41faa31a30fa0724699f05bca000d57c745a195ecdb56888a8605 md5: 4ac707a4279972357712af099cd1ae50 @@ -13427,6 +17020,7 @@ packages: - libgcc >=13 license: MIT license_family: MIT + purls: [] size: 58628 timestamp: 1734227592886 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda @@ -13436,6 +17030,7 @@ packages: - libgcc >=13 license: MIT license_family: MIT + purls: [] size: 60433 timestamp: 1734229908988 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda @@ -13448,6 +17043,7 @@ packages: - xorg-libice >=1.1.2,<2.0a0 license: MIT license_family: MIT + purls: [] size: 27590 timestamp: 1741896361728 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda @@ -13459,6 +17055,7 @@ packages: - xorg-libice >=1.1.2,<2.0a0 license: MIT license_family: MIT + purls: [] size: 28701 timestamp: 1741897678254 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda @@ -13470,6 +17067,7 @@ packages: - libxcb >=1.17.0,<2.0a0 license: MIT license_family: MIT + purls: [] size: 839652 timestamp: 1770819209719 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12_0.conda @@ -13480,6 +17078,7 @@ packages: - libxcb >=1.17.0,<2.0a0 license: MIT license_family: MIT + purls: [] size: 869058 timestamp: 1770819244991 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda @@ -13490,6 +17089,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 15321 timestamp: 1762976464266 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda @@ -13499,6 +17099,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 16317 timestamp: 1762977521691 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda @@ -13512,6 +17113,7 @@ packages: - xorg-libxrender >=0.9.11,<0.10.0a0 license: MIT license_family: MIT + purls: [] size: 32533 timestamp: 1730908305254 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcursor-1.2.3-h86ecc28_0.conda @@ -13524,6 +17126,7 @@ packages: - xorg-libxrender >=0.9.11,<0.10.0a0 license: MIT license_family: MIT + purls: [] size: 34596 timestamp: 1730908388714 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda @@ -13534,6 +17137,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 20591 timestamp: 1762976546182 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda @@ -13543,6 +17147,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 21039 timestamp: 1762979038025 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda @@ -13554,6 +17159,7 @@ packages: - xorg-libx11 >=1.8.12,<2.0a0 license: MIT license_family: MIT + purls: [] size: 50326 timestamp: 1769445253162 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda @@ -13564,6 +17170,7 @@ packages: - xorg-libx11 >=1.8.12,<2.0a0 license: MIT license_family: MIT + purls: [] size: 52409 timestamp: 1769446753771 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda @@ -13575,6 +17182,7 @@ packages: - xorg-libx11 >=1.8.12,<2.0a0 license: MIT license_family: MIT + purls: [] size: 20071 timestamp: 1759282564045 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda @@ -13585,6 +17193,7 @@ packages: - xorg-libx11 >=1.8.12,<2.0a0 license: MIT license_family: MIT + purls: [] size: 20704 timestamp: 1759284028146 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda @@ -13600,6 +17209,20 @@ packages: license_family: MIT size: 47179 timestamp: 1727799254088 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.3-hb03c661_0.conda + sha256: 495f99c8eacfa4ae2d8fed2a7f2105777af89acdc204df145d2bbbc380ac631b + md5: adba2e334082bb218db806d4c12277c9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.13,<2.0a0 + - xorg-libxext >=1.3.7,<2.0a0 + - xorg-libxfixes >=6.0.2,<7.0a0 + license: MIT + license_family: MIT + purls: [] + size: 47717 + timestamp: 1779111857071 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda sha256: 7b587407ecb9ccd2bbaf0fb94c5dbdde4d015346df063e9502dc0ce2b682fb5e md5: eeee3bdb31c6acde2b81ad1b8c287087 @@ -13612,6 +17235,19 @@ packages: license_family: MIT size: 48197 timestamp: 1727801059062 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.3-he30d5cf_0.conda + sha256: 0c1c7b39763469cfe0e9c6d0f9a39415321f477710719f4c5d63c61ea270271c + md5: f8ad5777ecc217d383a722598dbeb1ac + depends: + - libgcc >=14 + - xorg-libx11 >=1.8.13,<2.0a0 + - xorg-libxext >=1.3.7,<2.0a0 + - xorg-libxfixes >=6.0.2,<7.0a0 + license: MIT + license_family: MIT + purls: [] + size: 49292 + timestamp: 1779113229775 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda sha256: 80ed047a5cb30632c3dc5804c7716131d767089f65877813d4ae855ee5c9d343 md5: e192019153591938acf7322b6459d36e @@ -13623,6 +17259,7 @@ packages: - xorg-libxrender >=0.9.12,<0.10.0a0 license: MIT license_family: MIT + purls: [] size: 30456 timestamp: 1769445263457 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda @@ -13635,6 +17272,7 @@ packages: - xorg-libxrender >=0.9.12,<0.10.0a0 license: MIT license_family: MIT + purls: [] size: 31122 timestamp: 1769445286951 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda @@ -13646,6 +17284,7 @@ packages: - xorg-libx11 >=1.8.10,<2.0a0 license: MIT license_family: MIT + purls: [] size: 33005 timestamp: 1734229037766 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda @@ -13656,6 +17295,7 @@ packages: - xorg-libx11 >=1.8.10,<2.0a0 license: MIT license_family: MIT + purls: [] size: 33649 timestamp: 1734229123157 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxscrnsaver-1.2.4-hb9d3cd8_0.conda @@ -13668,6 +17308,7 @@ packages: - xorg-libxext >=1.3.6,<2.0a0 license: MIT license_family: MIT + purls: [] size: 14412 timestamp: 1727899730073 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxscrnsaver-1.2.4-h86ecc28_0.conda @@ -13679,6 +17320,7 @@ packages: - xorg-libxext >=1.3.6,<2.0a0 license: MIT license_family: MIT + purls: [] size: 15720 timestamp: 1750007336692 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda @@ -13692,6 +17334,7 @@ packages: - xorg-libxi >=1.7.10,<2.0a0 license: MIT license_family: MIT + purls: [] size: 32808 timestamp: 1727964811275 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda @@ -13704,6 +17347,7 @@ packages: - xorg-libxi >=1.7.10,<2.0a0 license: MIT license_family: MIT + purls: [] size: 33786 timestamp: 1727964907993 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2025.1-hb03c661_0.conda @@ -13714,6 +17358,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 570010 timestamp: 1766154256151 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-xorgproto-2025.1-he30d5cf_0.conda @@ -13723,6 +17368,7 @@ packages: - libgcc >=14 license: MIT license_family: MIT + purls: [] size: 569539 timestamp: 1766155414260 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda @@ -13814,6 +17460,19 @@ packages: - pkg:pypi/zipp?source=hash-mapping size: 24194 timestamp: 1764460141901 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_2.conda + sha256: ef408f85f664a4b9c9dac3cb2e36154d9baa15a88984ea800e11060e0f2394a1 + md5: 5187ecf958be3c39110fe691cbd6873e + depends: + - libzlib 1.3.2 hfd05255_2 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Zlib + license_family: Other + purls: [] + size: 850351 + timestamp: 1774072891049 - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 diff --git a/cuda_core/pixi.toml b/cuda_core/pixi.toml index d2e72807af7..4482db52db2 100644 --- a/cuda_core/pixi.toml +++ b/cuda_core/pixi.toml @@ -114,6 +114,31 @@ nvidia-sphinx-theme = "*" [feature.docs.target.linux.dependencies] make = "*" +# Dedicated environment for the MLIR numba-cuda example +# (examples/gl_interop_fluid_numba_cuda_mlir.py). numba-cuda-mlir pulls +# *published* cuda-core / cuda-bindings through its pypi closure, which would +# shadow (overwrite in site-packages) the editable dev path builds used +# everywhere else -- so it MUST live in its own environment, isolated from the +# local-deps path packages. The [cu13] extra makes it self-contained: nvvm, +# cudart, and nvrtc come from the nvidia pypi wheels, so no conda CUDA toolkit +# or CUDA_HOME wiring is needed. Linux-only: upstream ships manylinux wheels +# (cp311-cp314, x86_64 + aarch64) and no win-64 wheel. +[feature.numba-mlir.dependencies] +numpy = "*" +pyglet = "*" + +[feature.numba-mlir.system-requirements] +cuda = "13" + +[feature.numba-mlir.target.linux.dependencies] +libgl-devel = "*" + +[feature.numba-mlir.target.linux-64.pypi-dependencies] +numba-cuda-mlir = { version = "*", extras = ["cu13"] } + +[feature.numba-mlir.target.linux-aarch64.pypi-dependencies] +numba-cuda-mlir = { version = "*", extras = ["cu13"] } + # We keep both cu12 and cu13 because cuda.core works with either major version. # The local sibling checkouts are wired into the default/cu13/examples workflows; # cu12 intentionally solves against published packages instead. @@ -127,6 +152,9 @@ cu13 = { features = ["cu13", "test", "cython-tests", "local-deps"], solve-group cu12 = { features = ["cu12", "test", "cython-tests"], solve-group = "cu12" } examples = { features = ["cu13", "examples", "local-deps"], solve-group = "examples" } docs = { features = ["cu13", "docs", "local-deps"], solve-group = "docs" } +# Isolated: uses published cuda-core via numba-cuda-mlir's pypi closure, NOT the +# local-deps path builds (which it would otherwise shadow). +numba-mlir = { features = ["numba-mlir"] } # TODO: check if these can be extracted from pyproject.toml [package] diff --git a/cuda_core/tests/example_tests/test_basic_examples.py b/cuda_core/tests/example_tests/test_basic_examples.py index 43fab4241db..a826968a081 100644 --- a/cuda_core/tests/example_tests/test_basic_examples.py +++ b/cuda_core/tests/example_tests/test_basic_examples.py @@ -83,6 +83,8 @@ def has_recent_memory_pool_support() -> bool: SYSTEM_REQUIREMENTS = { "memory_pool_resources.py": has_recent_memory_pool_support, "gl_interop_plasma.py": has_display, + "gl_interop_fluid.py": has_display, + "gl_interop_mipmap_lod.py": has_display, "jit_lto_fractal.py": _can_load_generated_ptx, "pytorch_example.py": lambda: ( has_compute_capability_9_or_higher() and is_x86_64() diff --git a/cuda_core/tests/test_texture_surface.py b/cuda_core/tests/test_texture_surface.py new file mode 100644 index 00000000000..b0388bc92a0 --- /dev/null +++ b/cuda_core/tests/test_texture_surface.py @@ -0,0 +1,971 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +import gc + +import pytest + +import cuda.core +from cuda.core import ( + Device, +) +from cuda.core.textures import ( + AddressMode, + ArrayFormat, + CUDAArray, + FilterMode, + MipmappedArray, + ReadMode, + ResourceDescriptor, + SurfaceObject, + TextureDescriptor, + TextureObject, +) + + +def test_array_init_disabled(): + with pytest.raises(RuntimeError, match=r"^CUDAArray cannot be instantiated directly"): + cuda.core._array.CUDAArray() + + +def test_texture_object_init_disabled(): + with pytest.raises(RuntimeError, match=r"^TextureObject cannot be instantiated directly"): + cuda.core._texture.TextureObject() + + +def test_surface_object_init_disabled(): + with pytest.raises(RuntimeError, match=r"^SurfaceObject cannot be instantiated directly"): + cuda.core._surface.SurfaceObject() + + +def test_resource_descriptor_init_disabled(): + with pytest.raises(RuntimeError, match=r"^ResourceDescriptor cannot be instantiated"): + ResourceDescriptor() + + +def test_array_2d_create_and_properties(init_cuda): + arr = CUDAArray.from_descriptor(shape=(32, 16), format=ArrayFormat.FLOAT32, num_channels=1) + try: + assert arr.shape == (32, 16) + assert arr.format == ArrayFormat.FLOAT32 + assert arr.num_channels == 1 + assert arr.element_size == 4 + assert arr.size_bytes == 32 * 16 * 4 + assert arr.is_surface_load_store is False + assert arr.handle != 0 + assert isinstance(arr.device, Device) + finally: + arr.close() + + +def test_array_3d_with_surface_flag(init_cuda): + arr = CUDAArray.from_descriptor( + shape=(8, 8, 4), + format=ArrayFormat.UINT8, + num_channels=4, + is_surface_load_store=True, + ) + try: + assert arr.shape == (8, 8, 4) + assert arr.is_surface_load_store is True + assert arr.element_size == 4 + finally: + arr.close() + + +def test_array_rejects_bad_channels(init_cuda): + with pytest.raises(ValueError, match="num_channels"): + CUDAArray.from_descriptor(shape=(8,), format=ArrayFormat.UINT8, num_channels=3) + + +def test_array_rejects_bad_rank(init_cuda): + with pytest.raises(ValueError, match="shape rank"): + CUDAArray.from_descriptor(shape=(2, 2, 2, 2), format=ArrayFormat.UINT8, num_channels=1) + + +def test_array_roundtrip_copy(init_cuda): + import array as _array + + device = Device() + stream = device.create_stream() + arr = CUDAArray.from_descriptor(shape=(16,), format=ArrayFormat.UINT32, num_channels=1) + try: + src = _array.array("I", list(range(16))) + dst = _array.array("I", [0] * 16) + arr.copy_from(src, stream=stream) + arr.copy_to(dst, stream=stream) + stream.sync() + # Round-trip recovers data; src must not be mutated by copy_from. + assert list(dst) == list(range(16)) + assert list(src) == list(range(16)) + finally: + arr.close() + stream.close() + + +def test_array_copy_rejects_undersized_host_buffer(init_cuda): + import array as _array + + device = Device() + stream = device.create_stream() + arr = CUDAArray.from_descriptor(shape=(16,), format=ArrayFormat.UINT32, num_channels=1) + try: + # arr is 16 * 4 = 64 bytes; pass an 8-element (32-byte) host buffer. + too_small = _array.array("I", [0] * 8) + with pytest.raises(ValueError, match="smaller than the array extent"): + arr.copy_from(too_small, stream=stream) + with pytest.raises(ValueError, match="smaller than the array extent"): + arr.copy_to(too_small, stream=stream) + finally: + arr.close() + stream.close() + + +def test_array_copy_rejects_undersized_device_buffer(init_cuda): + device = Device() + stream = device.create_stream() + arr = CUDAArray.from_descriptor(shape=(16,), format=ArrayFormat.UINT32, num_channels=1) + # arr is 64 bytes; allocate a 32-byte device buffer. + small_buf = device.memory_resource.allocate(32, stream=device.default_stream) + try: + with pytest.raises(ValueError, match="smaller than the array extent"): + arr.copy_from(small_buf, stream=stream) + with pytest.raises(ValueError, match="smaller than the array extent"): + arr.copy_to(small_buf, stream=stream) + finally: + small_buf.close() + arr.close() + stream.close() + + +def test_texture_object_create(init_cuda): + arr = CUDAArray.from_descriptor(shape=(32, 16), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + tex_desc = TextureDescriptor( + address_mode=AddressMode.CLAMP, + filter_mode=FilterMode.LINEAR, + read_mode=ReadMode.ELEMENT_TYPE, + normalized_coords=True, + ) + tex = TextureObject.from_descriptor(resource=res, texture_descriptor=tex_desc) + try: + assert tex.handle != 0 + assert tex.resource is res + assert tex.texture_descriptor is tex_desc + finally: + tex.close() + finally: + arr.close() + + +def test_surface_object_create(init_cuda): + arr = CUDAArray.from_descriptor( + shape=(8, 8), + format=ArrayFormat.UINT8, + num_channels=4, + is_surface_load_store=True, + ) + try: + surf = SurfaceObject.from_array(arr) + try: + assert surf.handle != 0 + assert isinstance(surf.resource, ResourceDescriptor) + finally: + surf.close() + finally: + arr.close() + + +def test_surface_requires_ldst_flag(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.UINT8, num_channels=4) + try: + with pytest.raises(ValueError, match="is_surface_load_store=True"): + SurfaceObject.from_array(arr) + finally: + arr.close() + + +def test_address_mode_normalization(init_cuda): + # Direct unit test of the private normalizer: a scalar should expand to a + # 3-tuple; a shorter tuple should be padded by repeating the last entry. + from cuda.core._texture import _normalize_address_modes + + assert _normalize_address_modes(AddressMode.WRAP) == ( + AddressMode.WRAP, + AddressMode.WRAP, + AddressMode.WRAP, + ) + assert _normalize_address_modes((AddressMode.WRAP, AddressMode.CLAMP)) == ( + AddressMode.WRAP, + AddressMode.CLAMP, + AddressMode.CLAMP, + ) + assert _normalize_address_modes((AddressMode.WRAP, AddressMode.CLAMP, AddressMode.MIRROR)) == ( + AddressMode.WRAP, + AddressMode.CLAMP, + AddressMode.MIRROR, + ) + + # Smoke test: a 2-entry tuple is also accepted end-to-end. + arr = CUDAArray.from_descriptor(shape=(8, 8, 4), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + tex_desc = TextureDescriptor(address_mode=(AddressMode.WRAP, AddressMode.CLAMP)) + tex = TextureObject.from_descriptor(resource=res, texture_descriptor=tex_desc) + try: + assert tex.handle != 0 + finally: + tex.close() + finally: + arr.close() + + +# --- Linear / pitch2D resource descriptors ----------------------------------- + + +def _alloc_device_buffer(device, nbytes): + """Allocate a device Buffer using the device's default memory resource.""" + return device.memory_resource.allocate(nbytes, stream=device.default_stream) + + +def test_resource_descriptor_from_linear_defaults_size(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 4096) + try: + res = ResourceDescriptor.from_linear(buf, format=ArrayFormat.FLOAT32, num_channels=1) + assert res.kind == "linear" + assert res.format == ArrayFormat.FLOAT32 + assert res.num_channels == 1 + assert res.source is buf + # repr should include the kind/format hint + assert "linear" in repr(res) + finally: + buf.close() + + +def test_resource_descriptor_from_linear_size_override(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 4096) + try: + res = ResourceDescriptor.from_linear(buf, format=ArrayFormat.UINT32, num_channels=1, size_bytes=2048) + assert res._size_bytes == 2048 + finally: + buf.close() + + +def test_resource_descriptor_from_linear_rejects_oversize(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 1024) + try: + with pytest.raises(ValueError, match="exceeds buffer.size"): + ResourceDescriptor.from_linear(buf, format=ArrayFormat.UINT8, num_channels=1, size_bytes=2048) + finally: + buf.close() + + +def test_resource_descriptor_from_linear_rejects_bad_channels(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 1024) + try: + with pytest.raises(ValueError, match="num_channels"): + ResourceDescriptor.from_linear(buf, format=ArrayFormat.UINT8, num_channels=3) + finally: + buf.close() + + +def test_resource_descriptor_from_linear_rejects_non_buffer(): + with pytest.raises(TypeError, match="Buffer"): + ResourceDescriptor.from_linear(object(), format=ArrayFormat.UINT8, num_channels=1) + + +def test_resource_descriptor_from_linear_rejects_zero_size(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 1024) + try: + with pytest.raises(ValueError, match="at least one element"): + ResourceDescriptor.from_linear(buf, format=ArrayFormat.UINT32, num_channels=1, size_bytes=0) + finally: + buf.close() + + +def test_resource_descriptor_from_linear_rejects_non_multiple(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 1024) + try: + # UINT32 x 1 channel = 4 bytes/element; 10 bytes is not a multiple. + with pytest.raises(ValueError, match="multiple of element size"): + ResourceDescriptor.from_linear(buf, format=ArrayFormat.UINT32, num_channels=1, size_bytes=10) + finally: + buf.close() + + +def test_texture_object_from_linear(init_cuda): + """A linear-backed texture should bind even though sampling fields are + effectively ignored by the driver.""" + device = Device() + # 1024 float elements + buf = _alloc_device_buffer(device, 1024 * 4) + try: + res = ResourceDescriptor.from_linear(buf, format=ArrayFormat.FLOAT32, num_channels=1) + tex = TextureObject.from_descriptor(resource=res, texture_descriptor=TextureDescriptor()) + try: + assert tex.handle != 0 + assert tex.resource is res + finally: + tex.close() + finally: + buf.close() + + +def test_resource_descriptor_from_pitch2d_validates_pitch(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 64 * 1024) + try: + # element_size = 4 (UINT32 * 1 channel); width=16 -> min_pitch=64 + with pytest.raises(ValueError, match="pitch_bytes"): + ResourceDescriptor.from_pitch2d( + buf, + format=ArrayFormat.UINT32, + num_channels=1, + width=16, + height=8, + pitch_bytes=32, # < 64 = width*element_size + ) + finally: + buf.close() + + +def test_resource_descriptor_from_pitch2d_validates_buffer_size(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 4096) + try: + with pytest.raises(ValueError, match="exceeds buffer.size"): + ResourceDescriptor.from_pitch2d( + buf, + format=ArrayFormat.UINT8, + num_channels=4, + width=64, + height=128, + pitch_bytes=512, # 512 * 128 = 65536 > 4096 + ) + finally: + buf.close() + + +def test_texture_object_from_pitch2d(init_cuda): + """A pitch2D-backed texture should bind given driver-aligned pitch.""" + from cuda.bindings import driver + + device = Device() + # Query the device's required texture pitch alignment (typically 32-512). + err, align = driver.cuDeviceGetAttribute( + driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT, + device.device_id, + ) + assert int(err) == 0 + pitch = max(int(align), 256) + height = 16 + buf = _alloc_device_buffer(device, pitch * height) + try: + res = ResourceDescriptor.from_pitch2d( + buf, + format=ArrayFormat.UINT8, + num_channels=4, + width=32, + height=height, + pitch_bytes=pitch, + ) + assert res.kind == "pitch2d" + assert "pitch2d" in repr(res) + tex = TextureObject.from_descriptor(resource=res, texture_descriptor=TextureDescriptor()) + try: + assert tex.handle != 0 + finally: + tex.close() + finally: + buf.close() + + +def test_surface_rejects_linear_and_pitch2d(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 4096) + try: + res_lin = ResourceDescriptor.from_linear(buf, format=ArrayFormat.UINT32, num_channels=1) + with pytest.raises(ValueError, match="array-backed"): + SurfaceObject.from_descriptor(resource=res_lin) + + res_p2 = ResourceDescriptor.from_pitch2d( + buf, + format=ArrayFormat.UINT8, + num_channels=4, + width=8, + height=8, + pitch_bytes=64, + ) + with pytest.raises(ValueError, match="array-backed"): + SurfaceObject.from_descriptor(resource=res_p2) + finally: + buf.close() + + +# --- MipmappedArray ---------------------------------------------------------- + + +def test_mipmapped_array_init_disabled(): + with pytest.raises(RuntimeError, match=r"^MipmappedArray cannot be instantiated directly"): + cuda.core._mipmapped_array.MipmappedArray() + + +def test_mipmapped_array_from_descriptor_2d(init_cuda): + mip = MipmappedArray.from_descriptor( + shape=(64, 32), + format=ArrayFormat.FLOAT32, + num_channels=1, + num_levels=4, + ) + try: + assert mip.shape == (64, 32) + assert mip.format == ArrayFormat.FLOAT32 + assert mip.num_channels == 1 + assert mip.num_levels == 4 + assert mip.is_surface_load_store is False + assert mip.handle != 0 + assert isinstance(mip.device, Device) + finally: + mip.close() + + +def test_mipmapped_array_get_level_zero_matches_shape(init_cuda): + shape = (64, 32) + mip = MipmappedArray.from_descriptor( + shape=shape, + format=ArrayFormat.UINT8, + num_channels=4, + num_levels=4, + ) + try: + lvl0 = mip.get_level(0) + try: + assert isinstance(lvl0, CUDAArray) + # Level 0 must match the base shape and rank. + assert lvl0.shape == shape + assert lvl0.format == ArrayFormat.UINT8 + assert lvl0.num_channels == 4 + assert lvl0.handle != 0 + finally: + lvl0.close() + finally: + mip.close() + + +def test_mipmapped_array_get_level_halves_dims(init_cuda): + shape = (64, 32) + num_levels = 4 + mip = MipmappedArray.from_descriptor( + shape=shape, + format=ArrayFormat.UINT8, + num_channels=1, + num_levels=num_levels, + ) + try: + for level in range(num_levels): + lvl = mip.get_level(level) + try: + # Each dim halves per level, with a floor of 1; rank is preserved. + expected = tuple(max(1, dim >> level) for dim in shape) + assert lvl.shape == expected, f"level={level}: expected {expected}, got {lvl.shape}" + finally: + lvl.close() + finally: + mip.close() + + +def test_mipmapped_array_get_level_out_of_range(init_cuda): + mip = MipmappedArray.from_descriptor( + shape=(16, 16), + format=ArrayFormat.UINT8, + num_channels=1, + num_levels=2, + ) + try: + with pytest.raises(ValueError, match="num_levels"): + mip.get_level(mip.num_levels) + with pytest.raises(ValueError, match=">= 0"): + mip.get_level(-1) + finally: + mip.close() + + +def test_mipmapped_array_rejects_zero_levels(init_cuda): + with pytest.raises(ValueError, match="num_levels"): + MipmappedArray.from_descriptor( + shape=(8, 8), + format=ArrayFormat.UINT8, + num_channels=1, + num_levels=0, + ) + + +def test_resource_descriptor_from_mipmapped_array(init_cuda): + mip = MipmappedArray.from_descriptor( + shape=(32, 16), + format=ArrayFormat.FLOAT32, + num_channels=1, + num_levels=3, + ) + try: + res = ResourceDescriptor.from_mipmapped_array(mip) + assert res.kind == "mipmapped_array" + assert res.source is mip + finally: + mip.close() + + +def test_resource_descriptor_from_mipmapped_array_rejects_non_mipmap(): + with pytest.raises(TypeError, match="MipmappedArray"): + ResourceDescriptor.from_mipmapped_array(object()) + + +def test_texture_object_from_mipmapped_array(init_cuda): + mip = MipmappedArray.from_descriptor( + shape=(32, 32), + format=ArrayFormat.FLOAT32, + num_channels=1, + num_levels=3, + ) + try: + res = ResourceDescriptor.from_mipmapped_array(mip) + # Use non-default mipmap params so the driver exercises that path. + tex_desc = TextureDescriptor( + address_mode=AddressMode.CLAMP, + filter_mode=FilterMode.LINEAR, + normalized_coords=True, + mipmap_filter_mode=FilterMode.LINEAR, + mipmap_level_bias=0.0, + min_mipmap_level_clamp=0.0, + max_mipmap_level_clamp=float(mip.num_levels - 1), + ) + tex = TextureObject.from_descriptor(resource=res, texture_descriptor=tex_desc) + try: + assert tex.handle != 0 + assert tex.resource is res + finally: + tex.close() + finally: + mip.close() + + +def test_surface_rejects_mipmapped_array(init_cuda): + mip = MipmappedArray.from_descriptor( + shape=(16, 16), + format=ArrayFormat.UINT8, + num_channels=4, + num_levels=2, + is_surface_load_store=True, + ) + try: + res = ResourceDescriptor.from_mipmapped_array(mip) + with pytest.raises(ValueError, match="array-backed"): + SurfaceObject.from_descriptor(resource=res) + finally: + mip.close() + + +def test_mipmapped_array_level_outlives_dropped_parent(init_cuda): + """A level CUDAArray must keep the parent mipmap's storage alive structurally + (via the C++ handle box), so the level stays usable after the Python parent + is dropped and garbage-collected. + + The level holds no Python reference to the parent (no ``_parent_ref``); the + only thing keeping the underlying ``CUmipmappedArray`` alive after ``del mip`` + is the parent handle embedded in the level's box. A full round-trip copy on + the level touches that live storage and would fail with an invalid-handle + error if the parent had been destroyed. + """ + import array as _array + + device = Device() + stream = device.create_stream() + mip = MipmappedArray.from_descriptor( + shape=(16, 16), + format=ArrayFormat.UINT32, + num_channels=1, + num_levels=3, + ) + lvl = mip.get_level(1) # (8, 8) + # Drop the only Python reference to the parent and force GC. + del mip + gc.collect() + try: + assert lvl.handle != 0 + n = lvl.shape[0] * (lvl.shape[1] if len(lvl.shape) > 1 else 1) + src = _array.array("I", list(range(n))) + dst = _array.array("I", [0] * n) + lvl.copy_from(src, stream=stream) + lvl.copy_to(dst, stream=stream) + stream.sync() + assert list(dst) == list(range(n)) + finally: + lvl.close() + stream.close() + + +def test_texture_surface_close_is_idempotent(init_cuda): + """close() drops this object's handle reference; destruction happens once via + the handle deleter. A second close() (and the later __dealloc__) must be a + safe no-op, and handle must read back as 0.""" + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.UINT8, num_channels=1) + arr.close() + assert arr.handle == 0 + arr.close() # second close must not raise + + mip = MipmappedArray.from_descriptor(shape=(8, 8), format=ArrayFormat.UINT8, num_channels=1, num_levels=2) + mip.close() + assert mip.handle == 0 + mip.close() + + surf_arr = CUDAArray.from_descriptor( + shape=(8, 8), format=ArrayFormat.UINT8, num_channels=4, is_surface_load_store=True + ) + surf = SurfaceObject.from_array(surf_arr) + surf.close() + assert surf.handle == 0 + surf.close() + surf_arr.close() + + tex_arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + tex = TextureObject.from_descriptor( + resource=ResourceDescriptor.from_array(tex_arr), + texture_descriptor=TextureDescriptor(), + ) + tex.close() + assert tex.handle == 0 + tex.close() + tex_arr.close() + + +# --- Negative-path validation tests ------------------------------------------ + + +def test_array_from_descriptor_rejects_bad_format(init_cuda): + with pytest.raises(TypeError, match="format must be an ArrayFormat"): + CUDAArray.from_descriptor(shape=(8,), format=0, num_channels=1) + + +def test_array_from_descriptor_rejects_non_iterable_shape(init_cuda): + with pytest.raises(TypeError, match="shape must be a tuple"): + CUDAArray.from_descriptor(shape=8, format=ArrayFormat.UINT8, num_channels=1) + + +def test_array_from_descriptor_rejects_zero_dim(init_cuda): + with pytest.raises(ValueError, match=r"shape\[1\] must be >= 1"): + CUDAArray.from_descriptor(shape=(8, 0), format=ArrayFormat.UINT8, num_channels=1) + + +def test_array_copy_rejects_non_stream(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8,), format=ArrayFormat.UINT8, num_channels=1) + try: + import array as _array + + buf = _array.array("B", [0] * 8) + with pytest.raises(TypeError, match="Stream or GraphBuilder expected"): + arr.copy_from(buf, stream="not-a-stream") + with pytest.raises(TypeError, match="Stream or GraphBuilder expected"): + arr.copy_to(buf, stream="not-a-stream") + finally: + arr.close() + + +def test_array_copy_to_returns_dst(init_cuda): + """CUDAArray.copy_to returns the destination, for parity with Buffer.copy_to.""" + import array as _array + + device = Device() + stream = device.create_stream() + arr = CUDAArray.from_descriptor(shape=(16,), format=ArrayFormat.UINT32, num_channels=1) + try: + dst = _array.array("I", [0] * 16) + returned = arr.copy_to(dst, stream=stream) + stream.sync() + assert returned is dst + finally: + arr.close() + stream.close() + + +def test_array_copy_accepts_graph_builder(init_cuda): + """copy_from/copy_to accept a GraphBuilder so the array copy can be captured + into a CUDA graph (parity with Buffer, which accepts Stream | GraphBuilder).""" + device = Device() + stream = device.create_stream() + arr = CUDAArray.from_descriptor(shape=(16,), format=ArrayFormat.UINT32, num_channels=1) + buf_in = device.memory_resource.allocate(arr.size_bytes, stream=stream) + buf_out = device.memory_resource.allocate(arr.size_bytes, stream=stream) + stream.sync() + try: + gb = device.create_graph_builder().begin_building() + # These would raise TypeError before the Stream | GraphBuilder fix. + arr.copy_from(buf_in, stream=gb) + arr.copy_to(buf_out, stream=gb) + graph = gb.end_building().complete() + graph.launch(stream) + stream.sync() + finally: + buf_in.close() + buf_out.close() + arr.close() + stream.close() + + +def test_resource_descriptor_from_pitch2d_rejects_non_buffer(): + with pytest.raises(TypeError, match="buffer must be a Buffer"): + ResourceDescriptor.from_pitch2d( + object(), + format=ArrayFormat.UINT8, + num_channels=1, + width=8, + height=8, + pitch_bytes=64, + ) + + +def test_resource_descriptor_from_pitch2d_rejects_bad_format(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 4096) + try: + with pytest.raises(TypeError, match="format must be an ArrayFormat"): + ResourceDescriptor.from_pitch2d( + buf, + format=0, + num_channels=1, + width=8, + height=8, + pitch_bytes=64, + ) + finally: + buf.close() + + +def test_resource_descriptor_from_pitch2d_rejects_bad_channels(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 4096) + try: + with pytest.raises(ValueError, match="num_channels"): + ResourceDescriptor.from_pitch2d( + buf, + format=ArrayFormat.UINT8, + num_channels=3, + width=8, + height=8, + pitch_bytes=64, + ) + finally: + buf.close() + + +def test_resource_descriptor_from_pitch2d_rejects_zero_dims(init_cuda): + device = Device() + buf = _alloc_device_buffer(device, 4096) + try: + with pytest.raises(ValueError, match="width"): + ResourceDescriptor.from_pitch2d( + buf, + format=ArrayFormat.UINT8, + num_channels=1, + width=0, + height=8, + pitch_bytes=64, + ) + with pytest.raises(ValueError, match="height"): + ResourceDescriptor.from_pitch2d( + buf, + format=ArrayFormat.UINT8, + num_channels=1, + width=8, + height=0, + pitch_bytes=64, + ) + finally: + buf.close() + + +def test_mipmapped_array_rejects_bad_format(init_cuda): + with pytest.raises(TypeError, match="format must be an ArrayFormat"): + MipmappedArray.from_descriptor(shape=(8, 8), format=0, num_channels=1, num_levels=2) + + +def test_mipmapped_array_rejects_bad_channels(init_cuda): + with pytest.raises(ValueError, match="num_channels"): + MipmappedArray.from_descriptor(shape=(8, 8), format=ArrayFormat.UINT8, num_channels=3, num_levels=2) + + +def test_mipmapped_array_rejects_zero_dim(init_cuda): + with pytest.raises(ValueError, match=r"shape\[0\] must be >= 1"): + MipmappedArray.from_descriptor(shape=(0, 8), format=ArrayFormat.UINT8, num_channels=1, num_levels=1) + + +def test_texture_object_rejects_non_resource_descriptor(init_cuda): + with pytest.raises(TypeError, match="resource must be a ResourceDescriptor"): + TextureObject.from_descriptor(resource=object(), texture_descriptor=TextureDescriptor()) + + +def test_texture_object_rejects_non_texture_descriptor(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + with pytest.raises(TypeError, match="texture_descriptor must be a TextureDescriptor"): + TextureObject.from_descriptor(resource=res, texture_descriptor="nope") + finally: + arr.close() + + +def test_texture_object_rejects_bad_filter_mode(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(filter_mode=0) # int, not FilterMode + with pytest.raises(TypeError, match="filter_mode must be a FilterMode"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_texture_object_rejects_bad_read_mode(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(read_mode=0) # int, not ReadMode + with pytest.raises(TypeError, match="read_mode must be a ReadMode"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_texture_object_rejects_bad_mipmap_filter_mode(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(mipmap_filter_mode=0) # int, not FilterMode + with pytest.raises(TypeError, match="mipmap_filter_mode must be a FilterMode"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_texture_object_rejects_negative_anisotropy(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(max_anisotropy=-1) + with pytest.raises(ValueError, match="max_anisotropy"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_texture_object_rejects_bad_border_color_length(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(border_color=(0.0, 0.0)) # length 2, not 4 + with pytest.raises(ValueError, match="border_color must have 4"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_address_mode_rejects_non_addressmode_scalar(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(address_mode=42) # int, not AddressMode / iterable + with pytest.raises(TypeError, match="address_mode"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_address_mode_rejects_empty_tuple(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(address_mode=()) + with pytest.raises(ValueError, match="address_mode tuple must have 1-3"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_address_mode_rejects_too_long_tuple(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(address_mode=(AddressMode.WRAP, AddressMode.WRAP, AddressMode.WRAP, AddressMode.WRAP)) + with pytest.raises(ValueError, match="address_mode tuple must have 1-3"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_address_mode_rejects_non_addressmode_entry(init_cuda): + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + try: + res = ResourceDescriptor.from_array(arr) + td = TextureDescriptor(address_mode=(AddressMode.WRAP, "bad", AddressMode.CLAMP)) + with pytest.raises(TypeError, match=r"address_mode\[1\]"): + TextureObject.from_descriptor(resource=res, texture_descriptor=td) + finally: + arr.close() + + +def test_texture_object_keeps_backing_array_alive(init_cuda): + """Dropping the local references to the backing CUDAArray and the + ResourceDescriptor must NOT invalidate an existing TextureObject. The + TextureObject holds a strong ref through its _source_ref slot.""" + arr = CUDAArray.from_descriptor(shape=(8, 8), format=ArrayFormat.FLOAT32, num_channels=1) + res = ResourceDescriptor.from_array(arr) + tex = TextureObject.from_descriptor(resource=res, texture_descriptor=TextureDescriptor()) + # Verify the keepalive chain via gc referents: TextureObject -> _source_ref + # -> ResourceDescriptor -> _source -> CUDAArray. We can only walk one level + # at a time, so check tex's referents include the ResourceDescriptor. + arr_id = id(arr) + res_id = id(res) + del arr, res + gc.collect() + + referents = gc.get_referents(tex) + res_refs = [r for r in referents if id(r) == res_id] + assert len(res_refs) == 1, ( + f"TextureObject should still reference the ResourceDescriptor; got referents {referents!r}" + ) + res_back = res_refs[0] + arr_refs = [r for r in gc.get_referents(res_back) if id(r) == arr_id] + assert len(arr_refs) == 1, "ResourceDescriptor should still reference its CUDAArray" + + # tex.handle should still be valid (non-zero). + assert tex.handle != 0 + tex.close() + + +def test_surface_object_keeps_backing_array_alive(init_cuda): + arr = CUDAArray.from_descriptor( + shape=(8, 8), + format=ArrayFormat.UINT8, + num_channels=4, + is_surface_load_store=True, + ) + surf = SurfaceObject.from_array(arr) + arr_id = id(arr) + del arr + gc.collect() + + # The surface keeps the ResourceDescriptor alive, which keeps the CUDAArray + # alive. We verify the chain end-to-end the same way as the texture case. + referents = gc.get_referents(surf) + res_objs = [r for r in referents if isinstance(r, ResourceDescriptor)] + assert len(res_objs) == 1 + arr_refs = [r for r in gc.get_referents(res_objs[0]) if id(r) == arr_id] + assert len(arr_refs) == 1, "SurfaceObject should still reference its backing CUDAArray via the ResourceDescriptor" + assert surf.handle != 0 + surf.close()