如何通过TFORM实现多组符号方程的并行展开?
用TFORM并行展开多组符号方程的正确实现
TFORM的默认并行逻辑是将单个表达式的项拆分到多核心,而非自动把多个独立方程分配到不同核心。要实现多方程并行展开,需借助#fork预处理指令或分组批量处理,以下是两种可行方案:
方案1:#fork并行处理单个方程(推荐)
利用#fork创建独立并行任务,每个任务处理一个方程,完全匹配你的需求:
Off Statistics; CFunction a, d; Symbol r0, nu, I; #include coeffs.frm #include dvars.frm #include equations.frm #include numOfEquations.frm Format mathematica; Format nospaces, nolines; // 主进程统一打开输出文件,避免并行写入冲突 #open <expandedEquations.m> append #do i = 1, `numOfEquations' #ifdef Eq`i' // 启动并行子任务处理当前方程 #fork Local EqExpanded = Eq`i'; .sort #write <expandedEquations.m> "%E==0,", EqExpanded #endfork #endif #enddo // 等待所有子任务完成后再收尾 #waitforks #close <expandedEquations.m> .end
核心要点:
#fork会将块内代码分配给空闲的TFORM worker进程,实现多方程同时展开#waitforks强制主进程等待所有并行任务结束,防止提前退出导致结果丢失- 主进程统一管理输出文件,避免多进程同时操作文件引发的写入混乱
方案2:分组批量处理(适合方程数量远超核心数)
如果方程数量远多于CPU核心,可先将方程均匀分组,再用单个.sort并行处理所有分组:
Off Statistics; CFunction a, d; Symbol r0, nu, I; #include coeffs.frm #include dvars.frm #include equations.frm #include numOfEquations.frm Format mathematica; Format nospaces, nolines; // 手动指定CPU核心数,或通过环境变量获取 #def numCores 4 // 将方程均匀分配到对应核心的分组 #do i = 1, `numOfEquations' #ifdef Eq`i' #def groupIdx = ((i-1) % numCores) + 1 Group Group`groupIdx' += Eq`i'; #endif #enddo // 并行处理所有分组的方程 .sort // 提取展开结果并写入文件 #open <expandedEquations.m> #do i = 1, `numOfEquations' #ifdef Eq`i' #def groupIdx = ((i-1) % numCores) + 1 Local EqExpanded = Group`groupIdx'::Eq`i'; #write <expandedEquations.m> "%E==0,", EqExpanded #endif #enddo #close <expandedEquations.m> .end
核心要点:
- 按核心数分组,让每个核心处理一组方程,最大化利用硬件资源
- 单个
.sort会将所有分组的计算任务拆分到多核心并行执行
原写法失效原因解析
- 循环内单
.sort:每次只处理一个方程,TFORM无法并行,只能顺序执行 - 单
.sort处理所有方程:TFORM会把所有方程合并成一个全局工作负载,按项拆分到核心,而非按方程拆分,所以达不到你期望的"每个方程一个核心"的并行效果
内容的提问来源于stack exchange,提问作者kozapdh
相关产品推荐
相关产品推荐

