Skip to main content
IBM Quantum Platform

セッション内でジョブを実行する

  • このページ上のコードは、以下の要件に基づいて開発されました。 これらのバージョンまたはそれ以降のバージョンを使用することを推奨します。

    qiskit[all]~=2.3.1
    qiskit-ibm-runtime~=0.45.0
    scipy~=1.17.1
    

オープンプランのユーザーはセッションジョブを送信できません。 ワークロードは、 ジョブモードまたはバッチモードで実行しなければならない。

QPUへの専用アクセスが必要な場合は、セッションをご利用ください。


セッションを使用する設定

セッションを開始する前に、 IBM Quantum Compute クライアントを設定し、サービスとして初期化する必要があります

from qiskit_ibm_runtime import (
    QiskitRuntimeService,
    Session,
    SamplerV2 as Sampler,
    EstimatorV2 as Estimator,
    Executor,
)

service = QiskitRuntimeService()

セッションを開く

ランタイム・セッションを開くには、コンテキスト・マネージャー with Session(...) を使うか、あるいは Session クラスを初期化することで開くことができる。 セッションの開始時に、 backend オブジェクトを渡して QPU を指定する必要があります。 セッションは、最初のジョブが実行を開始した時点で開始する。

Note

セッションを開いたが、30分間ジョブを送信しなかった場合、セッションは自動的に終了する。

セッションクラス

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

backend = service.least_busy(operational=True, simulator=False)
session = Session(backend=backend)
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
executor = Executor(mode=session)
# Close the session because no context manager was used.
session.close()

コンテキスト・マネージャー

コンテキスト・マネージャーは自動的にセッションを開いたり閉じたりする。

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

from qiskit_ibm_runtime import (
    Session,
    SamplerV2 as Sampler,
    EstimatorV2 as Estimator,
    Executor,
)

backend = service.least_busy(operational=True, simulator=False)
with Session(backend=backend):
    estimator = Estimator()
    sampler = Sampler()
    executor = Executor()

セッションの長さ

最大セッション生存時間(TTL)は、セッションが実行できる時間を決定する。 この値は max_time パラメータで設定できる。 これは、最長ジョブの実行時間を上回るはずである。

このタイマーはセッション開始時にスタートする。 この値に達すると、セッションは終了する。 実行中のジョブはすべて終了するが、キューに残っているジョブは失敗する。

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

with Session(backend=backend, max_time="25m"):
  ...

また、設定できないインタラクティブTTL(interactive time to live)値もある。 そのウィンドウ内にセッション・ジョブがキューに入っていない場合、セッションは一時的に停止される。

デフォルト値:

インスタンスタイプ(オープンまたはプレミアムプラン)
インタラクティブTTL
最大 TTL
プレミアム・プラン60秒8 h*
* プレミアムプランのインスタンスによっては、異なる値が設定される場合があります。

セッションの最大TTLまたは対話的TTLを決定するには、 セッションの詳細を決定するの指示に従って、それぞれ max_timeinteractive_timeout


セッションを終了する

以下の場合、セッションは終了する:

  • 最大タイムアウト(TTL)値に達すると、キューに入れられたすべてのジョブがキャンセルされる。
  • セッションは手動でキャンセルされ、キューに入れられたジョブはすべてキャンセルされる。
  • セッションは手動で閉じられる。 セッションは新しいジョブの受け付けを停止するが、キューに入れられたジョブは優先的に実行し続ける。
  • Sessionをコンテキストマネージャーとして使用した場合、つまり with Session()、コンテキストが終了するとセッションは自動的に閉じられます( session.close() を使用した場合と同じ動作)。

セッションを閉じる

コンテキストマネージャーを終了すると、セッションは自動的に終了する。 セッション・コンテキスト・マネージャーが終了すると、セッションは「進行中、新規ジョブは受け付けない」ステータスになる。 これは、セッションが最大タイムアウト値に達するまで、実行中またはキューに入れられたすべてのジョブの処理を終了することを意味する。 すべてのジョブが終了すると、セッションは即座に終了する。 これにより、スケジューラは、セッション・インタラクティブのタイムアウトを待たずに次のジョブを実行できるようになり、平均ジョブ待ち行列時間が短縮される。 クローズド・セッションに求人を出すことはできない。

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

with Session(backend=backend) as session:
    estimator = Estimator()
    sampler = Sampler()
    job1 = estimator.run([estimator_pub])
    job2 = sampler.run([sampler_pub])

# The session is no longer accepting jobs but the submitted job will run to completion.
result = job1.result()
result2 = job2.result()
Tip

コンテキストマネージャーを使用していない場合は、不要なコストを避けるために手動でセッションを終了してください。 セッションへのジョブ投入が終わったら、すぐにセッションを閉じることができる。 セッションが session.close() で閉じられると、新しいジョブは受け付けられなくなりますが、すでに投入されたジョブは完了するまで実行され、その結果を取得することができます。

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

session = Session(backend=backend)

# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session)
sampler = Sampler(mode=session)
job1 = estimator.run([estimator_pub])
job2 = sampler.run([sampler_pub])
print(f"Result1: {job1.result()}")
print(f"Result2: {job2.result()}")

# Manually close the session. Running and queued jobs will run to completion.
session.close()

Output:

Result1: PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 2), dtype=float64>), stds=np.ndarray(<shape=(3, 2), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 2), dtype=float64>), shape=(3, 2)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
Result2: PrimitiveResult([SamplerPubResult(data=DataBin(meas=BitArray(<shape=(3, 2), num_shots=4096, num_bits=2>), meas0=BitArray(<shape=(3, 2), num_shots=4096, num_bits=156>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-03-15 07:33:44', stop='2026-03-15 07:33:51', size=24576>)])}, 'version': 2})

セッションの状態を確認する

セッションのステータスを照会して現在の状態を把握するには、 session.status() を使用するか、 ワークロードページを表示します。

セッション・ステータスは以下のいずれかである:

  • Pending:セッションが開始されていないか、無効になっています。 次のセッション・ジョブは、他のジョブと同じようにキューで待つ必要がある。
  • In progress, accepting new jobs:セッションはアクティブで、新しいジョブを受け付けています。
  • In progress, not accepting new jobs:セッションは有効ですが、新しいジョブを受け付けていません。 セッションへのジョブ投入は拒否されるが、未完了のセッション・ジョブは完了まで実行される。 すべてのジョブが終了すると、セッションは自動的に終了する。
  • Closed:セッションの最大タイムアウト値に達したか、セッションが明示的に閉じられた。

セッションの詳細を決定する

セッションのコンフィギュレーションとステータスの包括的な概要については、 session.details() method

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

from qiskit_ibm_runtime import (
    QiskitRuntimeService,
    Session,
    EstimatorV2 as Estimator,
)

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

with Session(backend=backend) as session:
    print(session.details())

Output:

{'id': 'a9fd2f9d-6239-4451-a19c-9b45aa6a0618', 'backend_name': 'ibm_torino', 'interactive_timeout': 60, 'max_time': 28800, 'active_timeout': 28800, 'state': 'open', 'accepting_jobs': True, 'last_job_started': None, 'last_job_completed': None, 'started_at': None, 'closed_at': None, 'activated_at': None, 'mode': 'dedicated', 'usage_time': None}

使用パターン

セッションは、古典的リソースと量子リソースの間で頻繁に通信を必要とするアルゴリズムに特に有効である。

例コスト関数を最小化するために古典的な SciPy オプティマイザを使用する反復作業負荷を実行する。 このモデルでは、 SciPy、コスト関数の出力を使って次の入力を計算する。

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

from scipy.optimize import minimize
from qiskit.circuit.library import efficient_su2


def cost_func(params, ansatz, hamiltonian, estimator):
    # Return estimate of energy from estimator

    energy = sum(
        estimator.run([(ansatz, hamiltonian, params)]).result()[0].data.evs
    )
    return energy


hamiltonian = SparsePauliOp.from_list(
    [("YZ", 0.3980), ("ZI", -0.3980), ("ZZ", -0.0113), ("XX", 0.1810)]
)
su2_ansatz = efficient_su2(hamiltonian.num_qubits)
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
ansatz = pm.run(su2_ansatz)
mapped_hamiltonian = [
    operator.apply_layout(ansatz.layout) for operator in hamiltonian
]

num_params = ansatz.num_parameters
x0 = 2 * np.pi * np.random.random(num_params)

session = Session(backend=backend)


# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `session=`
estimator = Estimator(mode=session, options={"default_shots": int(1e4)})
res = minimize(
    cost_func,
    x0,
    args=(ansatz, mapped_hamiltonian, estimator),
    method="cobyla",
    options={"maxiter": 25},
)

# Close the session because no context manager was used.
session.close()

スレッド化を使用して、1回のセッションで2つのVQEアルゴリズムを実行する

複数のワークロードを同時に実行することで、セッションからより多くの成果を得ることができる。 以下の例では、2つのVQEアルゴリズム(それぞれ異なる古典的オプティマイザを使用)を、1つのセッション内で同時に実行する方法を示しています。 ジョブタグは、各ワークロードとジョブを区別するためにも使用される。

Caution

次のコードブロックは、セッションを使用しているため、オープンプランのユーザーに対してエラーを返します。 オープンプラン上のワークロードは、 ジョブモードまたはバッチモードでのみ実行できます。

from concurrent.futures import ThreadPoolExecutor
from qiskit_ibm_runtime import EstimatorV2 as Estimator


def minimize_thread(estimator, method):
    return minimize(
        cost_func,
        x0,
        args=(ansatz, mapped_hamiltonian, estimator),
        method=method,
        options={"maxiter": 25},
    )


with Session(backend=backend), ThreadPoolExecutor() as executor:
    estimator1 = Estimator()
    estimator2 = Estimator()

    # Use different tags to differentiate the jobs.
    estimator1.options.environment.job_tags = ["cobyla"]
    estimator2.options.environment.job_tags = ["nelder-mead"]

    # Submit the two workloads.
    cobyla_future = executor.submit(minimize_thread, estimator1, "cobyla")
    nelder_mead_future = executor.submit(
        minimize_thread, estimator2, "nelder-mead"
    )

    # Get workload results.
    cobyla_result = cobyla_future.result()
    nelder_mead_result = nelder_mead_future.result()

次のステップ

推奨事項
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。