共用方式為


量子程式設計語言簡介 Q#

Q# 是一種高階、開放原始碼 程式設計語言,由Microsoft撰寫量子程式所開發。 Q# 包含在 Quantum Development Kit (QDK) 中。 如需詳細資訊,請參閱 設定 Quantum 開發工具包

作為量子程式設計語言,Q# 符合下列語言、編譯程式和運行時間的需求:

  • 硬體無關: 量子演算法中的量子位不會系結至特定的量子硬體或配置。 Q# 編譯程式和運行時間會處理從程式量子位到實體量子位的對應,讓相同的程式代碼在不同的量子處理器上執行。
  • 量子和傳統運算的整合:Q# 允許整合量子和傳統計算,這對通用量子運算至關重要。
  • 量子位管理:Q# 提供內建作業和功能來管理量子位,包括建立迭加狀態、糾纏量子位,以及執行量子測量。
  • 尊重物理規律:Q# 和量子演演算法必須遵循量子物理的規則。 例如,您無法直接複製或存取 中的 Q#量子位狀態。

如需 Q#來源的詳細資訊,請參閱部落格文章 為什麼我們需要 Q#?

Q#程序的結構

開始撰寫程式 Q# 之前,請務必瞭解其結構和元件。 請考慮下列程式 Q#,其名稱為 Superposition,它會建立疊加狀態:

namespace Superposition {
    @EntryPoint()
    operation MeasureOneQubit() : Result {
        // Allocate a qubit. By default, it's in the 0 state.  
        use q = Qubit();  
        // Apply the Hadamard operation, H, to the state.
        // It now has a 50% chance of being measured as 0 or 1.
        H(q);      
        // Measure the qubit in the Z-basis.
        let result = M(q);
        // Reset the qubit before releasing it.
        Reset(q);
        // Return the result of the measurement.
        return result;
    }
}

根據批注(//),Q# 程式會先配置量子位,然後套用操作以將量子位置於疊加態,再測量量子位狀態,重設量子位,最後傳回結果。

讓我們將此 Q# 程序細分成其元件。

使用者命名空間

Q# 程式可以選擇性地以使用者定義的命名空間開頭,例如:

namespace Superposition {
    // Your code goes here.
}

命名空間可協助您組織相關的功能。 命名空間在 Q# 程式中是選擇性的,這表示您可以撰寫程式而不定義命名空間。

例如, Superposition 範例中的程式也可以在沒有命名空間的情況下編寫,如下所示:

@EntryPoint()
operation MeasureOneQubit() : Result {
    // Allocate a qubit. By default, it's in the 0 state.  
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1.
    H(q);      
    // Measure the qubit in the Z-basis.
    let result = M(q);
    // Reset the qubit before releasing it.
    Reset(q);
    // Return the result of the measurement.
    return result;
}

注意

每個 Q# 程式只能有一個 namespace。 如果您未指定命名空間,則 Q# 編譯程式會使用檔名作為命名空間。

進入點

每個 Q# 程式都必須有一個進入點,這是程式的起點。 根據預設,編譯程式 Q# 會從 Main() 作業開始執行程式,如果有的話,它可以位於程式中的任何位置。 您可以選擇性地使用 @EntryPoint() 屬性,將程式中的任何作業指定為執行點。

例如,在 Superposition 程式中,MeasureOneQubit() 操作是程式的進入點,因為它在操作定義之前具有 @EntryPoint() 屬性。

@EntryPoint()
operation MeasureOneQubit() : Result {
    ...
}

不過,程式也可以藉由將 @EntryPoint() 作業重新命名為 MeasureOneQubit(),以在沒有 Main() 屬性的情況下撰寫,例如:

// The Q# compiler automatically detects the Main() operation as the entry point. 

operation Main() : Result {
    // Allocate a qubit. By default, it's in the 0 state.  
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1.
    H(q);      
    // Measure the qubit in the Z-basis.
    let result = M(q);
    // Reset the qubit before releasing it.
    Reset(q);
    // Return the result of the measurement.
    return result;
}

類型

類型在任何程式設計語言中都是不可或缺的,因為它們會定義程式可以使用的數據。 Q# 提供大部分語言通用的內建類型,包括 IntDoubleBoolString,以及定義範圍、陣列和 Tuple 的類型。

Q# 也提供量子運算特有的類型。 例如,Result 類型代表量子位測量的結果,而且可以有兩個值:ZeroOne

在程式中 SuperpositionMeasureOneQubit() 操作傳回一個 Result 類型,該類型對應於操作的 M 傳回類型。 度量結果會儲存在使用 let 語句定義的新變數中:

// The operation definition returns a Result type.
operation MeasureOneQubit() : Result {
    ...
    // Measure the qubit in the Z-basis, returning a Result type.
    let result = M(q);
    ...
}

量子特定型別的另一個範例是代表量子位的 Qubit 型別。

Q# 也可讓您定義自己的自定義類型。 如需詳細資訊,請參閱 型別宣告。

配置量子位元

在 Q#中,您可以使用 use 關鍵詞和 Qubit 類型來配置量子位。 量子位一律會配置在 $\ket{0}$ 狀態中。

例如,程式 Superposition 定義單一量子位元並將其儲存在變數 q中:

// Allocate a qubit.
use q = Qubit();

您也可以設定多個量子位,並透過其索引存取每個量子位:

use qubits = Qubit[2]; // Allocate two qubits.
H(qubits[0]); // Apply H to the first qubit.
X(qubits[1]); // Apply X to the second qubit.

量子運算

分配量子位之後,您可以將它傳遞給操作和函式。 作業是 Q# 程式的基本建置組塊。 作業 Q# 是量子子程式,或可呼叫的例程,其中包含變更量子位緩存器狀態的量子作業。

若要定義 Q# 作業,您可以指定作業的名稱、其輸入和輸出。 在 Superposition 程式中,MeasureOneQubit() 操作不採用任何參數,並傳回 Result 類型。

operation MeasureOneQubit() : Result {
    ...
}

以下是不接受任何參數且不需要回傳值的基本範例。 在其他語言中,Unit 值相當於 NULL

operation SayHelloQ() : Unit {
    Message("Hello quantum world!");
}

Q#標準程式庫也提供您可以在量子程式中使用的作業,例如程式中的 H Hadamard 作業Superposition。 在 Z 基底的量子位狀態下,H 將量子位放入等概率疊加狀態,其中有 50% 的機率會被測量為 ZeroOne

測量量子位元

雖然有許多類型的量子測量, Q# 但著重於單一量子位的投影測量,也稱為 Pauli測量

在 Q#中,作業會執行 Measure 操作,在指定的 Pauli 基礎上測量一或多個量子位,可以是 PauliXPauliYPauliZMeasure 會傳回 Result 型別,可能是 ZeroOne

若要在計算基礎 $\lbrace、\ket{0}\rbrace\ket{1}$ 中實作測量,您也可以使用 M 作業,以測量 Pauli Z 基底中的量子位。 這使 M 相當於 Measure([PauliZ], [qubit])

例如,Superposition 程式使用 M 作業:

// Measure the qubit in the Z-basis.
let result = M(q);

重設量子位元

在 Q#中,量子位在釋放時必須 處於 $\ket{0}$ 狀態,以避免量子硬體發生錯誤。 您可以使用程式結尾的 $\ket{0}$ 作業,將量子位重設為 Reset 狀態。 無法重設量子位會導致運行時錯誤。

// Reset a qubit.
Reset(q);

標準程式庫命名空間

標準 Q# 連結庫具有內建命名空間,其中包含您可以在量子程式中使用的函式和作業。 例如, Std.Intrinsic 命名空間包含常用的作業和函式,例如 M 測量結果,以及 Message 顯示程式中的任何位置的使用者訊息。

若要呼叫函式或作業,您可以指定完整命名空間或使用 語句,讓該命名空間的所有函式和作業都可供使用 import ,並讓您的程式代碼更容易閱讀。 下列範例會呼叫相同的作業:

Std.Intrinsic.Message("Hello quantum world!");
// imports all functions and operations from the Std.Intrinsic namespace.
import Std.Intrinsic.*;
Message("Hello quantum world!");

// imports just the `Message` function from the Std.Intrinsic namespace.
import Std.Intrinsic.Message;
Message("Hello quantum world!");

注意

程式Superpositionimport沒有任何具有完整命名空間的陳述式或呼叫。 這是因為 Q# 開發環境會自動載入兩個命名空間, Std.Core 以及 Std.Intrinsic,其中包含常用的函數和操作。

您可以利用 Std.Measurement 命名空間使用 MResetZ 作業來最佳化 Superposition 程式。 MResetZ 將度量和重設作業結合成一個步驟,如下列範例所示:

// Import the namespace for the MResetZ operation.
import Std.Measurement.*;

@EntryPoint()
operation MeasureOneQubit() : Result {
    // Allocate a qubit. By default, it's in the 0 state.      
    use q = Qubit();  
    // Apply the Hadamard operation, H, to the state.
    // It now has a 50% chance of being measured as 0 or 1. 
    H(q);   
    // Measure and reset the qubit, and then return the result value.
    return MResetZ(q);
}

瞭解如何使用 Q# 和 Azure Quantum 開發量子程式

Q# 和 Azure Quantum 是開發及執行量子程式的強大組合。 透過 Q# 和 Azure Quantum,您可以撰寫量子程式、模擬其行為、預估資源需求,並在實際的量子硬體上執行它們。 此整合可讓您探索量子運算的潛力,並開發複雜問題的創新解決方案。 無論您是初學者還是經驗豐富的量子開發人員, Q# Azure Quantum 都提供您解除鎖定量子運算能力所需的工具和資源。

下圖顯示當您使用 Q# 和 Azure Quantum 開發量子程式時,量子程式通過的階段。 您的程式會從開發環境開始,並以將作業提交到實際的量子硬體結束。

顯示量子程式設計開發工作流程的圖表。

讓我們細分圖表中的步驟。

選擇您的開發環境

在慣用的開發環境中執行量子程式。 您可以使用 Microsoft Quantum 網站中的線上程式碼編輯器、具有 Visual Studio Code 的本機開發環境,或在 Jupyter Notebooks 中將程式碼與 Python 程式碼結合。Q# 如需詳細資訊,請參閱 執行 Q# 程式的不同方式。

撰寫量子程式

您可以使用量子開發套件(QDK)在 Q# 中撰寫量子程式。 若要開始使用,請參閱 快速入門:建立您的第一個 Q# 程式

Q#此外,QDK 還提供量子運算其他語言的支援,例如 QiskitCirq

與 Python 整合

您可以在各種 IDE 中單獨或搭配 Python 使用 Q# 。 例如,您可以使用 Q# 專案搭配 Python 主程式來呼叫 Q# 作業,或在 Jupyter Notebooks 中整合 Q# 與 Python。 如需詳細資訊,請參閱 整合 Q# 和 Python

%%qsharp 命令

根據預設, Q# Jupyter Notebook 中的程式會 ipykernel 使用 Python 套件。 若要將 Q# 程式代碼新增至筆記本單元格,請使用 %%qsharp 命令,該命令會啟動 qsharp Python 套件,後面接上您的 Q# 程式代碼。

使用 %%qsharp時,請記住下列事項:

  • 您必須先執行 from qdk import qsharp 才能開啟 %%qsharp
  • %%qsharp 限定於它所在的筆記本資料格,並將儲存格型態從 Python 變更為 Q#。
  • 您無法在 之前或之後 %%qsharp放置 Python 語句。
  • Q# 下列程式 %%qsharp 代碼必須遵守 Q# 語法。 例如,使用 // 而非 # 表示批注和 ; 結束程式代碼行。

估計資源

在實際量子硬體上執行之前,您必須瞭解程式是否可以在現有硬體上執行,以及其耗用的資源數量。

Azure Quantum 資源估算器可讓您評估架構決策、比較量子位技術,以及判斷執行指定量子演算法所需的資源。 您可以選擇預先定義的容錯通訊協定,並指定基礎實體量子位模型的假設。

如需詳細資訊,請參閱 執行您的第一個資源估計

注意

Azure Quantum Resources 估算器是免費的,不需要 Azure 帳戶。

在模擬中執行程式

當您編譯和執行量子程式時,QDK 會建立量子模擬器的實例,並將程式 Q# 代碼傳遞給它。 模擬器會使用程式 Q# 代碼來建立量子位(量子粒子的模擬),並套用轉換來修改其狀態。 然後,模擬器中的量子作業結果會傳回給程式。 隔離模擬器中的程式 Q# 代碼可確保演算法遵循量子物理法,而且可以在量子計算機上正確執行。

將您的程式提交到真正的量子硬體

在模擬中測試程序之後,您就可以在實際的量子硬體上執行程式。 當您在 Azure Quantum 中執行量子程式時,您會建立 作業並在執行它。 若要將作業提交至 Azure Quantum 提供者,您需要 Azure 帳戶和量子工作區。 如果您沒有量子工作區,請參閱 建立 Azure Quantum 工作區

Azure Quantum 提供一些最具吸引力且最多樣化的量子硬體。 如需目前支持的硬體提供者清單,請參閱 量子運算提供者

提交作業之後,Azure Quantum 會管理作業生命週期,包括作業排程、執行和監視。 您可以追蹤作業的狀態,並在 Azure Quantum 入口網站中檢視結果。