junrushao1994 commented on a change in pull request #10368:
URL: https://github.com/apache/tvm/pull/10368#discussion_r817441218



##########
File path: python/tvm/meta_schedule/utils.py
##########
@@ -31,6 +31,107 @@
 from tvm.tir import FloatImm, IntImm
 
 
+def derived_object(cls: type) -> type:
+    """A decorator to register derived subclasses for TVM objects.
+
+    Parameters
+    ----------
+    cls : type
+        The derived class to be registered.
+
+    Returns
+    -------
+    cls : type
+        The decorated TVM object.
+
+    Example
+    -------
+    .. code-block:: python
+
+        @register_object("meta_schedule.PyRunner")
+        class _PyRunner(meta_schedule.Runner):
+            def __init__(self, methods: List[Callable]):
+                self.__init_handle_by_constructor__(_ffi_api.RunnerPyRunner, 
*methods)
+
+        class PyRunner():
+            _tvm_metadata = {
+                "cls": _PyRunner,
+                "methods": ["run"]
+            }
+            def run(self, runner_inputs):
+                raise NotImplementedError
+
+        @derived_object
+        class LocalRunner(PyRunner):
+            def run(self, runner_inputs):
+                ...
+    """
+
+    import functools  # pylint: disable=import-outside-toplevel
+    import weakref  # pylint: disable=import-outside-toplevel
+
+    def _extract(inst: type, name: str):
+        """Extract function from intrinsic class."""
+
+        def method(*args, **kwargs):
+            return getattr(inst, name)(*args, **kwargs)
+
+        if getattr(base, name) is getattr(cls, name) and name != "__str__":
+            # for task scheduler return None means calling default function
+            # otherwise it will trigger a TVMError of method not implemented
+            # on the c++ side when you call the method, __str__ not required
+            return None
+        return method
+
+    assert isinstance(cls.__base__, type)
+    assert hasattr(
+        cls, "_tvm_metadata"
+    ), "Please use the user-facing method overiding class, i.e., PyRunner."
+
+    base = cls.__base__
+    metadata = getattr(base, "_tvm_metadata")
+    members = metadata.get("members", [])
+    methods = metadata.get("methods", [])
+
+    class TVMDerivedObject(metadata["cls"]):  # type: ignore
+        """The derived object to avoid cyclic dependency."""
+
+        def __init__(self, *args, **kwargs):
+            """Constructor."""
+            self.handle = None
+            self._inst = cls(*args, **kwargs)
+
+            super().__init__(
+                # the constructor's parameters, builder, runner, etc.
+                *[getattr(self._inst, name) for name in members],
+                # the function methods, init_with_tune_context, build, run, 
etc.
+                [_extract(self._inst, name) for name in methods],
+            )
+
+            # for task scheduler hybrid funcs in c++ & python side
+            # using weakref to avoid cyclic dependency
+            self._inst._outer = weakref.ref(self)

Review comment:
       object(self.handle)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to