-
-
Notifications
You must be signed in to change notification settings - Fork 655
Closed
Labels
Description
🚀 Feature
The idea is coming from this discussion: Project-MONAI/MONAI#5958 (reply in thread)
We would like to support the following use-cases:
before/aftercan work together withevery
event = Events.ITERATION_COMPLETED(after=9, before=21, every=5)
# execute for iterations [10, 15, 20]
oncecan accept list of values
event = Events.ITERATION_COMPLETED(once=[5, 8, 23])
# execute once for iterations 5, 8 and 23
How to help with this issue
Events filtering logic is coded here:
ignite/ignite/engine/events.py
Lines 50 to 119 in 5d344a0
| def __call__( | |
| self, | |
| event_filter: Optional[Callable] = None, | |
| every: Optional[int] = None, | |
| once: Optional[int] = None, | |
| before: Optional[int] = None, | |
| after: Optional[int] = None, | |
| ) -> "CallableEventWithFilter": | |
| """ | |
| 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: a filter function to check if the event should be executed when | |
| the event type was fired | |
| every: a value specifying how often the event should be fired | |
| once: a value specifying when the event should be fired (if only once) | |
| before: a value specifying the number of occurrence that event should be fired before | |
| after: a value specifying the number of occurrence that event should be fired after | |
| Returns: | |
| CallableEventWithFilter: A new event having the same value but a different filter function | |
| """ | |
| if ( | |
| sum( | |
| ( | |
| event_filter is not None, | |
| every is not None, | |
| once is not None, | |
| (before is not None or after is not None), | |
| ) | |
| ) | |
| != 1 | |
| ): | |
| raise ValueError("Only one of the input arguments should be specified except before and after") | |
| 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 once should be integer and positive") | |
| if (before is not None) and not (isinstance(before, numbers.Integral) and before >= 0): | |
| raise ValueError("Argument before should be integer and greater or equal to zero") | |
| if (after is not None) and not (isinstance(after, numbers.Integral) and after >= 0): | |
| raise ValueError("Argument after should be integer and greater or equal to zero") | |
| 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) | |
| if before is not None or after is not None: | |
| event_filter = self.before_and_after_event_filter(before, after) | |
| # check signature: | |
| if event_filter is not None: | |
| _check_signature(event_filter, "event_filter", "engine", "event") | |
| return CallableEventWithFilter(self.value, event_filter, self.name) |
We would like to update the following functions:
ignite/ignite/engine/events.py
Line 110 in 5d344a0
| event_filter = self.once_event_filter(once) |
and
ignite/ignite/engine/events.py
Line 113 in 5d344a0
| event_filter = self.before_and_after_event_filter(before, after) |
such that we could cover proposed use-cases. Finally, we need to write few tests here: https://github.com/pytorch/ignite/blob/master/tests/ignite/engine/test_custom_events.py