Q# プロジェクトとカスタム ライブラリを作成および管理する方法
この記事では、 Q# プロジェクトを作成、管理、共有する方法について説明します。 Q# プロジェクトは、互いの操作と機能にアクセスできる複数の Q# ファイルを持つフォルダー構造です。 プロジェクトは、ソース コードを論理的に整理するのに役立ちます。 外部ソースからアクセスできるカスタム ライブラリとしてプロジェクトを使用することもできます。
前提条件
- Azure サブスクリプションの Azure Quantum ワークスペース。 ワークスペースを作成するには、Azure Quantum ワークスペースの作成に関するページを参照してください。
- Azure Quantum Development Kitと Python 拡張機能がインストールされている Visual Studio Code。
- 外部プロジェクトをパブリック GitHub リポジトリに発行する予定の場合は、GitHub アカウント。
Python プログラムを実行する場合は、次のものが必要です。
- Python と Pip がインストールされた Python 環境。
- Azure Quantum
qsharp
パッケージとazure-quantum
パッケージ。
プロジェクトの Q# のしくみ
Q# プロジェクトには、Q#という名前のマニフェスト ファイルと、指定したフォルダー構造内の 1 つ以上の *.qs ファイルが含まれています。 ユーザーが VS Code で *.qs ファイルを開くか、Jupyter Notebook または Python ファイルで project_root
を設定すると、コンパイラは、周囲のフォルダー階層でマニフェスト ファイルを検索し、プロジェクトのスコープを決定します。 マニフェスト ファイルが見つからない場合、コンパイラは 1 つのファイル モードで動作します。
外部 Q# プロジェクトは、別のディレクトリまたはパブリック GitHub リポジトリに存在し、カスタム ライブラリとして機能する標準の Q# プロジェクトです。 外部プロジェクトでは、 export
ステートメントを使用して、外部プログラムからアクセスできる関数と操作を定義します。 プログラムは、外部プロジェクトをマニフェスト ファイルの依存関係として定義し、 import
ステートメントを使用して、外部プロジェクト内の項目 (操作、関数、構造体、および名前空間) にアクセスします。 詳細については、「 プロジェクトを外部依存関係として使用する」を参照してください。
Q# プロジェクトを定義する
Q# プロジェクトは、qsharp.jsonという名前のマニフェスト ファイルと src フォルダー (Q# ソース ファイルを含む) の存在によって定義されます。これらはどちらもプロジェクトのルート フォルダーに存在する必要があります。 Q# プログラムと外部プロジェクトの場合、Q# コンパイラはプロジェクト フォルダーを自動的に検出します。 Python プログラムと Jupyter Notebook の場合は、Q# プロジェクト フォルダーqsharp.init
呼び出しで指定する必要があります。 ただし、 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# コンパイラは次のようになります。
- /src/TeleportOperation/PrepareState/ でqsharp.jsonを確認します。
- /src/TeleportOperation でqsharp.jsonを確認します。
- /srcでqsharp.jsonを確認します。
- qsharp.jsonの / を確認します。
- プロジェクトのルート ディレクトリとして / を確立し、マニフェスト ファイルの設定に従って、プロジェクトのルートの下にあるすべての *.qs ファイルを含めます。
マニフェスト ファイルの作成
マニフェスト ファイルは、author、license、lints フィールドを必要に応じて含めることができる、qsharp.jsonという名前の単純な.json ファイルです。 実行可能な最小マニフェスト ファイルは、文字列 {}
です。 VS Code で Q# プロジェクトを作成すると、最小限のマニフェスト ファイルが自動的に作成されます。
{}
マニフェスト ファイルの例
マニフェスト ファイルで Q# プロジェクトのスコープを定義する方法の例を次に示します。
この例では、 author が指定された唯一のフィールドであるため、このディレクトリ内のすべての *.qs ファイルとそのすべてのサブディレクトリが Q# プロジェクトに含まれます。
{ "author":"Microsoft", "license": "MIT" }
Q# プロジェクト内では、マニフェスト ファイルを使用して VS Code Q#リンター設定を微調整することもできます。 既定では、次の 3 つのリンター ルールがあります。
needlessParens
: default =allow
divisionByZero
: default =warn
redundantSemicolons
: default =warn
マニフェスト ファイルを使用すると、各ルールを
allow
、warn
、またはerror
に設定できます。たとえば、{ "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# プロジェクトの場合のみ
- 1 つのQ#操作によって定義されたエントリ ポイントを定義できるのは、
Main()
プロジェクト内の 1 つの *.qs ファイルだけです。 - エントリ ポイント定義を含む *.qs ファイルは、マニフェスト ファイルの下の任意のレベルに配置できます。
- Q# プロジェクト内の任意の場所にある *.qs ファイルからキャッシュされた操作または関数は、VS Code の予測テキストに表示されます。
- 選択した操作または関数の名前空間がまだインポートされていない場合、VS Code は必要な
import
ステートメントを自動的に追加します。
Q# プロジェクトを作成する手順
これらの手順は、すべての Q# プロジェクトに適用されます。
VS Code ファイル エクスプローラーで、Q# プロジェクトのルート フォルダーに使用するフォルダーを右クリックし、[Q# プロジェクトの作成] 選択するかフォルダーを開き、[View > コマンド パレット] >Q#: Q# プロジェクトの作成... を選択します。
VS Code は、フォルダーに最小限のマニフェスト ファイルを作成し、
/src
テンプレート ファイルを含むMain.qs
フォルダーを追加します。必要に応じてマニフェスト ファイルを編集します。 Manifest ファイルの例を参照してください。
Q# フォルダーの下に
/src
ソース ファイルを追加して整理します。Python プログラムまたは Jupyter Notebook からQ# プロジェクトにアクセスする場合は、を使用して
qsharp.init
root フォルダー パスを設定します。 この例では、プログラムが Q# プロジェクトの /src フォルダー内にあるものとします。qsharp.init(project_root = '../Teleportation_project')
VS Code で Q# ファイルのみを使用している場合、 Q# ファイルを開くと、コンパイラはマニフェスト ファイルを検索し、プロジェクトのルート フォルダーを決定し、サブフォルダーで *.qs ファイルをスキャンします。
Note
手順 2 でマニフェスト ファイルと /src
フォルダーを手動で作成することもできます。
プロジェクトの例
この量子テレポート プログラムは、前に示した 1 つのフォルダー構造に基づく Q# プロジェクトの例であり、VS Code のローカル シミュレーターで実行されます。 Azure Quantum ハードウェアまたはサード パーティのシミュレーターでプログラムを実行するには、「始める Q# プログラムと VSCode」の手順を参照して、プログラムをコンパイルし、Azure ワークスペースに接続してください。
この例では、次のディレクトリ構造を使用します。
- Teleportation_project
- qsharp.json
- src
- Main.qs
- TeleportOperations
- TeleportLib.qs
- PrepareState
- PrepareStateLib.qs
マニフェスト ファイルには、 author フィールドと license フィールドが含まれています。
{
"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()
操作を定義し、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 ファイルには、ベル ペアを作成するための標準の再利用可能な操作が含まれています。
operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
H(left);
CNOT(left, right);
}
プログラムの実行
プログラムを実行している環境のタブを選択します。
このプログラムを実行するには、VS Code で Main.qs ファイルを開き、 Run を選択します。
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"
}
}
}
Note
GitHub 依存関係の場合、"ref" は GitHub refspec を参照します。 特定のバージョンの依存関係に依存できるように、コミット ハッシュを常に使用することをお勧めします。
外部プロジェクト マニフェスト ファイル
外部 Q# プロジェクトがパブリック GitHub リポジトリに発行されている場合は、 must プロジェクトで使用されているすべてのファイルを含め、 files プロパティを外部プロジェクトのマニフェスト ファイルに追加します。
{
"author": "Microsoft",
"license": "MIT",
"files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}
"files" プロパティは、 "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;
Note
open
で現在使用されているQ#ステートメントは、ライブラリと名前空間を参照するために使用されますが、最終的には非推奨になります。 それまでの間は、必要に応じて、 import
ステートメントを使用するように現在のファイルを更新できます。 たとえば、open Microsoft.Quantum.Diagnostics;
は import Microsoft.Quantum.Diagnostics.*;
に置き換えることができます。
また、標準のimport
ライブラリで Q# ステートメントを使用する場合は、ルート名前空間をStd
に短縮できることにも注意してください。 たとえば、 import Microsoft.Quantum.Diagnostics.*;
は import Std.Diagnostics.*;
として記述できます。
外部プロジェクトの例
この例では、前の例と同じテレポート プログラムを使用しますが、呼び出し元のプログラムと呼び出し可能なプログラムを異なるプロジェクトに分割します。
"Project_A" や "Project_B" など、ローカル ドライブに 2 つのフォルダーを作成します。
Q# プロジェクトを作成するための手順手順に従って、各フォルダーにQ# プロジェクトを作成します。
Project_A、呼び出し元のプログラムで、次のコードをマニフェスト ファイルにコピーし、必要に応じてパスを編集Project_B
{ "author": "Microsoft", "license": "MIT", "dependencies": { "MyTeleportLib": { "path": "/Project_B" } } }
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); } }
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
Note
Project_Aのプログラムから直接呼び出されないため、
PrepareBellPair
操作をエクスポートする必要はありません。 Project_Bのローカル スコープ内にあるため、Teleport
操作によって既にアクセス可能ですプログラムを実行するには、VS Code で /Project_A/Main.qs を開き、 Run を選択します。
プロジェクトと暗黙的な名前空間
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
名前空間の動作の詳細については、「 User 名前空間」を参照してください。