目录
quaker

ci(remote): end-to-end remote CI orchestration script

Adds scripts/run_remote_ci.sh: a single command that drives the remote SPECFEM3D regression gate. Pipeline = rsync sync + remote build + remote ctest + remote examples/cpml xmesh → xgenerate_databases → xspecfem3D end-to-end. 7 stages, each with its own exit code (10/11/20/30/40/50/51) so CI can pinpoint the failing stage.

API: bash scripts/run_remote_ci.sh REMOTE=user@host bash scripts/run_remote_ci.sh SKIP_SMOKE=1 bash scripts/run_remote_ci.sh SKIP_BUILD=1 SKIP_TEST=1 bash scripts/run_remote_ci.sh SPECFEM3D_BIN=/path/to/xgen bash scripts/run_remote_ci.sh

Measured on ubuntu@43.159.43.117 (2-core, OpenMPI 4.1.6, SPECFEM3D 4.1.1): full pipeline ~100-140 s, SKIP_SMOKE ~80 s, smoke-only ~24 s.

Key design decisions:

  • 7-stage exit codes map to SPECFEM3D contract risks (precheck/ sync/build/test/xgen/xsolver/semd) so future CPML parameter format changes, database byte-layout changes, or poroelastic 17-double record changes all surface with a precise code.
  • Tilde path pre-expansion: ssh cannot expand ~ in quoted env vars, so the script sshes once for remote HOME and rewrites ~/xmesh_dev etc. to absolute paths before passing them on.
  • Per-stage stdout/stderr routed to .ci_logs//*.log for failure debugging (added to .gitignore).
  • SKIP_* flags are opt-in escapes for fast iteration; default is full pipeline.

Verified:

  • Full pipeline on default remote: 7/7 PASS, 25/25 ctest, 6 .semd.
  • SKIP_SMOKE: 4/4 PASS.
  • SKIP_BUILD + SKIP_TEST: 3/3 PASS, smoke reused cached build.
  • Unreachable remote: exit 10 (precheck FAIL), downstream stages SKIP.

Documentation updated (README, CLAUDE, PLAN, .gitignore) with the new script’s API, exit-code table, and measured timings.

1个月前69次提交

xmesh

面向地震动力学模拟的并行三维网格生成程序

概述

xmesh 生成用于 SPECFEM3D 地震波传播求解器的六面体谱元网格。它在 SPECFEM3D 的 xmeshfem3D 网格生成器基础上进行了扩展,支持通过 MPI 实现并行,并通过 Kokkos 实现 GPU 加速。

主要特性:

  • 支持层状介质与网格粗化的 Superbrick 网格生成
  • SFC-3D 分区算法(Z 加权切分 + Hilbert 曲线水平排序),完全确定性、无外部依赖
  • MPI 三维并行分解(列主序约定,xi 最外层)
  • 自动物理边界(面 1..6)与 MPI 界面检测
  • CPML(卷积完美匹配层)吸收边界:三向厚度配置,自动识别 7 类 PML 区域
  • 兼容 SPECFEM3D 的 Fortran 无格式二进制数据库输出(proc******_Database
  • 通过 Kokkos 实现 GPU 加速的 GLL 节点计算与 Jacobian 求值
  • 基于 YAML 的参数输入

依赖

  • C++17 编译器(GCC 9+、Clang 10+)
  • CMake >= 3.20
  • Kokkos(Serial、OpenMP、CUDA 或 HIP 后端)
  • MPI(OpenMPI、MPICH 或兼容实现)
  • yaml-cpp

可选依赖:

  • HDF5(用于替代输出格式)
  • ADIOS2(用于可扩展的并行 I/O)

构建

# 使用 Kokkos Serial 后端进行配置
cmake -B build \
    -DKokkos_ROOT=/path/to/kokkos/install \
    -DCMAKE_BUILD_TYPE=Release

# 构建
cmake --build build -j

# 启用单元测试
cmake -B build -DXMESH_BUILD_TESTS=ON
cmake --build build -j

选择 Kokkos 后端

# OpenMP 后端
-DKokkos_ENABLE_OPENMP=ON

# CUDA 后端
-DKokkos_ENABLE_CUDA=ON -DKokkos_ARCH_VOLTA70=ON

# HIP 后端(AMD GPU / 曙光 DCU)
-DKokkos_ENABLE_HIP=ON -DKokkos_ARCH_AMD_GFX90A=ON

曙光 DCU 构建(Hygon DCU,gfx936)

项目已提供专用脚本,使用 DTK 25.04 + HPCX MPI:

# 登录节点执行:构建 Kokkos HIP 后端(需先手动为 gfx936 打补丁)
bash scripts/build_kokkos_hip.sh

# 构建 xmesh HIP 版本
bash scripts/build_xmesh_hip.sh

# 提交 2 进程 CPU vs DCU 对比作业
bash scripts/submit_cpu_2proc_benchmark.sh hpctest06
bash scripts/submit_dcu_benchmark.sh hpctest06

# 提交 DCU 节点完整 ctest
bash scripts/submit_ctest_dcu.sh hpctest06

# 提交 8/16/32/64 DCU 弱扩展测试(固定 32,768 谱元/DCU)
bash scripts/submit_dcu_benchmark.sh hpctest06 2 2 2 mesh_parameters_weak_8.yaml
bash scripts/submit_dcu_benchmark.sh hpctest06 4 2 2 mesh_parameters_weak_16.yaml
bash scripts/submit_dcu_benchmark.sh hpctest06 4 4 2 mesh_parameters_weak_32.yaml
bash scripts/submit_dcu_benchmark.sh hpctest06 4 4 4 mesh_parameters_weak.yaml

当前在 2 DCU 共享场景下,check_mesh_quality+jacobian 较 CPU 提升约 ,完整 19/19 ctest 通过;hpctest06 已验证支持单节点 8 DCU、多节点累计 64 DCU,64 DCU 弱扩展总 wall 时间约 4.95 s

用法

# 串行运行
./build/xmesh examples/layered_halfspace/mesh_parameters.yaml

# MPI 并行(4 个进程:2x2 笛卡尔网格)
mpirun -np 4 ./build/xmesh examples/layered_halfspace/mesh_parameters.yaml

# MPI 三维并行(8 个进程:2x2x2 笛卡尔网格)
# 注意:ner_total 必须能被 nproc_z 整除,否则启动时报错
mpirun -np 8 ./build/xmesh examples/layered_halfspace/mesh_parameters.yaml

分区拓扑约束

维度 约束
XI(东西) nex_xi 必须是 nproc_xi 的整数倍
ETA(南北) nex_eta 必须是 nproc_eta 的整数倍
Z(垂直) ner_total 必须是 nproc_z 的整数倍

测试

# 构建并运行所有测试
cmake -B build -DXMESH_BUILD_TESTS=ON
cmake --build build -j
ctest --test-dir build --output-on-failure

# 单独运行单元测试
./build/test/test_hilbert
./build/test/test_weight
./build/test/test_jacobian
./build/test/test_database_format

# MPI 集成测试(不同进程数)
mpirun --allow-run-as-root --oversubscribe -np 1 ./build/test/test_partition_3d    # 1x1x1 拓扑
mpirun --allow-run-as-root --oversubscribe -np 2 ./build/test/test_partition_3d    # 2x1x1 拓扑
mpirun --allow-run-as-root --oversubscribe -np 4 ./build/test/test_partition_3d    # 2x2x1 拓扑
mpirun --allow-run-as-root --oversubscribe -np 8 ./build/test/test_partition_3d    # 2x2x2 拓扑

# MPI 端到端:xmesh → generate_mesh Jacobian 守护
mpirun --allow-run-as-root --oversubscribe -np 1 ./build/test/test_meshgen_jacobian
mpirun --allow-run-as-root --oversubscribe -np 4 ./build/test/test_meshgen_jacobian

SPECFEM3D 端到端 smoke

验证 xmesh 输出能被 SPECFEM3D 的 xgenerate_databases 完整读通,并可进一步跑通 solverxspecfem3D)生成地震图。需要本机或远程有 SPECFEM3D 可执行。

# 仅验证 xmesh → xgenerate_databases
SPECFEM3D_BIN=/path/to/xgenerate_databases \
    bash scripts/run_specfem_smoke.sh examples/smoke

# 完整流水线:xmesh → xgenerate_databases → xspecfem3D
SPECFEM3D_BIN=/path/to/xgenerate_databases \
XSPECFEM3D_BIN=/path/to/xspecfem3D \
    bash scripts/run_specfem_smoke.sh examples/mountain_basin

两个示例均已通过 SPECFEM3D 4.1.1 完整流水线验证 (本机构建路径: /home/public/Programs/gitlink/quaker/specfem3d_cartesian/bin/{xgenerate_databases,xspecfem3D})。 退出码 0 表示端到端跑通,并生成 OUTPUT_FILES/*.semd 地震图文件。

远程端到端 CI 编排

scripts/run_remote_ci.sh 在远程主机上同步、build、跑 ctest,并跑 examples/cpml/ 完整 SPECFEM3D 流水线,7 阶段汇总 PASS/FAIL。适合作为 SPECFEM3D 兼容性回归屏障。

# 默认远程(ubuntu@43.159.43.117)
bash scripts/run_remote_ci.sh

# 自定义远程
REMOTE=alice@cluster.example.com bash scripts/run_remote_ci.sh

# 跳过部分阶段
SKIP_SMOKE=1 bash scripts/run_remote_ci.sh
SKIP_BUILD=1 SKIP_TEST=1 bash scripts/run_remote_ci.sh

7 个阶段: precheck (ssh + 工具) → sync (rsync) → build (cmake) → test (ctest) → xgenerate_databases → xspecfem3D → semd (验证 .semd 文件)

退出码: 0=PASS / 10=precheck / 11=sync / 20=build / 30=test / 40=xgen / 50=xsolver / 51=semd

默认配置: 远程 2 核机器完整跑通 ≈ 100 秒;远程 SPECFEM3D bin 默认路径 ~/specfem3d_bin/{xgenerate_databases,xspecfem3D},可被 SPECFEM3D_BIN / XSPECFEM3D_BIN 环境变量覆盖。

运行时日志写入本地 .ci_logs/<timestamp>/(已加入 .gitignore),失败时 直接 tail 对应文件可定位 SPECFEM3D 报错行。

当前测试覆盖(ctest 25/25)

测试 类型 范围
partition_3d_1x1x1 集成 1 进程 1×1×1 分区
partition_3d_2x1x1 集成 2 进程 2×1×1 分区
partition_3d_2x2x1 集成 4 进程 2×2×1 分区
partition_3d_2x2x2 集成 8 进程 2×2×2 分区
meshgen_jacobian_1proc 集成 generate_mesh + Jacobian 守护(1 进程)
meshgen_jacobian_4proc 集成 generate_mesh + Jacobian 守护(4 进程)
topography 集成 平坦退化 + 高斯山丘 Jacobian 全正 + 双线性插值
curved_layers 集成 倾斜莫霍面材料分布 + 地表起伏/曲层 Jacobian 全正 + 宽高比护栏
mountain_basin_1proc 集成 3D 分区 + 地表地形 + 倾斜莫霍面合流(1 进程)
mountain_basin_4proc 集成 3D 分区 + 地表地形 + 倾斜莫霍面合流(4 进程 2×2×1)
mountain_basin_8proc 集成 3D 分区 + 地表地形 + 倾斜莫霍面合流(8 进程 2×2×2)
hilbert 单元 HilbertIndex 2D 曲线
weight 单元 WeightModel 权值
jacobian 单元 6 角点 Jacobian 正定性 + 错误消息
database_format 单元 SPECFEM3D Database 字节级格式契约(28 字节节点、17 doubles 材料、11 ints 元素、6 边界 header、6 元素列表、CPML、MPI 界面)
parameters_domain 单元 材料 domain 字段解析(声学/弹性/孔隙弹性)
partition_acoustic 单元 声学/弹性非均匀权重 SFC-3D 分区回归测试
poroelastic_layer_1proc 集成 孔隙弹性材料参数 MPI 广播 + Jacobian 全正(1 进程)
poroelastic_layer_4proc 集成 孔隙弹性材料参数 MPI 广播 + Jacobian 全正(4 进程 2×2×1)
weak_scaling_smoke_8proc 集成 矩形水平网格 2×2×2 分区 + Jacobian 全正(8 进程)
cpml 单元 CPML 区域分类(7 类:X/Y/Z 表面 + XY/XZ/YZ 棱 + XYZ 角)
cpml_integration_1proc 集成 CPML 检测 + 跨 rank 总数一致 + Jacobian 全正(1 进程)
cpml_integration_4proc 集成 CPML 检测 + 跨 rank 总数一致 + Jacobian 全正(4 进程 2×2×1)
cpml_curved_1proc 集成 CPML + 曲层界面(地表起伏)合流:8 角点 z 不再恒定时仍正确分类 + Jacobian 全正(1 进程)
cpml_curved_4proc 集成 CPML + 曲层界面合流:4 进程 2×2×1 跨 rank 一致性

输入格式

网格参数通过 YAML 文件指定(参见 examples/layered_halfspace/)。

model:
  utm_zone: 11
  x_min: 0.0
  x_max: 50000.0       # XI 方向 50 km
  y_min: 0.0
  y_max: 50000.0       # ETA 方向 50 km
  depth: 30000.0       # 深度 30 km

  # 可选:地表地形(B1)
  # topography:
  #   source: file        # 或 "flat"
  #   path: ./dem.txt     # ASCII (x y z) 规则网格;z 向下为正

mesh:
  nex_xi: 64            # XI 方向 64 个谱元
  nex_eta: 64           # ETA 方向 64 个谱元
  ngll: 5               # N=4(5 个 GLL 节点)
  regular: true         # 规则(均匀)网格
  ndoublings: 0         # 无网格粗化

partition:
  nproc_xi: 2           # XI 方向 2 个进程
  nproc_eta: 2          # ETA 方向 2 个进程
  nproc_z: 1            # Z 方向 1 个进程(二维分区)

layers:
  - depth: 0.0            # 第一层顶界面(地表)
    material_id: 1
  - depth: 15000.0        # 第二层顶界面 / 第一层底界面
    material_id: 2
    # 可选:B2 曲层界面
    # bottom:
    #   source: file
    #   path: ./moho_dem.txt

materials:
  - id: 1
    rho: 2600.0         # kg/m³
    vp: 5800.0          # m/s
    vs: 3400.0          # m/s
    Q: 100.0            # 品质因子

  - id: 2
    rho: 2800.0
    vp: 6500.0
    vs: 3800.0
    Q: 200.0

  # 孔隙弹性材料(domain 可选:acoustic / elastic / poroelastic,默认 elastic)
  # - id: 3
  #   domain: poroelastic
  #   rho_s: 2500.0
  #   rho_f: 1020.0
  #   phi: 0.4
  #   tort: 2.0
  #   eta_f: 1.0e-11
  #   kxx: 1.0e-11
  #   kyy: 1.0e-11
  #   kzz: 1.0e-11
  #   kappa_s: 16.0554e9
  #   kappa_f: 2.295e9
  #   kappa_fr: 10.0e9
  #   mu_fr: 9.63342e9

  # CPML 吸收边界(可选,默认关闭)
  #   cpml:
  #     enabled: true
  #     thickness_x: 2000.0     # X 方向厚度(m)
  #     thickness_y: 2000.0     # Y 方向厚度(m)
  #     thickness_z: 2000.0     # Z 方向厚度(m)
  #     free_surface: false     # 默认 false:仅物理底部 PML;
  #                             # true:地表也施加 PML(PML_INSTEAD_OF_FREE_SURFACE)
  # 注:thickness 简写同时设置三个方向
  #   cpml:
  #     enabled: true
  #     thickness: 2000.0

output:
  format: specfem3d
  path: "./OUTPUT_FILES/DATABASES_MPI/"

架构

src/
├── main.cpp               # 入口点、MPI/Kokkos 初始化、流水线编排
├── parameters.{h,cpp}     # YAML 参数解析与验证
├── geometry.{h,cpp}       # 界面、曲面与层结构
├── meshgen.{h,cpp}        # 网格生成(SFC-3D global_ids 驱动)
├── gll_library.cpp        # GLL 求积节点与 Jacobian 计算
│
├── partition.{h,cpp}      # MPI 笛卡尔拓扑、广播、gather_mesh
├── partition_sfc3d.{h,cpp}# SFC-3D 主控(Z 切 + Hilbert 水平切)
├── partition_z.{h,cpp}    # Z 方向按层界面加权切分
├── partition_weight.{h,cpp}# 单元权值模型(材料/加倍/地形/震源)
├── hilbert.{h,cpp}        # 2D Hilbert 曲线索引
│
├── boundaries.{h,cpp}     # 物理边界(面 1..6)+ MPI 界面检测
├── database_io.{h,cpp}    # SPECFEM3D Fortran 无格式二进制 I/O
├── quality.{h,cpp}        # 网格质量检查与 DT 估计(含 B2 宽高比护栏;通用 Kokkos Jacobian 扫描)
├── topography_io.{h,cpp}  # DEM 读取与双线性插值(B1/B2 复用)
├── cpml.{h,cpp}           # CPML 区域检测(8 角点判定 + SPECFEM3D 优先级)

include/
├── xmesh_config.h         # 编译期常量(默认 NGLL=5、六面体角点数=8)
├── xmesh_types.h          # 核心数据结构(LocalMesh 含 device 坐标 Views、ProcessInfo 等)
└── xmesh_kernels.h        # Kokkos 内核函数声明

test/
├── unit/
│   ├── test_hilbert.cpp             # HilbertIndex 单元测试
│   ├── test_weight.cpp              # WeightModel 单元测试
│   ├── test_jacobian.cpp            # Jacobian 正定性 14 个 case
│   ├── test_database_format.cpp     # SPECFEM3D Database 字节级契约
│   ├── test_parameters_domain.cpp   # 材料 domain 字段解析(含孔隙弹性)
│   └── test_partition_acoustic.cpp  # 声学/弹性非均匀权重分区回归测试
└── integration/
    ├── partition_3d.cpp         # 3D 分区集成测试(4 种 MPI 拓扑)
    ├── meshgen_jacobian.cpp     # generate_mesh + Jacobian 守护(1/4 进程;device/host 一致性)
    ├── weak_scaling_smoke.cpp   # 矩形水平网格 3D 分区本地 smoke(8 进程)
    ├── topography.cpp           # 地表地形支持回归测试(B1)
    ├── curved_layers.cpp        # 曲层界面支持回归测试(B2)
    ├── mountain_basin.cpp       # 3D 分区 + 地形 + 曲层合流回归测试(C)
    ├── poroelastic_layer.cpp    # 孔隙弹性材料 MPI 广播 + Jacobian 回归测试
    ├── cpml.cpp                 # CPML 检测 + 跨 rank 一致性回归测试(1proc/4proc)
    └── cpml_curved.cpp          # CPML + 曲层界面(地表起伏)合流回归测试(1proc/4proc)

scripts/
└── run_specfem_smoke.sh         # xmesh → xgenerate_databases 端到端 smoke

examples/
├── smoke/                       # B0.0c 端到端 smoke 模型(50 km × 50 km × 30 km 双层)
├── topography/                  # B1 地表地形示例(10 km × 10 km × 5 km + 高斯山丘)
├── curved_layers/               # B2 曲层界面示例(20 km × 20 km × 10 km + 倾斜莫霍面)
├── mountain_basin/              # C 阶段合流示例(16 km × 16 km × 8 km,2×2×2 + 高斯山丘 + 倾斜莫霍面)
├── poroelastic_layer/           # 孔隙弹性层示例(8 km × 8 km × 4 km,2×2×1)
├── multi_physics/               # 声学/弹性/孔隙弹性三物理场耦合示例(8 km × 8 km × 6 km,2×2×1)
├── cpml/                        # CPML 吸收边界示例(16 km × 16 km × 8 km,三向 2000 m PML,2×2×1)
└── benchmark_scaling/           # DCU 弱扩展基准配置(8/16/32/64 DCU,32,768 谱元/DCU)

分区算法(SFC-3D)

MeshParameters → ZAxisPartitioner ─→ Z 切片 {iz_min, iz_max}
                     │
                     ▼
              WeightModel::weight(iex, iey, iez)
                     │
         ┌───────────┴───────────┐
         ▼                       ▼
  水平退路(nex≤1)          Hilbert 路径
  (iex, iey) 行主序均匀切    HilbertIndex::hilbert → 排序
                                     │
                                     ▼
                              加权累计切分
                                     │
                                     ▼
                          Sfc3dPartitioner::compute
                                     │
                                     ▼
                          ElementOwnership.global_ids
                                     │
                                     ▼
                            generate_mesh(只生成 owned 单元)
关于

面向地震三维动力学模拟的网格生成程序

889.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号