Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
Mpi 在发送和接收过程中,何时使用不同的计数或类型?_Mpi - Fatal编程技术网

Mpi 在发送和接收过程中,何时使用不同的计数或类型?

Mpi 在发送和接收过程中,何时使用不同的计数或类型?,mpi,Mpi,MPI中描述发送和接收的许多例程(MPI_Sendrecv、MPI_Scatter等)都有用于发送和接收的计数和类型的参数。例如,在Fortran中,MPI_散点的签名为: MPI_SCATTER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR) 如果发送的数据量必须与接收的数据量相同,为什么两者都需要?这不就是引入了不一致的可能性吗 需要不同计数/类型的用例

MPI中描述发送和接收的许多例程(MPI_Sendrecv、MPI_Scatter等)都有用于发送和接收的计数和类型的参数。例如,在Fortran中,MPI_散点的签名为:

MPI_SCATTER(SENDBUF, SENDCOUNT, SENDTYPE, 
            RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR)
如果发送的数据量必须与接收的数据量相同,为什么两者都需要?这不就是引入了不一致的可能性吗


需要不同计数/类型的用例是什么?

对于发送方来说,这两个是相同的,但接收方可能不知道接收了多少元素

使用MPI派生类型时,可以将数组视为某些基本数字类型的
n
元素,也可以视为某些MPI派生类型的一个或多个元素。在这种情况下,不仅计数不同,而且数据类型也可能不同,尽管它们对应于相同的缓冲区


另一方面,它不受通信器中进程数的影响。通信器大小始终是隐式的,在调用集合时,您不能在任何地方直接输入它。

MPI要求发送和接收进程在数据类型和数量上达成一致(排序;对于点对点通信,接收器可以请求比发送更多的数据)。但是MPI数据类型也描述了数据在内存中的布局,这是发送方和接收方需要使用不同类型的一个非常常见的原因

你特别询问散射和FORTRAN,让我们看看这个例子。让我们考虑将<代码> size *n>代码>矩阵按行分散到不同的进程

    |---n---|  ---
     0 0 0 0    |
a =  1 1 1 1   size
     2 2 2 2    |
               ---
因此秩0得到
[0 0 0]
,秩1得到
[1 1]
,等等

在Fortran中,这些在内存中不是连续的;因此,要描述一行,必须使用
MPI\u Type\u向量

    call MPI_Type_vector(n, 1, size, MPI_REAL, row_type, ierr)
这描述了n个实数,但它们之间用大小实数分隔

另一方面,如果接收过程只是将数据接收到一维阵列中:

    real, dimension(n) :: b
那么它就不能用这种类型来描述数据
b
没有足够的空间容纳
n
REAL,每个REAL之间的间隙为
大小
!它希望像
n*MPI\u REAL
一样接收数据。如果必须发送数据列,这种不匹配在C中也是一样的

因此,这是以不同方式指定数据类型(以及计数)的常见原因;对于散射器,必须使用数据类型来描述数据,该数据类型包括保存要发送的值的较大数据结构的布局;但是分散ee很可能正在以不同的布局将数据接收到不同的数据结构中

下面是一个简单的示例

program scatterdemo
    use mpi
    implicit none
    real, allocatable, dimension(:,:) :: a
    real, allocatable, dimension(:) :: b
    integer :: ierr, rank, comsize
    integer, parameter :: n=4
    integer :: i
    integer :: row_type, row_type_sized, real_size
    integer(kind=MPI_ADDRESS_KIND) :: lb=0, extent

    call MPI_Init(ierr)
    call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
    call MPI_Comm_size(MPI_COMM_WORLD, comsize, ierr)

    if (rank == 0) then
        allocate( a(comsize, n) )
        do i=1,comsize
            a(i,:) = i-1
        enddo
    endif

    allocate( b(n) )

    call MPI_Type_size(MPI_REAL, real_size, ierr)

    call MPI_Type_vector(n, 1, comsize, MPI_REAL, row_type, ierr)
    extent = real_size*1
    call MPI_Type_create_resized(row_type, lb, extent, row_type_sized, ierr)
    call MPI_Type_commit(row_type_sized, ierr)

    call MPI_Scatter(a, 1, row_type_sized, b, n, MPI_REAL, 0, MPI_COMM_WORLD, ierr)

    print *, rank, b

    if (rank == 0) deallocate (a)
    deallocate(b)

    call MPI_Finalize(ierr)

end program scatterdemo
用六个处理器运行它可以

$ mpirun -np 6 ./scatter
           0  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
           3   3.000000       3.000000       3.000000       3.000000
           1   1.000000       1.000000       1.000000       1.000000
           5   5.000000       5.000000       5.000000       5.000000
           2   2.000000       2.000000       2.000000       2.000000
           4   4.000000       4.000000       4.000000       4.000000

@Felix不,绝对不是,它只是把它弄错了C。请参阅,这样的数据类型被调用(也被MPI标准调用)。此外,对于集合,标准要求源发送到给定进程的数据量等于后者愿意接收的数据量。这也是集体不输出
MPI\u状态
对象的原因。