From cd558efe464d783f27ba79d1ce1013ace24502b4 Mon Sep 17 00:00:00 2001 From: Yoshifumi Nakamura Date: Mon, 6 Jul 2026 14:48:24 +0900 Subject: [PATCH 1/2] Add SALMON benchmark program Signed-off-by: Yoshifumi Nakamura --- programs/salmon/build.sh | 127 ++++++++++++++++++++++++ programs/salmon/list.csv | 6 ++ programs/salmon/run.sh | 208 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 341 insertions(+) create mode 100644 programs/salmon/build.sh create mode 100644 programs/salmon/list.csv create mode 100644 programs/salmon/run.sh diff --git a/programs/salmon/build.sh b/programs/salmon/build.sh new file mode 100644 index 0000000..ded1232 --- /dev/null +++ b/programs/salmon/build.sh @@ -0,0 +1,127 @@ +#!/bin/bash +set -euo pipefail + +system="$1" + +REPO_URL="https://github.com/SALMON-TDDFT/SALMON2" +REPO_DIR="SALMON2" +VERSION_TAG="v.2.2.2" +BUILD_DIR="build-benchkit" +ARTIFACT_DIR="${PWD}/artifacts" + +source scripts/bk_functions.sh + +mkdir -p "${ARTIFACT_DIR}" +bk_fetch_source "${REPO_URL}" "${REPO_DIR}" "${VERSION_TAG}" + +cd "${REPO_DIR}" +rm -rf "${BUILD_DIR}" +mkdir -p "${BUILD_DIR}" + +common_cmake_args=( + -DUSE_MPI=ON + -DUSE_SCALAPACK=OFF + -DUSE_EIGENEXA=OFF + -DUSE_LIBXC=OFF + -DCMAKE_BUILD_TYPE=None + -DCMAKE_VERBOSE_MAKEFILE=ON +) + +case "${system}" in + Fugaku) + cmake_args=( + "${common_cmake_args[@]}" + -DCMAKE_Fortran_COMPILER=mpifrtpx + -DCMAKE_C_COMPILER=mpifccpx + -DCMAKE_Fortran_FLAGS="-Kfast -Kocl -Nlst=t -Koptmsg=2 -Ncheck_std=03s" + -DCMAKE_C_FLAGS="-Kfast -Kocl -Nlst=t -Koptmsg=2 -Xg -std=gnu99" + -DCMAKE_C_STANDARD_COMPUTED_DEFAULT=Fujitsu + "-DCMAKE_Fortran_MODDIR_FLAG=-M " + -DOPENMP_FLAGS="-Kopenmp -Nfjomplib" + -DLAPACK_VENDOR_FLAGS=-SSL2BLAMP + -DFortran_PP_FLAGS=-Cpp + ) + ;; + RC_GH200) + module purge + module load system/qc-gh200 nvhpc-hpcx-cuda12/25.7 + cmake_args=( + "${common_cmake_args[@]}" + -DCMAKE_Fortran_COMPILER=mpif90 + -DCMAKE_C_COMPILER=mpicc + -DOPENMP_FLAGS=-Mnoopenmp + -DUSE_OPENACC=ON + -DUSE_CUDA=ON + -DUSE_MPI_DEFAULT=ON + -DCMAKE_SYSTEM_PROCESSOR=openacc + -DCMAKE_Fortran_FLAGS="-O3 -Wall -fstrict-aliasing -acc=strict -gpu=cc90,managed,ptxinfo -cudalib=cublas -cuda -Minfo=accel -DUSE_OPENACC -DUSE_CUDA" + -DCMAKE_C_FLAGS="-O3 -Wall -alias=ansi -acc=strict -gpu=cc90,managed,ptxinfo -cudalib=cublas -cuda -Minfo=accel -DUSE_OPENACC -DUSE_CUDA" + -DCMAKE_CUDA_ARCHITECTURES=90 + -DCMAKE_CUDA_FLAGS=-arch=sm_90 + ) + ;; + RC_DGXSP) + source /etc/profile.d/modules.sh + module purge + module load system/ng-dgx nvhpc-hpcx-cuda13/26.3 + cmake_args=( + "${common_cmake_args[@]}" + -DCMAKE_Fortran_COMPILER=mpif90 + -DCMAKE_C_COMPILER=mpicc + -DOPENMP_FLAGS=-Mnoopenmp + -DUSE_OPENACC=ON + -DUSE_CUDA=ON + -DUSE_MPI_DEFAULT=ON + -DCMAKE_SYSTEM_PROCESSOR=openacc + -DCMAKE_Fortran_FLAGS="-O3 -Wall -fstrict-aliasing -acc=strict -gpu=cc90,cc100,cc120,managed,ptxinfo -cudalib=cublas -cuda -Minfo=accel -DUSE_OPENACC -DUSE_CUDA" + -DCMAKE_C_FLAGS="-O3 -Wall -alias=ansi -acc=strict -gpu=cc90,cc100,cc120,managed,ptxinfo -cudalib=cublas -cuda -Minfo=accel -DUSE_OPENACC -DUSE_CUDA" + -DCMAKE_CUDA_ARCHITECTURES="90;100;120" + -DCMAKE_CUDA_FLAGS= + ) + ;; + RC_GENOA) + module purge + module load system/genoa mpi/mpich-x86_64 + cmake_args=( + "${common_cmake_args[@]}" + -DCMAKE_Fortran_COMPILER=mpif90 + -DCMAKE_C_COMPILER=mpicc + -DCMAKE_Fortran_FLAGS="-O3 -ffree-line-length-none -fallow-argument-mismatch" + -DCMAKE_C_FLAGS=-O3 + ) + ;; + RC_FX700) + module purge + module load system/fx700 FJSVstclanga + cmake_args=( + "${common_cmake_args[@]}" + -DCMAKE_Fortran_COMPILER=mpifrt + -DCMAKE_C_COMPILER=mpifcc + -DCMAKE_Fortran_FLAGS="-Kfast -Kocl -Nlst=t -Koptmsg=2 -Ncheck_std=03s" + -DCMAKE_C_FLAGS="-Kfast -Kocl -Nlst=t -Koptmsg=2 -Xg -std=gnu99" + -DCMAKE_C_STANDARD_COMPUTED_DEFAULT=Fujitsu + "-DCMAKE_Fortran_MODDIR_FLAG=-M " + -DOPENMP_FLAGS="-Kopenmp -Nfjomplib" + -DLAPACK_VENDOR_FLAGS=-SSL2BLAMP + -DFortran_PP_FLAGS=-Cpp + ) + ;; + *) + echo "Unknown system: ${system}" >&2 + exit 1 + ;; +esac + +cmake -S . -B "${BUILD_DIR}" "${cmake_args[@]}" +cmake --build "${BUILD_DIR}" --target salmon --parallel 8 + +salmon_bin=$(find "${BUILD_DIR}" -type f -name salmon -perm -u+x | head -n 1) +if [[ -z "${salmon_bin}" ]]; then + salmon_bin=$(find "${BUILD_DIR}" -type f -name salmon | head -n 1) +fi +if [[ -z "${salmon_bin}" || ! -f "${salmon_bin}" ]]; then + echo "SALMON executable not found under ${BUILD_DIR}" >&2 + exit 1 +fi + +cp "${salmon_bin}" "${ARTIFACT_DIR}/salmon" diff --git a/programs/salmon/list.csv b/programs/salmon/list.csv new file mode 100644 index 0000000..fa1c447 --- /dev/null +++ b/programs/salmon/list.csv @@ -0,0 +1,6 @@ +system,enable,nodes,numproc_node,nthreads,elapse +Fugaku,yes,1,4,12,0:10:00 +RC_GH200,yes,1,1,1,0:10:00 +RC_DGXSP,yes,1,1,1,0:10:00 +RC_GENOA,yes,1,1,48,0:10:00 +RC_FX700,yes,1,1,48,0:30:00 diff --git a/programs/salmon/run.sh b/programs/salmon/run.sh new file mode 100644 index 0000000..3dbf33c --- /dev/null +++ b/programs/salmon/run.sh @@ -0,0 +1,208 @@ +#!/bin/bash +set -euo pipefail + +system="$1" +nodes="$2" +numproc_node="$3" +nthreads="$4" +n_ranks=$((nodes * numproc_node)) + +source "${PWD}/scripts/bk_functions.sh" + +RESULTS_DIR="${PWD}/results" +WORK_DIR="${PWD}/salmon_run" +INPUT_ARCHIVE_DEFAULT="/vol0003/rccs-sdt/data/a01010/benchmark_data/SALMON.tar.gz" +INPUT_ARCHIVE_CLOUD="/lvs0/dne1/rccs-nghpcadu/CX_input/SALMON/SALMON.tar.gz" +GS_THEORY="${BK_SALMON_GS_THEORY:-dft}" +RT_THEORY="${BK_SALMON_RT_THEORY:-tddft_response}" + +salmon_normalize_legacy_theory() { + local input_file="$1" + local theory="$2" + + [[ -f "${input_file}" ]] || return 0 + if grep -Eiq '^[[:space:]]*theory[[:space:]]*=' "${input_file}"; then + sed -i -E "s/^([[:space:]]*theory[[:space:]]*=[[:space:]]*)['\"][^'\"]*['\"]([[:space:]]*,?.*)$/\1'${theory}'\2/I" "${input_file}" + sed -i -E "s/^([[:space:]]*theory[[:space:]]*=[[:space:]]*)[^[:space:],!]+([[:space:]]*,?.*)$/\1'${theory}'\2/I" "${input_file}" + fi +} + +mkdir -p "${RESULTS_DIR}" +: > "${RESULTS_DIR}/result" + +if [[ ! -x artifacts/salmon ]]; then + echo "Required artifact not found or not executable: artifacts/salmon" >&2 + exit 1 +fi + +case "${system}" in + Fugaku) + input_archive="${INPUT_ARCHIVE_DEFAULT}" + exec_gs=(-stdin Si-1-1-1.nml ./salmon) + exec_rt=(-stdin Si-1-1-1-tddft.nml ./salmon) + ;; + RC_GH200|RC_DGXSP|RC_GENOA) + input_archive="${INPUT_ARCHIVE_CLOUD}" + exec_gs=(./salmon) + exec_rt=(./salmon) + ;; + RC_FX700) + input_archive="${INPUT_ARCHIVE_CLOUD}" + exec_gs=(-stdin Si-1-1-1.nml ./salmon) + exec_rt=(-stdin Si-1-1-1-tddft.nml ./salmon) + ;; + *) + echo "Unknown system: ${system}" >&2 + exit 1 + ;; +esac + +if [[ ! -f "${input_archive}" ]]; then + echo "Input archive not found: ${input_archive}" >&2 + exit 1 +fi + +rm -rf "${WORK_DIR}" +mkdir -p "${WORK_DIR}/input" +tar -xzf "${input_archive}" -C "${WORK_DIR}/input" + +input_dir=$(find "${WORK_DIR}/input" -type d -path "*/Si-1-1-1/input" | head -n 1) +if [[ -z "${input_dir}" ]]; then + input_dir=$(find "${WORK_DIR}/input" -type f -name "Si-1-1-1.nml" -printf '%h\n' | head -n 1) +fi +if [[ -z "${input_dir}" || ! -d "${input_dir}" ]]; then + echo "SALMON Si-1-1-1 input directory not found in ${input_archive}" >&2 + exit 1 +fi + +cp artifacts/salmon "${WORK_DIR}/salmon" +chmod +x "${WORK_DIR}/salmon" +cp "${input_dir}"/* "${WORK_DIR}/" +salmon_normalize_legacy_theory "${WORK_DIR}/Si-1-1-1.nml" "${GS_THEORY}" +salmon_normalize_legacy_theory "${WORK_DIR}/Si-1-1-1-tddft.nml" "${RT_THEORY}" +grep -Ein '^[[:space:]]*theory[[:space:]]*=' "${WORK_DIR}/Si-1-1-1.nml" "${WORK_DIR}/Si-1-1-1-tddft.nml" >&2 || true +cd "${WORK_DIR}" + +case "${system}" in + Fugaku) + export OMP_NUM_THREADS="${nthreads}" + ;; + RC_GH200) + module purge + module load system/qc-gh200 nvhpc-hpcx-cuda12/25.7 + export OMP_NUM_THREADS="${nthreads}" + ;; + RC_DGXSP) + source /etc/profile.d/modules.sh + module purge + module load system/ng-dgx nvhpc-hpcx-cuda13/26.3 + export OMP_NUM_THREADS="${nthreads}" + ;; + RC_GENOA) + module purge + module load system/genoa mpi/mpich-x86_64 + export OMP_NUM_THREADS="${nthreads}" + ;; + RC_FX700) + module purge + module load system/fx700 FJSVstclanga + export OMP_NUM_THREADS="${nthreads}" + ;; +esac + +run_salmon() { + local logfile="$1" + shift + mpiexec -n "${n_ranks}" "$@" > "${logfile}" 2>&1 +} + +salmon_output_has_marker_since() { + local logfile="$1" + local marker_file="$2" + local success_pattern='total[[:space:]]+calculation[[:space:]]+time|total[[:space:]]+.*elapsed[[:space:]]+time|elapsed[[:space:]]+time' + + if grep -Eiq "${success_pattern}" "${logfile}"; then + return 0 + fi + + while IFS= read -r -d '' output_file; do + if grep -Eiq "${success_pattern}" "${output_file}"; then + return 0 + fi + done < <(find . -type f -newer "${marker_file}" ! -path "./input/*" -print0) + + return 1 +} + +print_salmon_output_diagnostics() { + local marker_file="$1" + local output_file + + find . -maxdepth 4 -type f -newer "${marker_file}" ! -path "./input/*" -printf '%p\n' \ + | sort \ + | sed -n '1,120p' >&2 + + while IFS= read -r -d '' output_file; do + echo "---- ${output_file} tail ----" >&2 + tail -n 20 "${output_file}" >&2 || true + done < <( + find . -maxdepth 5 -type f -newer "${marker_file}" \ + \( -name 'stdout*' -o -name 'stderr*' -o -name '*.log' \) \ + ! -path "./input/*" -print0 \ + | sort -z + ) +} + +touch .gs_start_marker +gs_start=$(date +%s.%N) +if [[ "${system}" == "RC_GH200" || "${system}" == "RC_DGXSP" || "${system}" == "RC_GENOA" ]]; then + run_salmon gs.log "${exec_gs[@]}" < Si-1-1-1.nml +else + run_salmon gs.log "${exec_gs[@]}" +fi +gs_end=$(date +%s.%N) + +if [[ -d data_for_restart ]]; then + rm -rf restart + mv data_for_restart restart +fi + +touch .rt_start_marker +rt_start=$(date +%s.%N) +if [[ "${system}" == "RC_GH200" || "${system}" == "RC_DGXSP" || "${system}" == "RC_GENOA" ]]; then + run_salmon rt.log "${exec_rt[@]}" < Si-1-1-1-tddft.nml +else + run_salmon rt.log "${exec_rt[@]}" +fi +rt_end=$(date +%s.%N) + +gs_elapsed=$(awk -v start="${gs_start}" -v end="${gs_end}" 'BEGIN {printf "%.6f", end - start}') +rt_elapsed=$(awk -v start="${rt_start}" -v end="${rt_end}" 'BEGIN {printf "%.6f", end - start}') +total_elapsed=$(awk -v gs="${gs_elapsed}" -v rt="${rt_elapsed}" 'BEGIN {printf "%.6f", gs + rt}') + +cp gs.log rt.log "${RESULTS_DIR}/" + +if ! salmon_output_has_marker_since gs.log .gs_start_marker || ! salmon_output_has_marker_since rt.log .rt_start_marker; then + echo "SALMON success marker not found in both gs.log and rt.log" >&2 + echo "---- gs.log tail ----" >&2 + tail -n 40 gs.log >&2 || true + echo "---- rt.log tail ----" >&2 + tail -n 40 rt.log >&2 || true + echo "---- files updated since GS start ----" >&2 + print_salmon_output_diagnostics .gs_start_marker + echo "---- files updated since RT start ----" >&2 + print_salmon_output_diagnostics .rt_start_marker + exit 1 +fi + +{ + bk_emit_result \ + --fom "${total_elapsed}" \ + --fom-version "total_elapsed_time_s" \ + --exp "Si-1-1-1" \ + --nodes "${nodes}" \ + --numproc-node "${numproc_node}" \ + --nthreads "${nthreads}" + bk_emit_section gs "${gs_elapsed}" + bk_emit_section rt "${rt_elapsed}" +} >> "${RESULTS_DIR}/result" From bc31ddcc42f9f2ae74494fc04d7b789f7b83367d Mon Sep 17 00:00:00 2001 From: Yoshifumi Nakamura Date: Wed, 8 Jul 2026 08:35:34 +0900 Subject: [PATCH 2/2] Update estimation roadmap app references Signed-off-by: Yoshifumi Nakamura --- docs/cx/BENCHKIT_GAP_ANALYSIS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/cx/BENCHKIT_GAP_ANALYSIS.md b/docs/cx/BENCHKIT_GAP_ANALYSIS.md index 2ab6b6d..520727d 100644 --- a/docs/cx/BENCHKIT_GAP_ANALYSIS.md +++ b/docs/cx/BENCHKIT_GAP_ANALYSIS.md @@ -283,7 +283,7 @@ Once the estimation specification is clarified, many other design decisions beco - 推定モデルの種別と識別方法 - 再推定のトリガ、履歴、比較可能性と表示導線 -現状は `qws` が先行 app として、 +現状は `qws` と `genesis` が先行 app として、 - `weakscaling` - `instrumented_app_sections_dummy` @@ -291,7 +291,7 @@ Once the estimation specification is clarified, many other design decisions beco - side ごとの `model` 表現 まで動作確認済みである。 -したがって、入口確認段階はすでに超えており、次はこの形を複数 app に横展開できるよう引き上げる必要がある。 +したがって、入口確認段階はすでに超えており、次はこの形をさらに他 app に横展開できるよう引き上げる必要がある。 #### 5.1.1 推定機構の実装 GAP 再調査 / Re-Survey of Estimation Implementation Gaps @@ -333,7 +333,7 @@ Once the estimation specification is clarified, many other design decisions beco 推定機構について、次の実装順を推奨する。 -1. `qws` 以外の app へ推定方式を横展開する +1. `qws` / `genesis` で得た推定方式を他 app へ横展開する 2. `not_applicable` と compare を含む推定差分 UI を portal で見やすくする 3. 複数 detailed package 間の fallback と discovery を整理する 4. その後に再推定比較 UI と portal 起動導線へ進む