This is an automated email from the ASF dual-hosted git repository.

tlopex pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new d6e63342df [Bugfix] Prevent segfault when instantiating abstract 
SearchStrategy (#18534)
d6e63342df is described below

commit d6e63342df38018e2911f89bb888ad872dde9a69
Author: Dayuxiaoshui <[email protected]>
AuthorDate: Mon Dec 1 13:13:43 2025 +0800

    [Bugfix] Prevent segfault when instantiating abstract SearchStrategy 
(#18534)
    
    Add __init__ method to SearchStrategy class to prevent direct
    instantiation of the abstract class. This raises a TypeError with a
    helpful error message instead of causing a segmentation fault when
    SearchStrategy() is called directly or passed to TuneContext.
    
    Also add additional check in TuneContext.__init__ to ensure abstract
    SearchStrategy instances are not used.
    
    Fixes #18268
---
 .../search_strategy/search_strategy.py             | 15 +++++++++++
 python/tvm/meta_schedule/tune_context.py           |  9 +++++++
 .../test_meta_schedule_search_strategy.py          | 31 ++++++++++++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/python/tvm/meta_schedule/search_strategy/search_strategy.py 
b/python/tvm/meta_schedule/search_strategy/search_strategy.py
index 75b45cf424..cfb45dafde 100644
--- a/python/tvm/meta_schedule/search_strategy/search_strategy.py
+++ b/python/tvm/meta_schedule/search_strategy/search_strategy.py
@@ -87,6 +87,21 @@ class SearchStrategy(Object):
         ],
     ]
 
+    def __new__(cls, *args, **kwargs):  # pylint: disable=unused-argument
+        """Prevent direct instantiation of abstract SearchStrategy class.
+
+        SearchStrategy is an abstract class and cannot be directly 
instantiated.
+        Use SearchStrategy.create() or a concrete subclass instead.
+        """
+        if cls is SearchStrategy:
+            raise TypeError(
+                "Cannot instantiate abstract class SearchStrategy. "
+                "Use SearchStrategy.create() with a valid strategy type "
+                "(e.g., 'evolutionary', 'replay-trace', 'replay-func') "
+                "or use a concrete subclass instead."
+            )
+        return super().__new__(cls)  # pylint: disable=no-value-for-parameter
+
     def _initialize_with_tune_context(self, context: "TuneContext") -> None:
         """Initialize the search strategy with tuning context.
 
diff --git a/python/tvm/meta_schedule/tune_context.py 
b/python/tvm/meta_schedule/tune_context.py
index c3f496265a..35a8d468a7 100644
--- a/python/tvm/meta_schedule/tune_context.py
+++ b/python/tvm/meta_schedule/tune_context.py
@@ -123,6 +123,15 @@ class TuneContext(Object):
         if search_strategy is not None:
             if not isinstance(search_strategy, SearchStrategy):
                 search_strategy = SearchStrategy.create(search_strategy)
+            # Additional check: ensure it's not the abstract SearchStrategy 
class itself
+            # Use type() for exact type check (not isinstance which would 
match subclasses)
+            elif type(search_strategy) is SearchStrategy:  # pylint: 
disable=unidiomatic-typecheck
+                raise TypeError(
+                    "Cannot use abstract SearchStrategy class directly. "
+                    "Use SearchStrategy.create() with a valid strategy type "
+                    "(e.g., 'evolutionary', 'replay-trace', 'replay-func') "
+                    "or use a concrete subclass instead."
+                )
         if logger is None:
             logger = get_logger(__name__)
         if not isinstance(num_threads, int):
diff --git a/tests/python/meta_schedule/test_meta_schedule_search_strategy.py 
b/tests/python/meta_schedule/test_meta_schedule_search_strategy.py
index 29c20ced04..04a6e187a6 100644
--- a/tests/python/meta_schedule/test_meta_schedule_search_strategy.py
+++ b/tests/python/meta_schedule/test_meta_schedule_search_strategy.py
@@ -306,9 +306,40 @@ def 
test_meta_schedule_evolutionary_search_fail_init_population():  # pylint: di
     assert candidates is None
 
 
+def test_search_strategy_abstract_class_instantiation():
+    """Test that directly instantiating abstract SearchStrategy raises 
TypeError instead of segfault."""
+    from tvm.meta_schedule import SearchStrategy
+    from tvm.target import Target
+    from tvm.meta_schedule import TuneContext
+
+    # Test that direct instantiation raises TypeError
+    # This prevents segfault when SearchStrategy() is called directly
+    with pytest.raises(TypeError, match="Cannot instantiate abstract class 
SearchStrategy"):
+        SearchStrategy()
+
+    # Test that TuneContext with SearchStrategy() raises TypeError
+    # The error should occur when trying to create SearchStrategy() instance 
in the function call
+    # Since SearchStrategy() fails in __new__, it will fail before 
TuneContext.__init__ is called
+    with pytest.raises(TypeError, match="Cannot instantiate abstract class 
SearchStrategy"):
+        # This will fail when evaluating SearchStrategy() as an argument
+        TuneContext(
+            mod=Matmul,  # Use the existing Matmul module from the test file
+            target=Target("llvm"),
+            search_strategy=SearchStrategy(),  # This should fail in __new__ 
before reaching TuneContext
+        )
+
+    # Test that SearchStrategy.create() works correctly
+    strategy = SearchStrategy.create("evolutionary")
+    assert strategy is not None
+    assert isinstance(strategy, SearchStrategy)
+    # Verify it's not the abstract class itself
+    assert type(strategy) is not SearchStrategy
+
+
 if __name__ == "__main__":
     test_meta_schedule_replay_func(ms.search_strategy.ReplayFunc)
     test_meta_schedule_replay_func(ms.search_strategy.ReplayTrace)
     test_meta_schedule_evolutionary_search()
     test_meta_schedule_evolutionary_search_early_stop()
     test_meta_schedule_evolutionary_search_fail_init_population()
+    test_search_strategy_abstract_class_instantiation()

Reply via email to