Coder Social home page Coder Social logo

pyquest's Introduction

pyQuEST

A Python interface for the Quantum Exact Simulation Toolkit (QuEST) written mainly in Cython.

Getting started

After cloning the repository

$ git clone -b develop --recursive --shallow-submodules https://github.com/rrmeister/pyQuEST

it is recommended to create a virtual environment, e.g. with venv, we'll call it quantum-playground.

$ python3 -m venv quantum-playground
$ source quantum-playground/bin/activate

By default, pyQuEST will use double precision for its floating point variables, have multithreading enabled, but GPU acceleration and distributed computing disabled. These settings can be changed in the dictionary quest_config at the top of setup.py before compiling and installing the package.

After setting the compile options as required, the package can be compiled and installed using pip3.

$ pip3 install ./pyQuEST

For this last step — depending on your system — you might have to separately install the Python development headers, usually called python3-dev or python3-devel. Check your distribution for details if the installer cannot find Python.h.

Usage

After successful installation, we can start a Python interpreter — with e.g. ipython or python3 — and import pyQuEST to have a look at the environment it is running in.

Make sure to not launch your interpreter from within the pyQuEST folder, as the pyquest source directory would take precedence over the installed package and cause the import to fail.

In [1]: import pyquest

In [2]: pyquest.env
Out[2]: QuESTEnvironment(cuda=False, openmp=False, mpi=False, num_threads=1, num_ranks=1, precision=2)

The QuESTEnvironment class is automatically instantiated once upon module import and never needs to be called by the user. It contains internals and can return information about the execution environment, as above. If you changed the options in setup.py, make sure these are reflected in this output. If they are not, this indicates a problem during compiling.

Example

The most important classes are Register representing a quantum register, and the operators which can be applied to it. Let's create such a register with 3 qubits and look at its contents.

In [3]: from pyquest import Register

In [4]: from pyquest.unitaries import *

In [5]: reg = Register(3)

In [6]: reg[:]
Out[6]: array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])

Like in QuEST, the state is automatically initialised to the all-zero product state. To apply some gates to it, first import some unitaries and the Circuit class.

In [7]: from pyquest.unitaries import H, X, Ry

In [8]: from pyquest import Circuit

The operators are constructed from their classes with their target qubits, then any additional parameters (like a rotation angle), and then the control qubits as a keyword-only argument, e.g. Ry(0, .2, controls=[1]) creates a rotation operator about the y-axis of the Bloch sphere by 0.2 radians on qubit 0, controlled by qubit 1. A single operator can be applied to a register reg with reg.apply_operator(X(1)). To apply multiple operators at once, first collect them into a Circuit.

In [9]: circ = Circuit([H(0), X(2, controls=[0]), Ry(1, .23, controls=[2])])

In [10]: reg.apply_circuit(circ)

In [11]: reg[:]
Out[11]:
array([0.70710678+0.j, 0.        +0.j, 0.        +0.j, 0.        +0.j,
       0.        +0.j, 0.70243619+0.j, 0.        +0.j, 0.08113816+0.j])

Multiplying two registers together will return their inner product. For example, the expectation value of X(1) is

In [12]: temp = Register(copy_reg=reg)

In [13]: temp.apply_operator(X(1))

In [14]: reg * temp
Out[14]: (0.11398876176759418+0j)

A measurement can be performed with

In [15]: from pyquest.gates import M

In [16]: reg.apply_operator(M(1))
Out[16]: [0]

Remember that measurements are destructive.

In [17]: reg[:]
Out[17]:
array([0.70944592+0.j, 0.        +0.j, 0.        +0.j, 0.        +0.j,
       0.        +0.j, 0.70475988+0.j, 0.        +0.j, 0.        +0.j])

A register can also be directly modified, but may then end up in an invalid state if not properly normalised.

In [18]: reg[:] = 0

In [19]: reg[:]
Out[19]: array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])

In [20]: reg[4] = 1j

In [21]: reg[:]
Out[21]: array([0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j])

For further details on which operators are available and all methods of Register and Circuit, for now check out the documentation in the source files.

Development

If you want to contribute to the project or just play around with the source, you can use an editable install

$ pip3 install -e .

but this temporarily re-installs the build requirements every time the project is compiled and clutters the pyquest source directory with build artifacts. It is therefore a good idea to simply install the build requirements manually

$ pip3 install -r build_requirements.txt

and then call

$ python3 setup.py build

to build pyQuEST in the _skbuild/<os_id>/cmake-install/pyquest folder, or use

$ python3 setup.py install

to install the package without telling pip about it. This is really only recommended in a virtual environment.

pyquest's People

Contributors

rrmeister avatar

Stargazers

Simone Gasperini avatar Oleksii Borodenko avatar Ioannis Kolotouros avatar  avatar César Guerra avatar Ahmadrv avatar  avatar  avatar  avatar Luis Mantilla avatar Peter Morgan avatar Jonathan Foldager avatar  avatar  avatar Tom Flatters avatar Arthur avatar Tyson Jones avatar

Watchers

Tyson Jones avatar Matt Goh avatar  avatar

pyquest's Issues

Publish built wheels on PyPI

Hi Richard!
Would it be possible to publish the built wheels on PyPI so it is easier to integrate this into other environments without having to manually build (which sometimes fails locally, depending on the C config)?
Thanks!

Numpy 2.0 binary incompatibility

The dependency specified for numpy is >=1.20, but the pyquest wheels released on pypi.org are not compatible with numpy 2.0, which is an ABI-breaking release.

See numpy's advice for building compatible wheels: https://numpy.org/doc/stable/dev/depending_on_numpy.html#numpy-2-abi-handling.

It would be great to have pyquest wheels that are compatible with numpy ^2.0. Note that Numpy 2.0 drops support for Python 3.8. Python 3.8 is due to be end-of-lifed later this year, but if you wanted to keep supporting it then I think you could build your Python 3.8 wheels with 1.x numpy.

Release of pyQuEST package

Hi, I am just curious if you have any plans/estimations in the nearest future release of pyQuEST package?
I am looking for a Python interface to interact with the QuEST toolkit. So any kind of details regarding current progress and long term plans will be very helpful to make a correct decision on how to do such integration in the most efficient way.
Thanks.

Kraus map feature

I want to add custom Kraus maps to a circuit. However, this feature only exists in feature/kraus-op. I am working on Windows, and I cannot build pyQuEST from scratch, so I am using the built wheels on PyPI.

Would it be possible to either merge this branch into develop and build a new wheel, or to add a wheel from feature/kraus-op to PyPI?

Thanks!

Sampling from vector state

Hi, @rrmeister.
One of the features for the backend that I am looking for is connected to sampling from a vector state. Haven't found any relevant code to this functionality in pyQuest as well as in QuEST.
So in general was considering two options

  • Quantum Circuit Sampling (according to documentation measurements are destructive so candidate to implementation)
  • Direct sampling from state vector (but what about MPI and etc.?)
  • ... any other suggestions?
    but in any case will require additional effort to implement this but of course would like to have as a naive implementation in QuEST 😉
    Will be helpful if you can share your thoughts regarding sampling functionality...

No module named 'pyquest.core'

Hi, @rrmeister. I followed instructions from the develop branch and successfully built and installed pyquest but when I was trying to run it was missing some dependency. Can you help me to solve this issue?

>>> import pyquest
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "***\pyQuEST\pyquest\__init__.py", line 7, in <module>
    from pyquest.core import QuESTEnvironment, Register, Circuit  # noqa: F401
ModuleNotFoundError: No module named 'pyquest.core'

Documentation about distributed calculations

Hi, @rrmeister , @TysonRayJones.
I was working on configuration distributed calculations with pyQuEST and would like to share a few cases that appeared during setup. Would be glad to get feedback and if need will create separate tickets.

First of all I have started an investigation from the main QuEST repo looking for examples and documentation on how to set up distributed calculations in a simple app. Or I was so unlucky or information about configuration of distributed calculation was so limited that I found only reference to original article published in Scientific Report QuEST and High Performance Simulation of Quantum Computers and report with benchmarks, but it's not what I was looking for. Also I was looking into the pyQuEST package but probably because it's so new it's too early to add such an example. Anyway, I guess one small page can help decrease the entry barrier for newcomers and also demonstrates a real example of using distributed calculations with a small application similar to https://github.com/QuEST-Kit/QuEST/tree/master/examples. So, to start with something I come up with a small example:

import pyquest
from pyquest import Register, Circuit
from pyquest.unitaries import H
from mpi4py import MPI


def main() -> int:
    mpi_comm = MPI.COMM_WORLD
    mpi_rank = mpi_comm.Get_rank()
    mpi_size = mpi_comm.Get_size()

    print(pyquest.env)
    print(f"Rank: {mpi_rank}, Size: {mpi_size} running on {MPI.Get_processor_name()}")

    num_qubits = 16
    reg = Register(num_qubits)
    h_gates = [H(i) for i in range(num_qubits)]
    circ = Circuit(h_gates)
    reg.apply_circuit(circ)

    result = reg.prob_of_all_outcomes([i for i in range(num_qubits)])

    if mpi_rank == 0:
        print(result)

    return 0


if __name__ == "__main__":
    import sys

    sys.exit(main())

And indeed pyQuEST(QuEST) just works! but really you have to spent some time and it's not obvious from the first look how it just works.

Challenges have started to appear at the beginning, as always 🤓 I could't built pyQuEST for Python 3.10 because wheel for numpy==1.20.1 was absent in PyPi https://pypi.org/project/numpy/1.20.1/#files. I was so naive that decided to override it with numpy 2.0.0:

ValueError: Unable to avoid copy while creating an array as requested.
If using `np.array(obj, copy=False)` replace it with `np.asarray(obj)` to allow a copy when needed (no behavior change in NumPy 1.x).
For more details, see https://numpy.org/devdocs/numpy_2_0_migration_guide.html#adapting-to-changes-in-the-copy-keyword.
File "/main.py", line 35, in <module>
sys.exit(main())
File "/main.py", line 24, in main
result = reg.prob_of_all_outcomes([i for i in range(num_qubits)])
File "core.pyx", line 581, in pyquest.core.Register.prob_of_all_outcomes

after which I had to take the last compatible version numpy==1.26.4 that has the wheel for Python 3.10. So I am curious how pyQuEST was built for Python 3.10 if numpy wheel was missing? And suggestion, is it possible to update build requirements to latest numpy version 1.xx or am I missing something?

Next "challenge" was to understand importance of the following message

ERROR: Trying to initialize QuESTEnv multiple times. Ignoring…

you know, even if it just says Ignoring... at the end, it's kind of weird to see such a message as an error because after that I thought that initialization of pyQuEST must be done only once! but how can it be done if this script will run multiple times on the different nodes? Or may be something might become in inconsistent state in case of multiple initialization?

Another case was related to the question that was came in mind how calculations was really distributed across nodes? until I found this hidden 💎 here https://github.com/QuEST-Kit/QuEST/blob/master/QuEST/include/QuEST.h#L504. Definitely, code well documented and supported with explanations but spread across different projects and files which adds some complexity in understanding.

Missing library stubs or py.typed marker

Hi, @rrmeister. 👋

When mypy type checker have been added into the project then got the following messages

error: Skipping analyzing "pyquest.unitaries": module is installed, but missing library stubs or py.typed marker  [import-untyped]
note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
error: Skipping analyzing "pyquest": module is installed, but missing library stubs or py.typed marker  [import-untyped]
error: Skipping analyzing "pyquest.gates": module is installed, but missing library stubs or py.typed marker  [import-untyped]
error: Skipping analyzing "pyquest": module is installed, but missing library stubs or py.typed marker  [import-untyped]
error: Skipping analyzing "pyquest.initialisations": module is installed, but missing library stubs or py.typed marker  [import-untyped]

Basically we applied fix and ignore these messages but I guess it's a good practice to have help with type annotations/stubs or adding py.typed. What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.