Giter VIP home page Giter VIP logo

qflex's Introduction

Travis-CI Total alerts Language grade: Python Language grade: C++
Nature NPJ Quantum Information Quantum Science and Technology

qFlex: A flexible high-performance simulator for verifying and benchmarking quantum circuits implemented on real hardware

Description

Flexible Quantum Circuit Simulator (qFlex) implements an efficient tensor network, CPU-based simulator of large quantum circuits. qFlex computes exact probability amplitudes, a task that proves essential for the verification of quantum hardware, as well as mimics quantum machines by computing amplitudes with low fidelity. qFlex targets quantum circuits in the range of sizes expected for supremacy experiments based on random quantum circuits, in order to verify and benchmark such experiments.

Documentation

qFlex scientific documentation and results can be found in [1], [2] and [3]. For technical documentation on how to use qFlex, see qflex/docs.

[1] B. Villalonga, et al., "A flexible high-performance simulator for verifying and benchmarking quantum circuits implemented on real hardware", NPJ Quantum Information 5, 86 (2019)

[2] B. Villalonga, et al., "Establishing the Quantum Supremacy Frontier with a 281 Pflop/s Simulation", Quantum Science and Technology 5 (3), 034003 (2020)

[3] "Quantum supremacy using a programmable superconducting processor", Nature 574, 505โ€“510 (2019)

Build methods

To ensure cross-platform viability, qFlex supports multiple different build methods. If one of the build methods below does not work on your system, try using one of the other methods listed.

Local installation

To build qFlex on your machine, simply run:

$ autoreconf -i && autoconf && ./configure
$ make && make run-tests

To disable qFlex python interface, use ./configure --disable-pybind11.

If missing, python modules can be installed as follows:

$ python3 -m pip install -r scripts/requirements.txt

After running these commands, qFlex can be installed by running make install. By default, this installs qFlex in $HOME/local/. To change the installation folder, use ./configure --prefix=/new/installation/folder/.

qFlex provides an experimental support for OpenMP. To activate OpenMP, run ./configure with the extra-option --enable-openmp.

qFlex relies on OpenBLAS for optimized matrix operations.

For more information, see the installation guide.

Build Using Docker

Docker allows you to run qFlex in an isolated environment, without having to worry about managing dependencies.

To build qFlex with Docker, see the Docker guide.

An automated qFlex Docker container, synced with the master branch, can be pulled from Docker Hub as:

$ docker pull ngnrsaa/qflex

Build Using Rootless Containers

Rootless containers are an alternative to Docker targeted at users who may not have root privileges on their machine.

To run qFlex in a rootless container, see qflex/docs/rootless_container.md.

Using Google Cirq

Cirq is a framework for modeling and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.

To run qFlex on Google Cirq circuits, or just to call the simulator from Python, see qflex/docs/cirq_interface.md.

License

Copyright ยฉ 2019, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.

The Flexible Quantum Circuit Simulator (qFlex) framework is licensed under the Apache License, Version 2.0 (the "License"); you may not use this application except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

qflex's People

Contributors

95-martin-orion avatar alan-kao avatar alankao64 avatar alexandrupaler avatar benjaminvillalonga avatar dagart avatar dlyongemallo avatar dmitrylyakh avatar kkissell avatar mofeing avatar s-mandra avatar sboixo avatar viathor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qflex's Issues

Document directory structure

We should provide documentation for the following items (this list is incomplete):

  1. From-scratch qFlex installation process for at least one OS (preferably several)
  2. Directory structure and purpose of each library
  3. Expected input files and formatting for each

yapf checks .venv

I have a python virtual environment in the root of qflex. Yapf3 is checking the style in that folder.

Auto-order cut definitions

There is currently an unstated assumption that ordering-file cuts list the qubits they affect in index order (i.e. 'cut 28 40' is valid, but 'cut 40 28' is not). This causes segfaults if the qubits are given in the wrong order.

To resolve this, cuts read from file should be internally re-ordered to be in the correct order.

add unit tests

Unit tests need to be added before refactoring to ensure the same behaviour is maintained.

It probably makes the most sense to use gtest.

Optimize reorderings by decreasing number of unnecessary copying

NOT A PRIORITY. Right now general reorderings are split in three simpler ones. Every one of the simpler reorderings copies data from the tensor to scratch and back, so that each of the reorderings is complete and puts the data in the tensor data array. However, each simple reordering doesn't have to be complete in this sense, but only the end result of the three (or fewer, sometimes) simple reorderings. For this reason, a few copying parts of the reordering can be neglected, which can speed it up up to a 20-30% I estimate.

Create functionality for contraction with open indexes

When computing all amplitudes of the "open" region of the circuit, it is faster to contract that region without closing the indexes. The resulting tensor is contracted with the tensor resultant from the rest of the circuit.

grid layouts

Are the grid layouts bristlecone48 and bristlecone70 the only supported for the moment? Will there be other grids like sycamore_48?

The current file format is restricted to 12x12 grids. Is this a hard limit? Can it be, for example, 7x7 or 15x15?

profile memory usage

There appear to be several places in the code which may use more memory than necessary, though it's not clear if they're on the critical path. Would be good to create a memory profile using something like gperftools.

make after docopt

without this line (added doctopt.o to the OBJS1)
OBJS1 = evaluate_circuit.o tensor.o contraction_utils.o read_circuit.o docopt.o
the make returns

main.cpp:(.text.startup+0x9c): undefined reference to `docopt::docopt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)'
collect2: error: ld returned 1 exit status

fix memory management

Pointer ownership should be clarified using, e.g., std::unique_ptr. Right now, scratch pointers are being passed around all over the place, and it's not clear what the chain of ownership is. (The pointers are also just NULLed at the end, without any deletes.)

Improve failure-case behavior

In the event of a test failure, it's important that users get a clear idea of how and why the test failed. Steps to achieve this include:

  1. Unit-testing all assert() calls, to build user confidence in code correctness.
  2. Providing clear and unique error messages for each failure case, so users can tell at a glance where the test failed and why.
  3. Adding assertions and log messages to unprotected segfault locations, since segfaults are notoriously difficult to track down.

Cirq on Alpine (rootless-container)

Installing Cirq on Alpine seems problematic. The following commands:

# apk add libpng-dev
# apk add freetype-dev
# apk add python3
# apk add python3-dev
# apk add python3-tkinter
# apk add py3-scipy
# apk add py3-numpy
# apk add py-numpy-dev
# apk add openblas-dev
# pip3 install cirq

allow the installation of Cirq. However, I get the following error:

# python3 -m cirq
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/site-packages/cirq/__init__.py", line 41, in <module>
    from cirq.experiments import (
  File "/usr/lib/python3.7/site-packages/cirq/experiments/__init__.py", line 1, in <module>
    from cirq.experiments.google_v2_supremacy_circuit import (
  File "/usr/lib/python3.7/site-packages/cirq/experiments/google_v2_supremacy_circuit.py", line 19, in <module>
    from cirq import circuits, devices, google, ops
  File "/usr/lib/python3.7/site-packages/cirq/google/__init__.py", line 29, in <module>
    from cirq.google.sim import (
  File "/usr/lib/python3.7/site-packages/cirq/google/sim/__init__.py", line 18, in <module>
    from cirq.google.sim.xmon_simulator import (
  File "/usr/lib/python3.7/site-packages/cirq/google/sim/xmon_simulator.py", line 45, in <module>
    from cirq.google.sim import xmon_stepper
  File "/usr/lib/python3.7/site-packages/cirq/google/sim/xmon_stepper.py", line 29, in <module>
    from cirq.google.sim import mem_manager
  File "/usr/lib/python3.7/site-packages/cirq/google/sim/mem_manager.py", line 186, in <module>
    SharedMemManager.get_instance()
  File "/usr/lib/python3.7/site-packages/cirq/google/sim/mem_manager.py", line 137, in get_instance
    SharedMemManager._instance = SharedMemManager()
  File "/usr/lib/python3.7/site-packages/cirq/google/sim/mem_manager.py", line 47, in __init__
    self._lock = Lock()
  File "/usr/lib/python3.7/multiprocessing/context.py", line 67, in Lock
    return Lock(ctx=self.get_context())
  File "/usr/lib/python3.7/multiprocessing/synchronize.py", line 162, in __init__
    SemLock.__init__(self, SEMAPHORE, 1, 1, ctx=ctx)
  File "/usr/lib/python3.7/multiprocessing/synchronize.py", line 59, in __init__
    unlink_now)
FileNotFoundError: [Errno 2] No such file or directory

Any idea?

refactor out common code

There's code duplication all over the place. For example, functions to read different formats of circuit files have large overlaps.

There also appear to be a number of variables which are unused. Some of these are due to code being copied and changed.

Determining number of qubits

In read_circuit.cpp, the function circuit_data_to_grid_of_tensors(), num_qubits is set to I * J, then num_qubits == I * J is evaluated. This raises the question of whether or not the number of qubits should be determined from the circuit data or from inputs of I and J.

The method of determining num_qubits should be set straight, whether it be from the grid or from I * J

merge cpp_only branch into master branch

Instead of having two different branches for the cpp_only and master (C++ and Fortran) code, there should be one codebase, with flags in the Makefile to control which dependencies are used and so on.

add Rz, fSim, and sqrt(Hz) gates

These gates need to be added:

  • sqrt(Hz): single-qubit gate, not parameterized
  • Rz: single-qubit gate with one real parameter
  • fSim: two-qubit gate with two real parameters

Integrate with Cirq

qFlex should implement the Cirq "SimulatesAmplitudes" interface to allow high-performance simulation of Cirq circuits. Prerequisites for this:

  1. A Python wrapper for qFlex (e.g., using Cython).
  2. A method for generating qFlex input from Cirq circuits. The circuit and grid files should be simple, but "contraction ordering" is not a supported concept in Cirq AFAIK.

execution error

After the latest commit on the master branch I get the following error

./qflex.x 11 12 2 0.005 ./circuits/ben_11_16_0.txt ./ordering/bristlecone_48.txt ./grid/bristlecone_48.txt
The number of qubits read from the file: 70, does not match I*J: 132.
The second qubit of '1 cz 80 81' references (6, 9) which must be coordinates of an active qubit.
qflex.x: read_circuit.cpp:487: void qflex::circuit_data_to_grid_of_tensors(std::istream*, int, int, int, std::__cxx11::string, std::__cxx11::string, const std::optional<std::vector<std::vector<int> > >&, const std::optional<std::vector<std::vector<int> > >&, std::vector<std::vector<std::vector<qflex::Tensor> > >&, qflex::s_type*): Assertion `!second_qubit_off' failed.

Migrate away from assert-failures

Assertions aren't the best option for terminating processes, since they don't provide much in the way of logs. We should investigate alternatives (e.g. C++ exceptions) and migrate away from assert() calls.

This also affects our tests, where EXPECT_DEATH doesn't play nice with multithreading.

generalize contraction code

In order for qflex to support arbitrary circuit layouts, we need to write a generic version of the contraction code which can take contraction details (i.e., ordering and cuts) as input.

standardise input between qflex and ShallowQC

qflex has a variable num_qubits which is read in as the first line of an input file, and is assumed to be the number of qubits in a rectangular grid of size I * J. (All qubits set to off are ignored.)

ShallowQC also has a variable named num_qubits, which is also read in as the first line of an input file, but denotes the number of qubits in the circuit. Consequently, when qflex reads in a ShallowQC circuit file, it has to read the first line into a dummy variable, then calculate num_qubits based on I and J.

The file formats should be reconciled so that circuit files can be shared without modifications to inputs or source code.

Document post-cut patch restrictions

The "sanity checks" mentioned in contraction_utils.h should be documented in the input_formats file. In particular, the naming restrictions surrounding cuts need to be properly explained.

Some context: when performing a cut, we iterate over all projection values of the cut. Since we allocate memory on a per-patch-name basis, and memory space is shared across these iterative steps, it's crucial that patches modified before a cut are not also modified after that cut - otherwise, the changes will spill over to the next iteration.

It would be possible to avoid this restriction by saving all patches prior to a cut, but this has a substantial memory cost. Instead, we prefer allowing users to specify which patches to copy by 'renaming' them with a merge after the cut. An example of this using the original 7x7 grid contraction can be found in the "ExampleOrdering" test.

Remove "fidelity" parameter

Fidelity is now determined from cuts; the "fidelity" parameter can be removed.

Documentation should be updated to reflect this as well.

Improve documentation regarding how states are printed.

In #88, I would expect that amplitude[0].second correspond to the quantum state |11000> (where qubit=5 is in last position). However, it corresponds to the state |00011>. Similarly, amplitude[1].second should correspond to |11001>, and instead correspond to |10011>. Am I doing/assuming something wrong?

Makefile linking qflex.x

In order for the linker to work I had to change lines 18 and 19 from the Makefile

$(TARGET1): $(OBJS1)
	$(CXX) -o $(TARGET1).x $(OBJS1) $(FLAGS)

Otherwise it complained that in tensor.cpp the cblas_*** methods were not found

I can send a PR with this if necessary.

Edit: My compiler is c++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

use typedefs and define structs in some places

I'm not sure why s_type is defined the way it is, rather than using MKL_Complex8 from the MKL?

There are also a couple of places where a parameter or return value is a vector, when maybe it should be a struct.

I think there are also some places where ints should be size_ts or vice versa, to allow compilation on different architectures, but I will need to do some more investigation.

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.