Share via


セッションを管理する方法

この記事では、セッションを操作する方法について説明します。 セッションを使用すると、1 つまたは複数のジョブを 1 つの targetに対してグループ化できます。これにより、ジョブを効果的に管理できます。 詳細については、「 対話型量子コンピューティング: セッション」を参照してください。

注意

セッションは、インライン コードを実行 Q# している場合でも Python で管理されます。 詳細については、「セッションの概要」の「Q# + Python」セクション 参照してください。

セッションの取得、セッションの一覧表示、およびジョブの一覧表示

次の表は、特定のセッションのすべてのセッションとすべてのジョブの一覧を取得する Python コマンドを示しています。

コマンド 説明
workspace.list_sessions() または session.list_sessions() Quantum ワークスペース内のすべてのセッションの一覧を取得します。
workspace.get_session(sessionId) または session.get_session(sessionId) ID sessionIdを使用してセッションを取得します。 各セッションには一意の ID があります。
workspace.list_session_jobs(sessionId) または session.list_session_jobs(sessionId) ID sessionIdを持つセッション内のすべてのジョブの一覧を取得します。 各セッションには一意の ID があります。

たとえば、次のコードでは、最小数のジョブを含むセッションを取得する関数を定義しています。 次に、そのセッションに対して、すべてのジョブ、ジョブの合計数、および最初の 10 個のジョブが一覧表示されます。

def get_a_session_with_jobs(min_jobs):
    all_sessions = workspace.list_sessions() # list of all sessions
    for session in all_sessions:
        if len(workspace.list_session_jobs(session.id)) >= min_jobs:
            return session

session = get_a_session_with_jobs(min_jobs=3) # Get a Session with at least 3 jobs

session_jobs = workspace.list_session_jobs(session.id) # List of all jobs within Session ID

print(f"Job count: {len(session_jobs)} \n")
print(f"First 10 jobs for session {session.id}:")
for job in session_jobs[0:10]:
    print(f"Id: {job.id}, Name={job.details.name}")

セッションを開く/閉じる手動の方法

新しいセッションを作成するには、「 セッションの概要」 の手順に従うことをお勧めします。 ただし、セッションは手動で作成できます。

  1. まず、 Session オブジェクトを作成します。

    from azure.quantum.job.session import Session, SessionDetails, SessionJobFailurePolicy
    import uuid
    
    session = Session(
        workspace=workspace, # required
        id=f"{uuid.uuid1()}", # optional, if not passed will use uuid.uuid1()
        name="", # optional, will be blank if not passed
        provider_id="ionq", # optional, if not passed will try to parse from the target
        target="ionq.simulator", # required
        job_failure_policy=SessionJobFailurePolicy.ABORT # optional, defaults to abort
        )
    
    print(f"Session status: {session.details.status}")
    

    注意

    この時点で、セッションはクライアントにのみ存在し、状態が None であることがわかります。 セッションの状態を表示するには、サービスでセッションを作成する必要もあります。

  2. サービスでセッションを作成するには、 または session.open()を使用workspace.open_session(session)できます。

  3. を使用して 状態 とセッションの詳細 session.refresh()を更新するか、セッション ID から新しいセッション オブジェクトを取得します。

    same_session = workspace.get_session(session.id) 
    print(f"Session: {session.details} \n")
    print(f"Session: {same_session.details} \n")
    
  4. または workspace.close_session(session)を使用してセッションをsession.close()閉じます

  5. セッションを にtargetアタッチするには、 を使用target.latest_sessionできます。

  6. セッションが完了するまで つことができます。

    session_jobs = session.list_jobs()
    [session_job.id for session_job in session_jobs]
    
    import time
    while (session.details.status != "Succeeded" and session.details.status != "Failed" and session.details.status != "TimedOut"):
      session.refresh()
      time.sleep(5)
    

で引数を渡す Q#

操作が入力引数を Q# 受け取る場合、これらの引数はジョブの送信中に渡されます。これは Python コードです。 つまり、引数をオブジェクトとして Q# 書式設定するには注意が必要です。

引数をパラメーターとしてジョブに渡すときは、 を呼び出qsharp.compileすときにコードとしてQ#書式設定されるため、Python の値を有効なQ#構文として文字列に書式設定する必要があります。

次 Q# のプログラムについて考えてみましょう。これは、整数、、 nおよび角度 angleの配列 を入力として受け取ります。

open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Arrays;

operation GenerateRandomBits(n: Int, angle: Double[]) : Result[] {
   use qubits = Qubit[n]; // n parameter as the size of the qubit array
   for q in qubits {
       H(q);
   }
   R(PauliZ, angle[0], qubits[0]); // arrays as entry-points parameters
   R(PauliZ, angle[1], qubits[1]);
   let results = MeasureEachZ(qubits);
   ResetAll(qubits);
   return results;
}

操作を 3 回と異なる角度でn=2実行GenerateRandomBitsする必要があります。 次の Python コードを使用して、異なる角度で 3 つのジョブを送信できます。

angle = [0.0, 0.0]
with target.open_session(name="Q# session of three jobs") as session:
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 1", shots=100) # First job submission
    angle[0] += 1
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 2", shots=100) # Second job submission
    angle[1] += 1
    target.submit(input_data=qsharp.compile(f"GenerateRandomBits(2, {angle})"), name="Job 3", shots=100) # Third job submission

session_jobs = session.list_jobs()
[session_job.details.name for session_job in session_jobs]

この例では、Python の配列は既に [item0, item1, ...] として出力されているため、入力引数は書式設定と Q# 一致します。 他の Python データ構造では、互換性のある方法で に挿入 Q# された文字列値を取得するために、より多くの処理が必要になる場合があります。 たとえば、 Q# タプルはコンマ区切りの値でかっこで区切る必要があります。

セッション タイムアウト

セッション内で 10 分間新しいジョブが送信されない場合、セッションはタイムアウトします。 セッションは TimedOut の状態を報告します。 この状況を回避するには、 を使用して ブロックをwithbackend.open_session(name="Name")追加し、コード ブロックの最後にサービスによってセッションclose()が呼び出されるようにします。

注意

プログラムにエラーやバグがある場合、セッション内の前のジョブがすべて完了した後に新しいジョブを送信するのに 10 分以上かかる場合があります。

次のコード スニペットは、新しいジョブが送信されないため、10 分後にセッションがタイムアウトする例を示しています。 これを回避するために、次のコード スニペットでは、 ブロックを使用してセッションを with 作成する方法を示します。

#Example of a session that times out 

session = backend.open_session(name="Qiskit circuit session") # Session times out because only contains one job
backend.run(circuit=circuit, shots=100, job_name="Job 1")
#Example of a session that includes a with block to avoid timeout

with backend.open_session(name="Qiskit circuit session") as session:  # Use a with block to submit multiple jobs within a session
    job1 = backend.run(circuit=circuit, shots=100, job_name="Job 1") # First job submission
    job1.wait_for_final_state()
    job2 = backend.run(circuit=circuit, shots=100, job_name="Job 2") # Second job submission
    job2.wait_for_final_state()
    job3 = backend.run(circuit=circuit, shots=100, job_name="Job 3") # Third job submission
    job3.wait_for_final_state()

セッション内のジョブエラーポリシー

ジョブが失敗した場合のセッションの既定のポリシーは、そのセッションを終了することです。 同じセッション内で追加のジョブを送信した場合、サービスはそれを拒否し、セッションは失敗の状態を報告 します。 進行中のジョブはすべて取り消されます。

ただし、この動作は、セッションの作成時に既定SessionJobFailurePolicy.ABORTjob_failure_policy=SessionJobFailurePolicy.CONTINUEではなく、 のジョブ エラー ポリシーを指定することで変更できます。 ジョブエラー ポリシーが の場合、 CONTINUEサービスは引き続きジョブを受け入れます。 この場合、セッションは [失敗 ] の状態を報告します。この状態は、セッションが閉じられると [失敗] に変わります。

セッションが閉じずにタイムアウトした場合、ジョブが失敗した場合でも状態は TimedOut になります。

たとえば、次のプログラムは、3 つのジョブを含むセッションを作成します。 最初のジョブは入力データとして を指定 "garbage" するため、失敗します。 この時点でセッションの終了を回避するために、プログラムはセッションの作成時に を追加 job_failure_policy=SessionJobFailurePolicy.CONTINUE する方法を示します。

#Example of a session that does not close but reports Failure(s) when a jobs fails

with target.open_session(name="JobFailurePolicy Continue", job_failure_policy=SessionJobFailurePolicy.CONTINUE) as session:
    target.submit(input_data="garbage", name="Job 1") #Input data is missing, this job fails
    target.submit(input_data=quil_program, name="Job 2") #Subsequent jobs are accepted beacuse of CONTINUE policy
    target.submit(input_data=quil_program, name="Job 3")

次のステップ