diff --git a/qiskit/transpiler/preset_passmanagers/plugin.py b/qiskit/transpiler/preset_passmanagers/plugin.py index f4d1ae7e4b89..83d66ceae6a2 100644 --- a/qiskit/transpiler/preset_passmanagers/plugin.py +++ b/qiskit/transpiler/preset_passmanagers/plugin.py @@ -161,10 +161,11 @@ def pass_manager(self, pass_manager_config, optimization_level): PassManagerStagePlugin PassManagerStagePluginManager list_stage_plugins + passmanager_stage_plugins """ import abc -from typing import List, Optional +from typing import List, Optional, Dict import stevedore @@ -301,3 +302,47 @@ def list_stage_plugins(stage_name: str) -> List[str]: return plugin_mgr.scheduling_plugins.names() else: raise TranspilerError(f"Invalid stage name: {stage_name}") + + +def passmanager_stage_plugins(stage: str) -> Dict[str, PassManagerStagePlugin]: + """Return a dict with, for each stage name, the class type of the plugin. + + This function is useful for getting more information about a plugin: + + .. code-block:: python + + from qiskit.transpiler.preset_passmanagers.plugin import passmanager_stage_plugins + routing_plugins = passmanager_stage_plugins('routing') + basic_plugin = routing_plugins['basic'] + help(basic_plugin) + + .. code-block:: text + + Help on BasicSwapPassManager in module ...preset_passmanagers.builtin_plugins object: + + class BasicSwapPassManager(...preset_passmanagers.plugin.PassManagerStagePlugin) + | Plugin class for routing stage with :class:`~.BasicSwap` + | + | Method resolution order: + | BasicSwapPassManager + | ...preset_passmanagers.plugin.PassManagerStagePlugin + | abc.ABC + | builtins.object + ... + + Args: + stage: The stage name to get + + Returns: + dict: the key is the name of the plugin and the value is the class type for each. + + Raises: + TranspilerError: If an invalid stage name is specified. + """ + plugin_mgr = PassManagerStagePluginManager() + try: + manager = getattr(plugin_mgr, f"{stage}_plugins") + except AttributeError as exc: + raise TranspilerError(f"Passmanager stage {stage} not found") from exc + + return {name: manager[name].obj for name in manager.names()} diff --git a/releasenotes/notes/entry_point_obj-60625d9d797df1d9.yaml b/releasenotes/notes/entry_point_obj-60625d9d797df1d9.yaml new file mode 100644 index 000000000000..0494a059c644 --- /dev/null +++ b/releasenotes/notes/entry_point_obj-60625d9d797df1d9.yaml @@ -0,0 +1,18 @@ +--- +features: + - | + The function ``passmanager_stage_plugins`` in the module + ``qiskit.transpiler.preset_passmanagers.plugin`` was added to obtain a map between + plugin names and their class type. + This allows to identify and query passmanager plugin documentation. For example:: + + >>> from qiskit.transpiler.preset_passmanagers.plugin import passmanager_stage_plugins + >>> passmanager_stage_plugins('routing')['lookahead'].__class__ + qiskit.transpiler.preset_passmanagers.builtin_plugins.LookaheadSwapPassManager + + >>> help(passmanager_stage_plugins('routing')['lookahead']) + Help on BasicSwapPassManager in module qiskit.transpiler.preset_passmanagers.builtin_plugins object: + + class BasicSwapPassManager(qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin) + | Plugin class for routing stage with :class:`~.BasicSwap` + ... diff --git a/test/python/transpiler/test_stage_plugin.py b/test/python/transpiler/test_stage_plugin.py index 1242905e9f4e..1279fae467e8 100644 --- a/test/python/transpiler/test_stage_plugin.py +++ b/test/python/transpiler/test_stage_plugin.py @@ -22,9 +22,11 @@ from qiskit.compiler.transpiler import transpile from qiskit.test import QiskitTestCase from qiskit.transpiler import PassManager, PassManagerConfig, CouplingMap +from qiskit.transpiler.preset_passmanagers.builtin_plugins import BasicSwapPassManager from qiskit.transpiler.preset_passmanagers.plugin import ( PassManagerStagePluginManager, list_stage_plugins, + passmanager_stage_plugins, ) from qiskit.transpiler.exceptions import TranspilerError from qiskit.providers.basicaer import QasmSimulatorPy @@ -51,6 +53,16 @@ def test_list_stage_plugins_invalid_stage_name(self): with self.assertRaises(TranspilerError): list_stage_plugins("not_a_stage") + def test_passmanager_stage_plugins(self): + """Test entry_point_obj function.""" + basic_obj = passmanager_stage_plugins("routing") + self.assertIsInstance(basic_obj["basic"], BasicSwapPassManager) + + def test_passmanager_stage_plugins_not_found(self): + """Test entry_point_obj function with nonexistent stage""" + with self.assertRaises(TranspilerError): + passmanager_stage_plugins("foo_stage") + def test_build_pm_invalid_plugin_name_valid_stage(self): """Test get pm from plugin with invalid plugin name and valid stage.""" plugin_manager = PassManagerStagePluginManager()