예제 #1
0
파일: events.py 프로젝트: qtboi/ignite
    def __call__(self,
                 event_filter: Optional[Callable] = None,
                 every: Optional[int] = None,
                 once: Optional[int] = None):

        if not ((event_filter is not None) ^ (every is not None) ^
                (once is not None)):
            raise ValueError(
                "Only one of the input arguments should be specified")

        if (event_filter is not None) and not callable(event_filter):
            raise TypeError("Argument event_filter should be a callable")

        if (every is not None) and not (isinstance(every, numbers.Integral)
                                        and every > 0):
            raise ValueError(
                "Argument every should be integer and greater than zero")

        if (once is not None) and not (isinstance(once, numbers.Integral)
                                       and once > 0):
            raise ValueError("Argument every should be integer and positive")

        if every is not None:
            if every == 1:
                # Just return the event itself
                return self
            event_filter = CallableEvents.every_event_filter(every)

        if once is not None:
            event_filter = CallableEvents.once_event_filter(once)

        # check signature:
        _check_signature("engine", event_filter, "event_filter", "event")

        return EventWithFilter(self, event_filter)
예제 #2
0
파일: engine.py 프로젝트: zivzone/ignite
    def add_event_handler(self, event_name: str, handler: Callable, *args,
                          **kwargs):
        """Add an event handler to be executed when the specified event is fired.

        Args:
            event_name: An event to attach the handler to. Valid events are from :class:`~ignite.engine.Events`
                or any `event_name` added by :meth:`~ignite.engine.Engine.register_events`.
            handler (callable): the callable event handler that should be invoked
            *args: optional args to be passed to `handler`.
            **kwargs: optional keyword args to be passed to `handler`.

        Note:
            The handler function's first argument will be `self`, the :class:`~ignite.engine.Engine` object it
            was bound to.

            Note that other arguments can be passed to the handler in addition to the `*args` and  `**kwargs`
            passed here, for example during :attr:`~ignite.engine.Events.EXCEPTION_RAISED`.

        Returns:
            :class:`~ignite.engine.RemovableEventHandler`, which can be used to remove the handler.

        Example usage:

        .. code-block:: python

            engine = Engine(process_function)

            def print_epoch(engine):
                print("Epoch: {}".format(engine.state.epoch))

            engine.add_event_handler(Events.EPOCH_COMPLETED, print_epoch)


        Note:
            Since v0.3.0, Events become more flexible and allow to pass an event filter to the Engine.
            See :class:`~ignite.engine.Events` for more details.

        """
        if isinstance(event_name, EventWithFilter):
            event_name, event_filter = event_name.event, event_name.filter
            handler = Engine._handler_wrapper(handler, event_name,
                                              event_filter)

        if event_name not in self._allowed_events:
            self.logger.error(
                "attempt to add event handler to an invalid event %s.",
                event_name)
            raise ValueError(
                "Event {} is not a valid event for this Engine.".format(
                    event_name))

        event_args = (
            Exception(), ) if event_name == Events.EXCEPTION_RAISED else ()
        _check_signature(self, handler, 'handler', *(event_args + args),
                         **kwargs)

        self._event_handlers[event_name].append((handler, args, kwargs))
        self.logger.debug("added handler for event %s.", event_name)

        return RemovableEventHandle(event_name, handler, self)
예제 #3
0
    def __call__(self,
                 event_filter: Optional[Callable] = None,
                 every: Optional[int] = None,
                 once: Optional[int] = None) -> Any:
        """
        Makes the event class callable and accepts either an arbitrary callable as filter
        (which must take in the engine and current event value and return a boolean) or an every or once value

        Args:
            event_filter (callable, optional): a filter function to check if the event should be executed when
                the event type was fired
            every (int, optional): a value specifying how often the event should be fired
            once (int, optional): a value specifying when the event should be fired (if only once)

        Returns:
            CallableEventWithFilter: A new event having the same value but a different filter function
        """

        if not ((event_filter is not None) ^ (every is not None) ^
                (once is not None)):
            raise ValueError(
                "Only one of the input arguments should be specified")

        if (event_filter is not None) and not callable(event_filter):
            raise TypeError("Argument event_filter should be a callable")

        if (every is not None) and not (isinstance(every, numbers.Integral)
                                        and every > 0):
            raise ValueError(
                "Argument every should be integer and greater than zero")

        if (once is not None) and not (isinstance(once, numbers.Integral)
                                       and once > 0):
            raise ValueError("Argument every should be integer and positive")

        if every is not None:
            if every == 1:
                # Just return the event itself
                event_filter = None
            else:
                event_filter = self.every_event_filter(every)

        if once is not None:
            event_filter = self.once_event_filter(once)

        # check signature:
        if event_filter is not None:
            _check_signature("engine", event_filter, "event_filter", "event")

        return CallableEventWithFilter(self.value, event_filter, self.name)
예제 #4
0
 def _get_args_kwargs(self, engine_: Engine,
                      **kwargs: Any) -> Tuple[tuple, dict]:
     kwargs = CfgNode._eval(CfgNode(kwargs),
                            self.global_context,
                            self.local_context,
                            eval_all=True)
     if self._needs_engine is None:
         try:
             _check_signature(self.handler, 'handler', engine_, **kwargs)
             self._needs_engine = True
         except ValueError:
             self._needs_engine = False
     args = (engine_, ) if self._needs_engine else ()
     return args, kwargs
예제 #5
0
    def __init__(self, process_function):
        self._event_handlers = defaultdict(list)
        self.logger = logging.getLogger(__name__ + "." + self.__class__.__name__)
        self._process_function = process_function
        self.last_event_name = None
        self.should_terminate = False
        self.should_terminate_single_epoch = False
        self.state = None
        self._allowed_events = []

        self._dataloader_iter = None
        self._init_iter = []

        self.register_events(*Events)

        if self._process_function is None:
            raise ValueError("Engine must be given a processing function in order to run.")

        _check_signature(self, process_function, 'process_function', None)
예제 #6
0
    def __init__(self, process_function: Callable):
        self._event_handlers = defaultdict(list)  # type: Dict[Any, List]
        self.logger = logging.getLogger(__name__ + "." +
                                        self.__class__.__name__)
        self._process_function = process_function
        self.last_event_name = None  # type: Optional[Events]
        self.should_terminate = False
        self.should_terminate_single_epoch = False
        self.state = State()
        self._state_dict_user_keys = []  # type: List[str]
        self._allowed_events = []  # type: List[EventEnum]

        self._dataloader_iter = None  # type: Optional[Iterator[Any]]
        self._init_iter = []  # type: List[int]

        self.register_events(*Events)

        if self._process_function is None:
            raise ValueError(
                "Engine must be given a processing function in order to run.")

        _check_signature(process_function, "process_function", self, None)
예제 #7
0
    def add_event_handler(self, event_name: Any, handler: Callable, *args,
                          **kwargs):
        """Add an event handler to be executed when the specified event is fired.

        Args:
            event_name: An event or a list of events to attach the handler. Valid events are
                from :class:`~ignite.engine.events.Events` or any ``event_name`` added by
                :meth:`~ignite.engine.engine.Engine.register_events`.
            handler (callable): the callable event handler that should be invoked. No restrictions on its signature.
                The first argument can be optionally `engine`, the :class:`~ignite.engine.engine.Engine` object,
                handler is bound to.
            *args: optional args to be passed to ``handler``.
            **kwargs: optional keyword args to be passed to ``handler``.

        Note:
            Note that other arguments can be passed to the handler in addition to the `*args` and  `**kwargs`
            passed here, for example during :attr:`~ignite.engine.events.Events.EXCEPTION_RAISED`.

        Returns:
            :class:`~ignite.engine.RemovableEventHandle`, which can be used to remove the handler.

        Example usage:

        .. code-block:: python

            engine = Engine(process_function)

            def print_epoch(engine):
                print("Epoch: {}".format(engine.state.epoch))

            engine.add_event_handler(Events.EPOCH_COMPLETED, print_epoch)

            events_list = Events.EPOCH_COMPLETED | Events.COMPLETED

            def execute_something():
                # do some thing not related to engine
                pass

            engine.add_event_handler(events_list, execute_something)

        Note:
            Since v0.3.0, Events become more flexible and allow to pass an event filter to the Engine.
            See :class:`~ignite.engine.events.Events` for more details.

        """
        if isinstance(event_name, EventsList):
            for e in event_name:
                self.add_event_handler(e, handler, *args, **kwargs)
            return RemovableEventHandle(event_name, handler, self)
        if (isinstance(event_name, CallableEventWithFilter)
                and event_name.filter !=
                CallableEventWithFilter.default_event_filter):
            event_filter = event_name.filter
            handler = self._handler_wrapper(handler, event_name, event_filter)

        if event_name not in self._allowed_events:
            self.logger.error(
                "attempt to add event handler to an invalid event %s.",
                event_name)
            raise ValueError(
                "Event {} is not a valid event for this Engine.".format(
                    event_name))

        event_args = (
            Exception(), ) if event_name == Events.EXCEPTION_RAISED else ()
        try:
            _check_signature(handler, "handler", self, *(event_args + args),
                             **kwargs)
            self._event_handlers[event_name].append(
                (handler, (self, ) + args, kwargs))
        except ValueError:
            _check_signature(handler, "handler", *(event_args + args),
                             **kwargs)
            self._event_handlers[event_name].append((handler, args, kwargs))
        self.logger.debug("added handler for event %s.", event_name)

        return RemovableEventHandle(event_name, handler, self)