我在某种程度上本着 MPI I/O 的精神,从https://github.com/LadaF/PoisFFT/blob/master/src/testmpi.f90(在最后)对一个简单的 MPI-IO 子程序进行了现代化改造,混合单一- 和多进程输出。我的意图是在一个更重要的程序中使用这个过程。save_vtk()
我到达了这段代码,它产生了正确的输出(删除了错误检查):
这只做了一次,对性能来说是微不足道的:
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()
介于两者之间的,因此立即为标头和数组块的根进程设置视图,然后让根进程同时写入标头和数组块到视图中。
那可能吗?