Skip to content
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

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

isaacdevlugt
Copy link
Contributor

@isaacdevlugt isaacdevlugt commented May 15, 2024

@isaacdevlugt isaacdevlugt changed the title initial How to use Qiskit 1.0 with PennyLane May 15, 2024
Copy link

👋 Hey, looks like you've updated some demos!

🐘 Don't forget to update the dateOfLastModification in the associated metadata files so your changes are reflected in Glass Onion (search and recommendations).

Please hide this comment once the field(s) are updated. Thanks!

Copy link

github-actions bot commented May 15, 2024

Thank you for opening this pull request.

You can find the built site at this link.

Deployment Info:

  • Pull Request ID: 1104
  • Deployment SHA: 15c97a8dbf17e875c61cb4fff74f82ccf3660985
    (The Deployment SHA refers to the latest commit hash the docs were built from)

Note: It may take several minutes for updates to this pull request to be reflected on the deployed site.

Comment on lines +279 to +281
# 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")``).
Copy link
Member

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

@isaacdevlugt isaacdevlugt changed the title How to use Qiskit 1.0 with PennyLane [sc-63358] How to use Qiskit 1.0 with PennyLane Jun 12, 2024
"previewImages": [
{
"type": "thumbnail",
"uri": "/_static/demonstration_assets/regular_demo_thumbnails/thumbnail_variationally_quantum_thermalizer.png"
Copy link
Contributor Author

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

Comment on lines +67 to +74
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())
Copy link
Contributor Author

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)

Copy link

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.

Copy link

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.

Comment on lines +172 to +178
from qiskit.primitives import Estimator

estimator = Estimator()

job = estimator.run([qc] * len(operators), operators)
result = job.result()
print(result)

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.

Comment on lines +371 to +377
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}")
Copy link

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.

Copy link

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 😅 .

Copy link

@austingmhuang austingmhuang left a 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.

Copy link
Member

@josh146 josh146 left a 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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

Copy link
Member

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!

Comment on lines +12 to +16
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!
Copy link
Member

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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

Comment on lines +37 to +42
# 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# 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.

Copy link
Member

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 '.

Comment on lines +44 to +45
# 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# 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

Comment on lines +215 to +217
# 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.
Copy link
Member

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``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cross referencing

Comment on lines +306 to +309
######################################################################
# .. figure:: ../_static/demonstration_assets/how_to_use_qiskit_1_with_pennylane/qiskit_parameterized_circuit.png
# :align: center
# :width: 70%
Copy link
Member

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?

Comment on lines +308 to +309
# :align: center
# :width: 70%
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# :align: center
# :width: 70%
# :align: left
# :width: 20%

Comment on lines +402 to +404
# `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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# `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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants