このガイドは、BenchKit の既存アプリに性能推定を追加する開発者向けの実務メモです。
最初に押さえるべき点は次の 2 つです。
- app 側でまず決めるのは、FOM と section / overlap の名前、および各 section / overlap に使う
estimation_package - 採取手順、保存形式、再推定時の復元方法は、共通化できるものから BenchKit 側へ寄せる
- 最初に決めること
- 最小構成:
weakscalingを追加する - 詳細推定に入る
estimate.shに書くことrun.shで書くことestimate.shを入口として使う- 採取と保存の扱い
- 確認ポイント
- 今後の改善
アプリに性能推定を入れる前に、まず次を決めます。
- FOM を何にするか
- どの section / overlap を result に出すか
- 各 section / overlap にどの
estimation_packageを割り当てるか
最初の一歩としては、weakscaling から入るのが一番簡単です。
最小構成では、次の 2 つで十分です。
run.shで FOM を出すestimate.shでweakscalingを選ぶ
この段階では section や artifact は不要です。
#!/bin/bash
set -euo pipefail
source scripts/estimation/common.sh
myapp_declare_estimation_layout() {
bk_clear_estimation_defaults
bk_clear_estimation_declarations
bk_define_current_estimation_package weakscaling
bk_define_future_estimation_package weakscaling
bk_define_baseline_system Fugaku
bk_define_baseline_exp CASE0
bk_define_future_system FutureSystemA
bk_define_current_target_nodes 1024
bk_define_future_target_nodes 1024
}
myapp_declare_estimation_layout
bk_estimation_apply_declared_defaults
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
return 0 2>/dev/null || exit 0
fi
bk_estimation_run_declared_future_package "$1"
bk_estimation_run_recorded_current_with_weakscaling \
"${BK_ESTIMATION_BASELINE_SYSTEM}" \
"${BK_ESTIMATION_BASELINE_EXP}" \
"${BK_ESTIMATION_CURRENT_TARGET_NODES}" \
"${BK_ESTIMATION_CURRENT_PACKAGE}"
bk_estimation_write_output "results/estimate_${est_code}_0.json"この最小形で app 側が主に決めるのは、次の宣言です。
- current 側と future 側でどの top-level package を使うか
- baseline system / exp
- current / future の target nodes
逆に、model 名、model type、measurement、confidence、notes、assumptions の既定値は、原則として package metadata 側が持つ前提で考えると整理しやすいです。
詳細推定に入るときは、次の順で進めます。
run.shで section を出す- 必要なら overlap を出す
- section / overlap ごとに
estimation_packageを付ける estimate.shで上位 package を詳細側に切り替える
このとき app 側で最初に決めるべきなのは、どの section / overlap にどの推定 package を使うかです。
詳細推定では、app ごとの推定宣言を estimate.sh にまとめると整理しやすくなります。estimate.sh 自身は CI や再推定の入口になり、run.sh 側も必要に応じてこれを読み込む形にできます。
weakscaling を使う場合は、特に次の分担を前提にすると分かりやすいです。
- app 側
- section / overlap の時間を通常実行で出す
- 各 item に
identityまたはlogpを割り当てる
- package 側
identityは補正なしlogpは node 数比較にもとづく補正
- BenchKit 側
- section package の呼び分け
- current / future の合成
- top-level applicability の整理
ここでまず宣言したいのは次です。
- section 名
- overlap 名
- 各 section / overlap に割り当てる
estimation_package - target system や target nodes の app 既定値
イメージとしては次のようになります。
myapp_declare_estimation_layout() {
bk_clear_estimation_defaults
bk_clear_estimation_declarations
bk_define_current_estimation_package weakscaling
bk_define_future_estimation_package instrumented_app_sections_dummy
bk_define_baseline_system Fugaku
bk_define_baseline_exp CASE0
bk_define_future_system FutureSystemA
bk_define_current_target_nodes 1024
bk_define_future_target_nodes 256
bk_declare_section --side future prepare_rhs half
bk_declare_section --side future compute_solver half
bk_declare_section --side future allreduce logp
bk_declare_overlap --side future compute_hopping,halo_exchange half
}今の実装では、estimate.sh は「app 側の宣言」を置く場所として使い、package の model 定義や defaults まで持たせすぎない方が自然です。
特に次は package 側へ寄せてよい前提です。
- top-level / side-specific model 名
- model type と compatibility rule
- measurement の既定値
- confidence の既定値
- notes summary
- assumptions の package 固有部分
この宣言は estimate.sh にまとめ、run.sh 側では package 名を重ねて書かない形が望ましいです。app 側は「どの item にどの package を使うか」を先に決め、実行時には得られた値だけを出す形に寄せます。
この宣言は、実行後に section 値を代入するためのものではなく、「何を推定したいか」を実行前に示すためのものです。
最小構成で必要なのは FOM の出力です。
source "${PWD}/scripts/bk_functions.sh"
mkdir -p results && > results/result
bk_emit_result \
--fom "$FOM" \
--fom-version "$FOM_VERSION" \
--exp "$EXP" \
--nodes "$nodes" \
--numproc-node "$numproc_node" \
--nthreads "$nthreads" >> results/result詳細推定では、少なくとも次を result に載せます。
- 区間名
- 区間時間
- その区間に使いたい推定 package 名
bk_emit_declared_section \
--side future \
prepare_rhs 0.42 \
>> results/result
bk_emit_declared_section \
--side future \
compute_solver 1.03 \
results/estimation_inputs/compute_solver_papi.tgz \
>> results/result
bk_emit_declared_overlap \
--side future \
compute_hopping,halo_exchange 0.23 \
results/estimation_inputs/compute_halo_overlap.json \
>> results/resultさらに整理を進めるなら、section 時間の配分やダミー artifact 作成のような推定専用処理も estimate.sh 側の関数へ寄せ、run.sh ではその関数を 1 回呼ぶだけにしてよいです。
ここで app 側の主責務は、section 名と estimation_package の割当てを明示することです。
通常実行のあとに、必要であれば追加採取用の共通入口を呼ぶ形が自然です。
. ./estimate.sh
mpiexec ./a.out "$@"
bk_run_estimation_data_collection mpiexec ./a.out "$@"bk_run_estimation_data_collection は BenchKit の共通入口です。内部では割り当てられた package や site 側の wrapper に応じて必要な採取を分岐します。PAPI や GPU profiler のように追加実行が必要なものは、ここでまとめて扱う方が app 側が軽くなります。
estimate.sh は薄く保つ方がよいです。参照実装では、共通層に処理を寄せたうえで package 選択と最小限の app 固有設定だけを書く形を目指します。
#!/bin/bash
set -euo pipefail
source scripts/estimation/common.sh
myapp_declare_estimation_layout() {
bk_clear_estimation_defaults
bk_clear_estimation_declarations
bk_define_current_estimation_package weakscaling
bk_define_future_estimation_package instrumented_app_sections_dummy
bk_define_baseline_system Fugaku
bk_define_baseline_exp CASE0
bk_define_future_system FugakuNEXT
bk_define_current_target_nodes 1024
bk_define_future_target_nodes 256
bk_declare_section --side future prepare_rhs half
bk_declare_section --side future compute_hopping quarter
bk_declare_section --side future compute_solver half
bk_declare_section --side future halo_exchange quarter
bk_declare_section --side future allreduce logp
bk_declare_section --side future write_result half
bk_declare_overlap --side future compute_hopping,halo_exchange half
}
myapp_declare_estimation_layout
bk_estimation_apply_declared_defaults
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
return 0 2>/dev/null || exit 0
fi
bk_estimation_run_declared_future_package "$1"
bk_estimation_run_recorded_current_with_weakscaling \
"${BK_ESTIMATION_BASELINE_SYSTEM}" \
"${BK_ESTIMATION_BASELINE_EXP}" \
"${BK_ESTIMATION_CURRENT_TARGET_NODES}" \
"${BK_ESTIMATION_CURRENT_PACKAGE}"
bk_estimation_write_output "results/estimate_${est_code}_0.json"この形で app 側が最後まで責務として持つのは、
- どの section / overlap を result に出すか
- どの section / overlap にどの
estimation_packageを割り当てるか - current / future でどの top-level package を選ぶか
くらいにとどめるのが軽く保ちやすいです。
詳細推定では、区間パッケージが papi や trace のような採取種別を要求することがあります。
ただし weakscaling の場合は、追加採取を前提にしません。app 側が通常実行の中で section / overlap 時間を書き、identity と logp だけで推定する前提です。
app 側では、まず section 名と estimation_package を決めることを優先してください。採取手順、複数回実行の要否、保存先、再推定時の復元方法は、共通化できるものから BenchKit 側へ寄せるのがよいです。
特に PAPI のように複数回実行が必要になる採取は、app 側に細かく書かせすぎると重くなります。package 側は「papi が必要」と定義し、BenchKit 側が採取や保存の共通処理を引き受ける形が自然です。
現状の参照実装では results/estimation_inputs/ を使う例がありますが、これは将来も app 側が細かく書き続けるべきという意味ではありません。
bk_emit_section や bk_emit_overlap は残してよく、estimate.sh 内の宣言と共存できます。宣言は package 割当てを先に示し、bk_emit_* は実際に得られた値を Result JSON に流し込む手段として使います。
estimate*.jsonが出るestimate_metadata.estimation_packageが期待どおりperformance_ratioが出る
fom_breakdown.sectionsが出る- section ごとの
estimation_packageが残る - 必要なら
requested_estimation_packageと実適用 package が分かれる - 必要なら
estimate_metadata.current_packageとestimate_metadata.future_packageで両側の package を分けて持てる current_system側とfuture_system側で section / overlap の名前や粒度が一致しなくてもよい
- 一部区間だけ代替したとき
applicability.status = partially_applicable - 代替した区間に
requested_estimation_packageとfallback_usedが残る
- 不成立の区間は
time: null - top-level
fomとperformance_ratioはnull applicability.status = not_applicable
すでに進んでいること:
weakscalingを 1 本追加することestimate.shを薄く保つこと- requested / applied package の区別
- UUID / timestamp の保存
今後の改善:
- app 側に書く採取手順をさらに減らすこと
- 詳細推定の採取・保存・復元を BenchKit 側へより集約すること
- 複数アプリへの横展開を進めること