コード例 #1
0
def test_simulator_collapse_wavefunction(sim, mapper):
    engine_list = [LocalOptimizer()]
    if mapper is not None:
        engine_list.append(mapper)

    engine_list.append(GreedyScheduler())
    eng = HiQMainEngine(sim, engine_list=engine_list)
    qubits = eng.allocate_qureg(4)
    # unknown qubits: raises
    with pytest.raises(RuntimeError):
        eng.backend.collapse_wavefunction(qubits, [0] * 4)
    eng.flush()
    eng.backend.collapse_wavefunction(qubits, [0] * 4)
    assert pytest.approx(eng.backend.get_probability([0] * 4, qubits)) == 1.
    All(H) | qubits[1:]
    eng.flush()
    assert pytest.approx(eng.backend.get_probability([0] * 4, qubits)) == .125
    # impossible outcome: raises
    with pytest.raises(RuntimeError):
        eng.backend.collapse_wavefunction(qubits, [1] + [0] * 3)
    eng.backend.collapse_wavefunction(qubits[:-1], [0, 1, 0])
    probability = eng.backend.get_probability([0, 1, 0, 1], qubits)
    assert probability == pytest.approx(.5)

    # reinitialize qubits
    All(Measure) | qubits
    del qubits
    qubits = eng.allocate_qureg(4)

    H | qubits[0]
    CNOT | (qubits[0], qubits[1])
    eng.flush()
    eng.backend.collapse_wavefunction([qubits[0]], [1])
    probability = eng.backend.get_probability([1, 1], qubits[0:2])
    assert probability == pytest.approx(1.)
コード例 #2
0
def test_simulator_cheat(sim):
    # cheat function should return a tuple
    assert isinstance(sim.cheat(), tuple)
    # first entry is the qubit mapping.
    # should be empty:
    assert len(sim.cheat()[0]) == 0

    np = MPI.COMM_WORLD.Get_size()
    # state vector should only have np entries:
    assert len(sim.cheat()[1]) == np

    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qubit = eng.allocate_qubit()

    # one qubit has been allocated
    assert len(sim.cheat()[0]) == 1
    assert sim.cheat()[0][0] == 0
    assert len(sim.cheat()[1]) == 2 * np
    assert 1. == pytest.approx(abs(sim.cheat()[1][0]))

    qubit[0].__del__()
    eng.flush()

    # should be empty:
    assert len(sim.cheat()[0]) == 0
    # state vector should only have np entries:
    assert len(sim.cheat()[1]) == np
コード例 #3
0
def test_simulator_probability(sim, mapper):
    engine_list = [LocalOptimizer()]
    if mapper is not None:
        engine_list.append(mapper)

    engine_list.append(GreedyScheduler())
    eng = HiQMainEngine(sim, engine_list=engine_list)
    qubits = eng.allocate_qureg(6)
    All(H) | qubits
    eng.flush()
    bits = [0, 0, 1, 0, 1, 0]
    for i in range(6):
        assert (eng.backend.get_probability(
            bits[:i], qubits[:i]) == pytest.approx(0.5**i))
    extra_qubit = eng.allocate_qubit()
    with pytest.raises(RuntimeError):
        eng.backend.get_probability([0], extra_qubit)
    del extra_qubit
    All(H) | qubits
    Ry(2 * math.acos(math.sqrt(0.3))) | qubits[0]
    eng.flush()
    assert eng.backend.get_probability([0], [qubits[0]]) == pytest.approx(0.3)
    Ry(2 * math.acos(math.sqrt(0.4))) | qubits[2]
    eng.flush()
    assert eng.backend.get_probability([0], [qubits[2]]) == pytest.approx(0.4)
    assert (eng.backend.get_probability([0, 0],
                                        qubits[:3:2]) == pytest.approx(0.12))
    assert (eng.backend.get_probability([0, 1],
                                        qubits[:3:2]) == pytest.approx(0.18))
    assert (eng.backend.get_probability([1, 0],
                                        qubits[:3:2]) == pytest.approx(0.28))
    All(Measure) | qubits
コード例 #4
0
def test_simulator_no_uncompute_exception(sim):
    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qubit = eng.allocate_qubit()
    H | qubit
    with pytest.raises(RuntimeError):
        qubit[0].__del__()
        eng.flush()
    # If you wanted to keep using the qubit, you shouldn't have deleted it.
    assert qubit[0].id == -1
コード例 #5
0
def test_simulator_functional_measurement(sim):
    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qubits = eng.allocate_qureg(5)
    # entangle all qubits:
    H | qubits[0]
    for qb in qubits[1:]:
        CNOT | (qubits[0], qb)

    All(Measure) | qubits

    bit_value_sum = sum([int(qubit) for qubit in qubits])
    assert bit_value_sum == 0 or bit_value_sum == 5
コード例 #6
0
def test_simulator_functional_entangle(sim):
    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qubits = eng.allocate_qureg(5)
    # entangle all qubits:
    H | qubits[0]
    for qb in qubits[1:]:
        CNOT | (qubits[0], qb)

    eng.flush()

    id2pos, vec = sim.cheat()

    # check the state vector:
    assert .5 == pytest.approx(abs(vec[0])**2)  # amplitudes 00000 and 11111
    assert .5 == pytest.approx(abs(
        vec[31])**2)  # are never moved even if qubit reordering made
    for i in range(1, 31):
        assert 0. == pytest.approx(abs(vec[i]))

    # unentangle all except the first 2
    for qb in qubits[2:]:
        CNOT | (qubits[0], qb)

    # entangle using Toffolis
    for qb in qubits[2:]:
        Toffoli | (qubits[0], qubits[1], qb)

    eng.flush()

    # check the state vector:
    id2pos, vec = sim.cheat()
    assert .5 == pytest.approx(abs(vec[0])**2)
    assert .5 == pytest.approx(abs(vec[31])**2)
    for i in range(1, 31):
        assert 0. == pytest.approx(abs(vec[i]))

    # uncompute using multi-controlled NOTs
    with Control(eng, qubits[0:-1]):
        X | qubits[-1]
    with Control(eng, qubits[0:-2]):
        X | qubits[-2]
    with Control(eng, qubits[0:-3]):
        X | qubits[-3]
    CNOT | (qubits[0], qubits[1])
    H | qubits[0]

    eng.flush()

    id2pos, vec = sim.cheat()

    # check the state vector:
    assert 1. == pytest.approx(abs(vec[0])**2)
    for i in range(1, 32):
        assert 0. == pytest.approx(abs(vec[i]))

    All(Measure) | qubits
コード例 #7
0
def test_simulator_convert_logical_to_mapped_qubits(sim):
    mapper = BasicMapperEngine()

    def receive(command_list):
        pass

    mapper.receive = receive
    eng = HiQMainEngine(sim, [mapper, GreedyScheduler()])
    qubit0 = eng.allocate_qubit()
    qubit1 = eng.allocate_qubit()
    mapper.current_mapping = {
        qubit0[0].id: qubit1[0].id,
        qubit1[0].id: qubit0[0].id
    }
    assert (sim._convert_logical_to_mapped_qureg(qubit0 + qubit1) == qubit1 +
            qubit0)
コード例 #8
0
def test_simulator_amplitude(sim, mapper):
    engine_list = [LocalOptimizer()]
    if mapper is not None:
        engine_list.append(mapper)

    engine_list.append(GreedyScheduler())
    eng = HiQMainEngine(sim, engine_list=engine_list)
    qubits = eng.allocate_qureg(6)
    All(X) | qubits
    All(H) | qubits
    eng.flush()
    bits = [0, 0, 1, 0, 1, 0]
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(1. / 8.)
    bits = [0, 0, 0, 0, 1, 0]
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.)
    bits = [0, 1, 1, 0, 1, 0]
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.)
    All(H) | qubits
    All(X) | qubits
    Ry(2 * math.acos(0.3)) | qubits[0]
    eng.flush()
    bits = [0] * 6
    assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(0.3)
    bits[0] = 1
    assert (eng.backend.get_amplitude(bits, qubits) == pytest.approx(
        math.sqrt(0.91)))
    All(Measure) | qubits
    # raises if not all qubits are in the list:
    with pytest.raises(RuntimeError):
        eng.backend.get_amplitude(bits, qubits[:-1])
    # doesn't just check for length:
    with pytest.raises(RuntimeError):
        eng.backend.get_amplitude(bits, qubits[:-1] + [qubits[0]])
    extra_qubit = eng.allocate_qubit()
    eng.flush()
    # there is a new qubit now!
    with pytest.raises(RuntimeError):
        eng.backend.get_amplitude(bits, qubits)
コード例 #9
0
def test_simulator_kqubit_exception(sim):
    m1 = Rx(0.3).matrix
    m2 = Rx(0.8).matrix
    m3 = Ry(0.1).matrix
    m4 = Rz(0.9).matrix.dot(Ry(-0.1).matrix)
    m = numpy.kron(m4, numpy.kron(m3, numpy.kron(m2, m1)))

    class KQubitGate(BasicGate):
        @property
        def matrix(self):
            return m

    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qureg = eng.allocate_qureg(3)
    with pytest.raises(Exception):
        KQubitGate() | qureg
        eng.flush()
    with pytest.raises(Exception):
        H | qureg
        eng.flush()
コード例 #10
0
def test_simulator_measure_mapped_qubit(sim):
    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qb1 = WeakQubitRef(engine=eng, idx=1)
    qb2 = WeakQubitRef(engine=eng, idx=2)
    cmd0 = Command(engine=eng, gate=Allocate, qubits=([qb1], ))
    cmd1 = Command(engine=eng, gate=X, qubits=([qb1], ))
    cmd2 = Command(engine=eng,
                   gate=Measure,
                   qubits=([qb1], ),
                   controls=[],
                   tags=[LogicalQubitIDTag(2)])
    with pytest.raises(NotYetMeasuredError):
        int(qb1)
    with pytest.raises(NotYetMeasuredError):
        int(qb2)
    eng.send([cmd0, cmd1, cmd2])
    eng.flush()
    with pytest.raises(NotYetMeasuredError):
        int(qb1)
    assert int(qb2) == 1
コード例 #11
0
def test_simulator_kqubit_gate(sim):
    m1 = Rx(0.3).matrix
    m2 = Rx(0.8).matrix
    m3 = Ry(0.1).matrix
    m4 = Rz(0.9).matrix.dot(Ry(-0.1).matrix)
    m = numpy.kron(m4, numpy.kron(m3, numpy.kron(m2, m1)))

    class KQubitGate(BasicGate):
        @property
        def matrix(self):
            return m

    eng = HiQMainEngine(sim, [GreedyScheduler()])
    qureg = eng.allocate_qureg(4)
    qubit = eng.allocate_qubit()
    Rx(-0.3) | qureg[0]
    Rx(-0.8) | qureg[1]
    Ry(-0.1) | qureg[2]
    Rz(-0.9) | qureg[3]
    Ry(0.1) | qureg[3]
    X | qubit
    with Control(eng, qubit):
        KQubitGate() | qureg
    X | qubit
    with Control(eng, qubit):
        with Dagger(eng):
            KQubitGate() | qureg
    assert sim.get_amplitude('0' * 5, qubit + qureg) == pytest.approx(1.)

    class LargerGate(BasicGate):
        @property
        def matrix(self):
            return numpy.eye(2**6)

    with pytest.raises(Exception):
        LargerGate() | (qureg + qubit)
        eng.flush()
コード例 #12
0
from projectq.ops import X, Y, Z, T, H, CNOT, SqrtX, All, Measure
from hiq.projectq.backends import SimulatorMPI
from hiq.projectq.cengines import GreedyScheduler, HiQMainEngine
from projectq.backends import CommandPrinter
from projectq.setups.default import get_engine_list

import numpy as np
import random
import copy
from mpi4py import MPI

# Create main engine to compile the code to machine instructions(required)
#eng = HiQMainEngine(SimulatorMPI(gate_fusion=True, num_local_qubits=20))
eng = HiQMainEngine(engine_list=get_engine_list() + [CommandPrinter()])

# Qubit number N
num_of_qubit = 5

#Circuit Depth
depth = 30

# Gate
gate_set = [X, Y, Z, T, H, SqrtX, CNOT]

# Use the method provided by the main engine to create qubit registers
qureg = eng.allocate_qureg(num_of_qubit)

for i in range(depth):

    #Pick random gate from gate_set
    chosen_gate = random.sample(gate_set, 1)
コード例 #13
0
  		and run it on our backend. We will compare the final state your
  		circuit produces with our target state by ourselves.
  """
    simulated_circuit = 'H | qubit[0]; H | qubit[1]'
    return simulated_circuit


if __name__ == "__main__":
    # use projectq simulator
    #eng = MainEngine()
    # use hiq simulator

    backend = SimulatorMPI(gate_fusion=True)
    cache_depth = 10
    rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions])
    engines = [
        TagRemover(),
        LocalOptimizer(cache_depth),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(cache_depth),
        GreedyScheduler()
    ]
    # make the compiler and run the circuit on the simulator backend
    eng = HiQMainEngine(backend, engines)
    qureg = eng.allocate_qureg(5)
    target_state = [0.5, 0.5, 0.5, 0.5]
    mapper = '3\n1,2\n2,3'
    circuit = circuit_generator(eng, target_state, mapper)
    All(Measure) | qureg
    print(circuit)
コード例 #14
0
temp = LocalOptimizer(cache_depth)
engines = [
    TagRemover(), temp,
    AutoReplacer(rule_set),
    TagRemover(),
    LocalOptimizer(cache_depth),
    GreedyScheduler()
]

# create a list of restriction engines
restric_engine = restrictedgateset.get_engine_list(one_qubit_gates=(X, Y, Z, H,
                                                                    S, T, Rx,
                                                                    Ry, Rz),
                                                   two_qubit_gates=(CZ, CX))

eng = HiQMainEngine(backend, engine_list=engines + [CommandPrinter()])


class SqrtYGate(BasicGate):
    """ Square-root X gate class """
    @property
    def matrix(self):
        return (0.5 + 0.5j) * np.matrix([[1, -1], [1, 1]])

    def tex_str(self):
        return r'$\sqrt{Y}$'

    def __str__(self):
        return "SqrtY"

    def get_merged(self, other):
コード例 #15
0
ファイル: my_optimize.py プロジェクト: BoxiLi/Hiq-code
    else:
        raise NotMergeable


# Command.self_merge_multi = self_merge_multi
# LocalOptimizer._optimize = my_optimize
# LocalOptimizer.multigate_merge = multigate_merge
#################################


# create a list of restriction engines
restric_engine = restrictedgateset.get_engine_list(one_qubit_gates=(X,Y,Z,H,S,T,Rx,Ry,Rz),
                                                two_qubit_gates=(CZ,CX))

# eng = HiQMainEngine(backend, engine_list=[CommandPrinter()] + engines + [CommandPrinter()])
eng = HiQMainEngine(backend, engine_list= engines)
Qureg = eng.allocate_qureg(14)

theta1=0
theta2=0
theta3=0
theta4=0
theta5=0

from circuit import example_circuit

example_circuit(Qureg, theta1, theta2, theta3, theta4, theta5)

All(Measure) | Qureg

コード例 #16
0
    #     locations[i] = i
    # backend.set_qubit_locations(locations)

    cache_depth = 10
    rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions])
    engines = [
        TagRemover(),
        LocalOptimizer(cache_depth),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(cache_depth),
        #,CommandPrinter(),
        GreedyScheduler()
    ]

    eng = HiQMainEngine(backend, engines)
    m = 2
    epsilon = 0.1  # the estimation algorithm successs with probability 1 - epsilon
    n_accuracy = 3  # the estimation algorithm estimates with 3 bits accuracy
    n = _bits_required_to_achieve_accuracy(n_accuracy, epsilon)

    ## we create a unitary U = R(cmath.pi*3/4) \ox R(cmath.pi*3/4)
    U = BasicGate()
    theta = math.pi * 3 / 4
    U.matrix = np.matrix([[1, 0, 0, 0], [0, cmath.exp(1j * theta), 0, 0],
                          [0, 0, cmath.exp(1j * theta), 0],
                          [0, 0, 0, cmath.exp(1j * 2 * theta)]])

    state = eng.allocate_qureg(m + n)

    # prepare the input state to be |psi>=|01>
コード例 #17
0
ファイル: decompose_CR.py プロジェクト: BoxiLi/Hiq-code
rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions])
engines = [
    TagRemover(),
    LocalOptimizer(cache_depth),
    AutoReplacer(rule_set),
    TagRemover(),
    LocalOptimizer(cache_depth),
    GreedyScheduler()
]

# create a list of restriction engines
restric_engine = restrictedgateset.get_engine_list(one_qubit_gates=(X, Y, Z, H,
                                                                    S, T, Rx,
                                                                    Ry, Rz),
                                                   two_qubit_gates=(CZ, CX))

eng = HiQMainEngine(backend,
                    engine_list=restric_engine + engines + [CommandPrinter()])
qureg = eng.allocate_qureg(2)

H | qureg[0]
with Control(eng, qureg[0]):
    Rx(np.pi / 2) | qureg[1]
eng.flush(
)  # In order to have all the above gates sent to the simulator and executed
mapping, wavefunc = copy.deepcopy(eng.backend.cheat())

All(Measure) | qureg

print(wavefunc)
print(mapping)
コード例 #18
0
ファイル: qecc9_sta.py プロジェクト: i2000s/HiQsimulator-1
def run_qecc9():

    #init simulator
    simulator = StabilizerSimulator(12)
    eng = HiQMainEngine(simulator, [])

    #allocate
    qubits = eng.allocate_qureg(12)

    #start
    print("= Encoded the qubit, state is: |0>")
    #circuit
    CNOT | (qubits[0], qubits[3])
    CNOT | (qubits[3], qubits[0])

    CNOT | (qubits[3], qubits[6])
    CNOT | (qubits[3], qubits[9])
    H | qubits[3]
    CNOT | (qubits[3], qubits[4])
    CNOT | (qubits[3], qubits[5])
    H | qubits[6]
    CNOT | (qubits[6], qubits[7])
    CNOT | (qubits[6], qubits[8])
    H | qubits[9]
    CNOT | (qubits[9], qubits[10])
    CNOT | (qubits[9], qubits[11])

    H | qubits[3]
    H | qubits[4]
    H | qubits[5]
    H | qubits[6]
    H | qubits[7]
    H | qubits[8]
    H | qubits[9]
    H | qubits[10]
    H | qubits[11]
    CNOT | (qubits[1], qubits[3])
    CNOT | (qubits[1], qubits[4])
    CNOT | (qubits[1], qubits[5])
    CNOT | (qubits[1], qubits[6])
    CNOT | (qubits[1], qubits[7])
    CNOT | (qubits[1], qubits[8])
    CNOT | (qubits[1], qubits[9])
    CNOT | (qubits[1], qubits[10])
    CNOT | (qubits[1], qubits[11])
    H | qubits[3]
    H | qubits[4]
    H | qubits[5]
    H | qubits[6]
    H | qubits[7]
    H | qubits[8]
    H | qubits[9]
    H | qubits[10]
    H | qubits[11]

    CNOT | (qubits[2], qubits[3])
    CNOT | (qubits[2], qubits[4])
    CNOT | (qubits[2], qubits[5])
    CNOT | (qubits[2], qubits[6])
    CNOT | (qubits[2], qubits[7])
    CNOT | (qubits[2], qubits[8])
    CNOT | (qubits[2], qubits[9])
    CNOT | (qubits[2], qubits[10])
    CNOT | (qubits[2], qubits[11])

    CNOT | (qubits[9], qubits[11])
    CNOT | (qubits[9], qubits[10])
    H | qubits[9]
    CNOT | (qubits[6], qubits[8])
    CNOT | (qubits[6], qubits[7])
    H | qubits[6]
    CNOT | (qubits[3], qubits[5])
    CNOT | (qubits[3], qubits[4])
    H | qubits[3]
    CNOT | (qubits[3], qubits[9])
    CNOT | (qubits[3], qubits[6])

    Measure | qubits[3]
    #flush
    eng.flush()

    print("= Decoded the qubit, state is: |{}>".format(int(qubits[3])))
コード例 #19
0
ファイル: problem3.py プロジェクト: BoxiLi/Hiq-code
            break
    return amp_error.jac


if __name__ == "__main__":
    # use projectq simulator
    #eng = MainEngine()
    # use hiq simulator
    # TODO carefull with num_local_qubits
    backend = SimulatorMPI(gate_fusion=True)
    cache_depth = 10
    rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions])
    engines = [
        TagRemover(),
        LocalOptimizer(cache_depth),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(cache_depth),
        GreedyScheduler()
    ]
    # make the compiler and run the circuit on the simulator backend
    eng = HiQMainEngine(backend, engine_list=engines)
    qureg = eng.allocate_qureg(14)
    # Just an example, you need to design more final state cases for testing..
    final_state = [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1]
    # Function that need to be implemented by the contestants
    theta = calculate_theta(eng, final_state)
    run_circuit(qureg, theta)
    eng.flush()
    print(eng.backend.get_probability(final_state, qureg))
    All(Measure) | qureg
コード例 #20
0
ファイル: QBNN 3-2-1 Task 2.py プロジェクト: phylyd/QBNN
if __name__ == "__main__":

    backend = SimulatorMPI(gate_fusion=True, num_local_qubits=23)

    cache_depth = 10
    rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions])
    engines = [
        TagRemover(),
        LocalOptimizer(cache_depth),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(cache_depth),
        GreedyScheduler()
    ]

    eng = HiQMainEngine(backend, engines)

    if MPI.COMM_WORLD.Get_rank() == 0:

        #allocate all the qubits
        layer1_weight_reg = eng.allocate_qureg(6)
        layer1_input_reg = eng.allocate_qureg(6)

        layer2_weight_reg = eng.allocate_qureg(2)

        output_reg = eng.allocate_qureg(3)
        des_output = eng.allocate_qubit()
        ancilla_qubit = eng.allocate_qubit()
        ancilla2 = eng.allocate_qubit()
        phase_reg = eng.allocate_qureg(3)
コード例 #21
0
    #     locations[i] = i
    # backend.set_qubit_locations(locations)

    cache_depth = 10
    rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions])
    engines = [
        TagRemover(),
        LocalOptimizer(cache_depth),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(cache_depth),
        #,CommandPrinter(),
        GreedyScheduler()
    ]

    eng = HiQMainEngine(backend, engines)

    dataset = [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0]
    if not _is_power2(len(dataset)):
        raise ValueError("The size of the dataset must be a power of 2!")

    # choose the first element in Dataset to be the threshold:
    print(
        "======================================================================="
    )
    print("= This is the Unknown Number Gover Search algorithm demo")
    print("= The algorithm searches for one marked element in a given set")
    print("= There may be many marked element")
    print(
        "= The original Grover algorithm requires to know the number of \n"
        "    marked elements in advance. This algorithm fixes this requirement"
コード例 #22
0
ファイル: shor_mpi.py プロジェクト: i2000s/HiQsimulator-1
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        InstructionFilter(high_level_gates),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        GreedyScheduler(), resource_counter
    ]

    # make the compiler and run the circuit on the simulator backend
    eng = HiQMainEngine(SimulatorMPI(gate_fusion=True, num_local_qubits=20),
                        compilerengines)

    N = 0
    if MPI.COMM_WORLD.Get_rank() == 0:
        # print welcome message and ask the user for the number to factor
        print(
            "\n\t\033[37mH\033[91mI\033[37mQ\033[91m>\033[0m\n\t--------\n\tImplementation of Shor"
            "\'s algorithm.",
            end="")
        N = int(input('\n\tNumber to factor: '))
        print("")

    N = MPI.COMM_WORLD.bcast(N, root=0)

    print("\tFactoring N = {}: \033[0m".format(N), end="\n")