次の方法で共有


プロジェクトとカスタム ライブラリを作成および管理する方法

この記事では、 プロジェクトを作成、管理、共有する方法について説明します。 プロジェクトは、互いの操作と機能にアクセスできる複数の ファイルを含むフォルダー構造です。 プロジェクトは、ソース コードを論理的に整理するのに役立ちます。 外部ソースからアクセスできるカスタム ライブラリとしてプロジェクトを使用することもできます。

前提条件

  • Azure サブスクリプション内の Azure Quantum ワークスペース。 ワークスペースを作成するには、「Azure Quantum ワークスペースの作成を参照してください。
  • () に () および 拡張機能がインストールされている状態。
  • 外部プロジェクトをパブリック GitHub リポジトリに発行するには、GitHub アカウントが必要です。

Python プログラムを実行するには、次も必要です。

  • インストールされたPython環境でPythonとPip

  • qdk Python ライブラリと azure 追加。

    python -m pip install --upgrade "qdk[azure]"
    

プロジェクトはどのように動作するか

プロジェクトには、という名前のマニフェスト ファイルと、指定したフォルダー構造内の 1 つ以上のファイルと ファイルが含まれています。 プロジェクトは、手動で作成することも、で直接作成することもできます。

でまたは ファイルを開くと、コンパイラは、マニフェスト ファイルの周囲のフォルダー階層を検索し、プロジェクトのスコープを決定します。 コンパイラでマニフェスト ファイルが見つからない場合、コンパイラは 1 つのファイル モードで動作します。

project_root または Jupyter Notebook ファイルで Python を設定すると、コンパイラは project_root フォルダー内のマニフェスト ファイルを検索します。

外部Q# プロジェクトは、別のディレクトリまたはパブリック GitHub リポジトリにある標準の Q# プロジェクトであり、カスタム ライブラリとして機能します。 外部プロジェクトでは、 ステートメントを使用して、外部プログラムからアクセスできる関数と操作を定義します。 プログラムは、外部プロジェクトをマニフェスト ファイルの依存関係として定義し、 ステートメントを使用して、操作、関数、構造体、名前空間などの外部プロジェクト内の項目にアクセスします。 詳細については、「 プロジェクトを外部依存関係として使用する」を参照してください。

プロジェクトを定義する

プロジェクトは、 マニフェスト ファイルと フォルダーの存在によって定義されます。どちらもプロジェクトのルート フォルダーに存在する必要があります。 フォルダーには、ソース ファイルが含まれています。 プログラムと外部プロジェクトの場合、 コンパイラはプロジェクト フォルダーを自動的に検出します。 プログラムと ファイルの場合は、 プロジェクト フォルダー>を 呼び出しで指定<必要があります。 ただし、 プロジェクトのフォルダー構造は、すべての種類のプログラムで同じです。

プロジェクトのフォルダー構造と階層。

  • プログラムを使用する
  • または を使用します

プログラムのプロジェクト フォルダーを定義する

で ファイルを開くと、 コンパイラは、マニフェスト ファイルのフォルダー構造を上方向に検索します。 コンパイラがマニフェスト ファイルを見つけた場合、コンパイラは、 ディレクトリとそのサブディレクトリ内のすべての ファイルを含めます。 各ファイルで定義されている項目は、プロジェクト内の他のすべてのファイルで使用できるようになります。

たとえば、次のフォルダー構造を考えてみましょう。

  • テレポーテーションプロジェクト
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

ファイル を開くと、 コンパイラによって次の処理が実行されます。

  1. のを確認します。
  2. のを確認します。
  3. のを確認します。
  4. を確認し、ファイルを検索します。
  5. プロジェクトのルート ディレクトリとしてを確立し、プロジェクト内の ディレクトリの下にあるすべてのファイルと ファイルを含めます。 マニフェスト ファイルの場合。

メモ

におよび ファイル パスへの明示的な参照が含まれている場合、コンパイラはこれらのファイルを読み込み、自動検出プロセスを実行しません。 明示的なファイル パス参照は、Git 参照から読み込めるライブラリを定義する場合にのみ必要です。

マニフェスト ファイルの作成

マニフェスト ファイルは、オプションの、、およびフィールドを含めることができる、という名前の JSON ファイルです。 実行可能な最小マニフェスト ファイルは、文字列 です。 で プロジェクトを作成すると、最小限のマニフェスト ファイルが自動的に作成されます。

{}

マニフェスト ファイルの例

次の例は、マニフェスト ファイルが プロジェクトのスコープを定義する方法を示しています。

  • この例では、 のみが指定されたフィールドであるため、このディレクトリとそのサブディレクトリ内のすべての ファイルが プロジェクトに含まれます。

    {
        "author":"Microsoft"
    }
    
  • プロジェクト内では、マニフェスト ファイルを使用して、リンター設定を微調整することもできます。 既定では、次の 3 つのリンター ルールがあります。

    • : default =

    • : default =

    • : default =

      マニフェスト ファイル内の各ルールを、 、 、または に設定できます。 例えば次が挙げられます。

      {
          "author":"Microsoft",
          "lints": [
              {
                "lint": "needlessParens",
                "level": "allow"
              },
              {
                "lint": "redundantSemicolons",
                "level": "warn"
              },
              {
                "lint": "divisionByZero",
                "level": "error"
              }
            ]
      }
      
  • マニフェスト ファイルを使用して、外部 プロジェクトを依存関係として定義し、その外部プロジェクトの操作と関数にリモートでアクセスすることもできます。 詳細については、「 プロジェクトを外部依存関係として使用する」を参照してください。

プロジェクトの要件とプロパティ

次の要件と構成は、すべての プロジェクトに適用されます。

  • プロジェクトに含めるすべての ファイルは、 という名前のフォルダーの下に存在する必要があります。このフォルダーは、 プロジェクトのルート フォルダーの下にある必要があります。 で プロジェクトを作成すると、 フォルダーが自動的に作成されます。

  • マニフェスト ファイルは、 フォルダーと同じレベルにする必要があります。 で プロジェクトを作成すると、最小限のマニフェスト ファイルが自動的に作成されます。

  • ステートメントを使用して、プロジェクト内の他のファイルから操作と関数を参照します。

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

    または、名前空間を使用して個別に参照します。

    MyMathLib.Multiply(x,y); 
    

プロジェクトの場合のみ

  • エントリ ポイント操作は、 プロジェクト内の 1 つの ファイル (既定では操作) でのみ定義できます。
  • エントリ ポイント定義を含む ファイルは、マニフェスト ファイルの下のプロジェクト ディレクトリ レベルに配置する必要があります。
  • からキャッシュされた プロジェクト内のすべての操作と関数は、の予測テキストに表示されます。
  • 選択した操作または関数の名前空間がまだインポートされていない場合は、必要なステートメント自動的に追加されます。

プロジェクトを作成する方法

プロジェクトを作成するには、次の手順に従います。

  1. ファイル エクスプローラーで、 プロジェクトのルート フォルダーとして使用するフォルダーに移動します。

  2. [表示] メニューを開き、[コマンド パレット] を選択します。

  3. 「: プロジェクト作成」と入力します。 は、フォルダー内に最小限のマニフェスト ファイルを作成し、 テンプレート ファイルを含む フォルダーを追加します。

  4. プロジェクトのマニフェスト ファイルを編集します。 Manifest ファイルの例を参照してください。

  5. フォルダーの下にソース ファイルを追加して整理します。

  6. Q# プログラムまたは Python から Jupyter Notebook プロジェクトにアクセスする場合は、root フォルダー パスqsharp.init で設定します。 この例では、プログラムが プロジェクトの フォルダーにあることを前提としています。

    qsharp.init(project_root = '../Teleportation_project')
    
  7. でファイルのみを使用している場合、コンパイラは、 ファイルを開いたときにマニフェスト ファイルを検索し、プロジェクトのルート フォルダーを決定します。 次に、コンパイラは とそのサブディレクトリで ファイルと ファイルをスキャンします。

メモ

代わりに、マニフェスト ファイルと フォルダーを手動で作成できます。

プロジェクトの例

この量子テレポート プログラムは、のローカル シミュレーターで実行される プロジェクトの例です。 Azure Quantum ハードウェアまたはサードパーティのシミュレーターでプログラムを実行する場合は、プログラムをコンパイルしてAzure Quantum ワークスペースに接続する手順について、「Q#プログラムおよびVS Codeの使用を開始する」を参照してください。

この例には、次のディレクトリ構造があります。

  • テレポーテーションプロジェクト
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

マニフェスト ファイルには、 author フィールドと license フィールドが含まれています。

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

ソース ファイル

メイン ファイル にはエントリ ポイントが含まれており、から名前空間を参照します。

    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);
        }
    }

ファイルは、操作を定義し、 ファイルから操作を呼び出します。

    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);
    }

ファイルには、ベル ペアを作成するための標準の再利用可能な操作が含まれています。

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

プログラムを実行する

プログラムを実行する環境のタブを選択します。

このプログラムを実行するには、で ファイルを開き、[実行] を選択します。

プロジェクトを外部依存関係として構成する

プロジェクトをライブラリと同様に他のプロジェクトの外部依存関係として構成して、外部 プロジェクトの関数と操作を他の プロジェクトで使用できるようにすることができます。 外部依存関係は、ドライブ共有に存在することも、パブリック GitHub リポジトリに公開することもできます。

外部依存関係として プロジェクトを使用するには、次の手順を実行する必要があります。

  • 外部プロジェクトを依存関係として、呼び出し元プロジェクトのマニフェスト ファイルに追加します。
  • 外部プロジェクトがGitHubに発行されている場合は、files プロパティを外部プロジェクトのマニフェスト ファイルに追加します。
  • ステートメントを外部プロジェクトに追加します。
  • ステートメントを呼び出し元のプロジェクトに追加します。

マニフェスト ファイルを構成する

外部Q# プロジェクトは、ローカルまたはネットワーク ドライブ共有に配置することも、パブリック GitHub リポジトリに発行することもできます。

呼び出し元のプロジェクト マニフェスト ファイル

ドライブ共有上の外部プロジェクトに依存関係を追加するには、呼び出し元プロジェクトのマニフェスト ファイルで依存関係を定義します。

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

上記のマニフェスト ファイルでは、 は、操作を呼び出すときに名前空間を識別するユーザー定義文字列です。 たとえば、 という名前の依存関係を作成した場合、その依存関係から を使用して関数を呼び出すことができます。

パブリック GitHub リポジトリに発行されたプロジェクトに依存関係を追加するには、次のマニフェスト ファイルの例を使用します。

{
    "author": "Microsoft",
    "dependencies": {
        "MyDependency": {
            "github": {
                "owner": "GitHubUser",
                "repo": "GitHubRepoName",
                "ref": "CommitHash",
                "path": "/path/to/dependency"
            }
        }
    }
}

メモ

GitHub依存関係の場合、ref は GitHub refspec を参照します。 では、依存関係の特定のバージョンに依存できるように、コミット ハッシュを常に使用することをお勧めします。

外部プロジェクト マニフェスト ファイル

外部Q# プロジェクトがパブリック GitHub リポジトリに発行されている場合は、files プロパティを、プロジェクトが使用するすべてのファイルを含む外部プロジェクトのマニフェスト ファイルに追加する必要があります。

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

プロパティは、ローカルファイルパスベースのインポートを使用してインポートする外部プロジェクトの場合、省略可能です。 files プロパティは、GitHubに発行されたプロジェクトにのみ必要です。

ステートメントを使用する

外部プロジェクトの関数と操作を呼び出し元のプロジェクトからアクセスできるようにするには、 ステートメントを使用します。 ファイル内の任意またはすべての呼び出し可能オブジェクトをエクスポートできます。 ワイルドカード構文は使用できないため、エクスポートする呼び出し可能を各々指定する必要があります。

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;

ステートメントを使用する

外部依存関係の項目を使用できるようにするには、呼び出し元のプログラム ステートメントを使用します。 ステートメントは、マニフェスト ファイル内の依存関係に対して定義した名前空間を使用します。

たとえば、次のマニフェスト ファイルの依存関係について考えてみましょう。

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

次のコードを使用して、呼び出し可能ファイルをインポートします。

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

...

ステートメントでは、ワイルドカードの構文とエイリアスもサポートされています。

// 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; 

外部プロジェクトの例

この例では、前の例と同じテレポート プログラムを使用しますが、呼び出し元プログラムと呼び出し可能プログラムを異なるプロジェクトに分割します。

  1. やなど、ローカル ドライブに 2 つのフォルダーを作成します。

  2. 各フォルダーに プロジェクトを作成します。 詳細については、「 プロジェクトを作成する方法」の手順を参照してください。

  3. 、呼び出し元のプログラムで、次のコードをマニフェスト ファイルにコピーしますが、に必要に応じてパスを編集します。

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. で、次のコードをにコピーします。

    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. で、次のコードをにコピーします。

        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
    

    メモ

    プログラム内でその操作を直接呼び出さない場合、その操作をエクスポートする必要はありません。 ある操作は、(操作)がのローカルスコープ内にあるため、操作によって既にアクセス可能です。

  6. プログラムを実行するには、でを開き、[実行] を選択します。

プロジェクトと暗黙的な名前空間

プロジェクトでは、 プログラムで名前空間を指定しない場合、コンパイラはファイル名を名前空間として使用します。 次に、外部依存関係からの呼び出し可能なものを参照する場合は、構文を使用します。 ただし、ファイルに という名前が付けられている場合、コンパイラは名前空間と呼び出し元の構文が であると見なします。 たとえば、「 」のように入力します。

複数のプロジェクト ファイルがある可能性があるため、呼び出し可能ファイルを参照する場合は、正しい構文を考慮する必要があります。 たとえば、次のファイル構造を持つプロジェクトを考えてみましょう。

  • /src
    • Main.qs
    • MathFunctions.qs

次のコードは、外部依存関係を呼び出します。

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

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

名前空間の動作の詳細については、「 User 名前空間」を参照してください。