このドキュメントは、BenchKit に新しいベンチマーク実行拠点を追加する手順を拠点管理者向けにまとめたものです。 GitLab Runner と Jacamar-CI をユーザ権限でセットアップし、CI/CD パイプラインからバッチジョブを投入できるようにするまでを説明します。
- 前提条件
- ディレクトリ構成
- GitLab Runner のインストール
- Jacamar-CI のビルド・インストール
- カスタムランナースクリプトの作成
- ランナーの登録
- Jacamar 用ランナーの設定
- config.toml の設定
- BenchKit への拠点登録
- ランナーの常駐化(systemd user mode)
- トラブルシューティング
- 対象システムのログインノードにSSHアクセスできること
- ユーザ権限でソフトウェアをビルド・インストールできること
- GitLab プロジェクトの Runner 登録トークンを取得済みであること
- 以下のツールが利用可能であること:
git,curl,make,gcc/g++- (環境によっては)
gperf,libseccompのビルドが必要
ARM系とx86系で共有ボリュームをマウントしている環境では、アーキテクチャ別にディレクトリを分けます。
# x86系
mkdir -p gitlab-runner_jacamar-ci_amd
# ARM系
mkdir -p gitlab-runner_jacamar-ci_arm以降、作業ディレクトリを $BASE_DIR として説明します:
export BASE_DIR="$PWD/gitlab-runner_jacamar-ci_amd" # x86の場合
# export BASE_DIR="$PWD/gitlab-runner_jacamar-ci_arm" # ARMの場合
cd "$BASE_DIR"最終的なディレクトリ構成:
$BASE_DIR/
├── bin/
│ ├── gitlab-runner # GitLab Runner バイナリ
│ └── jacamar # Jacamar-CI バイナリ
├── builds/ # ビルド作業ディレクトリ
├── cache/ # キャッシュディレクトリ
├── config.toml # Runner 設定ファイル
├── custom-config.toml # Jacamar 設定ファイル
├── config.sh # カスタムランナー: config
├── prepare.sh # カスタムランナー: prepare
├── run.sh # カスタムランナー: run
└── cleanup.sh # カスタムランナー: cleanup
ユーザ権限でバイナリをダウンロードします。
mkdir -p "$BASE_DIR/bin"
curl -L --output "$BASE_DIR/bin/gitlab-runner" \
https://gitlab-runner-downloads.s3.amazonaws.com/v18.5.0/binaries/gitlab-runner-linux-amd64
chmod +x "$BASE_DIR/bin/gitlab-runner"mkdir -p "$BASE_DIR/bin"
curl -L --output "$BASE_DIR/bin/gitlab-runner" \
https://gitlab-runner-downloads.s3.amazonaws.com/v18.5.0/binaries/gitlab-runner-linux-arm64
chmod +x "$BASE_DIR/bin/gitlab-runner"Warning:
latestは使わず、必ずバージョンを固定してください。過去にlatestで取得したバージョンにバグがあり動作しなかったことがあります。動作確認済みのバージョン(例:v18.5.0)を明示的に指定することを強く推奨します。
cd "$BASE_DIR"
# Go のインストール
export GO_PKG=go1.25.0.linux-amd64.tar.gz # ARM: go1.25.0.linux-arm64.tar.gz
curl -OL "https://go.dev/dl/${GO_PKG}"
tar -C "$PWD" -xzf "${GO_PKG}"
rm "${GO_PKG}"
export GOROOT="$PWD/go"
export GOBIN="$GOROOT/bin"
export PATH="$GOBIN:$PATH"
# Jacamar のビルド
git clone https://gitlab.com/ecp-ci/jacamar-ci.git
# サイト固有パッチの適用(必要な場合のみ、後述)
# cp tools.go jacamar-ci/internal/executors/pbs/
cd jacamar-ci
export CC=gcc
export CXX=g++
export CGO_ENABLED=1
make build
make install PREFIX="$BASE_DIR"
# 後片付け
cd "$BASE_DIR"
rm -rf jacamar-ci go一部のジョブスケジューラ環境では、Jacamar のデフォルト実装がそのまま動作しない場合があります。
例えば Miyabi の PBS 環境では、qstat の出力形式やジョブ完了判定のロジックが標準と異なるため、
internal/executors/pbs/tools.go を差し替える必要がありました。
主な変更点(Miyabi PBS の例):
qstatの JSON 出力が使えないため、テキスト形式でパース- ジョブ完了判定:
qstat出力にジョブIDが含まれなくなったら完了と判定 Exit_statusの取得:-H -fオプションで履歴から抽出(テキスト形式)- ジョブが履歴に残らない場合は正常終了と見なす
パッチの適用方法:
git clone https://gitlab.com/ecp-ci/jacamar-ci.git
# パッチファイルを配置してからビルド
cp tools.go jacamar-ci/internal/executors/pbs/
cd jacamar-ci
make build
make install PREFIX="$BASE_DIR"Note: パッチが必要かどうかは、対象システムで
qstat -f -F json <jobid>が正常に動作するかで判断できます。JSON出力がサポートされていない場合はパッチが必要です。
一部の環境では libseccomp が必要です。その場合は gperf → libseccomp → Jacamar の順にビルドします。
cd "$BASE_DIR"
set -euo pipefail
# --- 変数定義 ---
WORKDIR="${PWD}"
GPERF_VER="3.1"
SEC_VER="2.5.5"
GO_PKG="go1.25.0.linux-amd64.tar.gz" # ARM: go1.25.0.linux-arm64.tar.gz
LOCAL_PREFIX="${WORKDIR}/local"
SEC_PREFIX="${LOCAL_PREFIX}/libseccomp"
GPERF_PREFIX="${LOCAL_PREFIX}/gperf"
GOROOT="${WORKDIR}/go"
mkdir -p "${LOCAL_PREFIX}"
# --- 1. Go ---
curl -sSL "https://go.dev/dl/${GO_PKG}" -o "${GO_PKG}"
tar -C "${WORKDIR}" -xzf "${GO_PKG}" && rm -f "${GO_PKG}"
export GOROOT GOBIN="${GOROOT}/bin" PATH="${GOROOT}/bin:${PATH}"
# --- 2. gperf ---
curl -sSL "https://ftp.gnu.org/gnu/gperf/gperf-${GPERF_VER}.tar.gz" -o gperf.tar.gz
tar xf gperf.tar.gz && rm gperf.tar.gz
cd "gperf-${GPERF_VER}"
./configure --prefix="${GPERF_PREFIX}"
make -j$(nproc) && make install
cd "${WORKDIR}"
export PATH="${GPERF_PREFIX}/bin:${PATH}"
# --- 3. libseccomp ---
curl -sSL "https://github.com/seccomp/libseccomp/releases/download/v${SEC_VER}/libseccomp-${SEC_VER}.tar.gz" -o libseccomp.tar.gz
tar xf libseccomp.tar.gz && rm libseccomp.tar.gz
cd "libseccomp-${SEC_VER}"
./configure --prefix="${SEC_PREFIX}" --disable-shared
make -j$(nproc) && make install
cd "${WORKDIR}"
export PKG_CONFIG_PATH="${SEC_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
export LD_LIBRARY_PATH="${SEC_PREFIX}/lib:${LD_LIBRARY_PATH:-}"
export LIBRARY_PATH="${SEC_PREFIX}/lib:${LIBRARY_PATH:-}"
export CPATH="${SEC_PREFIX}/include:${CPATH:-}"
# --- 4. Jacamar ---
git clone https://gitlab.com/ecp-ci/jacamar-ci.git
cd jacamar-ci
export CC=gcc CXX=g++ CGO_ENABLED=1
make build
make install PREFIX="${WORKDIR}"
# --- 5. 後片付け ---
cd "${WORKDIR}"
rm -rf jacamar-ci "gperf-${GPERF_VER}" "libseccomp-${SEC_VER}" goフロントエンド用ランナーには4つのスクリプトが必要です。以下を $BASE_DIR に作成してください。
#!/usr/bin/env bash
set -e
BASE_DIR="/path/to/gitlab-runner_jacamar-ci_amd" # ← 実際のパスに変更
BASE_BUILD_DIR="${BASE_DIR}/builds"
BASE_CACHE_DIR="${BASE_DIR}/cache"
SLUG="${CUSTOM_ENV_CI_PROJECT_PATH_SLUG:-unknown}"
JOB_ID="${CUSTOM_ENV_CI_JOB_ID:-$$}"
UNIQUE_BUILD_DIR="${BASE_BUILD_DIR}/${SLUG}/job_${JOB_ID}"
UNIQUE_CACHE_DIR="${BASE_CACHE_DIR}/${SLUG}/job_${JOB_ID}"
cat <<EOS
{
"builds_dir": "${UNIQUE_BUILD_DIR}",
"cache_dir": "${UNIQUE_CACHE_DIR}",
"builds_dir_is_shared": false,
"hostname": "runner-${JOB_ID}",
"driver": {
"name": "custom-runner",
"version": "v1.0"
},
"job_env": {
"CUSTOM_RUNNER_JOB_ID": "${JOB_ID}",
"CUSTOM_RUNNER_PROJECT_SLUG": "${SLUG}",
"CUSTOM_UNIQUE_BUILD_DIR": "${UNIQUE_BUILD_DIR}",
"CUSTOM_UNIQUE_CACHE_DIR": "${UNIQUE_CACHE_DIR}",
"CUSTOM_DIR": "${BASE_DIR}"
}
}
EOS#!/usr/bin/env bash
set -euo pipefail
exit 0#!/usr/bin/bash
source ~/.bashrc
set -eo pipefail
exec "$@"#!/bin/bash
set -e
LOGFILE="${CUSTOM_DIR}/custom_cleanup.log"
echo "CLEANUP STARTED at $(date)" >> "$LOGFILE"
echo "CUSTOM_ENV_CI_JOB_ID=$CUSTOM_ENV_CI_JOB_ID" >> "$LOGFILE"
BUILD_DIR="${CUSTOM_UNIQUE_BUILD_DIR}"
CACHE_DIR="${CUSTOM_UNIQUE_CACHE_DIR}"
[ -n "$BUILD_DIR" ] && [ -d "$BUILD_DIR" ] && rm -rf "$BUILD_DIR"
[ -n "$CACHE_DIR" ] && [ -d "$CACHE_DIR" ] && rm -rf "$CACHE_DIR"
echo "CLEANUP DONE at $(date)" >> "$LOGFILE"すべてのスクリプトに実行権限を付与:
chmod +x "$BASE_DIR"/{config,prepare,run,cleanup}.sh各拠点には2種類のランナーを登録します:
| ランナー | 用途 | executor |
|---|---|---|
| フロントエンド用 | ビルド・軽量処理 | custom(上記スクリプト) |
| Jacamar用 | バッチジョブ投入 | custom(Jacamar経由) |
"$BASE_DIR/bin/gitlab-runner" register \
--non-interactive \
--url "https://YOUR_GITLAB_SERVER" \
--registration-token "YOUR_TOKEN" \
--executor "custom" \
--description "site-login" \
--tag-list "your_site_login" \
--run-untagged="false" \
--locked="false" \
--builds-dir "$BASE_DIR/builds" \
--cache-dir "$BASE_DIR/cache" \
--config "$BASE_DIR/config.toml" \
--custom-config-exec="$BASE_DIR/config.sh" \
--custom-prepare-exec="$BASE_DIR/prepare.sh" \
--custom-run-exec="$BASE_DIR/run.sh" \
--custom-cleanup-exec="$BASE_DIR/cleanup.sh""$BASE_DIR/bin/gitlab-runner" register \
--non-interactive \
--url "https://YOUR_GITLAB_SERVER" \
--registration-token "YOUR_TOKEN" \
--executor "custom" \
--description "site-jacamar" \
--tag-list "your_site_jacamar" \
--run-untagged="false" \
--locked="false" \
--builds-dir "$BASE_DIR/builds" \
--cache-dir "$BASE_DIR/cache" \
--config "$BASE_DIR/config.toml" \
--custom-config-exec="$BASE_DIR/bin/jacamar" \
--custom-prepare-exec="$BASE_DIR/bin/jacamar" \
--custom-run-exec="$BASE_DIR/bin/jacamar" \
--custom-cleanup-exec="$BASE_DIR/bin/jacamar"Note: Jacamar 用ランナーの
--custom-*-execは登録時のプレースホルダです。実際の引数はconfig.tomlで設定します(次セクション参照)。
[general]
executor = "slurm" # or "pbs", "pjm" etc.
data_dir = "/path/to/gitlab-runner_jacamar-ci_amd"
retain_logs = true
[auth]
downscope = "setuid"
user_allowlist = ["your_username"] # ← ランナーを動かすユーザ名
[batch]
command_delay = "30s"executor: 拠点のジョブスケジューラに合わせて設定(slurm,pbs,pjm等)user_allowlist: ユーザモードで動かすため、自分のアカウント名を記載
ランナー登録後に生成される config.toml を編集します。
gitlab-runner をユーザ権限でインストールした場合、config.toml の [[runners]] セクションに environment で PATH を通す必要があります。これがないとアーティファクト保存時にエラーになります。
[[runners]]
environment = [
"PATH=/path/to/gitlab-runner_jacamar-ci_amd/bin:/usr/local/bin:/usr/bin:/bin"
][runners.custom]
config_exec = "/path/to/gitlab-runner_jacamar-ci_amd/bin/jacamar"
config_args = [
"--no-auth", "config",
"--configuration", "/path/to/gitlab-runner_jacamar-ci_amd/custom-config.toml"
]
prepare_exec = "/path/to/gitlab-runner_jacamar-ci_amd/bin/jacamar"
prepare_args = ["--no-auth", "prepare"]
run_exec = "/path/to/gitlab-runner_jacamar-ci_amd/bin/jacamar"
run_args = ["--no-auth", "run"]
cleanup_exec = "/path/to/gitlab-runner_jacamar-ci_amd/bin/jacamar"
cleanup_args = [
"--no-auth", "cleanup",
"--configuration", "/path/to/gitlab-runner_jacamar-ci_amd/custom-config.toml"
]ランナーが動作したら、BenchKit リポジトリに拠点情報を追加します。
system,mode,tag_build,tag_run,queue,queue_group
# 既存エントリ...
# cross モード(ビルドと実行が別ノード)
NewSystem,cross,newsystem_login,newsystem_jacamar,PBS_NewSystem,default
# native モード(同一ノードでビルドと実行)
NewSystemLN,native,,newsystem_login,none,defaultsystem: システム名(アプリのlist.csvから参照される)mode:cross(ビルドと実行が別ノード)またはnative(同一ノードで実行)tag_build: ビルド用GitLab Runnerタグ(nativeの場合は空)tag_run: 実行用GitLab Runnerタグ(nativeの場合はbuild_runジョブ用)queue:config/queue.csvのキュー名(ログインノードはnone)queue_group: キューグループ名
既存のキューシステム(FJ, PBS_Miyabi, SLURM_RC)に該当しない場合は追加:
queue,submit_cmd,template
PBS_NewSystem,qsub,"-q ${queue_group} -l select=${nodes} -l walltime=${elapse} -W group_list=your_group"テンプレート内で使える変数:${queue_group}, ${nodes}, ${numproc_node}, ${nthreads}, ${elapse}
Result Server や比較画面でシステム情報を見せるために、system_info.csv にも同じ system を追加します。
system,name,cpu_name,cpu_per_node,cpu_cores,gpu_name,gpu_per_node,memory,display_order
NewSystem,NewSystem,Example CPU,2,64,Example GPU,4,512GB,10systemconfig/system.csvやlist.csvと同じ system 名を使います
name- 画面表示に使う名前です
cpu_name,cpu_per_node,cpu_cores- CPU 構成です
gpu_name,gpu_per_node- GPU がある場合に設定します。GPU がない場合は
-を使います
- GPU がある場合に設定します。GPU がない場合は
memory- ノードあたりメモリ容量です
display_order- 一覧や比較画面での表示順です
system.csv に追加したのに system_info.csv を追加しないと、実行自体は通っても UI 側で説明情報が欠けることがあります。
拠点追加時に迷いやすい点ですが、BenchKit では設定の置き場所を次のように分けます。
config/system.csv- システム固有の実行モード、Runner タグ、キュー種別、キューグループを持つ
config/queue.csv- スケジューラ投入コマンドのテンプレートを持つ
config/system_info.csv- Result Server や比較画面に出すシステム表示情報を持つ
programs/<code>/list.csv- アプリごとのノード数、プロセス数、スレッド数、制限時間だけを持つ
programs/<code>/build.sh/run.shmodule load、コンパイラ、mpirun/srun/pjsubの使い方、affinity など、実行そのものの差異を持つ
言い換えると、system.csv と queue.csv は「どこでどう投入するか」、system_info.csv は「そのシステムをどう見せるか」、list.csv は「何条件で回すか」、build.sh / run.sh は「そのシステムでどう実行するか」の責務です。
新しい拠点を追加したら、最初の確認は次の順番で行うと切り分けが楽です。
get_sourcesまで到達すること- GitLab Runner がオンラインで、GitLab からソース取得できることを確認します。
- scheduler に投入できること
system.csvのqueueとqueue_group、queue.csvのテンプレートが正しいことを確認します。
module loadと build が通ることbuild.shのモジュール名、コンパイラ、依存ライブラリを確認します。
- run が
results/resultを生成することrun.shの launcher、affinity、引数の渡し方を確認します。
result0.jsonが作られることscripts/result.shが Result JSON を組み立てられることを確認します。
send_resultsまで通ること- API key、Result Server 接続、
results/result*.jsonの配置を確認します。
- API key、Result Server 接続、
最初の動作確認では、既存アプリで最小の 1 条件だけ list.csv に足して scripts/test_submit.sh で試すのが安全です。
拠点追加直後に起きやすい失敗は、だいたい次の層に分けられます。
| 失敗箇所 | よくある原因 | まず見る場所 |
|---|---|---|
get_sources |
Runner の Git 認証、GitLab 到達性、proxy 設定 | Runner ログ、config.toml の environment |
| scheduler submit | queue / queue_group の不一致、submit template の typo |
config/system.csv, config/queue.csv |
| build | module load の typo、コンパイラ不一致、依存ライブラリ不足 |
programs/<code>/build.sh |
| run | mpirun / srun の引数、affinity、ノード側環境差異 |
programs/<code>/run.sh, scheduler log |
| result 生成 | results/result がない、FOM 出力形式が違う、bk_emit_* 未使用 |
scripts/result.sh, scripts/bk_functions.sh |
| send_results | API key、Result Server 接続、JSON 不足 | scripts/result_server/send_results.sh, Result Server log |
CI ログでは、まず「どの stage まで進んだか」を見ると切り分けが早くなります。get_sources 前、build 前、run 前、send_results 前で原因の層がかなり絞れます。
- GitLab Runner または Jacamar-CI が対象ログインノードで常駐している
- GitLab の Runner 一覧で
onlineになっている -
config/system.csvに system が追加されている - 必要なら
config/queue.csvに queue template が追加されている -
config/system_info.csvに表示用メタデータが追加されている - 対象アプリの
build.sh/run.shに system 分岐が追加されている - 対象アプリの
list.csvに最小 1 条件が追加されている - build が通る
- run が通り、
results/resultが生成される -
result0.jsonが生成される - Result Server への送信まで通る
アーキテクチャごとに systemctl --user でサービスとして常駐させます。
mkdir -p ~/.config/systemd/user[Unit]
Description=GitLab Runner service (user mode, amd64)
After=network.target
ConditionHost=your-login-node # ← 実際のホスト名に変更
[Service]
ExecStart=%h/gitlab-runner_jacamar-ci_amd/bin/gitlab-runner run --config %h/gitlab-runner_jacamar-ci_amd/config.toml --working-directory %h
Restart=always
RestartSec=10
StandardOutput=append:%h/gitlab-runner_jacamar-ci_amd/gitlab-runner.log
StandardError=append:%h/gitlab-runner_jacamar-ci_amd/gitlab-runner.err
[Install]
WantedBy=default.target[Unit]
Description=GitLab Runner service (user mode, arm64)
After=network.target
ConditionHost=your-arm-login-node # ← 実際のホスト名に変更
[Service]
ExecStart=%h/gitlab-runner_jacamar-ci_arm/bin/gitlab-runner run --config %h/gitlab-runner_jacamar-ci_arm/config.toml --working-directory %h
Restart=always
RestartSec=10
StandardOutput=append:%h/gitlab-runner_jacamar-ci_arm/gitlab-runner.log
StandardError=append:%h/gitlab-runner_jacamar-ci_arm/gitlab-runner.err
[Install]
WantedBy=default.targetConditionHost= を設定することで、同じホームディレクトリを複数ノードで共有していても、指定したホストでのみサービスが起動します。
# systemd にファイルを認識させる
systemctl --user daemon-reload
# 自動起動を有効化
systemctl --user enable gitlab-runner-amd.service
# 起動
systemctl --user start gitlab-runner-amd.service
# 状態確認
systemctl --user status gitlab-runner-amd.service
# ログアウト後もサービスを維持(重要)
loginctl enable-linger $LOGNAMENote:
loginctl enable-lingerを実行しないと、ログアウト時にサービスが停止します。
GitLab の Settings → CI/CD → Runners で、登録したランナーが「online」になっていることを確認。
既存のアプリで新拠点のテストを行う場合:
# list.csv に新拠点の設定を追加してテスト
bash scripts/test_submit.sh qws 1config.toml の [[runners]] セクションに environment で PATH が通っているか確認:
environment = ["PATH=/path/to/gitlab-runner_jacamar-ci_amd/bin:..."]custom-config.toml の executor が正しいか確認。対応スケジューラ:
slurm- SLURMpbs- PBS/Torquepjm- PJM(富岳)
- ログインノードから GitLab サーバへの HTTPS 通信が可能か確認
- プロキシ設定が必要な場合は
config.tomlのenvironmentにhttps_proxyを追加
同じ共有ボリュームを異なるアーキテクチャのマシンがマウントしている場合、必ずアーキテクチャ別のディレクトリ(_amd / _arm)を使い分けてください。バイナリの混在はランタイムエラーの原因になります。
症状:
- ベンチマークジョブが実行されない
- GitLab CIログで「NFS同期問題」として現れる
wait_for_nfs.shがタイムアウトresultsディレクトリやJSONファイルが作成されない
根本原因: Jacamar-CI のPBSジョブ状態監視ロジックが、カスタムPBS環境に対応していない場合があります。 ジョブがQUEUED状態でも「completed」と誤判定され、実際にはジョブが実行されずに次のステップに進んでしまいます。
Note: 当初「NFS同期遅延」と思われていた問題が、実際にはJacamar-CIのバグだったという事例があります(Miyabi環境)。NFS待機時間を延長しても解決しない場合は、Jacamar-CIのジョブ監視を疑ってください。
診断方法:
# qstat の JSON 出力が使えるか確認
qstat -F json <job_id>
# 通常形式の出力確認
qstat -f <job_id>
# ジョブ履歴の確認
qstat -H -f <job_id>解決方法:
JSON形式の qstat がサポートされていない場合は、セクション4「サイト固有パッチについて」に記載の tools.go パッチを適用してください。
症状:
- 計算ノードで作成された
results/*.jsonがログインノードから見えない - アーティファクト収集で「No files to upload」エラー
対策:
custom-config.tomlのnfs_timeoutを調整:
[batch]
command_delay = "30s"
nfs_timeout = "2m" # 必要に応じて 5m, 10m に延長- ただし、NFS遅延が疑われる場合でも、まずJacamar-CIのジョブ監視が正常か確認すること(上記参照)
- PBSのバージョンとカスタマイズ内容を確認
-
qstatコマンドの出力形式を確認(JSON対応の有無) - ジョブIDの形式を確認(ホスト名付きかどうか)
- Jacamar-CI でテストジョブを実行して動作確認
-
config.tomlのenvironmentで PATH が通っているか確認 -
loginctl enable-lingerが設定されているか確認