# Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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.
from enum import Enum
from braket.ir.jaqcd.shared_models import (
Angle,
DoubleControl,
DoubleTarget,
MultiTarget,
SingleControl,
SingleTarget,
TwoDimensionalMatrix,
)
"""
Instructions that can be supplied to the braket.ir.jaqcd.Program.
To add a new instruction:
- Implement a class in this module.
- Class must contain a property, "type", that is an enum of the class implemented in the
next step.
- Implement a subclass, "Type", within this class that extends [str, enum].
All enum values must be unique across all instructions, otherwise de-serialization
will have undeterministic behaviors. These enums will be used to determine what type
the instruction is, i.e. what class to use for deserializing.
- NOTE: Due to how multiple inhertiance works in Python it is easiest to define a
type enum class within each instruction, instead of calling the relevant parent
constructors to initialize it correctly.
- Inherit any classes from braket.ir.jaqcd.shared_models.
- Write up docstrings to define the instruction, properties, and examples.
"""
[docs]class H(SingleTarget):
"""
Hadamard gate.
Attributes:
type (str): The instruction type. default = "h". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> H(target=1)
"""
[docs] class Type(str, Enum):
h = "h"
type = Type.h
[docs]class I(SingleTarget): # noqa: E742, E261
"""
Identity gate.
Attributes:
type (str): The instruction type. default = "i". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> I(target=1)
"""
[docs] class Type(str, Enum):
i = "i"
type = Type.i
[docs]class X(SingleTarget):
"""
Pauli-X gate.
Attributes:
type (str): The instruction type. default = "x". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> X(target=0)
"""
[docs] class Type(str, Enum):
x = "x"
type = Type.x
[docs]class Y(SingleTarget):
"""
Pauli-Y gate.
Attributes:
type (str): The instruction type. default = "y". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> Y(target=0)
"""
[docs] class Type(str, Enum):
y = "y"
type = Type.y
[docs]class Z(SingleTarget):
"""
Pauli-Z gate.
Attributes:
type (str): The instruction type. default = "z". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> Z(target=0)
"""
[docs] class Type(str, Enum):
z = "z"
type = Type.z
[docs]class Rx(SingleTarget, Angle):
"""
X-axis rotation gate.
Attributes:
type (str): The instruction type. default = "rx". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
Examples:
>>> Rx(target=0, angle=0.15)
"""
[docs] class Type(str, Enum):
rx = "rx"
type = Type.rx
[docs]class Ry(SingleTarget, Angle):
"""
Y-axis rotation gate.
Attributes:
type (str): The instruction type. default = "ry". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
Examples:
>>> Ry(target=0, angle=0.15)
"""
[docs] class Type(str, Enum):
ry = "ry"
type = Type.ry
[docs]class Rz(SingleTarget, Angle):
"""
Z-axis rotation gate.
Attributes:
type (str): The instruction type. default = "rz". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
Examples:
>>> Rz(target=0, angle=0.15)
"""
[docs] class Type(str, Enum):
rz = "rz"
type = Type.rz
[docs]class S(SingleTarget):
"""
S gate. Applies a 90 degree rotation around the Z-axis.
Attributes:
type (str): The instruction type. default = "s". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> S(target=0)
"""
[docs] class Type(str, Enum):
s = "s"
type = Type.s
[docs]class T(SingleTarget):
"""
T gate. Applies a 45 degree rotation around the Z-axis.
Attributes:
type (str): The instruction type. default = "t". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> T(target=0)
"""
[docs] class Type(str, Enum):
t = "t"
type = Type.t
[docs]class Si(SingleTarget):
"""
Si gate. Conjugate transpose of S gate.
Attributes:
type (str): The instruction type. default = "si". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> Si(target=0)
"""
[docs] class Type(str, Enum):
si = "si"
type = Type.si
[docs]class Ti(SingleTarget):
"""
Ti gate. Conjugate transpose of T gate.
Attributes:
type (str): The instruction type. default = "ti". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> Ti(target=0)
"""
[docs] class Type(str, Enum):
ti = "ti"
type = Type.ti
[docs]class Swap(DoubleTarget):
"""
Swap gate. Swaps the state of the two qubits.
Attributes:
type (str): The instruction type. default = "swap". (type) is optional.
This should be unique among all instruction types.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> Swap(targets=[0, 1])
"""
[docs] class Type(str, Enum):
swap = "swap"
type = Type.swap
[docs]class CSwap(SingleControl, DoubleTarget):
"""
Controlled swap gate.
Attributes:
type (str): The instruction type. default = "cswap". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit. This is an int >= 0.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> Swap(control=0, targets=[1, 2])
"""
[docs] class Type(str, Enum):
cswap = "cswap"
type = Type.cswap
[docs]class ISwap(DoubleTarget):
"""
ISwap gate. Swaps the state of two qubits, applying a -i phase to q1 when it is in the 1 state
and a -i phase to q2 when it is in the 0 state.
This is equivalent to XY(pi)
Attributes:
type (str): The instruction type. default = "iswap". (type) is optional.
This should be unique among all instruction types.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> ISwap(targets=[0, 1])
"""
[docs] class Type(str, Enum):
iswap = "iswap"
type = Type.iswap
[docs]class PSwap(DoubleTarget, Angle):
"""
Parameterized swap gate that takes in the angle of the phase to apply to the swapped gates.
Attributes:
type (str): The instruction type. default = "pswap". (type) is optional.
This should be unique among all instruction types.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> PSwap(targets=[0, 1], angle=0.15)
"""
[docs] class Type(str, Enum):
pswap = "pswap"
type = Type.pswap
[docs]class XY(DoubleTarget, Angle):
"""
Rotates between \\|01> and \\|10> by the given angle.
Attributes:
type (str): The instruction type. default = "xy". (type) is optional.
This should be unique among all instruction types.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> XY(targets=[0, 1], angle=0.15)
"""
[docs] class Type(str, Enum):
xy = "xy"
type = Type.xy
[docs]class PhaseShift(SingleTarget, Angle):
"""
Phase shift gate. Shifts the phase between \\|0> and \\|1> by a given angle.
Attributes:
type (str): The instruction type. default = "phaseshift". (type) is optional.
This should be unique among all instruction types.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> PhaseShift(target=1, angle=0.15)
"""
[docs] class Type(str, Enum):
phaseshift = "phaseshift"
type = Type.phaseshift
[docs]class CPhaseShift(SingleTarget, SingleControl, Angle):
"""
Controlled phase shift gate.
Attributes:
type (str): The instruction type. default = "cphaseshift". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit. This is an int >= 0.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CPhaseShift(control=0, target=1, angle=0.15)
"""
[docs] class Type(str, Enum):
cphaseshift = "cphaseshift"
type = Type.cphaseshift
[docs]class CPhaseShift00(SingleTarget, SingleControl, Angle):
"""
Controlled phase shift gate that phases the \\|00> state.
Attributes:
type (str): The instruction type. default = "cphaseshift00". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit. This is an int >= 0.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CPhaseShift00(control=0, target=1, angle=0.15)
"""
[docs] class Type(str, Enum):
cphaseshift00 = "cphaseshift00"
type = Type.cphaseshift00
[docs]class CPhaseShift01(SingleTarget, SingleControl, Angle):
"""
Controlled phase shift gate that phases the \\|01> state.
Attributes:
type (str): The instruction type. default = "cphaseshift01". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit. This is an int >= 0.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CPhaseShift01(control=0, target=1, angle=0.15)
"""
[docs] class Type(str, Enum):
cphaseshift01 = "cphaseshift01"
type = Type.cphaseshift01
[docs]class CPhaseShift10(SingleTarget, SingleControl, Angle):
"""
Controlled phase shift gate that phases the \\|10> state.
Attributes:
type (str): The instruction type. default = "cphaseshift10". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit. This is an int >= 0.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CPhaseShift10(control=0, target=1, angle=0.15)
"""
[docs] class Type(str, Enum):
cphaseshift10 = "cphaseshift10"
type = Type.cphaseshift10
[docs]class CNot(SingleTarget, SingleControl):
"""
Controlled not gate. Also known as the CX gate.
Attributes:
type (str): The instruction type. default = "cnot". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit. This is an int >= 0.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CNot(control=0, target=1)
"""
[docs] class Type(str, Enum):
cnot = "cnot"
type = Type.cnot
[docs]class CCNot(SingleTarget, DoubleControl):
"""
Doubly-controlled NOT gate. Also known as the Toffoli gate.
Attributes:
type (str): The instruction type. default = "ccnot". (type) is optional.
This should be unique among all instruction types.
controls (int): The control qubits.
This is a list with two items and all items are int >= 0.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CCNot(control=[0,1], target=1)
"""
[docs] class Type(str, Enum):
ccnot = "ccnot"
type = Type.ccnot
[docs]class CY(SingleTarget, SingleControl):
"""
Controlled Y-gate.
Attributes:
type (str): The instruction type. default = "cy". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CY(control=0, target=1)
"""
[docs] class Type(str, Enum):
cy = "cy"
type = Type.cy
[docs]class CZ(SingleTarget, SingleControl):
"""
Controlled Z-gate.
Attributes:
type (str): The instruction type. default = "cz". (type) is optional.
This should be unique among all instruction types.
control (int): The control qubit. This is an int >= 0.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> CZ(control=0, target=1)
"""
[docs] class Type(str, Enum):
cz = "cz"
type = Type.cz
[docs]class XX(DoubleTarget, Angle):
"""
The Ising (XX) gate.
Attributes:
type (str): The instruction type. default = "xx". (type) is optional.
This should be unique among all instruction types.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> XX(targets=[0, 1], angle=0.15)
"""
[docs] class Type(str, Enum):
xx = "xx"
type = Type.xx
[docs]class YY(DoubleTarget, Angle):
"""
The Ising (YY) gate.
Attributes:
type (str): The instruction type. default = "yy". (type) is optional.
This should be unique among all instruction types.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> YY(targets=[0, 1], angle=0.15)
"""
[docs] class Type(str, Enum):
yy = "yy"
type = Type.yy
[docs]class ZZ(DoubleTarget, Angle):
"""
The Ising (ZZ) gate.
Attributes:
type (str): The instruction type. default = "zz". (type) is optional.
This should be unique among all instruction types.
angle (float): The angle in radians.
inf, -inf, and NaN are not allowable inputs.
targets (List[int]): The target qubits.
This is a list with two items and all items are int >= 0.
Examples:
>>> ZZ(targets=[0, 1], angle=0.15)
"""
[docs] class Type(str, Enum):
zz = "zz"
type = Type.zz
[docs]class V(SingleTarget):
"""
Square root of NOT gate.
Attributes:
type (str): The instruction type. default = "v". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> V(target=0)
"""
[docs] class Type(str, Enum):
v = "v"
type = Type.v
[docs]class Vi(SingleTarget):
"""
Conjugate transpose of square root of NOT gate.
Attributes:
type (str): The instruction type. default = "vi". (type) is optional.
This should be unique among all instruction types.
target (int): The target qubit. This is an int >= 0.
Examples:
>>> Vi(target=0)
"""
[docs] class Type(str, Enum):
vi = "vi"
type = Type.vi
[docs]class Unitary(TwoDimensionalMatrix, MultiTarget):
"""
Arbitrary unitary matrix gate
Attributes:
type (str): The instruction type. default = "unitary". (type) is optional.
This should be unique among all instruction types.
targets (List[int]): The target qubits. This is a list with ints and all ints >= 0.
matrix (List[List[List[float]]]): The unitary matrix specifying the behavior of the gate.
Examples:
>>> Unitary(targets=[0], matrix=[[[0, 0], [1, 0]],[[1, 0], [0, 1]]])
"""
[docs] class Type(str, Enum):
unitary = "unitary"
type = Type.unitary