数值模拟通常具有简单但重要的结构:使用不同的参数多次运行同一程序,然后合并结果。
例如,在扫描相图时,每个参数点通常可以独立计算。如果有 100 个参数值,就有 100 个独立的作业。如果每个参数值还需要多个随机种子,独立作业的数量会进一步增加。
这是一种易于并行化的工作负载。并行化在概念上很简单,但周围的工作流程可能会变得混乱:
- 如何生成输入文件?
- 如何为每个作业命名?
- 如何实现计算密集型部分?
- 如何收集数百或数千个输出文件?
- 如何在以后重新运行工作流程而不忘记确切的参数?
本仓库展示了一种紧凑的解决方案:
https://github.com/kaityo256/pycpp-parallel-pipeline
它使用二维键渗流计算作为示例问题,但重点不在于渗流本身。重点在于可重用的流水线:
- 在一个 YAML 文件中编写工作流程参数。
- 使用 Python 生成许多小型输入文件。
- 为每个输入文件运行一个 C++ 模拟程序。
- 使用
cps并行分发这些命令。 - 使用 Python 聚合输出文件。
- 使用 gnuplot 绘制汇总结果。
为何以这种方式拆分工作流程?
Python 和 C++ 适用于工作的不同部分。
Python 便于编排:
- 读取 YAML
- 创建目录
- 生成许多输入文件
- 收集结果文件
- 计算平均值和标准误
C++ 适用于计算密集型核心:
- 紧密循环
- 随机采样
- 内存高效的数据结构
- 可预测的编译性能
该工作流程保持了这些职责的分离。Python 负责准备和分析。C++ 负责计算。并行调度器只需要一个纯文本任务文件,每行包含一个命令。
这种分离使得该仓库易于适应其他模拟问题。
仓库结构
重要文件包括:
generate_inputs.py # 生成每个作业的 YAML 文件和 task.sh
analyze_results.py # 读取 .dat 文件并计算统计数据
input.yaml # 顶层工作流程配置
cpp/main.cpp # C++ 入口点
cpp/percolation.hpp # 键渗流实现
cpp/param # C++ 参数文件解析器子模块
cps # 并行命令调度器子模块
plot.plt # gnuplot 脚本
fig/L128.png # 示例结果图
cps 和 cpp/param 目录是 Git 子模块,因此请递归克隆仓库:
git clone --recursive https://github.com/kaityo256/pycpp-parallel-pipeline.git
cd pycpp-parallel-pipeline
如果仓库已经克隆但未包含子模块:
git submodule update --init --recursive
顶层配置
整个运行始于 fr
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。