Bu örnekte, ilgili devre konfigürasyonunu kullanarak dağıtılmış kuantum faz tahmini (QPE: Quantum Phase Estimation) versiyonunu simüle ediyoruz.

Bu simüle edilmiş mimaride, ölçüm qubitlerini bir kuantum bilgisayara (devrenin üst kısmı), fazını tahmin etmek istediğimiz qubit'i ise başka bir kuantum bilgisayara (devrenin alt kısmı) yerleştiriyoruz. Bu durumda, yerel olmayan kontrol ünitelerinin doğru şekilde çalışabilmesi için ek talimatlar eklememiz gerekiyor. Bu örnekte, kuantum faz tahmini algoritması için devreyi olduğu gibi inşa etmemiz yeterli; Interlin-q, devreyi yeniden eşleştirip talimatların yürütülmesini sağlayacaktır.

Örneğe başlamak için gerekli kütüphaneleri içe aktarıyor ve konfigürasyonu başlatıyoruz:

import numpy as np
# QuNetSim Bileşenleri
from qunetsim.components import Network
from qunetsim.backends import EQSNBackend
# Interlin−q Bileşenleri
from interlinq import ControllerHost, Circuit,
  ComputingHost, Constants, Qubit

# Ağ nesnelerini başlangıç durumuna getir
network = Network.get_instance()
network.start()
controller_host = ControllerHost(
  host_id="controller",
  backend=EQSNBackend()
  )

# Dağıtık QPU ağını oluştur
  computing_hosts, q_map = controller_host \
  .create_distributed_network(
  num_computing_hosts=2,
  num_qubits_per_host=3
  )

# Kontrol birimini başlatarak ağı oluştur
controller_host.start()
network.add_host(controller_host)
network.add_hosts(computing_hosts)

 

QuNetSim’in ağ nesnesini kullanarak denetleyici (controller) ve hesaplama düğümlerini ağa ekliyoruz. create_distributed_network ControllerHost yöntemi, tamamen bağlı bir ağ topolojisi oluşturur ve bu durumda, her biri üç qubit'e sahip iki ComputingHost ile bu topolojiyi özel olarak kurarız. Sonraki adımda, ağ düğümlerinin her biri için protokol mantığını tanımlıyoruz:

 

def computing_host_protocol(host):
"""
Hesaplama birimi için ilgili protokol
"""
host.receive_schedule()
host.send_results()

def controller_host_protocol(host, q_map, input_gate):
"""
Kontol birimi için ilgili protokol
"""
# Kuantum faz tahmini için devreyi oluşturur
circuit = qpe_circuit(q_map, input_gate)
host.generate_and_send_schedules(circuit)
# Sonuçlar ulaşana kadar bloke eder
host.receive_results()
meas_results = host.results["QPU_1"]["val"]
output = [0] ∗ 3
print(results)
for qubit in meas_results.keys():
 output[int(qubit[−1])] = meas_results[qubit]
decimal_value = 0
output.reverse()
for i, bit in enumerate(output):
  decimal_value += ((2 ∗∗ i) ∗ bit)
phase = decimal_value / 8
print("Tahmin edilen faz {0}".format(phase))

 

Hesaplama düğümünün eylemleri genellikle aynı yapıya sahiptir: Denetleyiciden gelen talimatları beklemek ve ardından ölçüm sonuçlarını denetleyiciye geri göndermek. Denetleyici ise giriş olarak ağ topolojisini (tamamen bağlı olduğu varsayılır) ve faz tahmini adımı için kullanılacak üniteyi alır. Denetleyici bu bilgileri kullanarak devreyi oluşturur, kontrol talimatlarını üretir ve ardından hesaplama düğümlerine gönderir, ölçüm sonuçlarını bekler ve son işleme adımını gerçekleştirir. Devreyi oluşturmak için:

 

def phase_gate(theta):
return np.array([[1, 0], [0, np.exp(1j ∗ theta)]])

def quantum_phase_estimation_circuit(q_map, client_input_gate):
"""
Kuantum faz tahmini algoritması için monolitik devreyi verir
"""
phase_qubit = Qubit(computing_host_id=’QPU_0’, q_id=q_map[’QPU_0’][0])
phase_qubit.single(Operation.X)
meas_qubits = []

for q_id in q_map[’QPU_1’]:
 q = Qubit(computing_host_id=’QPU_1’, q_id=q_id)
 q.single(Operation.H)
 meas_qubits.append(q)
for i, q in enumerate(meas_qubits):
 for _ in range(2 ∗∗ i):
  q.two_qubit(Operation.CUSTOM_CONTROLLED, phase_qubit, client_input_gate)
# Ters Fourier Transformu
meas_qubits.reverse()
for i, q in enumerate(meas_qubits):
 for j, q2 in enumerate(meas_qubits[:i]):
 q2.two_qubit(Operation.CUSTOM_CONTROLLED, q, phase_gate(−np.pi ∗ (2 ∗∗ j) / (2 ∗∗ i)))
 q.single(gate=Operation.H)
# Kubitleri ölçelim:
for q in meas_qubits:
 q.measure()
return Circuit(q_map, qubits=meas_qubits + [phase_qubit])

 

Son olarak, devreyi çalıştırıp sonuçları alıyoruz:

 

# Faz 1/3 için:
input_gate = np.array([
 [1, 0],
 [0, np.exp(1j ∗ 2 ∗ np.pi / 3)]
 ])
t1 = controller_host.run_protocol(
 controller_host_protocol,
 (q_map, input_gate))
computing_hosts[0].run_protocol(computing_host_protocol)
computing_hosts[1].run_protocol(computing_host_protocol)
t1.join()
network.stop(True)

 

Seçtiğimiz EQSN arka plan simülatörü gürültüsüz bir simülatör olduğu için, kuantum faz tahmini için yalnızca bir çekim (shot) kullanmamız yeterlidir. Bu durumda, çıkan sonuç beklendiği gibi, 3 bitlik bir tahmin için hesaplanan faz 0,375'dir. Bu simülasyonda, algoritmayı yürütmek için ağda ne kadar iletişim gerektiğine dair istatistikler toplayabiliriz. Örnekte 3 ölçüm qubit'i kullandık, ancak num_qubits_per_host parametresini değiştirerek ölçüm qubitlerinin sayısını ayarlayabiliriz. Ölçüm qubit'lerinin Şekil 4'teki gibi ayrıldığı durumlarda, monolitik bir versiyon ile dağıtılmış bir versiyonu karşılaştırırsak, birçok kontrol işlemi, her bir ölçüm qubit'i için kontrol bilgisinin bir EPR çifti ve iki klasik mesaj kullanılarak aktarılabilmesi sayesinde, az miktarda klasik iletişim ve dolaşıklık ile gerçekleştirilebiliyor.

Sonuç olarak, bu örnek, dağıtılmış ve paralel kuantum hesaplama mimarisinin potansiyelini ve avantajlarını göz önüne seriyor. Interlin-q gibi simülasyon araçları, dağıtılmış sistemlerde kuantum algoritmalarının nasıl optimize edilebileceğini ve bu algoritmaların klasik bilgisayarlarla karşılaştırıldığında nasıl hızlandırılabileceğini anlamamıza yardımcı olabilir. Özellikle, QPE gibi kuantum algoritmalarının dağıtılmış versiyonları, mevcut kuantum bilgisayarlarındaki kısıtlarla başa çıkmak için önemli bir yaklaşım. Bu tür yaklaşımlar, gelecekte daha büyük ve karmaşık kuantum hesaplamalarının gerçekleştirilebilmesine olanak tanıyabilir.