qutip_qip.compiler¶
Compilers for the hardware models in device
Classes
|
Base class of compilers, including the |
|
Compiler for |
|
Compiler for |
|
Compiler for |
|
A gate (pulse) scheduler for quantum circuits (instructions). |
|
Representation of pulses that implement a quantum gate. |
- class qutip_qip.compiler.CavityQEDCompiler(num_qubits, params, global_phase=0.0, pulse_dict=None, N=None)[source]¶
Bases:
qutip_qip.compiler.gatecompiler.GateCompiler
Compiler for
DispersiveCavityQED
. Compiled pulse strength is in the unit of GHz.Supported native gates: “RX”, “RY”, “RZ”, “ISWAP”, “SQRTISWAP”, “GLOBALPHASE”.
Default configuration (see
GateCompiler.args
andGateCompiler.compile
):key
value
shape
rectangular
params
Hardware Parameters
- Parameters
- num_qubits: int
The number of qubits in the system.
- params: dict
A Python dictionary contains the name and the value of the parameters. See
CavityQEDModel
for the definition.- global_phase: float, optional
Record of the global phase change and will be returned.
Examples
>>> import numpy as np >>> from qutip_qip.circuit import QubitCircuit >>> from qutip_qip.device import ModelProcessor, CavityQEDModel >>> from qutip_qip.compiler import CavityQEDCompiler >>> >>> qc = QubitCircuit(2) >>> qc.add_gate("ISWAP", targets=[0, 1]) >>> >>> model = CavityQEDModel(2) >>> processor = ModelProcessor(model=model) >>> compiler = CavityQEDCompiler(2, params=model.params) >>> processor.load_circuit( ... qc, compiler=compiler) ({'sz0': array([ 0. , 2500. , 2500.01315789]), 'sz1': array([ 0. , 2500. , 2500.01315789]), 'g0': array([ 0. , 2500. , 2500.01315789]), 'g1': array([ 0. , 2500. , 2500.01315789])}, {'sz0': array([-0.5, -9.5]), 'sz1': array([-0.5, -9.5]), 'g0': array([0.01, 0. ]), 'g1': array([0.01, 0. ])})
Notice that the above example is equivalent to using directly the
DispersiveCavityQED
.- Attributes
- gate_compiler: dict
The Python dictionary in the form of {gate_name: decompose_function}. It saves the decomposition scheme for each gate.
- iswap_compiler(gate, args)[source]¶
Compiler for the ISWAP gate.
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- rx_compiler(gate, args)[source]¶
Compiler for the RX gate
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- rz_compiler(gate, args)[source]¶
Compiler for the RZ gate
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- sqrtiswap_compiler(gate, args)[source]¶
Compiler for the SQRTISWAP gate.
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
Notes
This version of sqrtiswap_compiler has very low fidelity, please use iswap
- class qutip_qip.compiler.GateCompiler(num_qubits=None, params=None, pulse_dict=None, N=None)[source]¶
Bases:
object
Base class of compilers, including the
GateCompiler.compile()
method. It compiles aQubitCircuit
into the pulse sequence for the processor. The core member function compile calls compiling method from the sub-class and concatenate the compiled pulses.- Parameters
- num_qubits: int
The number of the component systems.
- params: dict, optional
A Python dictionary contains the name and the value of the parameters, such as laser frequency, detuning etc. It will be saved in the class attributes and can be used to calculate the control pulses.
- Attributes
- gate_compiler: dict
The Python dictionary in the form of {gate_name: compiler_function}. It saves the compiling routine for each gate. See sub-classes for implementation. Note that for continuous pulse, the first coeff should always be 0.
- args: dict
The compilation configurations. It will be passed to each compiling functions. Available arguments:
shape
: The compiled pulse shape.rectangular
or one of the SciPy window functions.num_samples
: Number of samples for continuous pulses. It has no effect for rectangular pulses.params
: Hardware parameters computed in theProcessor
.
- compile(circuit, schedule_mode=None, args=None)[source]¶
Compile the the native gates into control pulse sequence. It calls each compiling method and concatenates the compiled pulses.
- Parameters
- circuit: :class:`.QubitCircuit` or list of
Gate
A list of elementary gates that can be implemented in the corresponding hardware. The gate names have to be in gate_compiler.- schedule_mode: str, optional
"ASAP"
for “as soon as possible” or"ALAP"
for “as late as possible” orFalse
orNone
for no schedule. Default is None.- args: dict, optional
A dictionary of arguments used in a specific gate compiler function.
- Returns
- tlist, coeffs: array_like or dict
Compiled ime sequence and pulse coefficients. if
return_array
is true, return A 2d NumPy array of the shape(len(ctrls), len(tlist))
. Each row corresponds to the control pulse sequence for one Hamiltonian. ifreturn_array
is false
- classmethod generate_pulse_shape(shape, num_samples, maximum=1.0, area=1.0)[source]¶
Return a tuple consisting of a coeff list and a time sequence according to a given pulse shape.
- Parameters
- shapestr
The name
"rectangular"
for constant pulse or the name of a Scipy window function. See the Scipy documentation for detail.- num_samplesint
The number of the samples of the coefficients.
- maximumfloat, optional
The maximum of the coefficients. The absolute value will be used if negative.
- areafloat, optional
The total area if one integrates coeff as a function of the time. If the area is negative, the pulse is flipped vertically (i.e. the pulse is multiplied by the sign of the area).
- Returns
- coeff, tlist :
If the default window
"shape"="rectangular"
is used, both are float numbers. If Scipy window functions are used, both are a 1-dimensional numpy array with the same size.
Notes
If Scipy window functions are used, it is suggested to set
Processor.pulse_mode
to"continuous"
. Notice that finite number of sampling points will also make the total integral of the coefficients slightly deviate fromarea
.Examples
from qutip_qip.compiler import GateCompiler import numpy as np compiler = GateCompiler() coeff, tlist= compiler.generate_pulse_shape( "hann", # Scipy Hann window 1000, # 100 sampling point maximum=3., # Notice that 2 pi is added to H by qutip solvers. area= 1., )
We can plot the generated pulse shape:
import matplotlib.pyplot as plt plt.plot(tlist, coeff) plt.show()
The pulse is normalized to fit the area. Notice that due to the finite number of sampling points, it is not exactly 1.
>>> round(np.trapz(coeff, tlist), 2) 1.0
- class qutip_qip.compiler.Instruction(gate, tlist=None, pulse_info=(), duration=1)[source]¶
Bases:
object
Representation of pulses that implement a quantum gate. It contains the control pulse required to implement the gate on a particular hardware model.
- Parameters
- gate: :class:`.Gate`
The quantum gate.
- duration: list, optional
The execution time needed for the instruction.
- tlist: array_like, optional
A list of time at which the time-dependent coefficients are applied. See
Pulse
for detailed information`- pulse_info: list, optional
A list of tuples, each tuple corresponding to a pair of pulse label and pulse coefficient, in the format (str, array_like). This pulses will implement the desired gate.
- Attributes
- targets: list, optional
The target qubits.
- controls: list, optional
The control qubits.
- used_qubits: set
Union of the control and target qubits.
- property controls¶
Control qubits
- Type
list
- property name¶
Corresponding gate name
- property targets¶
Target qubits
- Type
list
- class qutip_qip.compiler.SCQubitsCompiler(num_qubits, params)[source]¶
Bases:
qutip_qip.compiler.gatecompiler.GateCompiler
Compiler for
SCQubits
. Compiled pulse strength is in the unit of GHz.Supported native gates: “RX”, “RY”, “CNOT”.
Default configuration (see
GateCompiler.args
andGateCompiler.compile
):key
value
shape
hann
num_samples
1000
params
Hardware Parameters
For single-qubit gate, we apply the DRAG correction [8]
\[ \begin{align}\begin{aligned}\Omega^{x} &= \Omega_0 - \frac{\Omega_0^3}{4 \alpha^2}\\\Omega^{y} &= - \dot{\Omega}_0 / \alpha\\\Omega^{z} &= - \Omega_0**2 / \alpha + \frac{2 \Omega_0^2)}{ 4 \alpha }\end{aligned}\end{align} \]where \(\Omega_0\) is the original shape of the pulse. Notice that the \(\Omega_0\) and its first derivative should be 0 from the starts and the end.
- Parameters
- num_qubits: int
The number of qubits in the system.
- params: dict
A Python dictionary contains the name and the value of the parameters. See
SCQubitsModel()
for the definition.
Examples
>>> import numpy as np >>> from qutip_qip.circuit import QubitCircuit >>> from qutip_qip.device import ModelProcessor, SCQubitsModel >>> from qutip_qip.compiler import SCQubitsCompiler >>> >>> qc = QubitCircuit(2) >>> qc.add_gate("CNOT", targets=0, controls=1) >>> >>> model = SCQubitsModel(2) >>> processor = ModelProcessor(model=model) >>> compiler = SCQubitsCompiler(2, params=model.params) >>> processor.load_circuit(qc, compiler=compiler);
Notice that the above example is equivalent to using directly the
SCQubits
.- Attributes
- num_qubits: int
The number of the component systems.
- params: dict
A Python dictionary contains the name and the value of the parameters, such as laser frequency, detuning etc.
- gate_compiler: dict
The Python dictionary in the form of {gate_name: decompose_function}. It saves the decomposition scheme for each gate.
- cnot_compiler(gate, args)[source]¶
Compiler for CNOT gate using the cross resonance iteraction. See https://journals.aps.org/prb/abstract/10.1103/PhysRevB.81.134507 for reference.
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- rx_compiler(gate, args)[source]¶
Compiler for the RX gate
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- ry_compiler(gate, args)[source]¶
Compiler for the RZ gate
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- class qutip_qip.compiler.Scheduler(method='ALAP', allow_permutation=True, constraint_functions=None)[source]¶
Bases:
object
A gate (pulse) scheduler for quantum circuits (instructions). It schedules a given circuit or instructions to reduce the total execution time by parallelization. It uses heuristic methods mainly from in https://doi.org/10.1117/12.666419.
The scheduler includes two methods, “ASAP”, as soon as possible, and “ALAP”, as late as possible. The later is commonly used in quantum computation because of the finite lifetime of qubits.
The scheduler aims at pulse schedule and therefore does not consider merging gates to reduce the gates number. It assumes that the input circuit is optimized at the gate level and matches the hardware topology.
- Parameters
- method: str
“ASAP” for as soon as possible. “ALAP” for as late as possible.
- constraint_functions: list, optional
A list of hardware constraint functions. Default includes a function qubit_contraint, i.e. one qubit cannot be used by two gates at the same time.
- apply_constraint(ind1, ind2, instructions)[source]¶
Apply hardware constraint among the commuting gates to check if two instructions can be executed in parallel.
- Parameters
- ind1, ind2: int
indices of the two instructions
- instructions: list
The instruction list
- commutation_rules(ind1, ind2, instructions)[source]¶
Determine if two gates commute, given that their used qubits overlap. Since usually the input gates are already in a universal gate sets, it uses an oversimplified condition:
If the two gates do not have the same name, they are considered as not commuting. If they are the same gate and have the same controls or targets, they are considered as commuting. E.g. CNOT 0, 1 commute with CNOT 0, 2.
- schedule(circuit, gates_schedule=False, return_cycles_list=False, random_shuffle=False, repeat_num=0)[source]¶
Schedule a
QubitCircuit
, a list ofGates
or a list ofInstruction
. For pulse schedule, the execution time for eachInstruction
is given in itsduration
attributes.The scheduler first generates a quantum gates dependency graph, containing information about which gates have to be executed before some other gates. The graph preserves the mobility of the gates, i.e. commuting gates are not dependent on each other, even if they use the same qubits. Next, it computes the longest distance of each node to the start and end nodes. The distance for each dependency arrow is defined by the execution time of the instruction (By default, it is 1 for all gates). This is used as a priority measure in the next step. The gate with a longer distance to the end node and a shorter distance to the start node has higher priority. In the last step, it uses a list-schedule algorithm with hardware constraint and priority and returns a list of cycles for gates/instructions.
For pulse schedule, an additional step is required to compute the start time of each instruction. It adds the additional dependency caused by hardware constraint to the graph and recomputes the distance of each node to the start and end node. This distance is then converted to the start time of each instruction.
- Parameters
- circuit: QubitCircuit or list
For gate schedule, it should be a QubitCircuit or a list of Gate objects. For pulse schedule, it should be a list of Instruction objects, each with an attribute duration that indicates the execution time of this instruction.
- gates_schedule: bool, optional
True
, if only gates schedule is needed. This saves some computation that is only useful to pulse schedule. If the inputcircuit
is aQubitCircuit
, it will be assigned toTrue
automatically. Otherwise, the default is False.- return_cycles_list: bool, optional
If
True
, the method returns thecycles_list
, e.g.[{0, 2}, {1, 3}]
, which means that the first cycle contains gates0 and gates2 while the second cycle contains gates1 and gates3. It is only useful for gates schedule.- random_shuffle: bool, optional
If the commuting gates are randomly scuffled to explore larger search space.
- repeat_num: int, optional
Repeat the scheduling several times and use the best result. Used together with
random_shuffle=True
.
- Returns
- gate_cycle_indices or instruction_start_time: list
The cycle indices for each gate or the start time for each instruction.
Examples
>>> from qutip_qip.circuit import QubitCircuit >>> from qutip_qip.compiler import Scheduler >>> circuit = QubitCircuit(7) >>> circuit.add_gate("SNOT", 3) # gate0 >>> circuit.add_gate("CZ", 5, 3) # gate1 >>> circuit.add_gate("CZ", 4, 3) # gate2 >>> circuit.add_gate("CZ", 2, 3) # gate3 >>> circuit.add_gate("CZ", 6, 5) # gate4 >>> circuit.add_gate("CZ", 2, 6) # gate5 >>> circuit.add_gate("SWAP", [0, 2]) # gate6 >>> >>> scheduler = Scheduler("ASAP") >>> scheduler.schedule(circuit, gates_schedule=True) [0, 1, 3, 2, 2, 3, 4]
The result list is the cycle indices for each gate. It means that the circuit can be executed in 5 gate cycles:
[gate0, gate1, (gate3, gate4), (gate2, gate5), gate6]
Notice that gate3 and gate4 commute with gate2, therefore, the order is changed to reduce the number of cycles.
- class qutip_qip.compiler.SpinChainCompiler(num_qubits, params, setup='linear', global_phase=0.0, pulse_dict=None, N=None)[source]¶
Bases:
qutip_qip.compiler.gatecompiler.GateCompiler
Compiler for
SpinChain
. Compiled pulse strength is in the unit of MHz.Supported native gates: “RX”, “RY”, “RZ”, “ISWAP”, “SQRTISWAP”, “GLOBALPHASE”.
Default configuration (see
GateCompiler.args
andGateCompiler.compile
):key
value
shape
rectangular
params
Hardware Parameters
- Parameters
- num_qubits: int
The number of qubits in the system.
- params: dict
A Python dictionary contains the name and the value of the parameters. See
SpinChainModel
for the definition.- setup: string
“linear” or “circular” for two sub-classes.
- global_phase: bool
Record of the global phase change and will be returned.
- pulse_dict: dict, optional
A map between the pulse label and its index in the pulse list. If given, the compiled pulse can be identified with
(pulse_label, coeff)
, instead of(pulse_index, coeff)
. The number of key-value pairs should match the number of pulses in the processor. If it is empty, an integerpulse_index
needs to be used in the compiling routine saved under the attributesgate_compiler
.
Examples
>>> import numpy as np >>> from qutip_qip.circuit import QubitCircuit >>> from qutip_qip.device import ModelProcessor, SpinChainModel >>> from qutip_qip.compiler import SpinChainCompiler >>> >>> qc = QubitCircuit(2) >>> qc.add_gate("RX", 0, arg_value=np.pi) >>> qc.add_gate("RZ", 1, arg_value=np.pi) >>> >>> model = SpinChainModel(2, "linear", g=0.1) >>> processor = ModelProcessor(model=model) >>> compiler = SpinChainCompiler(2, params=model.params, setup="linear") >>> processor.load_circuit( ... qc, compiler=compiler) ({'sx0': array([0., 1.]), 'sz1': array([0. , 0.25, 1. ])}, {'sx0': array([0.25]), 'sz1': array([1., 0.])})
Notice that the above example is equivalent to using directly the
LinearSpinChain
.- Attributes
- num_qubits: int
The number of the component systems.
- params: dict
A Python dictionary contains the name and the value of the parameters, such as laser frequency, detuning etc.
- gate_compiler: dict
The Python dictionary in the form of {gate_name: decompose_function}. It saves the decomposition scheme for each gate.
- setup: string
“linear” or “circular” for two sub-classes.
- global_phase: bool
Record of the global phase change and will be returned.
- iswap_compiler(gate, args)[source]¶
Compiler for the ISWAP gate.
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- rx_compiler(gate, args)[source]¶
Compiler for the RX gate
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- rz_compiler(gate, args)[source]¶
Compiler for the RZ gate
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of
- sqrtiswap_compiler(gate, args)[source]¶
Compiler for the SQRTISWAP gate.
- Parameters
- gate
Gate
: The quantum gate to be compiled.
- argsdict
The compilation configuration defined in the attributes
GateCompiler.args
or given as a parameter inGateCompiler.compile
.
- gate
- Returns
- A list of
Instruction
, including the compiled pulse - information for this gate.
- A list of