Skip to content

Each c_if call linear in number of circuit Clbits #7249

@jakelishman

Description

@jakelishman

Information

  • Qiskit Terra version: main
  • Python version: any
  • Operating system: any

What is the current behavior?

Any call to Instruction.c_if is linear in the number of Clbit references in classical registers in the circuit. This is because of some lines in InstructionSet that unroll all registers on every call: https://github.com/Qiskit/qiskit-terra/blob/49110f9c596fc509f189f38cfbdbb3100407bff2/qiskit/circuit/instructionset.py#L61-L64

Steps to reproduce the problem

In [1]: from qiskit.circuit import QuantumCircuit
   ...: import numpy as np
   ...: import scipy.stats
   ...:
   ...: def build(n):
   ...:     qc = QuantumCircuit(1, n)
   ...:     instructions = qc.x(0)
   ...:     def payload():
   ...:         instructions.c_if(0, 0)
   ...:     return payload
   ...:
   ...: times = []
   ...: ns = [100, 300, 1000, 3000, 10000]
   ...: for n in ns:
   ...:     payload = build(n)
   ...:     out = %timeit -o payload()
   ...:     times.append(out.average)
   ...: scipy.stats.linregress(np.log(ns), np.log(times)).slope
10.8 µs ± 101 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
28.2 µs ± 922 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
94 µs ± 640 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
276 µs ± 5.04 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
919 µs ± 7.14 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Out[1]: 0.9710414298958975

What is the expected behavior?

This should be a constant-time operation.

Suggested solutions

This can easily be fixed by the same methods as #7246.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions