OpenLava のプリエンプション機能:原理、EDA における適用性と設定ガイド

OpenLava のプリエンプション機能の実装方法

OpenLava のプリエンプション機能は、主に キュー間の優先度とプリエンプション関係の設定 に基づいています。この機能は、マスタスケジューラプロセス `mbd` が各スケジューリング周期(`MBD_SLEEP_TIME`)で自動的に計算し、実行します。

1. トリガーの核心的なロジック

  1. トリガー条件:高優先度キュー(プリエンプションキュー)に `PEND` 状態のジョブがあり、クラスター内の空き Slot がない場合。
  2. 対象選択:`mbd` は「プリエンプション可能」とマークされた低優先度キュー内で実行中の(`RUN`)ジョブをスキャンします。
  3. プリエンプションアクション:
    • サスペンドモード(Suspend-based Preemption):スケジューラは低優先度ジョブに対して `SIGTSTP/SIGSTOP` シグナルを送り、その状態を `SSUSP`(システムサスペンド)に変更し、CPU 使用を一時停止します。
    • 終了/再キューイングモード(Kill/Requeue-based Preemption):スケジューラは低優先度ジョブに対して `SIGTERM/SIGKILL` シグナルを送ります。ジョブが `-r`(再キューイング可能)パラメータ付きで提出されている場合、そのジョブは再度 `PEND` キューに戻ります。それ以外の場合、ジョブは `EXIT` 失敗状態になります。
  4. リソースの引き継ぎ:高優先度ジョブが空いた Slot を使用して実行を開始します。
  5. 復旧ロジック(サスペンドモードのみ):高優先度ジョブが終了し、Slot が空いた後、`mbd` は `SIGCONT` シグナルを送って `SSUSP` 状態の低優先度ジョブを再開します。

現在の OpenLava がプリエンプションを有効化しているか確認する方法

コマンドラインツールと設定ファイルを組み合わせて、現在のクラスターのプリエンプション状態を確認できます。

方法 1: キューのプリエンプション属性の確認 (`bqueues -l`)

以下のコマンドを実行して、すべてのキューまたは特定のキューの詳細情報を表示します:

bqueues -l

重要な観察ポイント:

  • `PREEMPTION` フィールドが存在するか確認してください。
  • 出力に `PREEMPTION = PREEMPTIVE`(他のキューをプリエンプションできる)または `PREEMPTION = PREEMPTABLE`(他のキューからプリエンプションされる可能性がある)のような記述があれば、該当のキューはプリエンプション機能が有効です。
  • すべてのキューの `PREEMPTION` が未設定であるか、または `PREEMPTIVE` と `PREEMPTABLE` を同時に持つキューがない場合は、プリエンプション機能は有効になっていません。

方法 2: グローバルプリエンプション動作の確認 (`bparams -l`)

以下のコマンドを実行して、グローバルプリエンプションスイッチを確認します:

bparams -l | grep -i preempt
  • `PREEMPT_SLOT_SUSPEND = yes`:プリエンプション時に低優先度ジョブをサスペンド(プロセス/メモリを保持)します。
  • `PREEMPT_SLOT_SUSPEND = no`:プリエンプション時に低優先度ジョブを終了(プロセス/メモリを解放)します。
  • `MAX_PREEMPT_JOBS = 12`:各スケジューリング周期で最大でプリエンプションできるジョブ数。

方法 3: 実際のテストによる確認(最も直感的)

  1. クラスターの Slot を低優先度キュー(例:`low_q`)のタスクで満たします。
  2. 高優先度キュー(例:`high_q`)にタスクを提出します。
  3. `bjobs` コマンドを実行して観察します:
    • `low_q` のタスクの状態が `RUN` から `SSUSP` または `EXIT` に変わり、`high_q` のタスクがすぐに `RUN` に変わる場合、プリエンプション機能は正常に動作しています。

実際の EDA(電子設計自動化)シーンでのプリエンプション機能の必要性

結論:伝統的な「サスペンド式プリエンプション」は強く推奨されませんが、「終了/再キューイング式プリエンプション」は条件付きで有効にすることが可能です。ただし、厳格なキュー計画が必要です。

EDA シーンでは、プリエンプション機能は両刃の剣であり、その核心的な問題点は **EDA ツールがメモリとライセンスを特殊に占有する特性** にあります。

なぜ EDA シーンでは「サスペンド式プリエンプション」が忌避されるのか?

  1. EDA ライセンスのデッドロックと浪費(致命的な問題):
    • 現象:VCS シミュレーションや Innovus P&R タスクが `SSUSP`(サスペンド)された場合、CPU は解放されますが、FlexNet/FlexLM EDA ライセンスは絶対に解放されません。
    • 結果:低優先度ジョブがライセンスを占有したまま待機し、高優先度ジョブは CPU は確保できてもライセンスが不足して実行できません。これにより、全社の開発業務が中断する可能性があります。
  2. 物理メモリ(RAM)の解放なしによる OOM:
    • 現象:バックエンド Route タスクが 200GB のメモリを使用し、それがサスペンドされた場合、その 200GB のメモリは依然として物理メモリまたは Swap に保存されます。
    • 結果:高優先度ジョブが開始すると、ノードは物理メモリ不足により深刻な Swap または OOM によってダウンする可能性があります。

EDA シーンでプリエンプションが必要な場合

以下の緊急業務シーンでのみ、**Kill/Requeue(終了/再キューイング)** ベースのプリエンプションを有効にすることができます:

  1. Tapeout(流片)スプリント期間:Tapeout キューには絶対的な「優先権」が必要であり、リソースが不足した場合、Regression(回帰テスト)タスクを強制的に終了します。
  2. インタラクティブ Debug キュー vs バッチ処理 Regression キュー:エンジニアが Virtuoso GUI または Verdi で波形を見るために 10 秒以内に結果を得る必要がある場合、夜間のバッチ処理タスクを強制的にプリエンプションします。

EDA クラスターでプリエンプションを適切に設定する方法

OpenLava では、合理的な EDA プリエンプション設定は **「サスペンドせず、終了し、再キューイング」** の原則に従う必要があります。

設定目標アーキテクチャ設計

  • `interactive` キュー(インタラクティブデバッグ):**プリエンプション者 (Preemptive)**
  • `tapeout` キュー(緊急流片キュー):**プリエンプション者 (Preemptive)**
  • `regression` キュー(大量の夜間回帰テスト):**プリエンプション可能 (Preemptable)**、ジョブは再キューイング (`-r`) を必須とする。

具体的な設定手順とファイル修正

ステップ 1: グローバルパラメータファイル `lsb.params` の修正

プリエンプションされたタスクが直接終了し、メモリと EDA ライセンスを解放することを確認します。

  • ファイル位置:`$LSB_CONFDIR//configdir/lsb.params`
# サスペンドプリエンプションを無効化し、プリエンプションされたジョブを終了/再キューイングすることで RAM と EDA ライセンスを完全に解放
PREEMPT_SLOT_SUSPEND = no

# 各スケジューリング周期で最大でプリエンプションできる Slot 数を制限し、クラスターの激しい振動を防ぐ
MAX_PREEMPT_JOBS = 32

ステップ 2: キュー設定ファイル `lsb.queues` の修正

キューの優先度(`PRIORITY`)とプリエンプション関係(`PREEMPTION`)を定義します。

  • ファイル位置:`$LSB_CONFDIR//configdir/lsb.queues`
# ----------------------------------------------------
# 1. 緊急/流片キュー (最高優先度、regression キューをプリエンプション可能)
# ----------------------------------------------------
Begin Queue
NAME          = tapeout
PRIORITY      = 100
PREEMPTION    = PREEMPTIVE[regression]  # regression キューのみをプリエンプション可能に指定
DESCRIPTION   = Tapeout Emergency Queue
End Queue

# ----------------------------------------------------
# 2. インタラクティブ Debug キュー (高優先度、regression キューをプリエンプション可能)
# ----------------------------------------------------
Begin Queue
NAME          = interactive
PRIORITY      = 80
PREEMPTION    = PREEMPTIVE[regression]
RUNLIMIT      = 120    # 最大 2 時間の実行時間を強制制限し、乱用を防ぐ
DESCRIPTION   = Interactive Debug Queue
End Queue

# ----------------------------------------------------
# 3. 通常の開発と合成キュー (中程度の優先度、プリエンプションしない、プリエンプションされない)
# ----------------------------------------------------
Begin Queue
NAME          = normal
PRIORITY      = 50
DESCRIPTION   = Daily Normal Build & Synth
End Queue

# ----------------------------------------------------
# 4. 大量の回帰テストキュー (最低優先度、いつでも「犠牲」される準備ができている)
# ----------------------------------------------------
Begin Queue
NAME          = regression
PRIORITY      = 10
PREEMPTION    = PREEMPTABLE            # プリエンプション可能としてマーク
REQUEUE_EXIT_VALUES = 130 ZOMBIED       # ジョブが kill された場合、自動的に再キューイング (Requeue) する
DESCRIPTION   = Auto Nightly Regression Queue
End Queue

ステップ 3: 設定の再読み込み

badmin reconfig

EDA プリエンプションのベストプラクティスと代替案(運用経験からの提言)

実際の IC デザイン会社の運用では、強制的なプリエンプションは「やむを得ない手段」です。プリエンプションによる EDA ライセンスの浪費とタスクの再実行による計算負荷を避けるため、以下のような代替案を検討することをお勧めします。

メカニズム 実現方法 適用 EDA シーン 推奨度
Fairshare (公平共有) User/Group に基づくクォータ重みの動的割り当て あるエンジニアがクラスターを独占することを防ぎ、全員に基本的な計算力を保証 ⭐⭐⭐⭐⭐ (必須)
Host Reservation (ノード予約) 10% のサーバーを `interactive` キュー専用に割り当てる GUI/Debug タスクの即時起動を保証し、Regression との混在を防ぐ ⭐⭐⭐⭐⭐ (推奨)
Requeue Preemption (終了/再キューイングプリエンプション) `PREEMPT_SLOT_SUSPEND = no` 緊急 Tapeout キューが Regression キューをプリエンプションする場合のみ ⭐⭐⭐ (必要に応じて)
Suspend Preemption (サスペンドプリエンプション) `PREEMPT_SLOT_SUSPEND = yes` 絶対に禁止 (ライセンスのロックとメモリオーバーフローを引き起こす) (禁止)

開発チームへの規範提案のまとめ

  1. Regression スクリプトに `-r` を必須とする:Regression ジョブを提出する際に、スクリプトは `bsub -r -q regression ...` を統一して使用し、クラスターが空いたときに自動的に再実行されるようにします。
  2. プリエンプションキューの範囲を制限する:一般ユーザーが `tapeout` または `interactive` キューに数日間かかる長時間タスクを自由に提出できないように、`RUNLIMIT` パラメータで実行時間を制限します。

タグ: OpenLava EDA Preemption Cluster Management Job Scheduling

10月7日 00:49 投稿