Fortran Coder

标题: 并行收集不同长度的数据 [打印本页]

作者: Kieran    时间: 2019-12-20 05:31
标题: 并行收集不同长度的数据

大家好,


我想向大家请教一个利用FORTRAN写的并行程序的问题。


我的程序有两个文件,一个是主程序(main.f90),用于分配各个数据和调用各种子程序;另一个是附属程序(cal.f90),用于存储各种子程序。我把我的程序传到附件中了。


我想请教的是我在主程序(main.f90279行)中打开了一个文件(fermi_Surface.dat),然后将km(2)个数组分配给各个CPU做计算,每个数组都分别是一个有km(1)行,3列的二维数组。每个CPU利用附属程序(cal.f90292行)中的程序去做判断,如果该CPU接收到的维数组中的某一个元素对应的本征值(evg(i,j))符合条件(fermi-wfe ≤evg(i,j)≤fermi+wfe),就将这个元素写入fermi_Surface.dat文件中(cal.f90295行);否则就不写。这样一来,会出现两个问题。


第一,因为每个CPU接收到的数组中符合条件的元素个数未必相同,进而每个CPU写入fermi_Surface.dat文件的元素个数也不一定相同

第二,因为每个CPU分别各自都在fermi_Surface.dat文件里写入数据,所以后写数据到这个文件里的CPU会把之前所有其它CPU写到这个文件里的数据抹除掉。而我想把所有的CPU写入到这个文件里的数据都保留下来。

这两个问题,我不知道要如何解决。我有查到MPI_GATHERV命令可以从不同进程接收不同长度的数据,如果能用这个命令的话,可以把每个CPU判断后,符合条件的数据都收集到跟进程里,好像可以解决问题;但这个命令要求告知每个CPU会分别传递多少个数据到跟进程里。这个信息我事先是不知道的。所以不知道要如何使用这个命令。


我想麻烦大家给些建议,要如何解决这个问题呢?多谢大家啦。

cal.f90

11.57 KB, 下载次数: 1

附属程序

main.f90

15.76 KB, 下载次数: 1

主程序


作者: li913    时间: 2019-12-20 13:22
最简单的,每个进程写入结果到不同文件,最后让根进程把这些文件合成一个。
作者: Kieran    时间: 2019-12-21 00:40
li913 发表于 2019-12-20 13:22
最简单的,每个进程写入结果到不同文件,最后让根进程把这些文件合成一个。 ...

非常感谢你的回复。

是这样的,我的主程序(main.f90)里的数组的个数,也就是km(2)的值会达到1024。就是说主程序会调用1024回不同的CPU。每一回,不同的CPU都会在附属程序(cal.f90)中产生一个文件,当计算结束后,总共会产生1024个文件。想想满屏幕的文件,我感觉这实在太耗占空间了,当然,我不是指硬盘容量,我是指看起来上千个文件堆砌在那里,实在不太雅观。

请问有没有其它好些的方式把所有CPU写入的数据都保存在fermi_surface.dat文件中呢?谢谢啦。
作者: li913    时间: 2019-12-21 12:25
mpi提供写文件的操作,应该可以实现你的预期,但我没用过。你可以建立一个文件夹来存放1024个文件,最后把这个文件夹删除就是。
作者: Kieran    时间: 2019-12-22 11:49
li913 发表于 2019-12-21 12:25
mpi提供写文件的操作,应该可以实现你的预期,但我没用过。你可以建立一个文件夹来存放1024个文件,最后把 ...

谢谢你的建议。

我刚刚有想了下,是不是可以先使用MPI_GATHER命令,把每个CPU判断得到的,符合条件的数据的个数收集到根CPU上,再在根CPU上建立一个一维数组,长度是1024,每个元素的值就是从各个CPU上收集来的符合条件的数据的个数。然后再次使用MPI,这次使用MPI_GATHERV命令,根据这个一维数组里每个元素的值,分别从每个CPU上收集符合条件的不同数量的数据。

可是,我有一点不确定。先后两次使用MPI,每次使用时各个CPU的传递信息给根CPU的顺序是否会一致。因为只有一致,才能保证一维数组中每个元素都对第一次使用MPI时,每个CPU判断得到的符合条件的数据的个数。

这一点,我不是很确定。你觉得是否可行呢?谢谢。
作者: li913    时间: 2019-12-23 11:24
顺序不保证一致,但你可以根据进程号判断。
作者: necrohan    时间: 2019-12-23 16:59
本帖最后由 necrohan 于 2019-12-23 17:31 编辑

我很久没用mpi了,但是我印象中mpi计算是需要单独建立目录,所有需要的文件都要复制一份,最后有后处理程序整合数据和文件,怎么会同时读写一个文件?

如果是多个进程同时处理一个文件,我想到一个方法,就是用recl记录号的方式修改文件,指定读写的位置,但是打开文件时需要用共享方式打开,防止不同进程冲突。






欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2