Пример #1
0
 def duplicate_instruction(inst):
     """Create a fresh instruction from an input instruction."""
     if issubclass(inst.__class__,
                   Instruction) and inst.__class__ not in [
                       Instruction, Gate]:
         if inst.name == 'barrier':
             new_inst = inst.__class__(inst.num_qubits)
         elif inst.name == 'initialize':
             params = getattr(inst, 'params', [])
             new_inst = inst.__class__(params)
         elif inst.name == 'snapshot':
             label = inst.params[0]
             snap_type = inst.params[1]
             new_inst = inst.__class__(inst.num_qubits,
                                       inst.num_clbits,
                                       label, snap_type)
         else:
             params = getattr(inst, 'params', [])
             new_inst = inst.__class__(*params)
     else:
         if isinstance(inst, Gate):
             new_inst = Gate(inst.name, inst.num_qubits,
                             inst.params)
         else:
             new_inst = Instruction(name=inst.name,
                                    num_qubits=inst.num_qubits,
                                    num_clbits=inst.num_clbits,
                                    params=inst.params)
         new_inst.definition = inst.definition
     return new_inst
Пример #2
0
    def apply(self, operation, wires, par):
        # type: (Any, Sequence[int], List) -> None
        """Apply a quantum operation.

        Args:
            operation (str): name of the operation
            wires (Sequence[int]): subsystems the operation is applied on
            par (tuple): parameters for the operation
        """

        mapped_operation = self._operation_map[operation]

        if isinstance(mapped_operation, BasisState) and not self._first_operation:
            raise DeviceError("Operation {} cannot be used after other Operations have already been applied "
                              "on a {} device.".format(operation, self.short_name))
        self._first_operation = False

        qregs = [(self._reg, i) for i in wires]

        if isinstance(mapped_operation, str):
            dag = circuit_to_dag(QuantumCircuit(self._reg, self._creg, name=''))
            instruction = Instruction(mapped_operation, par, qregs, [], circuit=self._circuit)
            dag.apply_operation_back(instruction)
            qc = dag_to_circuit(dag)
            self._circuit = self._circuit + qc
        elif isinstance(mapped_operation, QiskitInstructions):
            op = mapped_operation  # type: QiskitInstructions
            op.apply(qregs=qregs, param=list(par), circuit=self._circuit)
        else:
            raise ValueError("The operation is not of an expected type. This is a software bug!")
def readout_error_circuits():
    """Readout error test circuits"""

    circuits = []

    # Test circuit: ideal bell state for 1-qubit readout errors
    qr = QuantumRegister(2, 'qr')
    cr = ClassicalRegister(2, 'cr')
    circuit = QuantumCircuit(qr, cr)
    circuit.h(qr[0])
    circuit.cx(qr[0], qr[1])
    # Ensure qubit 0 is measured before qubit 1
    circuit.barrier(qr)
    circuit.measure(qr[0], cr[0])
    circuit.barrier(qr)
    circuit.measure(qr[1], cr[1])

    # Add three copies of circuit
    circuits += 3 * [circuit]

    # 2-qubit correlated readout error circuit
    measure2 = Instruction("measure", 2, 2, [])  # 2-qubit measure
    qr = QuantumRegister(2, 'qr')
    cr = ClassicalRegister(2, 'cr')
    circuit = QuantumCircuit(qr, cr)
    circuit.h(qr)
    circuit.barrier(qr)
    circuit.append(measure2, [0, 1], [0, 1])

    circuits.append(circuit)

    return circuits
    def _generate_cqasm_from_instructions(instructions,
                                          number_of_qubits=2,
                                          full_state_projection=True):
        experiment_dict = {
            'instructions': instructions,
            'header': {
                'n_qubits': number_of_qubits,
                'number_of_clbits': number_of_qubits,
                'compiled_circuit_qasm': ''
            },
            'config': {
                'coupling_map': 'all-to-all',
                'basis_gates':
                'x,y,z,h,rx,ry,rz,s,cx,ccx,u1,u2,u3,id,snapshot',
                'n_qubits': number_of_qubits
            }
        }
        experiment = qiskit.qobj.QasmQobjExperiment.from_dict(experiment_dict)
        for instruction in experiment.instructions:
            if hasattr(instruction, 'params'):
                # convert params to params used in qiskit instructions
                qiskit_instruction = Instruction('dummy', 0, 0,
                                                 instruction.params)
                instruction.params = qiskit_instruction.params

        simulator = QuantumInspireBackend(Mock(), Mock())
        result = simulator._generate_cqasm(experiment, full_state_projection)
        return result
Пример #5
0
 def test_opaque_instruction(self):
     """test opaque instruction does not decompose"""
     q = QuantumRegister(4)
     c = ClassicalRegister(2)
     circ = QuantumCircuit(q, c)
     opaque_inst = Instruction(name="my_inst", num_qubits=3, num_clbits=1, params=[0.5])
     circ.append(opaque_inst, [q[3], q[1], q[0]], [c[1]])
     self.assertEqual(circ.data[0][0].name, "my_inst")
     self.assertEqual(circ.decompose(), circ)
 def test_opaque_instruction(self):
     """test opaque instruction"""
     inst = Instruction('opaque', 3, 0, [])
     gate = instruction_to_gate(inst)
     self.assertIsInstance(gate, Gate)
     inst_attr = inst.__dict__
     gate_attr = gate.__dict__
     for att, value in inst_attr.items():
         with self.subTest(name=att):
             self.assertEqual(value, getattr(gate, att))
     self.assertEqual(set(gate_attr.keys()) - set(inst_attr.keys()),
                      {'_label'})
 def test_append_rejects_wrong_types(self, specifier):
     """Test that various bad inputs are rejected, both given loose or in sublists."""
     test = QuantumCircuit(2, 2)
     # Use a default Instruction to be sure that there's not overridden broadcasting.
     opaque = Instruction("opaque", 1, 1, [])
     with self.subTest("q"), self.assertRaisesRegex(CircuitError, "Invalid bit index"):
         test.append(opaque, [specifier], [0])
     with self.subTest("c"), self.assertRaisesRegex(CircuitError, "Invalid bit index"):
         test.append(opaque, [0], [specifier])
     with self.subTest("q list"), self.assertRaisesRegex(CircuitError, "Invalid bit index"):
         test.append(opaque, [[specifier]], [[0]])
     with self.subTest("c list"), self.assertRaisesRegex(CircuitError, "Invalid bit index"):
         test.append(opaque, [[0]], [[specifier]])
Пример #8
0
 def test_qobj_to_circuits_with_opaque(self):
     """Check qobj_to_circuit's result with an opaque instruction."""
     opaque_inst = Instruction(name='my_inst',
                               num_qubits=4,
                               num_clbits=2,
                               params=[0.5, 0.4])
     q = QuantumRegister(6, name='q')
     c = ClassicalRegister(4, name='c')
     circ = QuantumCircuit(q, c, name='circ')
     circ.append(opaque_inst, [q[0], q[2], q[5], q[3]], [c[3], c[0]])
     dag = circuit_to_dag(circ)
     qobj = assemble(circ)
     out_circuit = qobj_to_circuits(qobj)[0]
     self.assertEqual(circuit_to_dag(out_circuit), dag)
Пример #9
0
 def test_assemble_opaque_inst(self):
     """Test opaque instruction is assembled as-is"""
     opaque_inst = Instruction(name='my_inst', num_qubits=4,
                               num_clbits=2, params=[0.5, 0.4])
     q = QuantumRegister(6, name='q')
     c = ClassicalRegister(4, name='c')
     circ = QuantumCircuit(q, c, name='circ')
     circ.append(opaque_inst, [q[0], q[2], q[5], q[3]], [c[3], c[0]])
     qobj = assemble(circ)
     self.assertIsInstance(qobj, QasmQobj)
     self.assertEqual(len(qobj.experiments[0].instructions), 1)
     self.assertEqual(qobj.experiments[0].instructions[0].name, 'my_inst')
     self.assertEqual(qobj.experiments[0].instructions[0].qubits, [0, 2, 5, 3])
     self.assertEqual(qobj.experiments[0].instructions[0].memory, [3, 0])
     self.assertEqual(qobj.experiments[0].instructions[0].params, [0.5, 0.4])
Пример #10
0
    def test_instructions_soft_compare(self):
        """Test soft comparison between instructions."""
        theta = Parameter('theta')
        phi = Parameter('phi')

        # Verify that we are insensitive when there are parameters.
        self.assertTrue(Instruction('u', 1, 0, [0.3, phi, 0.4]).soft_compare(
            Instruction('u', 1, 0, [theta, phi, 0.4])))

        # Verify that normal equality still holds.
        self.assertTrue(Instruction('u', 1, 0, [0.4, 0.5]).soft_compare(
            Instruction('u', 1, 0, [0.4, 0.5])))

        # Test that when names differ we get False.
        self.assertFalse(Instruction('u', 1, 0, [0.4, phi]).soft_compare(
            Instruction('v', 1, 0, [theta, phi])))

        # Test cutoff precision.
        self.assertFalse(Instruction('v', 1, 0, [0.401, phi]).soft_compare(
            Instruction('v', 1, 0, [0.4, phi])))

        # Test cutoff precision.
        self.assertTrue(Instruction('v', 1, 0, [0.4+1.0e-20, phi]).soft_compare(
            Instruction('v', 1, 0, [0.4, phi])))
Пример #11
0
 def test_opaque_instruction(self):
     """Test the disassembler handles opaque instructions correctly."""
     opaque_inst = Instruction(name="my_inst", num_qubits=4, num_clbits=2, params=[0.5, 0.4])
     q = QuantumRegister(6, name="q")
     c = ClassicalRegister(4, name="c")
     circ = QuantumCircuit(q, c, name="circ")
     circ.append(opaque_inst, [q[0], q[2], q[5], q[3]], [c[3], c[0]])
     qobj = assemble(circ)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, 6)
     self.assertEqual(run_config_out.memory_slots, 4)
     self.assertEqual(len(circuits), 1)
     self.assertEqual(circuits[0], circ)
     self.assertEqual({}, header)
    def test_repr_of_instructions(self):
        """Test the __repr__ method of the Instruction
        class"""

        ins1 = Instruction("test_instruction", 3, 5, [0, 1, 2, 3])
        self.assertEqual(
            repr(ins1),
            "Instruction(name='{}', num_qubits={}, num_clbits={}, params={})".
            format(ins1.name, ins1.num_qubits, ins1.num_clbits, ins1.params),
        )

        ins2 = random_circuit(num_qubits=4, depth=4,
                              measure=True).to_instruction()
        self.assertEqual(
            repr(ins2),
            "Instruction(name='{}', num_qubits={}, num_clbits={}, params={})".
            format(ins2.name, ins2.num_qubits, ins2.num_clbits, ins2.params),
        )
Пример #13
0
    def test_instructions_equal_with_parameters(self):
        """Test equality of instructions for cases with Parameters."""
        theta = Parameter('theta')
        phi = Parameter('phi')

        # Verify we can check params including parameters
        self.assertEqual(Instruction('u', 1, 0, [theta, phi, 0.4]),
                         Instruction('u', 1, 0, [theta, phi, 0.4]))

        # Verify we can test for correct parameter order
        self.assertNotEqual(Instruction('u', 1, 0, [theta, phi, 0]),
                            Instruction('u', 1, 0, [phi, theta, 0]))

        # Verify we can still find a wrong fixed param if we use parameters
        self.assertNotEqual(Instruction('u', 1, 0, [theta, phi, 0.4]),
                            Instruction('u', 1, 0, [theta, phi, 0.5]))

        # Verify we can find cases when param != float
        self.assertNotEqual(Instruction('u', 1, 0, [0.3, phi, 0.4]),
                            Instruction('u', 1, 0, [theta, phi, 0.5]))
Пример #14
0
    def test_instructions_equal(self):
        """Test equality of two instructions."""
        hop1 = Instruction('h', 1, 0, [])
        hop2 = Instruction('s', 1, 0, [])
        hop3 = Instruction('h', 1, 0, [])

        uop1 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])
        uop2 = Instruction('u', 1, 0, [0.4, 0.6, 0.5])
        uop3 = Instruction('v', 1, 0, [0.4, 0.5, 0.5])
        uop4 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])
        self.assertFalse(hop1 == hop2)
        self.assertTrue(hop1 == hop3)
        self.assertFalse(uop1 == uop2)
        self.assertTrue(uop1 == uop4)
        self.assertFalse(uop1 == uop3)
        self.assertTrue(HGate() == HGate())
        self.assertFalse(HGate() == CnotGate())
        self.assertFalse(hop1 == HGate())
    def test_instructions_equal_with_parameter_expressions(self):
        """Test equality of instructions for cases with ParameterExpressions."""
        theta = Parameter("theta")
        phi = Parameter("phi")
        sum_ = theta + phi
        product_ = theta * phi

        # Verify we can check params including parameters
        self.assertEqual(
            Instruction("u", 1, 0, [sum_, product_, 0.4]),
            Instruction("u", 1, 0, [sum_, product_, 0.4]),
        )

        # Verify we can test for correct parameter order
        self.assertNotEqual(Instruction("u", 1, 0, [product_, sum_, 0]),
                            Instruction("u", 1, 0, [sum_, product_, 0]))

        # Verify we can still find a wrong fixed param if we use parameters
        self.assertNotEqual(Instruction("u", 1, 0, [sum_, phi, 0.4]),
                            Instruction("u", 1, 0, [sum_, phi, 0.5]))

        # Verify we can find cases when param != float
        self.assertNotEqual(Instruction("u", 1, 0, [0.3, sum_, 0.4]),
                            Instruction("u", 1, 0, [product_, sum_, 0.5]))
Пример #16
0
    def test_instructions_equal(self):
        """Test equality of two instructions.
        """
        qr = QuantumRegister(3)
        cr = ClassicalRegister(3)
        hop1 = Instruction('h', [], qr, cr)
        hop2 = Instruction('s', [], qr, cr)
        hop3 = Instruction('h', [], qr, cr)

        uop1 = Instruction('u', [0.4, 0.5, 0.5], qr, cr)
        uop2 = Instruction('u', [0.4, 0.6, 0.5], qr, cr)
        uop3 = Instruction('v', [0.4, 0.5, 0.5], qr, cr)
        uop4 = Instruction('u', [0.4, 0.5, 0.5], qr, cr)
        self.assertFalse(hop1 == hop2)
        self.assertTrue(hop1 == hop3)
        self.assertFalse(uop1 == uop2)
        self.assertTrue(uop1 == uop4)
        self.assertFalse(uop1 == uop3)
        self.assertTrue(HGate(qr[0]) == HGate(qr[1]))
        self.assertFalse(HGate(qr[0]) == CnotGate(qr[0], qr[1]))
        self.assertFalse(hop1 == HGate(qr[2]))
Пример #17
0
    def test_instructions_equal(self):
        """Test equality of two instructions."""
        hop1 = Instruction('h', 1, 0, [])
        hop2 = Instruction('s', 1, 0, [])
        hop3 = Instruction('h', 1, 0, [])

        self.assertFalse(hop1 == hop2)
        self.assertTrue(hop1 == hop3)

        uop1 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])
        uop2 = Instruction('u', 1, 0, [0.4, 0.6, 0.5])
        uop3 = Instruction('v', 1, 0, [0.4, 0.5, 0.5])
        uop4 = Instruction('u', 1, 0, [0.4, 0.5, 0.5])

        self.assertFalse(uop1 == uop2)
        self.assertTrue(uop1 == uop4)
        self.assertFalse(uop1 == uop3)

        self.assertTrue(HGate() == HGate())
        self.assertFalse(HGate() == CnotGate())
        self.assertFalse(hop1 == HGate())

        eop1 = Instruction('kraus', 1, 0, [np.array([[1, 0], [0, 1]])])
        eop2 = Instruction('kraus', 1, 0, [np.array([[0, 1], [1, 0]])])
        eop3 = Instruction('kraus', 1, 0, [np.array([[1, 0], [0, 1]])])
        eop4 = Instruction('kraus', 1, 0, [np.eye(4)])

        self.assertTrue(eop1 == eop3)
        self.assertFalse(eop1 == eop2)
        self.assertFalse(eop1 == eop4)
Пример #18
0
 def to_instruction(self):
     """Convert the ReadoutError to a circuit Instruction."""
     return Instruction("roerror", 0, self.number_of_qubits,
                        self._probabilities)
Пример #19
0
    def _to_circuit(cls, op):
        if isinstance(op, QuantumCircuit):
            return op
        if isinstance(op, tuple):
            inst, qubits = op
            circ = QuantumCircuit(max(qubits) + 1)
            circ.append(inst, qargs=qubits)
            return circ
        if isinstance(op, Instruction):
            if op.num_clbits > 0:
                raise NoiseError(
                    f"Unable to convert instruction with clbits: {op.__class__.__name__}"
                )
            circ = QuantumCircuit(op.num_qubits)
            circ.append(op, qargs=list(range(op.num_qubits)))
            return circ
        if isinstance(op, QuantumChannel):
            if not op.is_cptp(atol=cls.atol):
                raise NoiseError("Input quantum channel is not CPTP.")
            try:
                return cls._to_circuit(Kraus(op).to_instruction())
            except QiskitError as err:
                raise NoiseError(
                    f"Fail to convert {op.__class__.__name__} to Instruction."
                ) from err
        if isinstance(op, BaseOperator):
            if hasattr(op, 'to_instruction'):
                try:
                    return cls._to_circuit(op.to_instruction())
                except QiskitError as err:
                    raise NoiseError(
                        f"Fail to convert {op.__class__.__name__} to Instruction."
                    ) from err
            else:
                raise NoiseError(
                    f"Unacceptable Operator, not implementing to_instruction: "
                    f"{op.__class__.__name__}")
        if isinstance(op, list):
            if all(isinstance(aop, tuple) for aop in op):
                num_qubits = max([max(qubits) for _, qubits in op]) + 1
                circ = QuantumCircuit(num_qubits)
                for inst, qubits in op:
                    try:
                        circ.append(inst, qargs=qubits)
                    except CircuitError as err:
                        raise NoiseError(
                            f"Invalid operation type: {inst.__class__.__name__},"
                            f" not appendable to circuit.") from err
                return circ
            # Support for old-style json-like input TODO: to be removed
            elif all(isinstance(aop, dict) for aop in op):
                warnings.warn(
                    'Constructing QuantumError with list of dict representing a mixed channel'
                    ' has been deprecated as of qiskit-aer 0.10.0 and will be removed'
                    ' no earlier than 3 months from that release date.',
                    DeprecationWarning,
                    stacklevel=3)
                # Convert json-like to non-kraus Instruction
                num_qubits = max([max(dic['qubits']) for dic in op]) + 1
                circ = QuantumCircuit(num_qubits)
                for dic in op:
                    if dic['name'] == 'reset':
                        # pylint: disable=import-outside-toplevel
                        from qiskit.circuit import Reset
                        circ.append(Reset(), qargs=dic['qubits'])
                    elif dic['name'] == 'kraus':
                        circ.append(Instruction(name='kraus',
                                                num_qubits=len(dic['qubits']),
                                                num_clbits=0,
                                                params=dic['params']),
                                    qargs=dic['qubits'])
                    elif dic['name'] == 'unitary':
                        circ.append(UnitaryGate(data=dic['params'][0]),
                                    qargs=dic['qubits'])
                    else:
                        with warnings.catch_warnings():
                            warnings.filterwarnings(
                                "ignore",
                                category=DeprecationWarning,
                                module=
                                "qiskit.providers.aer.noise.errors.errorutils")
                            circ.append(UnitaryGate(label=dic['name'],
                                                    data=standard_gate_unitary(
                                                        dic['name'])),
                                        qargs=dic['qubits'])
                return circ
            else:
                raise NoiseError(f"Invalid type of op list: {op}")

        raise NoiseError(
            f"Invalid noise op type {op.__class__.__name__}: {op}")
Пример #20
0
 def measure_n(num_qubits):
     """Multi-qubit measure instruction."""
     return Instruction("measure", num_qubits, num_qubits, [])
Пример #21
0
def append_tk_command_to_qiskit(
    op: "Op",
    args: List["UnitID"],
    qcirc: QuantumCircuit,
    qregmap: Dict[str, QuantumRegister],
    cregmap: Dict[str, ClassicalRegister],
    symb_map: Dict[Parameter, sympy.Symbol],
    range_preds: Dict[Bit, Tuple[List["UnitID"], int]],
) -> Instruction:
    optype = op.type
    if optype == OpType.Measure:
        qubit = args[0]
        bit = args[1]
        qb = qregmap[qubit.reg_name][qubit.index[0]]
        b = cregmap[bit.reg_name][bit.index[0]]
        return qcirc.measure(qb, b)

    if optype == OpType.Reset:
        qb = qregmap[args[0].reg_name][args[0].index[0]]
        return qcirc.reset(qb)

    if optype in [
            OpType.CircBox, OpType.ExpBox, OpType.PauliExpBox, OpType.Custom
    ]:
        subcircuit = op.get_circuit()
        subqc = tk_to_qiskit(subcircuit)
        qargs = []
        cargs = []
        for a in args:
            if a.type == UnitType.qubit:
                qargs.append(qregmap[a.reg_name][a.index[0]])
            else:
                cargs.append(cregmap[a.reg_name][a.index[0]])
        if optype == OpType.Custom:
            instruc = subqc.to_gate()
            instruc.name = op.get_name()
        else:
            instruc = subqc.to_instruction()
        return qcirc.append(instruc, qargs, cargs)
    if optype == OpType.Unitary2qBox:
        qargs = [qregmap[q.reg_name][q.index[0]] for q in args]
        u = op.get_matrix()
        g = UnitaryGate(u, label="u2q")
        return qcirc.append(g, qargs=qargs)
    if optype == OpType.Barrier:
        qargs = [qregmap[q.reg_name][q.index[0]] for q in args]
        g = Barrier(len(args))
        return qcirc.append(g, qargs=qargs)
    if optype == OpType.RangePredicate:
        if op.lower != op.upper:
            raise NotImplementedError
        range_preds[args[-1]] = (args[:-1], op.lower)
        # attach predicate to bit,
        # subsequent conditional will handle it
        return Instruction("", 0, 0, [])
    if optype == OpType.ConditionalGate:
        if args[0] in range_preds:
            assert op.value == 1
            condition_bits, value = range_preds[args[0]]
            del range_preds[args[0]]
            args = condition_bits + args[1:]
            width = len(condition_bits)
        else:
            width = op.width
            value = op.value
        regname = args[0].reg_name
        if len(cregmap[regname]) != width:
            raise NotImplementedError(
                "OpenQASM conditions must be an entire register")
        for i, a in enumerate(args[:width]):
            if a.reg_name != regname:
                raise NotImplementedError(
                    "OpenQASM conditions can only use a single register")
            if a.index != [i]:
                raise NotImplementedError(
                    "OpenQASM conditions must be an entire register in order")
        instruction = append_tk_command_to_qiskit(op.op, args[width:], qcirc,
                                                  qregmap, cregmap, symb_map,
                                                  range_preds)

        instruction.c_if(cregmap[regname], value)
        return instruction
    # normal gates
    qargs = [qregmap[q.reg_name][q.index[0]] for q in args]
    if optype == OpType.CnX:
        return qcirc.mcx(qargs[:-1], qargs[-1])

    # special case
    if optype == OpType.CnRy:
        # might as well do a bit more checking
        assert len(op.params) == 1
        alpha = param_to_qiskit(op.params[0], symb_map)
        assert len(qargs) >= 2
        if len(qargs) == 2:
            # presumably more efficient; single control only
            new_gate = CRYGate(alpha)
        else:
            new_ry_gate = RYGate(alpha)
            new_gate = MCMT(gate=new_ry_gate,
                            num_ctrl_qubits=len(qargs) - 1,
                            num_target_qubits=1)
        qcirc.append(new_gate, qargs)
        return qcirc

    # others are direct translations
    try:
        gatetype = _known_qiskit_gate_rev[optype]
    except KeyError as error:
        raise NotImplementedError("Cannot convert tket Op to Qiskit gate: " +
                                  op.get_name()) from error
    params = [param_to_qiskit(p, symb_map) for p in op.params]
    g = gatetype(*params)
    return qcirc.append(g, qargs=qargs)