# This file was generated by stubgen-pyx v0.2.6 from cuda_core/cuda/core/_event.pyx

from __future__ import annotations

from dataclasses import dataclass

import cuda.bindings.driver
import cython
from cuda.core._context import Context
from cuda.core._device import Device


@dataclass
class EventOptions:
    """Customizable :obj:`~_event.Event` options.

    Attributes
    ----------
    timing_enabled : bool, optional
        Event will record timing data. (Default to False)
    blocking_sync : bool, optional
        If True, the event uses blocking synchronization: a CPU
        thread that calls :meth:`Event.sync` blocks (yields) until
        the event has completed. Otherwise (the default), the CPU
        thread busy-waits until the event has completed.
        (Default to False)
    ipc_enabled : bool, optional
        Event will be suitable for interprocess use.
        Note that timing_enabled must be False. (Default to False)

    """
    timing_enabled: bool | None = False
    blocking_sync: bool | None = False
    ipc_enabled: bool | None = False

class Event:
    """Represent a record at a specific point of execution within a CUDA stream.

    Applications can asynchronously record events at any point in
    the program. An event keeps a record of all previous work within
    the last recorded stream.

    Events can be used to monitor device's progress, query completion
    of work up to event's record, help establish dependencies
    between GPU work submissions, and record the elapsed time (in milliseconds)
    on GPU:

    .. code-block:: python

        # To create events and record the timing:
        s = Device().create_stream()
        e1 = Device().create_event({"timing_enabled": True})
        e2 = Device().create_event({"timing_enabled": True})
        s.record(e1)
        # ... run some GPU works ...
        s.record(e2)
        e2.sync()
        print(f"time = {e2 - e1} milliseconds")

    Directly creating an :obj:`~_event.Event` is not supported due to ambiguity,
    and they should instead be created through a :obj:`~_stream.Stream` object.

    """

    def close(self):
        """Destroy the event.

        Releases the event handle. The underlying CUDA event is destroyed
        when the last reference is released.
        """

    def __init__(self, *args, **kwargs) -> None:
        ...

    def __isub__(self, other: object):
        ...

    def __rsub__(self, other: object):
        ...

    def __sub__(self, other: Event) -> float:
        ...

    def __hash__(self) -> int:
        ...

    def __eq__(self, other: object) -> bool:
        ...

    def __repr__(self) -> str:
        ...

    @property
    def ipc_descriptor(self) -> IPCEventDescriptor:
        """Descriptor for sharing this event with other processes."""

    @classmethod
    def from_ipc_descriptor(cls, ipc_descriptor: IPCEventDescriptor) -> Event:
        """Import an event that was exported from another process.

        Parameters
        ----------
        ipc_descriptor : :obj:`~_memory._ipc.IPCEventDescriptor`
            The IPC descriptor obtained from :attr:`~Event.ipc_descriptor` in
            another process.

        Returns
        -------
        :obj:`~_event.Event`
            A new event backed by the imported IPC handle.

        """

    @property
    def is_ipc_enabled(self) -> bool:
        """Return True if the event can be shared across process boundaries, otherwise False."""

    @property
    def is_timing_enabled(self) -> bool:
        """Return True if the event records timing data, otherwise False."""

    @property
    def is_blocking_sync(self) -> bool:
        """Return True if the event uses blocking synchronization (the CPU
        thread blocks on :meth:`sync` instead of busy-waiting), otherwise False.
        """

    def sync(self) -> None:
        """Synchronize until the event completes.

        If the event was created with ``blocking_sync=True``, the
        calling CPU thread blocks (yields) until the event has been
        completed by the device. Otherwise (the default) the CPU
        thread busy-waits until the event has completed.

        """

    @property
    def is_done(self) -> bool:
        """Return True if all captured works have been completed, otherwise False."""

    @property
    def handle(self) -> cuda.bindings.driver.CUevent:
        """Return the underlying CUevent object.

        .. caution::

            This handle is a Python object. To get the memory address of the underlying C
            handle, call ``int(Event.handle)``.
        """

    @property
    def device(self) -> Device:
        """Return the :obj:`~_device.Device` singleton associated with this event.

        Note
        ----
        The current context on the device may differ from this
        event's context. This case occurs when a different CUDA
        context is set current after a event is created.

        """

    @property
    def context(self) -> Context:
        """Return the :obj:`~_context.Context` associated with this event."""

class IPCEventDescriptor:
    """Serializable object describing an event that can be shared between processes."""

    def __init__(self, *arg, **kwargs) -> None:
        ...

    @staticmethod
    def _init(reserved: bytes, is_blocking_sync: cython.bint) -> IPCEventDescriptor:
        ...

    def __eq__(self, other: object) -> bool:
        ...

    def __reduce__(self) -> tuple[object, ...]:
        ...
__all__ = ['Event', 'EventOptions']

def _reduce_event(event: Event) -> tuple[object, ...]:
    ...