如何使用 Q# 專案

透過 Azure Quantum Development Kit,您可以定義 Q# 專案,這些專案是具有多個 Q# 檔案的資料夾結構,可存取彼此的作業和函式。 項目有助於以邏輯方式組織原始程式碼。 您也可以使用專案作為外部相依性,或可從外部來源存取的自定義連結庫。

Q#專案包含Q#名為 qsharp.json 的指令清單檔,以及指定資料夾結構中的一或多個 *.qs 檔案。 當使用者在 VS Code 中開啟 *.qs 檔案,或在 Jupyter Notebook 或 Python 檔案中設定 project_root 時,編譯程式會搜尋周圍資料夾階層中的指令清單檔,並判斷專案的範圍。 如果找不到指令清單檔,編譯程式會以單一檔案模式運作。 Q#您可以手動或在 VS Code 中直接建立專案。

外部 Q# 項目是 Q# 位於另一個目錄或公用 GitHub 存放庫的標準專案,並使用 export 語句來定義外部程式可以存取哪些函式和作業。 程式會將外部專案定義為其指令清單檔中的相依性,並使用 import 語句來存取外部專案中的專案(作業、函式、結構及命名空間)。 如需詳細資訊,請參閱 使用專案作為外部相依性

必要條件

  • Azure 訂用帳戶中的 Azure Quantum 工作區。 若要建立工作區,請參閱 建立 Azure Quantum 工作區
  • 已安裝 Azure Quantum Development KitPython 延伸模組的 Visual Studio Code。
  • 如果您打算將外部專案發佈至公用 GitHub 存放庫,則為 GitHub 帳戶。

若要執行 Python 程式,您也需要:

  • 已安裝 Python 和 Pip 的 Python 環境。
  • Azure Quantum qsharpazure-quantum 套件。

Q#定義專案

Q#專案是由指令清單檔的存在所定義,名為 qsharp.json,以及 src 資料夾(其中包含Q#原始程序檔),這兩者都必須位於專案的根資料夾中。 針對 Q# 程式和外部項目,編譯程式 Q# 會自動偵測項目資料夾。 針對 Python 程式和 Jupyter Notebook,您必須使用qsharp.init呼叫來指定Q#項目資料夾。 不過,對於所有類型的程式而言,專案的資料夾結構 Q# 會維持不變。

顯示專案資料夾階層的 Q# 圖片。

定義項目資料夾 (Q# 程式)

在 VS Code 中開啟 *.qs 檔案時,編譯 Q# 程式會在資料夾結構中向上搜尋指令清單檔。 如果找到指令清單檔,編譯程序接著會在 /src 目錄或其任何子目錄中包含所有 Q# 檔案。 每個檔案的專案都可供專案中的所有其他檔案使用。

例如,假設這個資料夾結構:

  • Teleportation_project
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

當您開啟 /src/TeleportOperation/PrepareState/PrepareStateLib.qs 檔案時,編譯程式Q#:

  1. 檢查 /src/TeleportOperation/PrepareState/ 是否有qsharp.json。
  2. 檢查 /src/TeleportOperation 是否有qsharp.json。
  3. 檢查 /src 是否有qsharp.json。
  4. 檢查 / qsharp.json。
  5. /根據指令清單檔的設定,建立為專案的根目錄,並包含專案根目錄下的所有 *.qs 檔案。

建立資訊清單檔

指令清單檔案是名為 qsharp.json 的簡單.json 檔案,可以選擇性地包含 作者授權lints 字段。 最小可行的指令清單檔是字串 {}。 當您在 VS Code 中建立 Q# 專案時,會為您建立最小的指令清單檔。

{}

指令清單檔案範例

以下是指令清單檔如何定義專案範圍的 Q# 一些範例。

  • 在此範例中, author 是唯一指定的欄位,因此此目錄中的所有 *.qs 檔案及其所有子目錄都會包含在 Q# 專案中。

    {
        "author":"Microsoft",
        "license": "MIT"
    }
    
  • 在 Q# 專案中,您也可以使用指令清單檔來微調 VS Code Q# Linter 設定。 根據預設,三個 Linter 規則為:

    • needlessParens:default = allow
    • divisionByZero:default = warn
    • redundantSemicolons:default = warn

    使用指令清單檔,您可以將每個規則設定為 allowwarnerror,例如

    {
        "author":"Microsoft",
        "lints": [
            {
              "lint": "needlessParens",
              "level": "allow"
            },
            {
              "lint": "redundantSemicolons",
              "level": "warn"
            },
            {
              "lint": "divisionByZero",
              "level": "error"
            }
          ]
    }
    
  • 您也可以使用指令清單檔,將外部 Q# 專案定義為相依性,並遠端訪問該外部專案中的作業和函式。 如需詳細資訊,請參閱 使用專案作為外部相依性

Q# 專案需求和屬性

下列需求和組態適用於所有 Q# 專案。

  • 您想要包含在專案中的所有 *.qs 檔案都必須位於名為 src 的資料夾底下,該資料夾必須位於專案根資料夾底下 Q# 。 當您在 VS Code 中建立 Q# 專案時, /src 會自動建立資料夾。

  • 指令清單檔應該與 src 資料夾位於相同的層級。 當您在 VS Code 中建立 Q# 專案時,會自動建立最少的檔案。

  • 您可以使用 語句,從專案中的來源檔案存取作業和函式import

    import MyMathLib.*;  //imports all the callables in the MyMathLib namespace
    ...
        Multiply(x,y);
    

    或使用 命名空間個別參考它們

    MyMathLib.Multiply(x,y);  
    

僅適用於 Q# 專案

  • 專案中只有一個 *.qs 檔案 Q# 可以定義由單 Main() 一作業定義的進入點。
  • 具有進入點定義的 *.qs 檔案可以位於指令清單檔案下方的任何層級。
  • 從 *.qs 檔案快取的任何作業或函式,專案中的任何 Q# 位置會顯示在 VS Code 中的預測文字中。
  • 如果選取之作業或函式的命名空間尚未明確新增,VS Code 會自動新增必要的 import 語句。

建立 Q# 專案的步驟

這些步驟適用於所有 Q# 專案。

  1. 在 VS Code 檔案總管中,以滑鼠右鍵按下您要用於Q#專案根資料夾的資料夾,然後選取 [建立Q#專案],或開啟資料夾,然後選取 [檢視>命令選擇區>Q#:建立Q#專案...]。

  2. VS Code 會在資料夾中建立最少的指令清單檔案,並使用範本檔案新增 /src 資料夾 Main.qs

  3. 視需要編輯指令清單檔案。 請參閱 指令清單檔案範例

  4. 在資料夾下/src新增並組織您的Q#原始程序檔。

  5. 如果您要從 Python 程式或 Jupyter Notebook 存取Q#專案,請使用 qsharp.init設定根資料夾路徑。 這個範例假設您的程式位於專案的 /src 資料夾中 Q# :

    qsharp.init(project_root = '../Teleportation_project')
    
  6. 如果您只 Q# 使用 VS Code 中的檔案,當您開啟 Q# 檔案時,編譯程式會搜尋指令清單檔、判斷專案根資料夾,然後掃描子資料夾是否有 *.qs 檔案。

注意

您也可以在步驟 2 中手動建立指令清單檔案和 /src 資料夾。

範例專案

此量子遠端傳送程式是以稍早所示的單一 Q# 資料夾結構為基礎的專案範例,並在 VS Code 中的本機模擬器上執行。 若要在 Azure Quantum 硬體或第三方模擬器上執行程式,請參閱 開始使用 Q# 程式和 VSCode 以取得編譯程式並連線到 Azure 工作區的步驟。

這個範例會使用此目錄結構:

  • Teleportation_project
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

指令清單檔案包含 作者授權 欄位:

{
    "author":"Microsoft",
    "license":"MIT"
}

Q# 來源檔案

Main.qs 主要檔案包含進入點,並從 TeleportLib.qs 參考 TeleportOperations.TeleportLib 命名空間。


    import TeleportOperations.TeleportLib.Teleport;   // references the Teleport operation from TeleportLib.qs

    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();

        H(msg);
        Teleport(msg, target);    // calls the Teleport() operation from TeleportLib.qs
        H(target);

        if M(target) == Zero {
            Message("Teleported successfully!");
        
        Reset(msg);
        Reset(target);
        }
    }

TeleportLib.qs 會定義作業,Teleport()並從 PrepareStateLib.qs 呼叫PrepareBellPair()作業


    import TeleportOperations.PrepareState.PrepareStateLib.*;     // references the namespace in PrepareStateLib.qs
 
    operation Teleport(msg : Qubit, target : Qubit) : Unit {
        use here = Qubit();

        PrepareBellPair(here, target);      // calls the PrepareBellPair() operation from PrepareStateLib.qs
        Adjoint PrepareBellPair(msg, here);

        if M(msg) == One { Z(target); }
        if M(here) == One { X(target); }

        Reset(here);
    }

PrepareStateLib.qs 檔案包含標準可重複使用的作業,可建立 Bell 配對。

    
    operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
        H(left);
        CNOT(left, right);
    }

執行程式

選取您執行程式之環境的索引標籤。

若要執行此程式,請在 VS Code 中開啟 Main.qs 檔案,然後選取 [ 執行]。

將項目設定 Q# 為外部相依性

Q#專案也可以設定為其他專案的外部相依性,這與連結庫類似,其中外部Q#專案中的函式和作業可供多個Q#專案使用。 外部相依性可以位於磁碟驅動器共用上,或發佈至公用 GitHub 存放庫。

若要使用 Q# 專案作為外部相依性,您需要:

  • 將外部專案新增為呼叫專案的指令清單檔中的相依性。
  • 如果外部專案發佈至 GitHub,請將 「files」 屬性新增至外部專案的指令清單檔。
  • 將語句新增 export 至外部專案。
  • 將語句新增 import 至呼叫的專案。

設定指令清單檔

外部 Q# 專案可以位於本機或網路磁碟驅動器共用上,或發佈至公用 GitHub 存放庫。

呼叫的專案指令清單檔

若要將相依性新增至磁碟驅動器共用上的外部專案,請在呼叫專案的指令清單檔中定義相依性。

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyDependency": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

其中 「MyDependency」 是使用者定義的字串,可在呼叫作業時識別命名空間。 例如,如果您建立名為 「MyMathFunctions」 的相依性,您可以使用 從該相依性呼叫函式 MyMathFunctions.MyFunction()

將相依性新增至發佈至公用 GitHub 存放庫的專案

{
    "author": "Microsoft",
    "dependencies": {
        "MyDependency": {
            "github": {
                "owner": "GitHubUser",
                "repo": "GitHubRepoName",
                "ref": "CommitHash",
                "path": "/path/to/dependency"
            }
        }
}
  • 針對 GitHub 相依性,“ref” 是指 GitHub refspec。 Microsoft建議一律使用認可哈希,因此您可以依賴特定版本的相依性。

外部專案指令清單檔

如果您的外部Q#專案發佈至公用 GitHub 存放庫,您必須files 屬性新增至外部專案的指令清單檔,包括專案中使用的所有檔案。

{
    "author": "Microsoft",
    "license": "MIT",
    "files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}

「檔案」屬性是透過匯入的外部專案選擇性屬性(也就是本機 filepath 型匯入 "path" )。 只有發行至 GitHub 的專案才需要此專案。

使用 export 語句

若要讓外部專案中的函式和作業可供呼叫專案存取,請使用 export 語句。 您可以匯出檔案中的任何或所有可呼叫者。 不支援通配符語法,您必須指定要導出的每個可呼叫專案。

operation Operation_A() : Unit {
...
}
operation Operation_B() : Unit  {
...
}

// makes just Operation_A available to calling programs
export Operation_A;           

// makes Operation_A and Operation_B available to calling programs         
export Operation_A, Operation_B, etc.; 

// makes Operation_A available as 'OpA'
export Operation_A as OpA;             

使用 import 語句

從呼叫程式,您可以使用 import 語句讓外部相依性的專案可供使用。 import 語句會使用針對指令清單檔中相依性定義的命名空間。 例如,針對此相依性

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyMathFunctions": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

您匯入可呼叫專案為

import MyMathFunctions.MyFunction;  // imports "MyFunction()" from the namespace
...

語句 import 也支援通配符語法和別名

// imports all items from the "MyMathFunctions" namespace
import MyMathFunctions.*;        

// imports the namespace as "Math", all items are accessible via "Math.<callable>"
import MyMathFunctions as Math;   

// imports a single item, available in the local scope as "Add"
import MyMathFunctions.MyFunction as Add;        

// imports can be combined on one line
import MyMathFunctions.MyFunction, MyMathFunctions.AnotherFunction as Multiply; 

注意

中目前使用的 open 語句 Q#,用於參考連結庫和命名空間,仍受支援,但最終將會被取代。 同時,您可以選擇性地更新目前的檔案以使用 import 語句。 例如, open Microsoft.Quantum.Diagnostics; 可以取代為 import Microsoft.Quantum.Diagnostics.*;

范例外部專案

在此範例中,您將使用與先前範例相同的遠端傳送程式,但將呼叫程式和可呼叫者分成不同的專案。

  1. 在您的本機磁碟驅動器上建立兩個資料夾,例如 「Project_A」 和 「Project_B」。

  2. Q#遵循建立專案的步驟中的步驟,在每個資料夾中建立Q#專案

  3. Project_A中,呼叫程式會將下列程式代碼複製到指令清單檔案,視需要編輯路徑,以Project_B

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. 在 Project_A中,將下列程式代碼複製到 Main.qs

    import MyTeleportLib.Teleport;   // imports the Teleport operation from the MyTeleportLib namespace defined in the manifest file
    
    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();
    
        H(msg);
        Teleport(msg, target);    // calls the Teleport() operation from the MyTeleportLib namespace
        H(target);
    
        if M(target) == Zero {
            Message("Teleported successfully!");
    
        Reset(msg);
        Reset(target);
        }
    }   
    
  5. Project_B 中,將下列程式代碼複製到 Main.qs

    
        operation Teleport(msg : Qubit, target : Qubit) : Unit {
            use here = Qubit();
    
            PrepareBellPair(here, target); 
            Adjoint PrepareBellPair(msg, here);
    
            if M(msg) == One { Z(target); }
            if M(here) == One { X(target); }
    
            Reset(here);
        }
    
        operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
            H(left);
            CNOT(left, right);
        }
    
        export Teleport;       //  makes the Teleport operation available to external programs
    

    注意

    請注意, PrepareBellPair 作業不需要匯出,因為它不會直接從程式Project_A呼叫。 因為它位於Project_B的本機範圍內,所以作業已經可供存取 Teleport

  6. 若要執行程式,請在 VS Code 中開啟 /Project_A/Main.qs,然後選取 [ 執行]。

專案和隱含命名空間

在 Q# 專案中,如果未在 *.qs 程式中指定命名空間,則編譯程式會使用檔名作為命名空間。 從外部相依性參考可呼叫的 ,然後使用語法 <dependencyName>。<namespace>。<可>呼叫。 不過,如果檔案名為 「Main.qs」,則編譯程式會假設命名空間,而呼叫語法為 <dependencyName>。<可>呼叫,如上一個範例所示。 import MyTeleportLib.Teleport

由於有多個項目檔並不罕見,因此在參考可呼叫專案時,您必須考慮正確的語法。 例如,在具有下列檔案結構的專案中

  • src/
    • Main.qs
    • MathFunctions.qs

外部相依性呼叫會是

import MyTeleportLib.MyFunction;        // "Main" namespace is implied

import MyTeleportLib.MathFunctions.MyFunction;   // "Math" namespace must be explicit 

如需命名空間行為的詳細資訊,請參閱 使用者命名空間