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
Types Fortran 90中具有派生数据类型的MPI。广播故障_Types_Fortran_Mpi - Fatal编程技术网

Types Fortran 90中具有派生数据类型的MPI。广播故障

Types Fortran 90中具有派生数据类型的MPI。广播故障,types,fortran,mpi,Types,Fortran,Mpi,一段时间以来,我一直在使用使用模块、派生数据类型和MPI的Fortran 90代码 我的问题是,在广播派生数据类型之后,只有主节点的变量具有正确的值,所有其他节点上的变量不包含它们应该包含的值。我从更大的代码中提取了一个最小的示例。它包含主程序: 输出包含两个print语句,其中第一个语句只打印proc_id(工作正常),第二个语句打印出相应节点上的变量(这就是我遇到的问题,只有主节点上的值正常)。变量通过主节点上的读入来实现 此外,还有一个定义类型的模块: 正如我所说的,我从一个更大的

一段时间以来,我一直在使用使用模块、派生数据类型和MPI的Fortran 90代码

我的问题是,在广播派生数据类型之后,只有主节点的变量具有正确的值,所有其他节点上的变量不包含它们应该包含的值。我从更大的代码中提取了一个最小的示例。它包含主程序:



输出包含两个print语句,其中第一个语句只打印proc_id(工作正常),第二个语句打印出相应节点上的变量(这就是我遇到的问题,只有主节点上的值正常)。变量通过主节点上的读入来实现

此外,还有一个定义类型的模块:



正如我所说的,我从一个更大的代码中提取了这个模块,所以这个模块可能看起来没用,但在原始代码中是有意义的

第三个模块包含一个子例程,用于计算导出数据类型广播的位移。。。。。 我从开始就遵循了Fortran的MPI用户指南




对于安装:该代码旨在在CentOs6下的ETH Brutus群集上运行,该群集使用英特尔fortran编译。但是,我们在一些出现相同问题的机器上进行了测试,因此我认为这不是版本问题。

这不是版本问题。简而言之,MPI不喜欢具有可分配数组的类型。这是一样的。它与指针和虚拟内存地址有关,引用的答案向您展示了如果您真的需要如何做。然而,如果可能的话,我会用下面概述的方法2

有两种可能的方法可以做到这一点。 1) 在
type\u hello\u world中创建固定长度数组

type circle_
   real :: straal(100)
   real :: diameter(100)
end type circle_
include 'hello_types.f90'
include 'mpi_circle.f90'

program hello_world

use mpi
use type_hello_world
use create_mpi_types

implicit none

integer                    :: ierr, num_procs, my_id, mpi_circle_t
type(circle_), allocatable :: circles(:)

call MPI_Init(ierr)

!find out MY process ID, and how many processes were started.

call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr)
call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr)

allocate(circles(num_procs))

if (my_id==0) then
    !print*,'enter straal and diameter'
    !read*,circle%diameter(1),circle%straal(1)
    circles(:)%diameter = 10.0
    circles(:)%straal = 2.0
endif

call build_derived_circle(mpi_circle_t)

call MPI_BCAST(circles,num_procs,mpi_circle_t,0,MPI_COMM_WORLD,ierr)

print *, "Hello world! I'm process ", my_id, " out of", num_procs, " processes."
print*,my_id,circles(my_id+1)%diameter,circles(my_id+1)%straal

call MPI_TYPE_FREE(mpi_circle_t, ierr)
deallocate(circles)

call MPI_Finalize(ierr)
2) 创建一种只有一个元素的
,然后创建一个圆数组

type circle_
   real :: straal
   real :: diameter
end type circle_
我喜欢第二种方法。还要注意,位移应为MPI_地址类型。因此,您的代码将更改为
create\u mpi\u types

module create_mpi_types

contains

subroutine build_derived_circle(mesg_mpi_circle)

use type_hello_world
use mpi

implicit none


! local
type(circle_)                  :: circle
integer,parameter              :: number=2
integer                        :: ierr, i
integer                        :: block_lengths(number)
integer(kind=MPI_ADDRESS_KIND) :: displacements(number)
integer                        :: typelist(number)
real                           :: r

!output
integer,intent(out) :: mesg_mpi_circle

!----------------------------------------

do i = 0, number
    typelist(i) = MPI_REAL
    block_lengths(i) = 1
    displacements(i) = i * sizeof(r)
enddo
! build the derived data type
call MPI_Type_create_struct(number,block_lengths,displacements,&
                typelist,mesg_mpi_circle,ierr)
if (ierr /= 0 ) then
    print *, 'got an error in type create: ', ierr
    call MPI_Abort(MPI_COMM_WORLD, ierr, ierr)
endif

! commit it to the system, so it knows we ll use it
! for communication
call MPI_TYPE_COMMIT(mesg_mpi_circle,ierr)
if (ierr /= 0 ) then
    print *, 'got an error in type commit: ', ierr
    call MPI_Abort(MPI_COMM_WORLD, ierr, ierr)
endif

return

end subroutine build_derived_circle

!------------- END SUBROUTINE----------------------------
end module create_mpi_types
然后在
hello\u world

type circle_
   real :: straal(100)
   real :: diameter(100)
end type circle_
include 'hello_types.f90'
include 'mpi_circle.f90'

program hello_world

use mpi
use type_hello_world
use create_mpi_types

implicit none

integer                    :: ierr, num_procs, my_id, mpi_circle_t
type(circle_), allocatable :: circles(:)

call MPI_Init(ierr)

!find out MY process ID, and how many processes were started.

call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr)
call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr)

allocate(circles(num_procs))

if (my_id==0) then
    !print*,'enter straal and diameter'
    !read*,circle%diameter(1),circle%straal(1)
    circles(:)%diameter = 10.0
    circles(:)%straal = 2.0
endif

call build_derived_circle(mpi_circle_t)

call MPI_BCAST(circles,num_procs,mpi_circle_t,0,MPI_COMM_WORLD,ierr)

print *, "Hello world! I'm process ", my_id, " out of", num_procs, " processes."
print*,my_id,circles(my_id+1)%diameter,circles(my_id+1)%straal

call MPI_TYPE_FREE(mpi_circle_t, ierr)
deallocate(circles)

call MPI_Finalize(ierr)
提示:不要
包含“mpif.h”
,而是
使用mpi
。它可以帮助你找到一些bug。
include 'hello_types.f90'
include 'mpi_circle.f90'

program hello_world

use mpi
use type_hello_world
use create_mpi_types

implicit none

integer                    :: ierr, num_procs, my_id, mpi_circle_t
type(circle_), allocatable :: circles(:)

call MPI_Init(ierr)

!find out MY process ID, and how many processes were started.

call MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr)
call MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr)

allocate(circles(num_procs))

if (my_id==0) then
    !print*,'enter straal and diameter'
    !read*,circle%diameter(1),circle%straal(1)
    circles(:)%diameter = 10.0
    circles(:)%straal = 2.0
endif

call build_derived_circle(mpi_circle_t)

call MPI_BCAST(circles,num_procs,mpi_circle_t,0,MPI_COMM_WORLD,ierr)

print *, "Hello world! I'm process ", my_id, " out of", num_procs, " processes."
print*,my_id,circles(my_id+1)%diameter,circles(my_id+1)%straal

call MPI_TYPE_FREE(mpi_circle_t, ierr)
deallocate(circles)

call MPI_Finalize(ierr)