Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran MPI_Recv会覆盖它不应该访问的部分内存_Fortran_Mpi - Fatal编程技术网

Fortran MPI_Recv会覆盖它不应该访问的部分内存

Fortran MPI_Recv会覆盖它不应该访问的部分内存,fortran,mpi,Fortran,Mpi,在下面的代码中,xysize的值会发生更改,如果我没有将其声明为参数(通常我不能这样做)。只有在gfortran 4.7.2和OpenMPI 1.6中进行了O2等优化后,才会出现这种情况。怎么可能呢?我找不到从mpi.mod导入的确切接口,但C原型明确指出,count是按值传递的,因此它不能更改 write(*,*) im,"receiving from",image_index([iim,jim,kim+1]),"size",& size(D%A(D%starti

在下面的代码中,
xysize
的值会发生更改,如果我没有将其声明为参数(通常我不能这样做)。只有在gfortran 4.7.2和OpenMPI 1.6中进行了O2等优化后,才会出现这种情况。怎么可能呢?我找不到从
mpi.mod
导入的确切接口,但C原型明确指出,
count
是按值传递的,因此它不能更改

     write(*,*) im,"receiving from",image_index([iim,jim,kim+1]),"size",&
      size(D%A(D%starti:D%endi,D%startj:D%endj,D%endk)),xysize

    call MPI_RECV(D%A(D%starti:D%endi,D%startj:D%endj,D%endk+1),xysize , MPI_REAL, image_index([iim,jim,kim+1])-1,&
           5000, comm, status, ierr)

    write(*,*) im,"received size",&
      size(D%A(D%starti:D%endi,D%startj:D%endj,D%endk)),xysize
输出:

1 receiving from           2 size        4096        4096
1 received size        4096        5000

为了将来的访客,我想我会回答这个问题,尽管上面的评论中已经给出了答案

据我所知,如果程序运行正常,则不能在调用
MPI\u Recv
时更改该参数(“count”)的值


您的参数
status
太小,它应该是一个数组
status(MPI\u status\u SIZE)
,并且您会遇到缓冲区溢出——这通常会导致分段错误,但有时(取决于编译器如何在内存中打包变量),这可能会导致像这样有趣的行为。

为了未来的访问者,我想我会回答这个问题,尽管上面的评论中已经给出了答案

据我所知,如果程序运行正常,则不能在调用
MPI\u Recv
时更改该参数(“count”)的值


您的参数
status
太小,它应该是一个数组
status(MPI\u status\u SIZE)
,并且您会遇到缓冲区溢出——这通常会导致分段错误,但有时(取决于编译器如何在内存中打包变量),它会导致类似这样的有趣行为。

出于好奇,从
mpi\u get\u count(状态、mpi\u REAL、n、ierr)中可以得到什么;print*,n
——我真的很想知道是否缓冲区溢出导致了有趣的行为……感谢您的建议!问题显然出在status中的声明中,它是一个普通的标量整数。我不知道为什么它是在
MPI\u Recv
中编译的,因为
MPI\u Get\u count
的接口检查捕捉到了这一点。我很高兴它抓住了它
MPI_Recv
可以将接口声明为
integer status(*)
,以便它可以接受标量或数组。这样,
MPI\u STATUS\u IGNORE
就可以是一个标量。。。似乎
MPI\u STATUS\u SIZE
足够小,这无关紧要,但是,我想这个库正在努力提高内存效率或者其他什么<另一方面,code>MPI\u Get\u count不能接受
MPI\u STATUS\u IGNORE
。@mgilson,
MPI\u RECV
(以及任何其他将用户数据缓冲区作为参数的例程)可以将无数不同的数据类型作为其第一个参数,因此在模块接口中几乎不存在。为了生成这些例程的接口,必须编译带有特殊标志的openmpi。然后,它需要花费很长的时间来编译,并且只涉及可能的类型的一个相对较小的子集。MPI 3.0中提供了一个临时解决方案-定义了新的F2008绑定,它们使用F2008的
类型(*)、维度(…)
功能。另外,F2008的另一个功能,
异步
用于非阻塞调用的新MPI 3.0接口,如
MPI Isend
。这意味着在palce中使用完全兼容F2008的编译器,可以安全地将数组子部分传递给非阻塞调用;print*,n——我真的很想知道是否缓冲区溢出导致了有趣的行为……感谢您的建议!问题显然出在status中的声明中,它是一个普通的标量整数。我不知道为什么它是在
MPI\u Recv
中编译的,因为
MPI\u Get\u count
的接口检查捕捉到了这一点。我很高兴它抓住了它
MPI_Recv
可以将接口声明为
integer status(*)
,以便它可以接受标量或数组。这样,
MPI\u STATUS\u IGNORE
就可以是一个标量。。。似乎
MPI\u STATUS\u SIZE
足够小,这无关紧要,但是,我想这个库正在努力提高内存效率或者其他什么<另一方面,code>MPI\u Get\u count不能接受
MPI\u STATUS\u IGNORE
。@mgilson,
MPI\u RECV
(以及任何其他将用户数据缓冲区作为参数的例程)可以将无数不同的数据类型作为其第一个参数,因此在模块接口中几乎不存在。为了生成这些例程的接口,必须编译带有特殊标志的openmpi。然后,它需要花费很长的时间来编译,并且只涉及可能的类型的一个相对较小的子集。MPI 3.0中提供了一个临时解决方案-定义了新的F2008绑定,它们使用F2008的
类型(*)、维度(…)
功能。另外,F2008的另一个功能,
异步
用于非阻塞调用的新MPI 3.0接口,如
MPI Isend
。这意味着在palce中使用完全兼容F2008的编译器,可以安全地将数组子部分传递给非阻塞调用。这通常发生在堆栈变量用作调用参数且使用中的指针未被覆盖/损坏时(调用函数堆栈帧中的返回地址就是这样的指针).@HristoIliev——很明显,你没有使用过我的一些代码;-)。旧的f77风格的内存管理,其中所有内容都是
等价的
d,在一个大数组中,当传递给子例程时,该数组将被分区…:)嘿,现在是2012年,我们像GCC一样。。。和cookies:)这通常发生在堆栈变量用作调用参数并且使用中的指针未被覆盖/损坏(返回值)时