Fortran中coarray写入的可见时机与位置?程序运行异常咨询
Fortran Coarray写入可见性与输出异常问题
问题描述
编写了如下Fortran Coarray程序,预期2个镜像(image)运行时,镜像1输出1 1.0 2.0、镜像2输出2 1.0 2.0,但实际镜像1输出1 1.0 1.0,镜像2输出2 1.0 2.0,同时伴随UCX通信警告。
程序代码
program main implicit none double precision, allocatable :: a[:] allocate(a[*]) a = this_image() sync all write(*, *) this_image(), a[1], a[2] deallocate(a) end program main
编译与运行命令
- 编译:
gfortran -fcoarray=lib minimal.f90 -lcaf_mpich - 运行:
mpirun.mpich -n 2 ./a.out
环境信息
gfortran 12.2.0、OpenCoarrays 2.10.1搭配MPICH 4.0.2
实际输出
1 1.0000000000000000 1.0000000000000000 2 1.0000000000000000 2.0000000000000000 [1689752680.508753] [thomas-laptop:14602:0] tag_match.c:62 UCX WARN unexpected tag-receive descriptor 0x55b38d7fb8c0 was not matched [1689752680.509388] [thomas-laptop:14601:0] tag_match.c:62 UCX WARN unexpected tag-receive descriptor 0x564edbce58c0 was not matched
解答
一、Fortran Coarray写入的可见性规则
- 本地镜像对自身coarray分量的写入(如代码中
a = this_image(),等价于a[this_image()] = this_image()),本地镜像立即可见,但不会自动同步到其他镜像。 - 要让其他镜像看到该写入结果,必须通过同步操作确保内存可见性:
sync all:所有镜像到达该同步点后,所有镜像之前对coarray的写入操作,对其他所有镜像可见。sync images([image_list]):仅同步指定镜像集合,确保这些镜像之间的coarray写入可见。- 原子操作(如
atomic_add):执行原子操作时会自动同步对应coarray分量的可见性。
二、输出不符合预期的原因
你的代码逻辑完全符合Fortran标准,但实际输出异常伴随UCX警告,大概率是OpenCoarrays与MPICH/UCX的兼容性问题,或是gfortran 12.2.0在coarray实现上的bug:
- 镜像1读取
a[2]时未获取到镜像2写入的2.0,反而读到了自身a[1]的1.0,说明跨镜像的coarray数据读取未正确完成。 - UCX的警告提示未匹配到接收描述符,表明底层通信层在同步coarray数据时出现异常,导致镜像1未能正确接收镜像2的coarray数据。
三、解决建议
- 升级OpenCoarrays到最新版本(当前2.10.1版本较旧,新版本已修复大量通信相关bug)。
- 更换通信后端:比如改用OpenMPI替代MPICH,或通过环境变量
MPICH_OFI_PROVIDER=verbs让MPICH使用verbs而非UCX通信。 - 测试简化逻辑:尝试用
sync images([1,2])替代sync all,或在同步后增加显式的coarray读写验证。
内容的提问来源于stack exchange,提问作者asdfldsfdfjjf
相关产品推荐
相关产品推荐

