Skip to content
This repository has been archived by the owner on Jun 12, 2023. It is now read-only.

Migrate Quantum Volume circuits to use circuit library #460

Merged
merged 5 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 42 additions & 44 deletions qiskit/ignis/verification/quantum_volume/circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@
Generates quantum volume circuits
"""

import copy
import itertools
import warnings

import numpy as np
import qiskit
from qiskit.quantum_info.random import random_unitary

from qiskit.circuit.library import QuantumVolume
from qiskit.circuit.quantumcircuit import QuantumCircuit


def qv_circuits(qubit_lists=None, ntrials=1,
qr=None, cr=None):
def qv_circuits(qubit_lists, ntrials=1,
qr=None, cr=None, seed=None):
"""
Return a list of square quantum volume circuits (depth=width)

Expand All @@ -36,64 +41,57 @@ def qv_circuits(qubit_lists=None, ntrials=1,
ntrials (int): number of random iterations
qr (QuantumRegister): quantum register to act on (if None one is created)
cr (ClassicalRegister): classical register to measure to (if None one is created)
seed (int): An optional RNG seed to use for the generated circuit

Returns:
tuple: A tuple of the type (``circuits``, ``circuits_nomeas``) wheere:
``circuits`` is a list of lists of circuits for the qv sequences
(separate list for each trial) and `` circuitss_nomeas`` is the
same circuits but with no measurements for the ideal simulation
"""
if qr is not None:
warnings.warn("Passing in a custom quantum register is deprecated and "
"will be removed in a future release. This argument "
"never had any effect.",
DeprecationWarning)

if cr is not None:
warnings.warn("Passing in a custom classical register is deprecated "
"and will be removed in a future release. This argument "
"never had any effect.",
DeprecationWarning)
for qubit_list in qubit_lists:
count = itertools.count(qubit_list[0])
for qubit in qubit_list:
if qubit != next(count):
warnings.warn("Using a qubit list to map a virtual circuit to "
"a physical layout is deprecated and will be "
"removed in a future release. Instead use "
"''qiskit.transpile' with the "
"'initial_layout' parameter")
depth_list = [len(qubit_list) for qubit_list in qubit_lists]

circuits = [[] for e in range(ntrials)]
circuits_nomeas = [[] for e in range(ntrials)]

# get the largest qubit number out of all the lists (for setting the
# register)

depth_list = [len(qubit_list) for qubit_list in qubit_lists]

# go through for each trial
for trial in range(ntrials):

# go through for each depth in the depth list
for depthidx, depth in enumerate(depth_list):

n_q_max = np.max(qubit_lists[depthidx])

qr = qiskit.QuantumRegister(int(n_q_max+1), 'qr')
qr2 = qiskit.QuantumRegister(int(depth), 'qr')
cr = qiskit.ClassicalRegister(int(depth), 'cr')

qc = qiskit.QuantumCircuit(qr, cr)
qc2 = qiskit.QuantumCircuit(qr2, cr)

qv_circ = QuantumVolume(depth, depth, seed=seed)
# TODO: Remove this when we remove support for doing pseudo-layout
# via qubit lists
if n_q_max != depth:
qc = QuantumCircuit(int(n_q_max + 1))
qc2 = copy.copy(qv_circ)
qc.compose(qv_circ, qubit_lists[depthidx], inplace=True)
else:
qc = qv_circ
qc2 = copy.copy(qc)
qc.measure_active()
qc.name = 'qv_depth_%d_trial_%d' % (depth, trial)
qc2.name = qc.name

# build the circuit
for _ in range(depth):
# Generate uniformly random permutation Pj of [0...n-1]
perm = np.random.permutation(depth)
# For each pair p in Pj, generate Haar random SU(4)
for k in range(int(np.floor(depth/2))):
unitary = random_unitary(4)
pair = int(perm[2*k]), int(perm[2*k+1])
qc.append(unitary, [qr[qubit_lists[depthidx][pair[0]]],
qr[qubit_lists[depthidx][pair[1]]]])
qc2.append(unitary, [qr2[pair[0]],
qr2[pair[1]]])

# append an id to all the qubits in the ideal circuits
# to prevent a truncation error in the statevector
# simulators
qc2.u1(0, qr2)

circuits_nomeas[trial].append(qc2)

# add measurement
for qind, qubit in enumerate(qubit_lists[depthidx]):
qc.measure(qr[qubit], cr[qind])

circuits[trial].append(qc)

return circuits, circuits_nomeas
50 changes: 50 additions & 0 deletions releasenotes/notes/refactor-qv-518f99d2114c9c2e.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
features:
- |
The :func:`qiskit.ignis.verification.qv_circuits` function has a new
kwarg ``seed`` which can be used to specify a seed for the random number
generator used to generate the Quantum Volume circuits. This can be useful
for having a reproducible circuit.
deprecations:
- |
The kwargs ``qr`` and ``cr`` for the
:func:`qiskit.ignis.verification.qv_circuits` function have been deprecated
and will be removed in a future release. These kwargs were documented as
being used for specifing a :class:`qiskit.circuit.QuantumRegister` and
:class:`qiskit.circuit.ClassicalRegister` to use in the generated Quantum
Volume circuits instead of creating new ones. However, the parameters were
never actually respected and a new Register would always be created
regardless of whether they were set or not. This behavior is unchanged and
these kwargs still do not have any effect, but are being deprecated prior
to removal to avoid a breaking change for users who may have been setting
either.
- |
Support for passing in subsets of qubits as a list in the ``qubit_lists``
parameter for the :func:`qiskit.ignis.verification.qv_circuits` function
has been deprecated and will removed in a future release. In the past
this was used to specify a layout to run the circuit on a device. In
other words if you had a 5 qubit device and wanted to run a 2 qubit
QV circuit on qubits 1, 3, and 4 of that device. You would pass in
``[1, 3, 4]`` as one of the lists in ``qubit_lists``, which would
generate a 5 qubit virtual circuit and have qv applied to qubits 1, 3,
and 4 in that virtual circuit. However, this functionality is not necessary
and overlaps with the concept of ``initial_layout`` in the transpiler and
whether a circuit has been embedded with a layout set. Moving forward
instead you should just run :func:`~qiskit.compiler.transpile` or
:func:`~qiskit.execute.execute` with initial layout set to do this. For
example, running the above example would become::

from qiskit import execute
from qiskit.ignis.verification import qv_circuits

initial_layout = [1, 3, 4]
qv_circs, _ = qv_circuits([list(range3)])
execute(qv_circuits, initial_layout=initial_layout)

upgrade:
- |
The :func:`qiskit.ignis.verification.qv_circuits` function is now using
the circuit library class :class:`~qiskit.circuit.library.QuantumVolume`
to construct its output instead of building the circuit from scratch.
This may result in subtle differences from the output from the previous
version.
98 changes: 0 additions & 98 deletions test/quantum_volume/generate_data.py

This file was deleted.

Loading