Bagikan melalui


Cara men-debug dan menguji kode kuantum Anda

Seperti halnya pemrograman klasik, penting untuk dapat memeriksa bahwa program kuantum bertindak sebagaimana dimaksud, dan untuk dapat mendiagnosis perilaku yang salah. Artikel ini membahas alat yang ditawarkan oleh Azure Quantum Development Kit untuk menguji dan men-debug program kuantum.

Men-debug program Anda Q#

Ekstensi Visual Studio Code Azure Quantum Development Kit (QDK) menyertakan debugger untuk Q# program. Anda dapat mengatur titik henti, menelusuri kode Anda dan ke setiap fungsi atau operasi, dan melacak tidak hanya variabel lokal, tetapi juga status kuantum qubit.

Catatan

Debugger Visual Studio Code hanya berfungsi dengan Q# file (.qs) dan tidak berfungsi dengan Q# sel di Jupyter Notebook. Untuk menguji sel Jupyter Notebook, lihat Menguji kode Anda.

Contoh berikut menunjukkan fitur dasar debugger. Untuk informasi lengkap tentang menggunakan debugger Visual Studio Code, lihat Penelusuran kesalahan.

Di Visual Studio Code, buat dan simpan file .qs baru dengan kode berikut:

import Microsoft.Quantum.Arrays.*;
import Microsoft.Quantum.Convert.*;

operation Main() : Result {
    use qubit = Qubit();
    H(qubit);
    let result = M(qubit);
    Reset(qubit);
    return result;
}
  1. Atur titik henti pada baris H(qubit) dengan mengklik di sebelah kiri nomor baris.
  2. Pilih ikon debugger untuk membuka panel debugger dan pilih Jalankan dan Debug. Kontrol debugger ditampilkan di bagian atas layar.
  3. Pilih F5 untuk memulai penelusuran kesalahan dan lanjutkan ke titik henti. Di panel Variabel debugger, perluas kategori Status Quantum. Anda dapat melihat bahwa kubit telah diinisialisasi dalam status |0> .
  4. Masuk ke (F11) H operasi dan kode sumber untuk H operasi ditampilkan. Saat Anda menelusuri operasi, perhatikan perubahan nilai kuantum saat H operasi menempatkan qubit ke dalam superposisi.
  5. Saat Anda melangkahi (F10) M operasi, nilai kuantum diselesaikan ke |0> atau |1> sebagai hasil pengukuran, dan nilai variabel result klasik ditampilkan.
  6. Saat Anda melangkahi Reset operasi, qubit diatur ulang ke |0>.

Menguji kode

Meskipun debugger Visual Studio Code Q# tidak tersedia untuk Q# sel di Jupyter Notebook, Azure QDK menyediakan beberapa ekspresi dan fungsi yang dapat membantu memecahkan masalah kode Anda.

Ekspresi gagal

fail Ekspresi mengakhiri komputasi sepenuhnya, sesuai dengan kesalahan fatal yang menghentikan program.

Pertimbangkan contoh sederhana ini yang memvalidasi nilai parameter:

# import qsharp package to access the %%qsharp magic command
import qsharp 
// use the %%qsharp magic command to change the cell type from Python to Q#
%%qsharp 
function PositivityFact(value : Int) : Unit {
    if value <= 0 {
        fail $"{value} isn't a positive number.";
    }   
}
PositivityFact(0);
Error: program failed: 0 isn't a positive number.
Call stack:
    at PositivityFact in line_2
Qsc.Eval.UserFail

  × runtime error
  ╰─▶ program failed: 0 isn't a positive number.
   ╭─[line_2:5:1]
 5 │ 
 6 │             fail $"{value} isn't a positive number.";
   ·             ────────────────────┬───────────────────
   ·                                 ╰── explicit fail
 7 │     }   
   ╰────

Di sini, fail ekspresi mencegah program terus berjalan dengan data yang tidak valid.

Fungsi Fact()

Anda dapat menerapkan perilaku yang sama dengan contoh sebelumnya menggunakan Fact() fungsi dari Microsoft.Quantum.Diagnostics namespace layanan. Fungsi ini Fact() mengevaluasi kondisi klasik tertentu dan melemparkan pengecualian jika salah.

import qsharp 
%%qsharp
function PositivityFact(value : Int) : Unit {
    Fact(value > 0, "Expected a positive number."); 
}
PositivityFact(4);
Error: program failed: Expected a positive number.
Call stack:
    at Microsoft.Quantum.Diagnostics.Fact in diagnostics.qs
    at PositivityFact in line_4
Qsc.Eval.UserFail

  × runtime error
  ╰─▶ program failed: Expected a positive number.
    ╭─[diagnostics.qs:29:1]
 29 │         if (not actual) {
 30 │             fail message;
    ·             ──────┬─────
    ·                   ╰── explicit fail
 31 │         }
    ╰────

Fungsi DumpMachine()

DumpMachine() adalah Q# fungsi yang memungkinkan Anda untuk membuang informasi tentang status target komputer saat ini ke konsol dan terus menjalankan program Anda.

Catatan

Dengan rilis Azure Quantum Development Kit, DumpMachine() fungsi sekarang menggunakan pemesanan big-endian untuk outputnya.

import qsharp
%%qsharp
import Microsoft.Quantum.Diagnostics.*;
operation MultiQubitDumpMachineDemo() : Unit {
    use qubits = Qubit[2];
    X(qubits[1]);
    H(qubits[1]);
    DumpMachine();

    R1Frac(1, 2, qubits[0]);
    R1Frac(1, 3, qubits[1]);
    DumpMachine();
    
    ResetAll(qubits);
}
MultiQubitDumpMachineDemo();
Basis State
(|𝜓₁…𝜓ₙ⟩)	Amplitude	Measurement Probability	Phase
|00⟩	0.7071+0.0000𝑖	 50.0000%	↑	0.0000
|01⟩	−0.7071+0.0000𝑖	 50.0000%	↓	-3.1416

Basis State
(|𝜓₁…𝜓ₙ⟩)	Amplitude	Measurement Probability	Phase
|00⟩	0.7071+0.0000𝑖	 50.0000%	↑	0.0000
|01⟩	−0.6533−0.2706𝑖	 50.0000%	↙	-2.7489   

fungsi dump_machine()

dump_machine adalah fungsi Python yang mengembalikan jumlah kubit yang dialokasikan saat ini dan kamus Python dari amplitudo status jarang yang dapat Anda uraikan. Menggunakan salah satu fungsi ini dalam Jupyter Notebook memungkinkan Anda untuk menelusuri operasi Anda seperti debugger. Menggunakan program contoh sebelumnya:

import qsharp 
%%qsharp
use qubits = Qubit[2];
X(qubits[0]);
H(qubits[1]);
dump = qsharp.dump_machine()
dump

Basis State
(|𝜓₁…𝜓ₙ⟩)	Amplitude	Measurement Probability	Phase
|10⟩	0.7071+0.0000𝑖	 50.0000%	↑	0.0000
|11⟩	0.7071+0.0000𝑖	 50.0000%	↑	0.0000
%%qsharp
R1Frac(1, 2, qubits[0]);
R1Frac(1, 3, qubits[1]);
dump = qsharp.dump_machine()
dump
Basis State
(|𝜓₁…𝜓ₙ⟩)	Amplitude	Measurement Probability	Phase
|10⟩	0.5000+0.5000𝑖	 50.0000%	↗	0.7854
|11⟩	0.2706+0.6533𝑖	 50.0000%	↗	1.1781    
# you can print an abbreviated version of the values
print(dump)
STATE:
|10⟩: 0.5000+0.5000𝑖
|11⟩: 0.2706+0.6533𝑖
# you can access the current qubit count
dump.qubit_count
2
# you can access individual states by their index
dump[2]
(0.5+0.5000000000000001j)
dump[3]
(0.27059805007309845+0.6532814824381883j)

Operasi CheckZero() dan CheckAllZero()

CheckZero() dan CheckAllZero() adalah Q# operasi yang dapat memeriksa apakah status array qubit atau qubit saat ini adalah $\ket{0}$. CheckZero() mengembalikan true jika kubit berada dalam status $\ket{0}$, dan false jika berada dalam status lain. CheckAllZero()true mengembalikan jika semua qubit dalam array berada dalam status $\ket{0}$, dan false jika qubit berada dalam status lain.

import Microsoft.Quantum.Diagnostics.*;

operation Main() : Unit {
    use qs = Qubit[2];
    X(qs[0]); 
    if CheckZero(qs[0]) {
        Message("X operation failed");
    }
    else {
        Message("X operation succeeded");
    }
    ResetAll(qs);
    if CheckAllZero(qs) {
        Message("Reset operation succeeded");
    }
    else {
        Message("Reset operation failed");
    }
}

fungsi dump_operation()

dump_operation adalah fungsi Python yang mengambil operasi, atau definisi operasi, dan sejumlah qubit yang akan digunakan, dan mengembalikan matriks persegi dari bilangan kompleks yang mewakili output operasi.

Anda mengimpor dump_operation dari qsharp.utils.

import qsharp
from qsharp.utils import dump_operation

Contoh ini mencetak matriks gerbang identitas qubit tunggal dan gerbang Hadamard.

res = dump_operation("qs => ()", 1)
print(res)
res = dump_operation("qs => H(qs[0])", 1)
print(res)
[[(1+0j), 0j], [0j, (1+0j)]]
[[(0.707107+0j), (0.707107+0j)], [(0.707107+0j), (-0.707107-0j)]]

Anda juga dapat menentukan fungsi atau operasi menggunakan qsharp.eval() lalu mereferensikannya dari dump_operation. Satu qubit yang diwakili sebelumnya juga dapat diwakili sebagai

qsharp.eval("operation SingleQ(qs : Qubit[]) : Unit { }")

res = dump_operation("SingleQ", 1)
print(res)
[[(1+0j), 0j], [0j, (1+0j)]]

Contoh ini menggunakan Controlled Ry gerbang untuk menerapkan rotasi ke kubit kedua

qsharp.eval ("operation ControlRy(qs : Qubit[]) : Unit {qs[0]; Controlled Ry([qs[0]], (0.5, qs[1]));}")

res = dump_operation("ControlRy", 2)
print(res)
[[(1+0j), 0j, 0j, 0j], [0j, (1+0j), 0j, 0j], [0j, 0j, (0.968912+0j), (-0.247404+0j)], [0j, 0j, (0.247404+0j), (0.968912+0j)]]

Kode berikut mendefinisikan Q# operasi ApplySWAP dan mencetak matriksnya bersama dengan operasi identitas dua qubit.

qsharp.eval("operation ApplySWAP(qs : Qubit[]) : Unit is Ctl + Adj { SWAP(qs[0], qs[1]); }")

res = dump_operation("qs => ()", 2)
print(res)
res = dump_operation("ApplySWAP", 2)
print(res)
[[(1+0j), 0j, 0j, 0j], [0j, (1+0j), 0j, 0j], [0j, 0j, (1+0j), 0j], [0j, 0j, 0j, (1+0j)]]
[[(1+0j), 0j, 0j, 0j], [0j, 0j, (1+0j), 0j], [0j, (1+0j), 0j, 0j], [0j, 0j, 0j, (1+0j)]]

Contoh lain dari operasi pengujian menggunakan dump_operation() dapat ditemukan di halaman sampel Operasi Pengujian di QDK.