我正在从https://github.com/LadaF/PoisFFT/blob/master/src/testmpi.f90 (最后是save_vtk())更新一个简单的MPI-IO子例程,这多少有点像MPI I/O, mix of single- and multiple-process output的精神。我的目的是在一个更重要的程序中使用这个过程。
我看到了这段代码,它会产生正确的输出(删除错误检查):
这只完成了一次,并且对性能影响不大:
if (master) then
header = ... !the header from the link above in a long string
end if
call MPI_Bcast(header_len, storage_size(header_len)/8, &
MPI_BYTE, 0, glob_comm, ie)
call MPI_Type_create_subarray(3, int(ng), int(nxyz), int(off), &
MPI_ORDER_FORTRAN, MPI_RP, filetype, ie)
call MPI_type_commit(filetype, ie)这样做了很多次:
call MPI_File_open(glob_comm,"out.vtk", &
IOR(IOR(MPI_MODE_CREATE, MPI_MODE_WRONLY), &
MPI_MODE_EXCL), MPI_INFO_NULL, fh, ie)
if (ie/=0) then !should not happen in serious computations
call MPI_Barrier(glob_comm, ie)
if (master) call MPI_File_delete("out.vtk",MPI_INFO_NULL, ie)
call MPI_Barrier(glob_comm, ie)
call MPI_File_open(glob_comm,"out.vtk", &
IOR(MPI_MODE_CREATE, MPI_MODE_WRONLY),&
MPI_INFO_NULL, fh, ie)
end if
call MPI_File_set_view(fh, 0_MPI_OFFSET_KIND, &
MPI_CHARACTER, MPI_CHARACTER, "native", &
MPI_INFO_NULL, ie)
if (master) then
call MPI_File_write(fh, header, header_len, &
MPI_CHARACTER, MPI_STATUS_IGNORE, ie)
end if
call MPI_Barrier(glob_comm, ie)
call MPI_File_set_view(fh, header_len, MPI_RP, &
filetype, "native", MPI_INFO_NULL, ie)
call MPI_File_write_all(fh, buffer, nx*ny*nz, MPI_RP, &
MPI_STATUS_IGNORE, ie)
call MPI_File_close(fh, ie)代码首先测试文件是否已经存在,如果存在,则删除该文件并重新打开。完整的可测试代码位于新的git分支(https://github.com/LadaF/PoisFFT/blob/new_mpi_io/src/testmpi.f90)中。
我想去掉重复的MPI_File_set_view(),或者至少去掉其间的MPI_Barrier(),以便直接为数组的头和块设置根进程的视图,然后让根进程将头和数组块都写入视图中。
这有可能吗?
发布于 2018-04-20 00:42:29
我会让根进程只使用带有'replace‘的fortran streamIO来去掉MPI_File_delete以及多个视图和屏障调用:
if (master) then
open(file="out.vtk", access='stream', status='replace', newunit=out)
write(out) header
close(out)
endif
call MPI_Barrier(...)
call MPI_File_open(...)
call MPI_File_setview(...)
call MPI_File_write_all(...)
call MPI_File_close(...)仍然有一个障碍,但我看不到绕过它的方法。
https://stackoverflow.com/questions/49925937
复制相似问题