Exemple #1
0
def test_recognize_incorrect_gates():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend)
    qubit = eng.allocate_qubit()
    ctrl_qubit = eng.allocate_qubit()
    ctrl_qureg = eng.allocate_qureg(2)
    eng.flush()
    with Control(eng, ctrl_qubit):
        Rx(0.3) | qubit
    X | qubit
    with Control(eng, ctrl_qureg):
        X | qubit
    eng.flush(deallocate_qubits=True)
    for cmd in saving_backend.received_commands:
        assert not cnu2toffoliandcu._recognize_CnU(cmd)
def test_unitary_functional_measurement():
    eng = MainEngine(UnitarySimulator())
    qubits = eng.allocate_qureg(5)
    # entangle all qubits:
    H | qubits[0]
    for qb in qubits[1:]:
        CNOT | (qubits[0], qb)
    eng.flush()
    All(Measure) | qubits

    bit_value_sum = sum([int(qubit) for qubit in qubits])
    assert bit_value_sum == 0 or bit_value_sum == 5

    qb1 = WeakQubitRef(engine=eng, idx=qubits[0].id)
    qb2 = WeakQubitRef(engine=eng, idx=qubits[1].id)
    with pytest.raises(ValueError):
        eng.backend._handle(Command(engine=eng, gate=Measure, qubits=([qb1],), controls=[qb2]))
Exemple #3
0
def _initialize_register(num_bit, mode='simulator'):
    '''
    use an engine instead of current one.
    '''
    import projectq.setups.default

    # create a main compiler engine with a specific backend:
    if mode == 'graphical':
        backend = CircuitDrawer()
    elif mode == 'simulator':
        backend = Simulator()
    else:
        raise
    eng = MainEngine(backend)

    # initialize register
    qureg = eng.allocate_qureg(num_bit)
    return qureg
Exemple #4
0
def test_flush_deallocates_all_qubits():
    mapper = BoundedQubitMapper(10)
    engine = MainEngine(
        Simulator(),
        engine_list=[mapper],
        verbose=True,
    )
    # needed to prevent GC from removing qubit refs
    qureg = engine.allocate_qureg(10)
    assert len(mapper.current_mapping.keys()) == 10
    assert len(engine.active_qubits) == 10
    engine.flush()
    # Should still be around after flush
    assert len(engine.active_qubits) == 10
    assert len(mapper.current_mapping.keys()) == 10

    # GC will clean things up
    del qureg
    assert len(engine.active_qubits) == 0
    assert len(mapper.current_mapping.keys()) == 0
def test_recognize_incorrect_gates():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend)
    qubit = eng.allocate_qubit()
    ctrl_qubit = eng.allocate_qubit()
    ctrl_qureg = eng.allocate_qureg(2)
    eng.flush()
    with Control(eng, ctrl_qubit):
        # Does not have matrix attribute:
        BasicGate() | qubit
        # Two qubit gate:
        two_qubit_gate = BasicGate()
        two_qubit_gate.matrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                                 [0, 0, 0, 1]]
        two_qubit_gate | qubit
    with Control(eng, ctrl_qureg):
        # Too many Control qubits:
        Rx(0.3) | qubit
    eng.flush(deallocate_qubits=True)
    for cmd in saving_backend.received_commands:
        assert not carb1q._recognize_carb1qubit(cmd)
Exemple #6
0
def run_qft(a=11, param = "draw"):
    # Initialisation
    if param == "draw":
        drawing_engine = CircuitDrawer()
        eng = MainEngine(drawing_engine)
    else:
        eng = MainEngine()
    [La, n] = int2bit(a)
    xa = eng.allocate_qureg(n)

    # initialisation de a et b
    for i in range(n):
        if La[i]:
            X | xa[i]

    # On passe de a a phi(a) : QTF
    eng.flush()
    for i in range(n):
        N = n - i - 1
        H | xa[N]
        for k in range(2, N + 2):
            with Control(eng, xa[N - k + 1]):
                R((2*math.pi) / (1 << k)) | xa[N]

    eng.flush()

    if param != "draw":
        amp_xa = []
        for i in range(1 << n):
            phase_reel = phase(eng.backend.get_amplitude(adapt_binary(bin(i), n), xa)) / (2 * math.pi)
            amp_xa.append(Fraction(phase_reel).limit_denominator(10))
            print(amp_xa)

    All(Measure) | xa
    eng.flush()

    if param == "draw":
        print(drawing_engine.get_latex())
Exemple #7
0
def test_unitary_after_deallocation_or_measurement():
    eng = MainEngine(backend=UnitarySimulator(), engine_list=[])
    qubit = eng.allocate_qubit()
    X | qubit

    assert not eng.backend.history

    eng.flush()
    Measure | qubit

    # FlushGate and MeasureGate do not append to the history
    assert not eng.backend.history
    assert np.allclose(eng.backend.unitary, X.matrix)

    with pytest.warns(UserWarning):
        Y | qubit

    # YGate after FlushGate and MeasureGate does not append current unitary (identity) to the history
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.unitary,
                       Y.matrix)  # Reset of unitary when applying Y above
    assert np.allclose(eng.backend.history[0], X.matrix)

    # Still ok
    eng.flush()
    Measure | qubit

    # FlushGate and MeasureGate do not append to the history
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.unitary, Y.matrix)
    assert np.allclose(eng.backend.history[0], X.matrix)

    # Make sure that the new gate will trigger appending to the history and modify the current unitary
    with pytest.warns(UserWarning):
        Rx(1) | qubit
    assert len(eng.backend.history) == 2
    assert np.allclose(eng.backend.unitary, Rx(1).matrix)
    assert np.allclose(eng.backend.history[0], X.matrix)
    assert np.allclose(eng.backend.history[1], Y.matrix)

    # --------------------------------------------------------------------------

    eng = MainEngine(backend=UnitarySimulator(), engine_list=[])
    qureg = eng.allocate_qureg(2)
    All(X) | qureg

    XX_matrix = np.kron(X.matrix, X.matrix)
    assert not eng.backend.history
    assert np.allclose(eng.backend.unitary, XX_matrix)

    eng.deallocate_qubit(qureg[0])

    assert not eng.backend.history

    with pytest.warns(UserWarning):
        Y | qureg[1]

    # An internal call to flush() happens automatically since the X
    # gate occurs as the simulator is in an invalid state (after qubit
    # deallocation)
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.history[0], XX_matrix)
    assert np.allclose(eng.backend.unitary, Y.matrix)

    # Still ok
    eng.flush()
    Measure | qureg[1]

    # Nothing should have changed
    assert len(eng.backend.history) == 1
    assert np.allclose(eng.backend.history[0], XX_matrix)
    assert np.allclose(eng.backend.unitary, Y.matrix)
def test_openqasm_allocate_deallocate(qubit_id_redux):
    qc_list = []

    def _process(circuit):
        qc_list.append(circuit)

    backend = OpenQASMEngine(_process, qubit_id_mapping_redux=qubit_id_redux)
    assert backend._qubit_id_mapping_redux == qubit_id_redux

    eng = MainEngine(backend)
    qubit = eng.allocate_qubit()
    eng.flush()

    assert len(backend._qreg_dict) == 1
    assert len(backend._creg_dict) == 1
    assert backend._reg_index == 1
    assert not backend._available_indices
    assert len(qc_list) == 1
    qasm = qc_list[0].qasm()
    assert re.search(r'qreg\s+q0\[1\]', qasm)
    assert re.search(r'creg\s+c0\[1\]', qasm)

    qureg = eng.allocate_qureg(5)
    eng.flush()

    assert len(backend._qreg_dict) == 6
    assert len(backend._creg_dict) == 6
    assert backend._reg_index == 6
    assert not backend._available_indices
    assert len(qc_list) == 2
    qasm = qc_list[1].qasm()
    for i in range(1, 6):
        assert re.search(r'qreg\s+q{}\[1\]'.format(i), qasm)
        assert re.search(r'creg\s+c{}\[1\]'.format(i), qasm)

    del qubit
    eng.flush()
    if qubit_id_redux:
        assert len(backend._qreg_dict) == 5
        assert len(backend._creg_dict) == 5
        assert backend._reg_index == 6
        assert backend._available_indices == [0]
    else:
        assert len(backend._qreg_dict) == 6
        assert len(backend._creg_dict) == 6
        assert backend._reg_index == 6
        assert not backend._available_indices

    qubit = eng.allocate_qubit()
    eng.flush()

    if qubit_id_redux:
        assert len(backend._qreg_dict) == 6
        assert len(backend._creg_dict) == 6
        assert backend._reg_index == 6
        assert not backend._available_indices
    else:
        assert len(backend._qreg_dict) == 7
        assert len(backend._creg_dict) == 7
        assert backend._reg_index == 7
        assert not backend._available_indices
Exemple #9
0
    SqrtY | x[8]

    SqrtX | x[10]

    SqrtX | x[11]

    SqrtY | x[17]

    SqrtY | x[18]

    SqrtX | x[20]

    SqrtY | x[21]


start = datetime.datetime.now()
print(start)
x = eng.allocate_qureg(nqubits)
# Alice creates a nice state to send
eng.flush()
run(eng)

result = eng.backend.cheat()
All(Measure) | x
print(result)

end = datetime.datetime.now()
print(end)
print("time used:", (end - start))
Exemple #10
0
class ProjectQContext(object):
    '''
    Context for running circuits.

    Args:
        num_bit (int): number of bits in register.
        task ('ibm'|'draw'|'simulate'): task that decide the environment type.
        ibm_config (dict): extra arguments for IBM backend.
    '''

    def __init__(self, num_bit, task, ibm_config=None):
        self.task = task
        self.num_bit = num_bit
        self.ibm_config = ibm_config

    def __enter__(self):
        '''
        Enter context,

        Attributes:
            eng (MainEngine): main engine.
            backend ('graphical' or 'simulate'): backend used.
            qureg (Qureg): quantum register.
        '''
        if self.task=='ibm':
            import projectq.setups.ibm
        else:
            import projectq.setups.default

        # create a main compiler engine with a specific backend:
        if self.task == 'draw':
            self.backend = CircuitDrawer()
            # locations = {0: 0, 1: 1, 2: 2, 3:3} # swap order of lines 0-1-2.
            # self.backend.set_qubit_locations(locations)
        elif self.task == 'simulate':
            print('ProjecQ simulation in training can be slow, since in scipy context, we cached a lot gates.')
            self.backend = Simulator()
        elif self.task == 'ibm':
            # choose device
            device = self.ibm_config.get('device', 'ibmqx2' if self.num_bit<=5 else 'ibmqx5')
            # check data
            if self.ibm_config is None:
                raise
            if device == 'ibmqx5':
                device_num_bit = 16
            else:
                device_num_bit = 5
            if device_num_bit < self.num_bit:
                raise AttributeError('device %s has not enough qubits for %d bit simulation!'%(device, self.num_bit))

            self.backend = IBMBackend(use_hardware=True, num_runs=self.ibm_config['num_runs'],
                    user=self.ibm_config['user'],
                    password=self.ibm_config['password'],
                    device=device, verbose=True)
        else:
            raise ValueError('engine %s not defined' % self.task)
        self.eng = MainEngine(self.backend)
        # initialize register
        self.qureg = self.eng.allocate_qureg(self.num_bit)
        return self

    def __exit__(self, exc_type, exc_val, traceback):
        '''
        exit, meanwhile cheat and get wave function.

        Attributes:
            wf (1darray): for 'simulate' task, the wave function vector.
            res (1darray): for 'ibm' task, the measurements output.
        '''
        if traceback is not None:
            return False
        if self.task == 'draw':
            self._viz_circuit()
        elif self.task == 'simulate':
            self.eng.flush()
            order, qvec = self.backend.cheat()
            self.wf = np.array(qvec)
            order = [order[i] for i in range(len(self.qureg))]
            self.wf = np.transpose(self.wf.reshape([2]*len(self.qureg), order='F'), axes=order).ravel(order='F')
            Measure | self.qureg
            self.eng.flush()
        elif self.task == 'ibm':
            Measure | self.qureg
            self.eng.flush()
            self.res = self.backend.get_probabilities(self.qureg)
        else:
            raise
        return self

    def _viz_circuit(self):
        Measure | self.qureg
        self.eng.flush()
        # print latex code to draw the circuit:
        s = self.backend.get_latex()

        # save graph to latex file
        os.chdir(TEX_FOLDER)
        with open(TEX_FILENAME, 'w') as f:
            f.write(s)

        # texfile = os.path.join(folder, 'circuit-%d.tex'%bench_id)
        pdffile = TEX_FILENAME[:-3]+'pdf'
        os.system('pdflatex %s'%TEX_FILENAME)
        openfile(pdffile)
Exemple #11
0
from projectq.libs.revkit import PermutationOracle, PhaseOracle
from projectq.meta import Compute, Dagger, Uncompute
from projectq.ops import All, H, Measure, X


# phase function
def f(a, b, c, d, e, f):
    """Phase function."""
    return (a and b) ^ (c and d) ^ (e and f)


# permutation
pi = [0, 2, 3, 5, 7, 1, 4, 6]

eng = MainEngine()
qubits = eng.allocate_qureg(6)
x = qubits[::2]  # qubits on odd lines
y = qubits[1::2]  # qubits on even lines

# circuit
with Compute(eng):
    All(H) | qubits
    All(X) | [x[0], x[1]]
    PermutationOracle(pi) | y
PhaseOracle(f) | qubits
Uncompute(eng)

with Compute(eng):
    with Dagger(eng):
        PermutationOracle(pi, synth=revkit.dbs) | x
PhaseOracle(f) | qubits
Exemple #12
0
def test_ibm_backend_functional_test(monkeypatch):
    correct_info = {
        'json': [
            {'qubits': [1], 'name': 'u2', 'params': [0, 3.141592653589793]},
            {'qubits': [1, 2], 'name': 'cx'},
            {'qubits': [1, 3], 'name': 'cx'},
            {'qubits': [1], 'name': 'u3', 'params': [6.28318530718, 0, 0]},
            {'qubits': [1], 'name': 'u1', 'params': [11.780972450962]},
            {'qubits': [1], 'name': 'u3', 'params': [6.28318530718, 0, 0]},
            {'qubits': [1], 'name': 'u1', 'params': [10.995574287564]},
            {'qubits': [1, 2, 3], 'name': 'barrier'},
            {
                'qubits': [1],
                'name': 'u3',
                'params': [0.2, -1.5707963267948966, 1.5707963267948966],
            },
            {'qubits': [1], 'name': 'measure', 'memory': [1]},
            {'qubits': [2], 'name': 'measure', 'memory': [2]},
            {'qubits': [3], 'name': 'measure', 'memory': [3]},
        ],
        'nq': 4,
        'shots': 1000,
        'maxCredits': 10,
        'backend': {'name': 'ibmq_qasm_simulator'},
    }

    def mock_send(*args, **kwargs):
        assert args[0] == correct_info
        return {
            'data': {'counts': {'0x0': 504, '0x2': 8, '0xc': 6, '0xe': 482}},
            'header': {
                'clbit_labels': [['c', 0], ['c', 1], ['c', 2], ['c', 3]],
                'creg_sizes': [['c', 4]],
                'memory_slots': 4,
                'n_qubits': 32,
                'name': 'circuit0',
                'qreg_sizes': [['q', 32]],
                'qubit_labels': [
                    ['q', 0],
                    ['q', 1],
                    ['q', 2],
                    ['q', 3],
                    ['q', 4],
                    ['q', 5],
                    ['q', 6],
                    ['q', 7],
                    ['q', 8],
                    ['q', 9],
                    ['q', 10],
                    ['q', 11],
                    ['q', 12],
                    ['q', 13],
                    ['q', 14],
                    ['q', 15],
                    ['q', 16],
                    ['q', 17],
                    ['q', 18],
                    ['q', 19],
                    ['q', 20],
                    ['q', 21],
                    ['q', 22],
                    ['q', 23],
                    ['q', 24],
                    ['q', 25],
                    ['q', 26],
                    ['q', 27],
                    ['q', 28],
                    ['q', 29],
                    ['q', 30],
                    ['q', 31],
                ],
            },
            'metadata': {
                'measure_sampling': True,
                'method': 'statevector',
                'parallel_shots': 1,
                'parallel_state_update': 16,
            },
            'seed_simulator': 465435780,
            'shots': 1000,
            'status': 'DONE',
            'success': True,
            'time_taken': 0.0045786460000000005,
        }

    monkeypatch.setattr(_ibm, "send", mock_send)

    backend = _ibm.IBMBackend(verbose=True, num_runs=1000)
    import sys

    # no circuit has been executed -> raises exception
    with pytest.raises(RuntimeError):
        backend.get_probabilities([])
    mapper = BasicMapperEngine()
    res = {}
    for i in range(4):
        res[i] = i
    mapper.current_mapping = res
    ibm_setup = [mapper]
    setup = restrictedgateset.get_engine_list(
        one_qubit_gates=(Rx, Ry, Rz, H), two_qubit_gates=(CNOT,), other_gates=(Barrier,)
    )
    setup.extend(ibm_setup)
    eng = MainEngine(backend=backend, engine_list=setup)
    # 4 qubits circuit is run, but first is unused to test ability for
    # get_probability to return the correct values for a subset of the total
    # register
    unused_qubit = eng.allocate_qubit()
    qureg = eng.allocate_qureg(3)
    # entangle the qureg
    Entangle | qureg
    Tdag | qureg[0]
    Sdag | qureg[0]
    Barrier | qureg
    Rx(0.2) | qureg[0]
    del unused_qubit
    # measure; should be all-0 or all-1
    All(Measure) | qureg
    # run the circuit
    eng.flush()
    prob_dict = eng.backend.get_probabilities([qureg[2], qureg[1]])
    assert prob_dict['00'] == pytest.approx(0.512)
    assert prob_dict['11'] == pytest.approx(0.488)
    result = "\nu2(0,pi/2) q[1];\ncx q[1], q[2];\ncx q[1], q[3];"
    if sys.version_info.major == 3:
        result += "\nu3(6.28318530718, 0, 0) q[1];\nu1(11.780972450962) q[1];"
        result += "\nu3(6.28318530718, 0, 0) q[1];\nu1(10.995574287564) q[1];"
    else:
        result += "\nu3(6.28318530718, 0, 0) q[1];\nu1(11.780972451) q[1];"
        result += "\nu3(6.28318530718, 0, 0) q[1];\nu1(10.9955742876) q[1];"
    result += "\nbarrier q[1], q[2], q[3];"
    result += "\nu3(0.2, -pi/2, pi/2) q[1];\nmeasure q[1] -> c[1];"
    result += "\nmeasure q[2] -> c[2];\nmeasure q[3] -> c[3];"

    assert eng.backend.get_qasm() == result

    with pytest.raises(RuntimeError):
        eng.backend.get_probabilities(eng.allocate_qubit())
Exemple #13
0
def test_ibm_retrieve(monkeypatch):
    # patch send
    def mock_retrieve(*args, **kwargs):
        return {
            'data': {'counts': {'0x0': 504, '0x2': 8, '0xc': 6, '0xe': 482}},
            'header': {
                'clbit_labels': [['c', 0], ['c', 1], ['c', 2], ['c', 3]],
                'creg_sizes': [['c', 4]],
                'memory_slots': 4,
                'n_qubits': 32,
                'name': 'circuit0',
                'qreg_sizes': [['q', 32]],
                'qubit_labels': [
                    ['q', 0],
                    ['q', 1],
                    ['q', 2],
                    ['q', 3],
                    ['q', 4],
                    ['q', 5],
                    ['q', 6],
                    ['q', 7],
                    ['q', 8],
                    ['q', 9],
                    ['q', 10],
                    ['q', 11],
                    ['q', 12],
                    ['q', 13],
                    ['q', 14],
                    ['q', 15],
                    ['q', 16],
                    ['q', 17],
                    ['q', 18],
                    ['q', 19],
                    ['q', 20],
                    ['q', 21],
                    ['q', 22],
                    ['q', 23],
                    ['q', 24],
                    ['q', 25],
                    ['q', 26],
                    ['q', 27],
                    ['q', 28],
                    ['q', 29],
                    ['q', 30],
                    ['q', 31],
                ],
            },
            'metadata': {
                'measure_sampling': True,
                'method': 'statevector',
                'parallel_shots': 1,
                'parallel_state_update': 16,
            },
            'seed_simulator': 465435780,
            'shots': 1000,
            'status': 'DONE',
            'success': True,
            'time_taken': 0.0045786460000000005,
        }

    monkeypatch.setattr(_ibm, "retrieve", mock_retrieve)
    backend = _ibm.IBMBackend(retrieve_execution="ab1s2", num_runs=1000)
    mapper = BasicMapperEngine()
    res = {}
    for i in range(4):
        res[i] = i
    mapper.current_mapping = res
    ibm_setup = [mapper]
    setup = restrictedgateset.get_engine_list(one_qubit_gates=(Rx, Ry, Rz, H), two_qubit_gates=(CNOT,))
    setup.extend(ibm_setup)
    eng = MainEngine(backend=backend, engine_list=setup)
    unused_qubit = eng.allocate_qubit()
    qureg = eng.allocate_qureg(3)
    # entangle the qureg
    Entangle | qureg
    Tdag | qureg[0]
    Sdag | qureg[0]
    Barrier | qureg
    Rx(0.2) | qureg[0]
    del unused_qubit
    # measure; should be all-0 or all-1
    All(Measure) | qureg
    # run the circuit
    eng.flush()
    prob_dict = eng.backend.get_probabilities([qureg[0], qureg[2], qureg[1]])
    assert prob_dict['000'] == pytest.approx(0.504)
    assert prob_dict['111'] == pytest.approx(0.482)
    assert prob_dict['011'] == pytest.approx(0.006)
Exemple #14
0
"""Example of a 4-qubit phase function."""

from projectq.cengines import MainEngine
from projectq.libs.revkit import PhaseOracle
from projectq.meta import Compute, Uncompute
from projectq.ops import All, H, Measure, X


# phase function
def f(a, b, c, d):
    """Phase function."""
    return (a and b) ^ (c and d)


eng = MainEngine()
x1, x2, x3, x4 = qubits = eng.allocate_qureg(4)

with Compute(eng):
    All(H) | qubits
    X | x1
PhaseOracle(f) | qubits
Uncompute(eng)

PhaseOracle(f) | qubits
All(H) | qubits
All(Measure) | qubits

eng.flush()

print("Shift is {}".format(8 * int(x4) + 4 * int(x3) + 2 * int(x2) + int(x1)))