-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[sc-63358] How to use Qiskit 1.0 with PennyLane #1104
base: master
Are you sure you want to change the base?
Conversation
👋 Hey, looks like you've updated some demos! 🐘 Don't forget to update the Please hide this comment once the field(s) are updated. Thanks! |
demonstrations/tutorial_how_to_use_qiskit1.0_with_pennylane.metadata.json
Outdated
Show resolved
Hide resolved
demonstrations/tutorial_how_to_use_qiskit1.0_with_pennylane.metadata.json
Outdated
Show resolved
Hide resolved
demonstrations/tutorial_how_to_use_qiskit1.0_with_pennylane.metadata.json
Outdated
Show resolved
Hide resolved
demonstrations/how_to_use_qiskit1.0_with_pennylane.metadata.json
Outdated
Show resolved
Hide resolved
demonstrations/how_to_use_qiskit1.0_with_pennylane.metadata.json
Outdated
Show resolved
Hide resolved
Thank you for opening this pull request. You can find the built site at this link. Deployment Info:
Note: It may take several minutes for updates to this pull request to be reflected on the deployed site. |
# You’ll notice, too, that ``pl_func`` has the call signature that you would expect: | ||
# ``pl_qfunc(phis, theta)``, just like the name we gave them when we defined them in Qiskit | ||
# (``ParameterVector("phis", n-1)`` and ``Parameter("theta")``). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it, thanks for highlighting this
…b.com/PennyLaneAI/qml into tutorial-use-qiskit1.0-with-pennylane
"previewImages": [ | ||
{ | ||
"type": "thumbnail", | ||
"uri": "/_static/demonstration_assets/regular_demo_thumbnails/thumbnail_variationally_quantum_thermalizer.png" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just putting a note here to change this when the image is ready
qc = QuantumCircuit(2, 1) | ||
|
||
qc.h(0) | ||
qc.cx(0, 1) | ||
qc.measure(1, 0) | ||
|
||
sampler = Sampler(options={"shots": 1024}) | ||
print(sampler.run(qc).result()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@austingmhuang with my example below using qiskit.basicsim
, should I be using BasicProvider
here instead? (https://docs.quantum.ibm.com/api/qiskit/providers_basic_provider)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use BasicProvider
here instead.
The Sampler
you're importing here from qiskit.primitives
is SamplerV1
, and there's no particular backend specified (In this case it's a statevector simulator I think). Whereas for qiskit.basicsim
we are specifically getting backend = BasicProvider().get_backend('basic_simulator')
and running the device using said backend. So it would be a little confusing.
For reference on our side, we don't import Sampler
from qiskit.primitives
, but from qiskit_ibm_runtime
as per https://docs.quantum.ibm.com/api/migration-guides/v2-primitives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing to note is that sampler.run(qc).result())
gives SamplerResult(quasi_dists=[{0: 0.5234375, 1: 0.4765625}], metadata=[{'shots': 1024}])
, which is quite different, format wise, from what we get from PL [0.50488281 0.49511719]
Maybe you can try qml.expval()
instead? Or format the answer so it matches a bit better.
from qiskit.primitives import Estimator | ||
|
||
estimator = Estimator() | ||
|
||
job = estimator.run([qc] * len(operators), operators) | ||
result = job.result() | ||
print(result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just fyi this is using EstimatorV1 and EstimatorV1 syntax.
opt = qml.AdamOptimizer(0.1) | ||
|
||
for i in range(100): | ||
(phis, theta), new_loss = opt.step_and_cost(cost, phis, theta) | ||
|
||
print(f"Optimized parameters: phis = {phis}, theta = {theta}") | ||
print(f"Optimized cost function value: {new_loss}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great example.
It would be great if we get the new qiskit device merged into master then we can update this to use the qiskit_session
context manager so that a real user knows they don't have to wait and queue for each iteration of the optimizer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isaacdevlugt It would also be nice to know that this actually works with our qiskit_session
context manager... if you have time, could you checkout new_device_feature_branch
and try running this code with the qiskit_session
? You might have to use real hardware though (not sure). If not I can always find time to try this out myself though 😅 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @isaacdevlugt!
Just a general comment but I'd just like to highlight something that is distinctly neat about using PL over using Qiskit: You don't need to swap between Estimator and Sampler in order to get what you want.
E.g. in Qiskit if you had some circuit and you wanted both the expectation value and the counts (admittedly, this is a bit of a contrived example), you would need to initialize Estimator and Sampler, and then write a lot of repeated, syntactically complicated code (e.g. expval = estimator.run()[0].data.evs anyone?) to do so. In Pennylane? Easy as return qml.expval(obs), qml.counts(obs)
. Syntactic sugar like this is always nice IMO.
I wouldn't go out of my way to make a statement pointing this out, because the tone that's best is one that's friendly and helpful -- not combative. But I think there is room to select an example where we can subtly showcase the difference in # of lines of code and how clean it is in comparison i.e. just write the code and let the code speak for itself. All this to say, an example where a user would have to initialize and use both the estimator and the sampler would be a good example to highlight a nice feature about the plugin and PL in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @isaacdevlugt, this is looking great! I've left a (conditional) approval, conditional on my review comments.
Something to note: This is another case where this should probably be two how-tos (and your intro somewhat backs this up!):
- How to execute PennyLane workflows using IBM and Qiskit devices
- How to convert your existing Qiskit code to PennyLane
I'm happy for it to be merged as is (I think it is a massive net benefit for readers overall!), but would have suggested the above instead if we had discussed earlier.
Amazon Braket — you name it! | ||
With the first stable release of Qiskit in February 2024 (Qiskit 1.0), we subsequently shipped some | ||
excellent features and upgrades with the PennyLane-Qiskit plugin, allowing users familiar with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
excellent features and upgrades with the PennyLane-Qiskit plugin, allowing users familiar with | |
excellent features and upgrades with the PennyLane-Qiskit plugin, allowing | |
anyone familiar with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mostly just personal preference, but I prefer not to use 'user' in content and documentation, as it can feel a bit impersonal. Rather, we can speak directly to the reader!
On that note of IBM hardware, the PennyLane-Qiskit plugin enables you to integrate your existing | ||
Qiskit code and run circuits on IBM devices with PennyLane, encompassing two real-world scenarios: | ||
(1) working in PennyLane from the start and executing your work on an IBM device and (2) converting | ||
your existing Qiskit code to PennyLane and executing that on *any* device, including IBM devices, | ||
Amazon Braket — you name it! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😉 I think you know what I'm going to say here (will leave it for the review comment lol)
One of PennyLane’s claims to fame is that it’s *hardware agnostic*; PennyLane doesn’t care about | ||
what you want to execute quantum circuits on. This is made possible by our `plugin | ||
suite <https://pennylane.ai/plugins/#plugins>`__, which contains several plugins that are maintained |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suite <https://pennylane.ai/plugins/#plugins>`__, which contains several plugins that are maintained | |
suite <https://pennylane.ai/plugins/#plugins>`__, which provide additional simulator and hardware devices and other functionality that are maintained |
# If you want to distill how a PennyLane plugin works down to one thing, it’s all in the devices! In | ||
# PennyLane, you just create your circuit (a quantum function) and decorate it with | ||
# ``@qml.qnode(dev)``, where ``dev`` is (one of) a plugin’s device(s). In PennyLane and its plugins, | ||
# devices are called upon by their short name: ``qml.device("shortname", ...)``. If you’ve | ||
# seen PennyLane code before, you’ve probably seen ``"default.qubit"`` or ``"lightning.qubit"`` as | ||
# short names for our Python and C++ statevector simulators, respectively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# If you want to distill how a PennyLane plugin works down to one thing, it’s all in the devices! In | |
# PennyLane, you just create your circuit (a quantum function) and decorate it with | |
# ``@qml.qnode(dev)``, where ``dev`` is (one of) a plugin’s device(s). In PennyLane and its plugins, | |
# devices are called upon by their short name: ``qml.device("shortname", ...)``. If you’ve | |
# seen PennyLane code before, you’ve probably seen ``"default.qubit"`` or ``"lightning.qubit"`` as | |
# short names for our Python and C++ statevector simulators, respectively. | |
# If you want to distill how a PennyLane plugin works down to one thing, it’s all in the provided devices! In | |
# PennyLane, you just :doc:`create your circuit (a quantum function) </introduction/circuits>` and decorate it with | |
# the QNode decorator :func:`@qml.qnode(dev) <~.qnode>`, where ``dev`` is (one of) a plugin’s device(s). | |
# | |
# In PennyLane and its plugins, | |
# devices are called upon by their short name, and can be loaded via the :func:`~.device` function: | |
# | |
# .. code-block:: python | |
# | |
# qml.device("shortname", *device_options) | |
# | |
# If you’ve | |
# seen PennyLane code before, you’ve probably seen ``"default.qubit"`` or ``"lightning.qubit"`` as | |
# short names for our Python and C++ statevector simulators, respectively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of things here:
- Inserted a space between paragraphs for legibility
- Always good practice to cross reference the docstring if users want to see more details!
- 'display' codeblocks can help emphasize the usage (similar to display mathmode)
It's also always good to link to other content. E.g., you could finish this paragraph with 'If you would like to read more about how to use PL and devices, see '.
# In the PennyLane-Qiskit plugin, there are `several Qiskit | ||
# devices <https://docs.pennylane.ai/projects/qiskit/en/stable/#devices>`__ you can use, but here are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# In the PennyLane-Qiskit plugin, there are `several Qiskit | |
# devices <https://docs.pennylane.ai/projects/qiskit/en/stable/#devices>`__ you can use, but here are | |
# In the PennyLane-Qiskit plugin, there are `several IBM | |
# devices <https://docs.pennylane.ai/projects/qiskit/en/stable/#devices>`__ you can use, but here are |
# Next, we convert the Qiskit ``QuantumCircuit``, ``qc``, to PennyLane with ``qml.from_qiskit``. We | ||
# can append the measurements — expectation values (``qml.expval``) of ``pl_operators`` — with the | ||
# ``measurements`` keyword argument, which accepts a list of PennyLane measurements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here with cross referencing :)
# What’s really useful about being able to append measurements to the end of a circuit with | ||
# ``qml.from_qiskit`` is being able to measure something that isn’t available in Qiskit 1.0 but is | ||
# available in PennyLane, like the classical shadow measurement protocol, for example. In PennyLane, | ||
# you can measure this with ``qml.classical_shadow``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cross referencing
###################################################################### | ||
# .. figure:: ../_static/demonstration_assets/how_to_use_qiskit_1_with_pennylane/qiskit_parameterized_circuit.png | ||
# :align: center | ||
# :width: 70% |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isaacdevlugt this figure is very large, can we reduce the size?
# :align: center | ||
# :width: 70% |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# :align: center | |
# :width: 70% | |
# :align: left | |
# :width: 20% |
# `plugin homepage <https://docs.pennylane.ai/projects/qiskit/en/stable/>`__. In the upcoming v0.37 release, | ||
# we’ll be refreshing our integration with Qiskit 1.0 `runtimes <https://cloud.ibm.com/quantum>`__ and | ||
# `primitives <https://docs.quantum.ibm.com/api/qiskit/primitives>`__, so stay tuned for that! In the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# `plugin homepage <https://docs.pennylane.ai/projects/qiskit/en/stable/>`__. In the upcoming v0.37 release, | |
# we’ll be refreshing our integration with Qiskit 1.0 `runtimes <https://cloud.ibm.com/quantum>`__ and | |
# `primitives <https://docs.quantum.ibm.com/api/qiskit/primitives>`__, so stay tuned for that! In the | |
# `plugin homepage <https://docs.pennylane.ai/projects/qiskit/en/stable/>`__. In the |
Demos are 'time invariant', so we avoid having content that would make it feel out of date accidentally :) So I would remove this here (although this would make much more sense in a blog post).
Title: How to use Qiskit 1.0 with PL
Shortcut: https://app.shortcut.com/xanaduai/story/63358/how-to-how-to-use-qiskit-1-0-with-pennylane