メインコンテンツへスキップ

コンピューティングリソースとリソース管理

リソースモデルと古典リソース

このセクションでは、ノートパソコンから大規模なスーパーコンピューターまで適用できる、コンピューティング環境について考えるための枠組みを提供します。このセクションが終わるころには、コンピューティング環境の基本的な構成要素と、それらが互いにどのように関係しているかを理解できるようになります。以下の動画で、Iskandar Sitdikov がこれらすべてについて説明しています。

リソースモデル

古典コンピューティング環境はいずれも、アプリケーションを効率よく実行するために連携する複数の相互関連リソースで構成されています。主なリソースは次のとおりです。

  • CPU(Central Processing Unit): CPU はプログラムの命令を解釈・実行するコア処理ユニットです。論理演算、算術演算、制御操作を処理し、システムの「頭脳」として機能します。

  • CPU キャッシュ(L1、L2、L3): これはシステム内で最も高速なメモリで、CPU コアに直接組み込まれているか、非常に近い位置に配置されています。CPU がすぐに必要とするデータや命令のごく一部を保持します。各レベル(L1、L2、L3)はトレードオフを表しており、L1 は最小かつ最速、L3 は最大かつ最低速ですが、それでも RAM より桁違いに高速です。

  • RAM(Random Access Memory): プログラムの命令や使用中のデータを一時的に格納する大容量の揮発性メモリです。CPU が実行中に必要な情報に素早くアクセスできるようにし、低速なストレージデバイスへの依存を減らします。

  • ストレージ(ローカルおよびネットワーク接続型): ストレージはシステムの電源が切れてもデータとソフトウェアを保持し、大規模なデータセットやアプリケーションの長期的な保存を可能にします。ハイパフォーマンスコンピューティングでは、膨大な量の科学データや分析データをスピードと信頼性の両面で扱えるストレージソリューションが必要です。ローカルストレージには SSD(ソリッドステートドライブ)と HDD(ハードディスクドライブ)があり、低レイテンシと高スループットの点から SSD が好まれます。大規模なデータ処理には、並列ファイルシステム、共有ネットワークストレージ、オブジェクトベースシステムが多数のコンピューティングノード間での高速アクセスを実現し、クラウドやアーカイブストレージ層が長期保存とスケーラビリティを支えます。

  • GPU(Graphics Processing Unit): もともとグラフィックスのレンダリング向けに設計されましたが、現代の GPU は強力な並列プロセッサです。ディープラーニング、物理シミュレーション、ビッグデータ分析など、多数の同時計算を必要とするタスクに広く活用されています。GPU が CPU を置き換えるわけではない点に注意が必要です。CPU が高度なプログラムロジックを指示し、GPU が高度に並列なステップを高速化します。

  • 接続/バス: CPU、メモリ、ストレージ、周辺機器をつなぐ通信経路です。バスはシステム各部間のデータ転送と調整を可能にし、コンピューティング環境全体の円滑な通信を確保します。HPC システムでは、CPU、GPU、ストレージデバイスなどのコンポーネントが高速インターコネクトで接続され、迅速なデータ交換を実現しています。GPU は通常、複数のデータレーンを持つ標準インターフェースである PCIe を介してシステムに接続されます。より高い性能が求められる場合は、NVLink が GPU 間や GPU-CPU 間を直接高帯域幅で結び、レイテンシを低減して並列ワークロードを加速します。

  • ファイルシステム: ファイルシステムはストレージデバイス上のデータを整理します。ファイルの保存、取得、管理の構造を提供し、プログラムとユーザーが一貫した論理的な方法で情報にアクセスできるようにします。

各リソースタイプにはそれぞれ固有のパフォーマンス関連の計測単位があります。たとえば、CPU は通常「コア数」と「クロック速度」で測られます。ノートパソコンを購入するとき、仕様にコア数が記載されているのが一般的です。データセンターのコンピューティングノードにも同様の概念が適用され、各ノードには特定のコア数が対応しています。CPU、GPU、さらには QPU など複数のリソースタイプを含むコンピューティング環境は、__ヘテロジニアス(異種混在)コンピューティング環境__と呼ばれます。このような構成は、各プロセッサタイプの強みを活かすことで、多様なワークロードをより効率的に処理します。たとえば、一般的なタスクには CPU を、並列処理には GPU を使用するといった具合です。リソース管理とスケジューリングの文脈では — 特にヘテロジニアスコンピューティング環境において — ここで説明した単位に加えて、さらに追加の計測単位が必要になる場合があります。

メモリの計測単位はメガ/ギガ/テラバイトです。

グラフィックスカードやその他のアクセラレーターの計測単位は、文脈によって異なります。その真の計算能力は処理コア数、メモリサイズ、メモリ帯域幅といった細粒度の指標で測られますが、クラスターリソースやジョブスケジューリングに関する高レベルな議論では、GPU や類似のアクセラレーターを割り当てられたデバイス全体の数(たとえば GPU 3 台)でデバイスレベルに定量化することができます。

ネットワーク/コネクティビティ/バスは、コンピューティングコンポーネント間のデータ転送速度を左右するため、あらゆるコンピューティングインフラにとって重要な要素です。CPU からCPU のキャッシュへ、RAM へ、PCI カードへ、ネットワーク接続デバイスへ — すべては通信であり、HPC 向けに高度に最適化されたアルゴリズムを設計するためには、その正確なメンタルモデルを持つことが不可欠です。

各コンピューティングノードに多くの種類のリソースが含まれる場合があることを示す図。

古典リソースのスケーリング

ハイパフォーマンスコンピューティング(HPC)は、処理時間の短縮や同時に扱えるデータ量の増加(たとえば探索できる解空間のサイズを拡大する)を実現するために、これらの古典リソースをスケーリングすることを指します。これは次の方法で達成できます。

  • 垂直スケーリング: 個々のリソースの性能を向上させる方法です。たとえば、より強力な CPU を使用したり、1 つの物理ノード内にメモリを追加したりすることが含まれます。ここでいうノードとは、複数のコンピューティングリソースを内包するコンピュータークラスターの単位です。

  • 水平スケーリング: 複数の CPU や GPU などのリソースを追加して、1 つのノード上や、より一般的には複数のノード上で協調動作させ、分散コンピューティングを実現する方法です。

単一ノード内にメモリなどのリソースを追加する垂直スケーリングと、異なるリソースタイプを含む接続ノード数を増やす水平スケーリングを示す図。

このセクションで扱ったスケーリングの概念の一部は、次の量子コンピューティングリソースのセクションにも適用できます。量子リソースの他の側面は、新しい方法で定量化されます。

理解度チェック

上記の説明をもとに、垂直スケーリングと水平スケーリングそれぞれの利点と欠点を推察してみてください。

答え:

正解はいくつも考えられます。垂直スケーリングは、特に必要なリソース量が固定された予測可能なワークロードがある場合に、よりシンプルなことが多いです。しかし、水平スケーリングと比べてコンピューティングの基本単位を分割しにくいため、アップグレードのコストが高くなる可能性があります。水平スケーリングは管理が複雑で、ノード間の接続に関する困難やレイテンシが生じる場合がありますが、変動するリソース要件への適応性が高く、アップグレード時にモジュール式で対応できます。

新しいリソースタイプ:QPU(Quantum Processing Unit)

このセクションでは、新しいリソースタイプである量子リソースを紹介し、その定義、計測単位、古典インフラへの接続について説明します。

QPU の定義

  • 量子処理ユニット(QPU): QPU は、実行可能な量子命令セット(量子回路)を受け取り、正確な結果を返すためのすべてのハードウェアを含みます。

    これは、QPU が 1 つ以上の量子チップ(例:Heron)、希釈冷凍機内の量子アンプ、制御エレクトロニクス、命令と波形をメモリに保持したり結果を蓄積したり将来の誤り訂正デコードを行ったりといったタスクに必要な古典コンピュートなど、複数の追加コンポーネントを含むことを意味します。希釈冷凍機はこれらのタスクを実行するために必要ですが、同じ冷凍機内に複数の QPU が存在するケースを考慮して、この定義から希釈冷凍機は除外します。

  • 量子コンピューター: 量子コンピューターは QPU と、ランタイム環境をホストする古典コンピュートで構成されます。

  • ランタイム環境: プログラムを実行可能にするハードウェアとソフトウェアの組み合わせです。

量子回路のレイヤー

古典コンピューティングと量子コンピューティングのどちらにおいても、プロセスは逐次的または並列に実行できます。量子ビットは古典ビットと比べて豊かな状態空間を持つため、1 つの量子ビットに対して複数の単一量子ビットゲートを連続して実行することが意味をなす場合があります(たとえば R_x ゲートに続いて R_z ゲートを実行するなど)。量子コンピューティングでは量子ビット間のエンタングルメントが重要であるため、量子回路に多くの量子ビットにまたがるエンタングルゲートのセットが含まれることも一般的です。これらの要因から、量子回路において個々のゲート操作のレベルで並列実行できるプロセスを特定することが一般的になっています。古典コンピューティングでもビットレベルの並列性は可能ですが、ゲートレベルでの並列性はあまり考慮されず、より大きなスケールでの並列・逐次プロセスを指すことが多いです。

量子コンピューティングでは、同時に実行できるゲートの「レイヤー」という概念があります。多くのアプリケーションでは、すべての量子ビットに回転操作を行い、次に量子ビットのペア間にエンタングルゲートを適用するというパターンが有用です。このような文脈では、「回転レイヤー」(R_xR_yR_z などのゲートのレイヤー)と「エンタングルレイヤー」(CNOT ゲートなど)という言葉が使われます。回路内のレイヤー数が「回路深さ」であり、深さが増すほどノイズとエラーが積み重なるため、これは重要な指標です。

バリアを使ってレイヤーを整列させていない場合、ゲートのレイヤーを視覚的に識別するのは難しいことがあります。Qiskit では、バリアは量子回路における命令として機能し、視覚的な区切りとコンパイル時の制約の両方として働きます。回路の描画においても実行においても、バリアをまたいでゲートが移動することはありません。これは、特定のエラータイプを抑制するために恒等演算となるゲートを意図的に実装するダイナミカルデカップリングなどの文脈で重要です。ダイナミカルデカップリングの詳細についてはこのガイドを参照してください。バリアの視覚的効果を比較するために、同じ回路の 2 つの画像を見てみましょう。1 枚目はバリアなし、2 枚目はレイヤーの整列を強制するバリアありです。

レイヤーの整列を強制するバリアがない 4 量子ビット量子回路。ゲートはやや不規則に配置されている。

レイヤーの整列を強制するバリアが配置された 4 量子ビット量子回路。これによりレイヤーの計数がはるかに容易になる。

これらは同じ回路であり、同じレイヤー数を持っています。しかし 2 枚目では、整列によって回路が以下を持つことが容易に確認できます。

  • 2 つの回転レイヤー:Y 軸まわりに π/5\pi/5、Z 軸まわりに π/4\pi/4 の回転。
  • 3 つのエンタングルレイヤー。論理操作を変えずに CNOT を並列化できないため、各 CNOT はそれぞれ独立した「レイヤー」と見なせます。
  • さらに 2 つの回転レイヤー:Y 軸まわりに π/3\pi/3、Z 軸まわりに π/2\pi/2 の回転。
  • さらに 2 つのエンタングルレイヤー。今回は最初のエンタングルレイヤーのセットよりも最初のレイヤーがやや並列化されています。

各回路の深さは 9 です。

計測単位

量子コンピューティングでは、量子システムの能力は通常、スケール、品質、速度という 3 つの主要なパフォーマンス指標で評価されます。これらの指標は量子デバイスの計算潜在能力を表すだけでなく、実際のアプリケーションにおけるリソースの管理とスケジューリングにも影響します。

  • スケールは、システム内の量子ビット(qubit)数を指し、デバイスが保持できる量子情報の量を表します。リソース管理の観点では、これは特定の量子タスクを実行するために必要な量子ビット数である回路幅に直接影響します。量子ユニットは割り当てられたタスクをサポートするのに十分な量子ビットを持っている必要があります。

  • 品質は、量子操作がどれほど正確に実行されるかを表します。多くの場合、レイヤーフィデリティによって定量化されます。これはすべての量子ビットにわたって量子ゲートの完全なレイヤーを実行する精度を測定します。スケジューリングの観点では、より高いフィデリティによってより深い回路を確実に実行できるため、エラー軽減やタスク分解の必要性に影響します。

  • 速度は CLOPS(Circuit Layer Operations Per Second)で測定され、システムが 1 秒間に実行できる量子操作のレイヤー数を示します。これはタスク実行のスループットとレイテンシに影響し、量子ユニットが特定のワークロードをどれだけ迅速に完了できるかを判断するのに役立ちます。量子コンピューターでは古典コンピューターと比べて量子ビットがより大きなノイズとエラーの影響を受けるため、この速度は特に重要です。量子ビットが有用な形で量子情報を保持できる時間は__コヒーレンス時間__と呼ばれ、Heron r3 プロセッサでは通常 200〜300 μs\mu\text{s} のオーダーです。

量子指標と古典指標の違い

CLOPS は FLOPS の緩やかな量子アナログと考えることができますが、いくつかの重要な違いがあります。CLOPS は量子プロセッサが量子回路、特に回路内の操作レイヤーを実行する速度を測定し、量子実行と回路実行に必要な古典計算の両方が含まれます。IBM Quantum によって量子コンピューターの実行速度の総合的な指標として開発されたもので、量子実行時間と回路更新のためのリアルタイム古典処理をカバーしています。一方、FLOPS は古典プロセッサにおける浮動小数点演算能力のみを純粋に測定するものです。

CLOPS は既存のハードウェアでベンチマーク可能な測定可能なパフォーマンス指標を提供します。IBM Quantum はさまざまな量子プロセッサの CLOPS ベンチマークを実施しており、その値は IBM Quantum Platform のコンピューティングリソースページで確認できます。CLOPS 値はハードウェア性能、ゲート速度、古典処理速度、およびそれらの統合に依存します。

量子ビット数は特定の QPU に対して固定された値です。CLOPS と品質は定期的なキャリブレーションとメンテナンスに依存し、単一の QPU であっても時間とともにわずかに変動する場合があります。

これらの指標は、量子システムの割り当てとスケジューリングを導くものです。多くの場合、量子システム全体が単一のユニットとして扱われます。しかし、量子ビット数、回路深さ、実行速度のいずれかの点でタスクが 1 つのユニットの容量を超える場合は、回路切断/接合(circuit cutting/knitting)などの手法が使用できます。回路切断とは、大きな量子タスクをより小さく管理しやすいサブタスクに分解し、複数の量子チップに分散させることで、ハードウェアの制限にもかかわらずスケーラブルな量子計算を実現するプロセスです。回路接合とは、回路切断の後に続くプロセス — 小さなサブ回路の結果を「接合」または統合する古典後処理ステップです。

量子コンピューターには、RAM や GPU メモリのような永続的でアドレス指定可能なストレージという意味での従来のメモリはありません。古典コンピューティングリソースはメモリに保存された個別のビットを持ち、計算中にデータを保存、取得、再利用できます。量子リソースは量子ビットを使用しますが、量子ビットは古典的な意味でのメモリを保存しません。代わりに、量子ビットは 0 と 1 の重ね合わせを同時に表す量子状態に存在し、状態空間での指数的な並列性を可能にします。しかし、量子ビットの状態はデリケートであり、量子状態を崩さずに中間ステップでクローンを作ったり確定的に読み取ったりすることはできないため、計算中にメモリのような永続的な動作は存在しません。量子ビットは実行中を通じてコヒーレントな状態に保たれる必要があり、「メモリ」は本質的に量子状態そのものです。古典メモリは量子プロセッサと並列にのみ使用でき、内部の量子メモリとしては使用できません。これは重要な影響をもたらします。古典コンピューティングリソースは中間結果を自由に再利用・保存できますが、量子リソースは計算を乱す測定なしにはこれを行うことができません。

古典インフラへの接続

QPU はネットワークやさまざまな API(Application Programming Interface)を通じて古典インフラに接続でき、ソフトウェア開発者がプログラムから QPU を操作することを可能にします。これらの API は通常、SDK(ソフトウェア開発キット)やライブラリ(Qiskit など)の背後に隠されており、プログラミングの抽象化(第 3 章のプログラミングモデルで扱う Qiskit Primitives など)の形で計算科学者に提供されます。

量子リソースと古典リソースの緊密な統合と疎な統合の違いを区別することは重要です。現在、QPU は古典コンピューティングリソースと同じノード上にはありません。実際、QPU は現在 PCIe ではなくネットワーク経由で接続されています。これは将来変わる可能性がありますが、QPU と古典コンピューティングリソースにとって最適な環境条件に関するエンジニアリング上の課題があります。

量子リソースのスケーリング

量子リソースのスケーリングも垂直と水平に分類できます。

  • 垂直スケーリングは、チップあたりの量子ビット数を増やすか、デバイスのフィデリティを向上させることです。
  • 水平スケーリングは、カプラーや古典インターコネクトを使ってチップを接続することです。

量子リソースの垂直スケーリングとしてチップ上の量子ビット増加、水平スケーリングとしてカプラーを使った多数のチップの接続を示す図。

理解度チェック

古典コンピューティングにおける(a)情報のビットと(b)プロセッサ速度の量子アナログは何でしょうか?

答え:

(a) 量子ビット(qubit)— 古典的な対応物(0 または 1 の状態しか取れない)とは異なり、0 と 1 の重ね合わせに同時に存在できる情報の単位です。

(b) CLOPS(Circuit Layer Operations Per Second)— QPU が 1 秒間に実行できる逐次操作の数で、回路からパラメーターをロードするなど、古典コンピューティングリソースとのインターフェースも含まれます。

リソース管理

HPC リソースと量子リソースはどちらも貴重で複雑であるため、慎重に管理する必要があります。このセクションでは、ユーザープログラムのリソース管理方法について説明します。コンピューティングインフラにおけるリソース管理とは、(1)計画、(2)割り当て、(3)管理/制御というプロセスを通じて、CPU、メモリ、ストレージ、ネットワーク帯域幅などのコンピューティングリソースの使用を最適化・効率化する取り組みです。

計画 — リソース見積もり

どんなプログラムもリソースを消費するため、効率的なリソース管理には必要なリソースの見積もりが不可欠です。これには、プログラムを実行するために必要な CPU、メモリ、その他のリソースの量を見積もることが含まれます。量子リソースについても同様です。ただし、量子リソースはまったく異なるスケールで存在します。IBM Quantum® Heron r3 量子プロセッサは 156 量子ビットを持ち、一般的なノートパソコンの何十億もの古典ビットと比較されます。時間とコストも考慮事項です。現在、IBM Quantum はOpen Planという無料プランを提供しており、ユーザーは月に 10 分間の QPU 時間を使って量子コンピューティングを探索できます。一部の研究機関では QPU 時間が非常に多く必要なため、専用の IBM 量子コンピューターをオンプレミスで所有しています。

量子コンピューティング固有のリソース見積もりのステップの一つが回路深さです。前述のように、各量子ゲートおよび操作間の各待機時間にはノイズとエラーの発生確率が伴います。量子回路が深くなるほど、ノイズは大きくなります。これには 2 つの微妙な点があります。2 量子ビットゲートは 1 量子ビットゲートよりもエラー率がはるかに高いため、1 量子ビットの深さはしばしば無視できます。さらに、量子チップ上のすべての量子ビットが直接接続されているわけではありません。必要なエンタングルメントを実行するために、量子ビット間で情報をスワップする必要がある場合があり、このスワッププロセス自体に 2 量子ビットゲートが必要です。そのスワッピングは「トランスパイル」と呼ばれるプロセスで処理されますが、これはより複雑なプロセスであり他の目的も果たします。詳細については次のレッスンで説明します。関連する制限量は、したがって、トランスパイル後の 2 量子ビット深さです。高フィデリティな結果が得られる正確な最大深さは回路によって異なります。しかし、現代のエラー軽減技術を活用することで、80 以上のトランスパイル後 2 量子ビット深さでも高フィデリティな結果を得ることができます。

割り当て — スケジューリング

スケジューリングとは、リソースをプログラムに割り当て、その実行を管理するプロセスです。これには以下が含まれます。

  • ジョブ提出:ユーザーが HPC システムにリクエスト(ジョブ)を送信し、実行に必要な計算作業とリソースを指定するプロセス。
  • リソース割り当て:提出されたジョブの要件に基づいて、利用可能な HPC システムリソース(ノード、CPU、メモリなど)をジョブに割り当てること。
  • ジョブ実行:割り当てられた HPC リソース上でジョブによって定義された計算タスクを実際に実行すること。

量子コンピューターにもこれらのプロセスすべてに対応するものがあります。

  • ジョブは Qiskit Runtime を活用してユーザーが提出し、通常は SamplerEstimator などの Qiskit Runtime プリミティブを使用します。
  • ユーザーはアクセスできるバックエンドのリストから選択します。利用可能なバックエンドの完全なリストは IBM Quantum Platform のコンピューティングリソースページで確認できます。通常は最もビジー度の低い量子コンピューターを使用するのが一般的です。しかし、デバイスレイアウトの考慮事項や過去の計算の再現などの理由から、特定のものを使用することが重要な場合もあります。
  • 量子ジョブの実行は HPC の場合と類似しています。いくつかの違いはすでに説明しましたが、ここで繰り返す価値があるものもあります。QPU は現在一般的に古典コンピューティングリソースと同じノードに配置されておらず、ネットワークを通じて接続されています。これはスケジューリングに影響を与える可能性があります。さらに、量子コンピューターは待機時間が長くなる場合があり、この待機時間は変動するため、タイミングの正確な制御が難しくなります。この状況は専用システムでは異なる場合があり、それは量子コンピューターの内部管理に依存します。

管理/制御 — ワークロード管理

オーケストレーションとも呼ばれるワークロード管理は、複数のプログラムとそのリソース要件を管理するプロセスです。これには以下が含まれます。

  • リソースプロビジョニング:ジョブが使用できるよう HPC リソースを準備・提供するプロセスで、ハードウェアとソフトウェアのセットアップが含まれます。後述するように、QPU は前のセクションの注意事項を踏まえつつ、古典 HPC リソースと同様にプロビジョニングできるコンピューティングリソースです。
  • ジョブスケジューリング:スケジューラーソフトウェアがどのジョブをいつどのリソースで実行するかを決定し、優先度とキューを管理して HPC システムを効率的に活用する活動です。この広義の説明は量子リソースにも当てはまりますが、他のリソースと比べてタイミングの制御が少ない場合があります。

ワークロード(ボックスとして表示)が、一方の軸が時間、もう一方がリソースを表す 2 次元グリッドに最適に配置・整理される様子を示す図。 例:

リソース管理を理解するための文脈として、よく知られたタスクを考えてみましょう。大きな数の素因数を求めるタスクです。さらに、使用するアルゴリズムがすべての潜在的な約数を総当たりで確認するものであると仮定します。これは最も効率的な方法ではないことが多いですが、ワークロードの管理方法を理解しやすい例です。

計画 — リソース見積もり

  • 素因数分解に必要な CPU 時間とメモリの量を見積もります。
  • タスクの並列化を計画します — いくつの CPU/コアを使用しますか?

割り当て — スケジューリング

  • ジョブ提出時に、スケジューラーは素因数分解タスクに CPU コアとメモリを割り当てます。たとえば、末尾が 1、3、7、9 の潜在的な約数をそれぞれ 4 つのコアの 1 つに割り当てるかもしれません。
  • ジョブ実行:素因数分解アルゴリズムが実行され、タスクが完了するまで割り当てられたリソースで割り算やその他の因数分解ステップが実行されます。

管理/制御 — ワークロード管理

  • システムは素因数分解ジョブの順序とタイミングをオーケストレーションしてスループットを最適化します。
  • 最も簡単に想像できるケースは、いずれかのコアがターゲットの素因数を見つけた場合です。この場合、他のコアでの計算を停止し、それらを次のタスクに使用できるようにする必要があります。

ハイパフォーマンスコンピューティング環境では、これらのステップを実行してリソースを管理するための特別なソフトウェアが使用されます。次のセクションでは、広く採用されているリソース管理ソフトウェアシステムである Slurm について学びます。

量子リソースを使った例:

このコースの他のレッスンで取り上げるワークフローの一つが、サンプルベース量子対角化(SQD)を使用した化学基底状態とエネルギーの決定です。これはレッスン 4 でより詳しく説明され、IBM Quantum LearningSQD に関するこのコース と関連手法も参照できます。この議論に必要なのは、ワークフローが以下のステップを含むという点だけです。

  • 量子回路を準備する
  • 量子回路を測定する
  • 測定結果を使って問題を有用なサブ空間に射影する
  • 古典コンピューティングリソースを使って小さく射影された行列を対角化する
  • 繰り返し処理(電荷保存などの考慮による自己無撞着性の確保のため、および変分パラメーターを持つ場合は量子回路の繰り返しも含む)。

計画 — リソース見積もり

  • 電子軌道を量子ビットにマッピングして、必要な量子ビット数を確立します。
  • マッピングされた系のハミルトニアンと(場合によっては変分的な)状態を量子回路に組み合わせ、トランスパイル後の 2 量子ビット深さを確認します。それが妥当であることを確認します。
  • 射影するサブ空間のサイズを見積もります。そこから、対角化に必要な CPU 時間とメモリを見積もります。
  • タスクの並列化を計画します — いくつの CPU/コアを使用しますか?

割り当て — スケジューリング

  • ユーザーが QPU を選択します。トランスパイルのプロセスにより、抽象的な量子回路内の量子ビットが QPU 上の物理的な量子ビットに自動的にマッピングされます。これは抽象的な回路が直接的な接続性を仮定している場合など、チップ上に存在しない接続を要求する場合があるなどの理由から重要です。
  • Qiskit Runtime を通じたジョブ提出後、ジョブは選択した QPU のキューに入ります。ユーザーは待機時間を制御できませんが、専用システムではこれが異なる場合があります。
  • 古典コンピューティングリソースが量子結果を待ちます。
  • 対角化ジョブが HPC リソースに提出されます。ジョブ提出時に、スケジューラーは対角化タスクに CPU コアとメモリを割り当てます。
  • ジョブ実行:対角化アルゴリズムが実行され、タスクが完了するまで小さく射影された行列を対角化します。

管理/制御 — ワークロード管理

  • システムは量子ステップと古典ステップの順序とタイミングを全体にわたってオーケストレーションします。たとえば、射影行列が対角化されて基底状態エネルギーが得られたら、収束基準に応じて、ワークフローが新しい量子回路(新しい変分パラメーターを持つ)に戻ることがあります。
  • 基底状態エネルギーが収束基準を満たしたら、すべてのコアでの計算が停止します。

ハイパフォーマンスコンピューティング環境では、これらのステップを実行してリソースを管理するための特別なソフトウェアが使用されます。次のセクションでは、広く採用されているリソース管理ソフトウェアシステムである Slurm について学びます。Slurm は上記で説明したすべてのステップをサポートしているわけではない点に注意が必要です。Slurm はジョブの計画サポートも、ワークロードコンポーネント間の通信などの詳細なワークロード管理も提供しません。これは、QPU が通常ネットワーク経由でアクセスされる HPC における量子コンピューティングの現状に適しています。

理解度チェック

ソートされていないデータベースを検索して「ターゲット」と呼ぶ要素を見つけようとしているとします。次の各操作について、リソース管理のどの段階に対応するかを答えてください。 (a) データベースのサイズと各要素の確認に必要な時間を見積もること (b) あるGPU でターゲットを見つけた場合、他のGPU での処理を停止して次の問題に解放すること (c) 探索空間を(たとえば 10 個の)GPU ごとに領域に分割すること

答え:

(a) 計画 (b) 管理/制御 (c) 割り当て/スケジューリング

ソフトウェア:Slurm

このセクションでは、この章で学んだ概念を応用して、人気のリソース管理システムである Slurm の使い方を練習します。

Slurm の概要

Slurm は、ハイパフォーマンスコンピューティング環境で広く使用されているオープンソースのリソース管理システムです。リソースの管理、ジョブのスケジューリング、システムパフォーマンスの監視のための包括的なツールセットを提供します。

ここでは Slurm の基本的な使い方を説明します。

  • ジョブ提出
  • リソース割り当て
  • ジョブ監視

このコースの受講生全員に HPC リソースを提供することは実際には難しいため、少しチートをして、実際の HPC クラスターを小規模で模倣した Slurm 付きの Docker イメージを含むリポジトリを用意しました。これにより、安全で再現可能な環境で学んだ概念を練習できます。

現在、すべての量子リソースと古典リソースは実験全体の期間中割り当てられています。現時点では、混合リソースのインターリーブ割り当ては行われていません。最後の注意点として、ジョブが起動した後も、頻繁に HPC を使用するユーザーが期待するような形で量子システムが直接制御されるわけではありません。ジョブは任意の x86 ノード上で起動され、Qiskit Runtime サービスを実行し、そのランタイムサービスがユーザーが直接制御できない別のスケジューラーに接続します。このワークフローと関連する問題は、GPU ノードへの排他アクセスの早期追求(gres の元の使用)で早期に経験を積んだ HPC ユーザーには馴染みがあるかもしれません。

インストール手順とセットアップの概要

量子リソースと HPC リソースの組み合わせを練習するには、実際の HPC 環境にアクセスするか、ローカルマシンで HPC 環境をシミュレートする必要があります。Docker を使ったローカルセットアップのインストールガイドはこのリポジトリにあります。このガイドでは、IBM Cloud® アカウントのセットアップと QRMI の SPANK プラグインのインストールに関するサポートへのリンクが含まれています。また、そのリポジトリには環境をテストするための Python ファイルもいくつか含まれています。

インストールが完了したら、以下のコマンドを使ってターミナルで Slurm のコンピューティングリソースを確認してみましょう。インストールが成功していれば、合計 3 つの仮想ノードを確認できるはずです。

$ sinfo

PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
normal up 5-00:00:00 2 idle c[1-2]
quantum* up infinite 1 idle q1
$ scontrol show node

NodeNAME=q1 Arch=x86_64 CoresPerSocket=1
CPUAlloc=0 CPUTot=1 CPULoad=0.34
AvailableFeatures=(null)
ActiveFeatures=(null)
Gres=qpu:1
NodeAddr=q1 NodeHostName=q1 Version=21.08.6
...

2 つのパーティション(ノードグループ)があります:normal と quantum です。normal パーティションは古典リソースのみにアクセスできるノードで構成されています。quantum パーティションは量子リソースにアクセスできます。scontrol show nodes を実行すると各ノードの詳細を確認できます。

Slurmで簡単なHello Worldの例を実行する

まず、Slurmを使って簡単な古典的な hello world の例を実行してみましょう。ここではPythonを使用します。内容が自明なhello_world.pyを作成しましょう。

$ vim hello_world.py

import time
time.sleep(10)
print("Hello, World!")
~

次に、このプログラムを実行するために必要なリソースをリソースマネージャーに伝える必要があります。Slurmでは、ジョブに関するすべてのメタデータをサブミッションスクリプトで指定できます。これはSlurm固有のアノテーションが付いたシェルスクリプトです。これらのアノテーションを使って、リソース要件やスケジュールパラメータなどを指定できます。そのためのシェルスクリプト hello_world.sh を作成しましょう。

$ vim hello_world.sh

#SBATCH --job-name=hello-world
#SBATCH --output=hello-world.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=normal

srun hello_world.py
~

サブミッションファイルの内容を確認してみましょう。

#SBATCH ディレクティブは、プログラム実行に必要な要件を指定するためのアノテーションです。ノード数、ノードあたりのタスク数、ノードおよびタスクあたりのタスク数とCPU数などのリソース量のほか、出力ファイル名などのオプションを指定できます。利用可能なオプションの全一覧はSlurmのドキュメントを参照してください。

いよいよSlurmジョブを実行します。sbatch はサブミッションファイルを受け取り、ジョブをSlurmの実行キューに登録するコマンドです。

$ sbatch hello_world.sh

Submitted batch job 63

squeue コマンドを使ってプログラムのステータスを確認しましょう。

$ squeue

# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_world root R 0:01 1 c1

ジョブが完了したら、出力ファイルを確認して結果を見ることができます。

$ cat hello_world_logs.txt
Hello, World!

理解度チェック

以下のSlurmシェルスクリプトについて、(a) ジョブ名、(b) Pythonファイル名、(c) 出力ファイル名はそれぞれ何ですか?また、(d) このスクリプトは量子リソースを使用できますか?

vim hello_learner.sh

#SBATCH --job-name=hello-learner
#SBATCH --output=hello-learner.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum

srun hello_learner_qm.py

答え:

(a) hello-learner (b) hello-learner_qm.py (c) hello-learner.out (d) はい、使用できます。quantumパーティションを使用しています。

SlurmでシンプルなQiskitのHello Worldの例を実行する

次に、量子リソースも使用してみましょう。量子リソースを使ったシンプルな「Hello, Qiskit」プログラムを作成して実行してみます。

$ vim hello_qiskit.py

# hello_qiskit.py
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import EstimatorV2 as Estimator

# Create a new circuit with two qubits
qc = QuantumCircuit(2)

# Add a Hadamard gate to qubit 0
qc.h(0)

# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)

observables_labels = ["IZ", "IX", "ZI", "XI", "ZZ", "XX"]
observables = [SparsePauliOp(label) for label in observables_labels]

# switch to QRMI service
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

backend = service.backend("...")

# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)

# Construct the Estimator instance.

estimator = Estimator(mode=backend)
estimator.options.resilience_level = 1
estimator.options.default_shots = 5000

mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]

# One pub, with one circuit to run against five different observables.
job = estimator.run([(isa_circuit, mapped_observables)])

job_result = job.result()

pub_result = job.result()[0]

print("Result", pub_result)

ここでは、量子リソースとジョブのサポートのためのSlurm SPANKプラグインであるQRMI(量子リソース管理インターフェース)を使用します。QRMIはIBM、Pasqal、The Hartree Center、およびRPIが共同で開発しました。ランダムな初期値を持つシンプルなpauli-2-design回路と単純なオブザーバブルを作成し、Estimatorを使って期待値を計算します。実行するには、量子リソースを要件として指定したサブミッションスクリプト hello_qiskit.sh が再び必要になります。

$ vim hello_qiskit.sh

#SBATCH --job-name=hello-qiskit
#SBATCH --output=hello_qiskit.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-nodes=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
#SBATCH --gres=qpu:1

srun python /data/ch2/hello_qiskit/hello_qiskit.py
~

サブミッションファイルを確認して、何が行われているか見てみましょう。新たに追加されたオプションは gres です。gres は追加の計算リソースを定義するためのSlurmオプションです。この場合、新しいリソースは量子リソースになります。リソースと量子リソースが利用可能なクラスターのパーティションを指定することで、Qiskitのプリミティブはこれらに割り当てられたリソースを使用して量子ペイロードを実行します。

いよいよSlurmジョブを実行します。

$ sbatch hello_qiskit.sh

次に、squeue コマンドを使ってプログラムのステータスを確認しましょう。

$ squeue
# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_qiskit root R 0:01 1 q1

ジョブが完了したら、ログと結果を確認できます。

$ cat hello_qiskit.out | grep Exp
Expectation Value: 0.8372900070983516

まとめ

ここまでで、計算リソースとは何か、またそれらを使用して異種環境でプログラムを実行する方法を学びました。さらに、古典リソース向けと量子リソース向けの2種類のシンプルな「Hello World」プログラムを作成・実行し、タスクを送信して結果を確認するためのシェルスクリプトの作成方法も学びました。

次のレッスンでは、このリソース管理の知識を基に、ジョブ実行中に取得したリソースにプログラミングモデルを適用する方法について学びます。

この章で使用したすべてのコードとスクリプトは、GitHubリポジトリからご利用いただけます。