Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
4.83k stars 2.29k forks source link

Custom Transpiler Stage Plugin (layout) not showing #12615

Closed iyanmv closed 1 week ago

iyanmv commented 1 week ago

Environment

What is happening?

I tried to create a custom layout plugin following this documentation. My custom layout did not appear when executing list_stage_plugins("layout") so I tried to to use the exact same example provided in the documentation. I created a python package, a pyproject.toml, etc. I install the new package without issues, but the plugin is still not listed with list_stage_plugins("layout").

This is the structure of my package:

pyproject.toml
src/
   qiskit_custom_layout
      __init__.py
      custom_layout_plugin.py

In the module custom_layout_plugin.py I copy-paste the example from the docs. And this is my pyproject.toml:

[project]
name = "qiskit-custom-layout"
version = "0.1.0"
description = "A transpiler stage plugin that implements a custom layout"
authors = [
    {name = "Iyán Méndez Veiga", email = "me@iyanmv.com"},
]
dependencies = [
    "qiskit>=1.0.0",
    "gmpy2>=2.1.5",
]
requires-python = ">=3.8"
readme = "README.md"
license = {text = "MIT"}

[project.entry-points."qiskit.transpiler.layout"]
custom_layout = "custom_layout_plugin:VF2LayoutPlugin"

I tried both with custom_layout and "custom_layout" as in the Qiskit docs the entry point variable is done with quotes but in the setuptools docs is always without, but it doesn't make a difference.

Am I doing something wrong?

How can we reproduce the issue?

Try to create a custom plugin exactly as described in the documentation.

What should happen?

Custom layout plugin should appear.

Any suggestions?

No response

jakelishman commented 1 week ago

In your entry point, you've not included the name of your package in the lookup path for the object. Your Python package is saying it's installing something that's called qiskit_custom_layout, so the plugin object is (presumably) found at qiskit_custom_layout.custom_layout_plugin.VF2LayoutPlugin.

iyanmv commented 1 week ago

In your entry point, you've not included the name of your package in the lookup path for the object. Your Python package is saying it's installing something that's called qiskit_custom_layout, so the plugin object is (presumably) found at qiskit_custom_layout.custom_layout_plugin.VF2LayoutPlugin.

Thanks for the quick answer! I just tried but it still doesn't work.

Oh, and I forgot to share before the contents of the __init__.py. I simply added this for the test:

from .custom_layout_plugin import VF2LayoutPlugin
jakelishman commented 1 week ago

Did you pip install again after you'd changed it? If you're ever changing plugins / entry points, you'll need to do that quite a lot, because you have to get the Python virtual environment to rewrite the metadata.

If you've updated the __init__.py file to that, then the shortest way you could write the entry point would be to have it set to

custom_layout = "qiskit_custom_layout.VF2LayoutPlugin"

I think.

iyanmv commented 1 week ago

Did you pip install again after you'd changed it? If you're ever changing plugins / entry points, you'll need to do that quite a lot, because you have to get the Python virtual environment to rewrite the metadata.

Yes, I'm running pip install . after each change.

If you've updated the __init__.py file to that, then the shortest way you could write the entry point would be to have it set to

No, this is what I had from the beginning, I just forgot to include it in the issue.

custom_layout = "qiskit_custom_layout.VF2LayoutPlugin"

Okay, let me try this :crossed_fingers:

iyanmv commented 1 week ago

Nothing... but if I run this

from importlib.metadata import entry_points
display_eps = entry_points(group="qiskit.transpiler.layout")
print(display_eps)

I can correctly see my custom entry point.

[EntryPoint(name='custom_layout', value='qiskit_custom_layout.VF2LayoutPlugin', group='qiskit.transpiler.layout'), EntryPoint(name='default', value='qiskit.transpiler.preset_passmanagers.builtin_plugins:DefaultLayoutPassManager', group='qiskit.transpiler.layout'), EntryPoint(name='dense', value='qiskit.transpiler.preset_passmanagers.builtin_plugins:DenseLayoutPassManager', group='qiskit.transpiler.layout'), EntryPoint(name='sabre', value='qiskit.transpiler.preset_passmanagers.builtin_plugins:SabreLayoutPassManager', group='qiskit.transpiler.layout'), EntryPoint(name='trivial', value='qiskit.transpiler.preset_passmanagers.builtin_plugins:TrivialLayoutPassManager', group='qiskit.transpiler.layout')]
iyanmv commented 1 week ago

Oh, now it worked! I had to write this:

[project.entry-points."qiskit.transpiler.layout"]
custom_layout = "qiskit_custom_layout:VF2LayoutPlugin"

Note the : instead of . to select the class.

Thanks for the help! I never worked with entry points so I was a bit confused (I still am :sweat_smile: )

jakelishman commented 1 week ago

Ahh thanks yeah, I'd missed the colon vs dot too sorry.