MPI_IO write_all 子数组和组件编号
The MPI_IO write_all subarray and the component number
我正在尝试使用 MPI_SET_VIEW 和 MPI_WRITE_ALL 编写一个 4 * 4 数组。 xx 是一个 4 * 4 数组,我希望此代码的 xx = (0,1,2,3; 0,1,2,3; 0,1,2,3; 0,1,2,3) 。 globle_size 和 local_size 等于 4 和 2。我首先创建一个子数组 2 * 2 文件类型,以便我将这个 4 * 4 数组分成 4 个部分,即 2 * 2。然后我设置此文件类型的视图,并写入 xx.结果应等于 (0,1,2,3; 0,1,2,3; 0,1,2,3; 0,1,2,3),但事实并非如此。结果有的是对的,有的是错的。
1 当我执行 j=ls2,le2, i = ls1,le1, xx(i,j)=i 时,数组 xx() 是 4*4 数组还是 2*2 数组? ls1=ls2=0,le1=le2=1.
2 对于MPI_WRITE_ALL,我应该使用4 * 4 数组还是2 * 2 数组?我应该计算什么?1 或 4?
3 对于 MPI_WRITE_ALL,我应该使用文件类型作为类型样式吗?
integer::filesize,buffsize,i,Status(MPI_STATUS_SIZE),charsize,disp,filetype,j,count
integer::nproc,cart_comm,ierr,fh,datatype
INTEGER(KIND=MPI_OFFSET_KIND) offset
integer,dimension(dim):: sizes,inersizes,start,sb,ss
character:: name*50,para*100,zone*100
do j=local_start(2),local_end(2)
do i=local_start(1),local_end(1)
xx(i,j)=i
enddo
enddo
count=1
offset=0
start=cart_coords*local_length
call MPI_TYPE_CREATE_SUBARRAY(2,global_length,local_length,start,MPI_ORDER_FORTRAN,&
MPI_integer,filetype,ierr)
call MPI_TYPE_COMMIT(filetype,ierr)
call MPI_File_open(MPI_COMM_WORLD,'out.dat', &
MPI_MODE_WRONLY + MPI_MODE_CREATE,MPI_INFO_NULL,fh,ierr)
call MPI_File_set_view(fh,offset,MPI_integer,filetype,&
"native",MPI_INFO_NULL,ierr)
CALL MPI_FILE_WRITE(fh, xx,1, filetype, MPI_STATUS_ignore, ierr)
下面是我认为可以满足您要求的代码。它基于您昨天发布然后删除的内容 - 请不要这样做,而是编辑问题以改进它。我还更改为使用 6x4 全局大小和 3x2 进程网格,因为矩形网格更有可能捕获错误。
总之回答你的问题
1 - 你只在本地存储了数组的一部分,所以数组只需要声明为 (1:2,1:2) - 这几乎就是分布式内存编程的重点,每个进程只持有整个数据结构的一部分
2 - 您在本地只有一个 2x2 数组,因此它应该是一个 2x2 数组,其中包含要在本地存储的任何数据。你正在写一个整数数组,所以我认为说你正在写 4 个整数是最简单的
3 - 见上文 - 您正在编写一个整数数组,所以我认为最简单的说法是您正在编写 4 个整数。文件类型(根据我的经验)仅用于调用 MPI_File_set_view
以通过文件类型参数描述文件中数据的布局。当你实际写入数据时,只需告诉 mpi_file_write
和朋友你在写什么
ijb@ijb-Latitude-5410:~/work/stack$ mpif90 --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ijb-Latitude-5410:~/work/stack$ mpif90 --showme:version
mpif90: Open MPI 4.0.3 (Language: Fortran)
ijb@ijb-Latitude-5410:~/work/stack$ cat mpiio.f90
Program test
Use mpi
Implicit None
Integer::rank,nproc,ierr,filetype,cart_comm
Integer::fh
Integer(kind=mpi_offset_kind):: offset=0
Integer,Dimension(2,2)::buff
Integer::gsize(2)
Integer::start(2)
Integer::subsize(2)
Integer::coords(2)
Integer:: nprocs_cart(2)=(/3,2/)
Integer :: i, j
Logical::periods(2)
Character( Len = * ), Parameter :: filename = 'out.dat'
gsize= [ 6,4 ]
subsize= [ 2,2 ]
periods = [ .False., .False. ]
offset=0
Call MPI_init(ierr)
Call MPI_COMM_SIZE(MPI_COMM_WORLD, nproc, ierr)
Call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
Call MPI_Dims_create(nproc, 2, nprocs_cart, ierr)
Call MPI_Cart_create(MPI_COMM_WORLD, 2, nprocs_cart, periods, .True., &
cart_comm, ierr)
Call MPI_Comm_rank(cart_comm, rank, ierr)
Call MPI_Cart_coords(cart_comm, rank, 2, coords, ierr)
start=coords * subsize
Do j = 1, 2
Do i = 1, 2
buff( i, j ) = ( start( 1 ) + ( i - 1 ) ) + &
( start( 2 ) + ( j - 1 ) ) * gsize( 1 )
End Do
End Do
Call MPI_TYPE_CREATE_SUBARRAY(2,gsize,subsize,start,MPI_ORDER_FORTRAN,&
MPI_integer,filetype,ierr)
Call MPI_TYPE_COMMIT(filetype,ierr)
! For testing make sure we have a fresh file every time
! so don't get confused by looking at the old version
If( rank == 0 ) Then
Call mpi_file_delete( filename, MPI_INFO_NULL, ierr )
End If
Call mpi_barrier( mpi_comm_world, ierr )
! Open in exclusive mode making sure the delete has occurred
Call MPI_File_open(MPI_COMM_WORLD,filename,&
MPI_MODE_WRONLY + MPI_MODE_CREATE + MPI_MODE_EXCL, MPI_INFO_NULL, fh,ierr)
Call MPI_File_set_view(fh,offset,MPI_integer,filetype,&
"native",MPI_INFO_NULL,ierr)
Call MPI_FILE_WRITE_all(fh, buff, 4, mpi_integer, MPI_STATUS_ignore, ierr)
Call MPI_File_close(fh,ierr)
Call MPI_FINALIZE(ierr)
End Program test
ijb@ijb-Latitude-5410:~/work/stack$ mpif90 -Wall -Wextra -fcheck=all -O -g -std=f2008 -fcheck=all mpiio.f90
ijb@ijb-Latitude-5410:~/work/stack$ mpirun --oversubscribe -np 6 ./a.out
ijb@ijb-Latitude-5410:~/work/stack$ od -v -Ad -t d4 out.dat
0000000 0 1 2 3
0000016 4 5 6 7
0000032 8 9 10 11
0000048 12 13 14 15
0000064 16 17 18 19
0000080 20 21 22 23
0000096
我正在尝试使用 MPI_SET_VIEW 和 MPI_WRITE_ALL 编写一个 4 * 4 数组。 xx 是一个 4 * 4 数组,我希望此代码的 xx = (0,1,2,3; 0,1,2,3; 0,1,2,3; 0,1,2,3) 。 globle_size 和 local_size 等于 4 和 2。我首先创建一个子数组 2 * 2 文件类型,以便我将这个 4 * 4 数组分成 4 个部分,即 2 * 2。然后我设置此文件类型的视图,并写入 xx.结果应等于 (0,1,2,3; 0,1,2,3; 0,1,2,3; 0,1,2,3),但事实并非如此。结果有的是对的,有的是错的。
1 当我执行 j=ls2,le2, i = ls1,le1, xx(i,j)=i 时,数组 xx() 是 4*4 数组还是 2*2 数组? ls1=ls2=0,le1=le2=1.
2 对于MPI_WRITE_ALL,我应该使用4 * 4 数组还是2 * 2 数组?我应该计算什么?1 或 4?
3 对于 MPI_WRITE_ALL,我应该使用文件类型作为类型样式吗?
integer::filesize,buffsize,i,Status(MPI_STATUS_SIZE),charsize,disp,filetype,j,count
integer::nproc,cart_comm,ierr,fh,datatype
INTEGER(KIND=MPI_OFFSET_KIND) offset
integer,dimension(dim):: sizes,inersizes,start,sb,ss
character:: name*50,para*100,zone*100
do j=local_start(2),local_end(2)
do i=local_start(1),local_end(1)
xx(i,j)=i
enddo
enddo
count=1
offset=0
start=cart_coords*local_length
call MPI_TYPE_CREATE_SUBARRAY(2,global_length,local_length,start,MPI_ORDER_FORTRAN,&
MPI_integer,filetype,ierr)
call MPI_TYPE_COMMIT(filetype,ierr)
call MPI_File_open(MPI_COMM_WORLD,'out.dat', &
MPI_MODE_WRONLY + MPI_MODE_CREATE,MPI_INFO_NULL,fh,ierr)
call MPI_File_set_view(fh,offset,MPI_integer,filetype,&
"native",MPI_INFO_NULL,ierr)
CALL MPI_FILE_WRITE(fh, xx,1, filetype, MPI_STATUS_ignore, ierr)
下面是我认为可以满足您要求的代码。它基于您昨天发布然后删除的内容 - 请不要这样做,而是编辑问题以改进它。我还更改为使用 6x4 全局大小和 3x2 进程网格,因为矩形网格更有可能捕获错误。
总之回答你的问题
1 - 你只在本地存储了数组的一部分,所以数组只需要声明为 (1:2,1:2) - 这几乎就是分布式内存编程的重点,每个进程只持有整个数据结构的一部分
2 - 您在本地只有一个 2x2 数组,因此它应该是一个 2x2 数组,其中包含要在本地存储的任何数据。你正在写一个整数数组,所以我认为说你正在写 4 个整数是最简单的
3 - 见上文 - 您正在编写一个整数数组,所以我认为最简单的说法是您正在编写 4 个整数。文件类型(根据我的经验)仅用于调用 MPI_File_set_view
以通过文件类型参数描述文件中数据的布局。当你实际写入数据时,只需告诉 mpi_file_write
和朋友你在写什么
ijb@ijb-Latitude-5410:~/work/stack$ mpif90 --version
GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ijb@ijb-Latitude-5410:~/work/stack$ mpif90 --showme:version
mpif90: Open MPI 4.0.3 (Language: Fortran)
ijb@ijb-Latitude-5410:~/work/stack$ cat mpiio.f90
Program test
Use mpi
Implicit None
Integer::rank,nproc,ierr,filetype,cart_comm
Integer::fh
Integer(kind=mpi_offset_kind):: offset=0
Integer,Dimension(2,2)::buff
Integer::gsize(2)
Integer::start(2)
Integer::subsize(2)
Integer::coords(2)
Integer:: nprocs_cart(2)=(/3,2/)
Integer :: i, j
Logical::periods(2)
Character( Len = * ), Parameter :: filename = 'out.dat'
gsize= [ 6,4 ]
subsize= [ 2,2 ]
periods = [ .False., .False. ]
offset=0
Call MPI_init(ierr)
Call MPI_COMM_SIZE(MPI_COMM_WORLD, nproc, ierr)
Call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
Call MPI_Dims_create(nproc, 2, nprocs_cart, ierr)
Call MPI_Cart_create(MPI_COMM_WORLD, 2, nprocs_cart, periods, .True., &
cart_comm, ierr)
Call MPI_Comm_rank(cart_comm, rank, ierr)
Call MPI_Cart_coords(cart_comm, rank, 2, coords, ierr)
start=coords * subsize
Do j = 1, 2
Do i = 1, 2
buff( i, j ) = ( start( 1 ) + ( i - 1 ) ) + &
( start( 2 ) + ( j - 1 ) ) * gsize( 1 )
End Do
End Do
Call MPI_TYPE_CREATE_SUBARRAY(2,gsize,subsize,start,MPI_ORDER_FORTRAN,&
MPI_integer,filetype,ierr)
Call MPI_TYPE_COMMIT(filetype,ierr)
! For testing make sure we have a fresh file every time
! so don't get confused by looking at the old version
If( rank == 0 ) Then
Call mpi_file_delete( filename, MPI_INFO_NULL, ierr )
End If
Call mpi_barrier( mpi_comm_world, ierr )
! Open in exclusive mode making sure the delete has occurred
Call MPI_File_open(MPI_COMM_WORLD,filename,&
MPI_MODE_WRONLY + MPI_MODE_CREATE + MPI_MODE_EXCL, MPI_INFO_NULL, fh,ierr)
Call MPI_File_set_view(fh,offset,MPI_integer,filetype,&
"native",MPI_INFO_NULL,ierr)
Call MPI_FILE_WRITE_all(fh, buff, 4, mpi_integer, MPI_STATUS_ignore, ierr)
Call MPI_File_close(fh,ierr)
Call MPI_FINALIZE(ierr)
End Program test
ijb@ijb-Latitude-5410:~/work/stack$ mpif90 -Wall -Wextra -fcheck=all -O -g -std=f2008 -fcheck=all mpiio.f90
ijb@ijb-Latitude-5410:~/work/stack$ mpirun --oversubscribe -np 6 ./a.out
ijb@ijb-Latitude-5410:~/work/stack$ od -v -Ad -t d4 out.dat
0000000 0 1 2 3
0000016 4 5 6 7
0000032 8 9 10 11
0000048 12 13 14 15
0000064 16 17 18 19
0000080 20 21 22 23
0000096