Fortran coarray如何实现部分并行、其余代码串行执行
问题根因
Coarray Fortran 是基于SPMD(单程序多数据)模型设计的,程序启动后你设置的N个并行进程(coarray里叫image)会各自独立加载完整程序,从主程序第一行开始执行,根本不存在“默认主程序串行、调用coarray子程序才拉起并行”的自动调度机制。你现在看到主程序打印4次,就是4个image都执行了主程序里write语句的正常结果,不是程序运行出错。
实现方法
不需要改编译选项,也不需要修改子程序,只要用coarray内置的this_image()函数判断当前运行的是第几个image,把主程序里要串行执行的逻辑限定在1号image上运行就行,调用coarray子程序时所有image自然会并行进入执行。
修改后的主程序代码
program main implicit none ! 仅1号image执行主程序的串行逻辑 if (this_image() == 1) then write (*,*) "Hello from main " end if ! 可选:加全局同步,确保1号image的主程序逻辑跑完再进子程序,避免时序错乱 sync all ! 所有image并行执行coarray子程序 call coarray_test end program
子程序代码
你原来的coarray_test子程序不需要做任何修改,所有image进入后都会执行打印逻辑,正好输出4次子程序的提示内容:
subroutine coarray_test implicit none write (*,*) "Hello from Subroutine coarray_test " return end subroutine coarray_test
编译运行命令
和你之前用的命令完全一致,不需要调整:
export FOR_COARRAY_NUM_IMAGES=4 ifort -g -coarray -o test.out main.f90 coarray_test.f90 ./test.out
运行结果
执行后输出完全匹配你的预期:
Hello from main Hello from Subroutine coarray_test Hello from Subroutine coarray_test Hello from Subroutine coarray_test Hello from Subroutine coarray_test
注意:不存在“启动时只跑1个主进程,调用coarray子程序时临时拉起剩下进程”的用法,coarray的所有image都是程序启动阶段就完成初始化的,通过this_image()做分支区分串行/并行代码段是标准写法,性能开销可以忽略,所有生产环境的coarray代码都是这么实现的。
内容的提问来源于stack exchange,提问作者codegeek
相关产品推荐
相关产品推荐

