Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.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
C++ MPI_Scatterv中的disfs参数是什么?_C++_C_Mpi_Scatterview - Fatal编程技术网

C++ MPI_Scatterv中的disfs参数是什么?

C++ MPI_Scatterv中的disfs参数是什么?,c++,c,mpi,scatterview,C++,C,Mpi,Scatterview,MPI\u Scatterv()函数的disfs参数被称为“整数数组(长度组大小)。条目i指定位移(相对于sendbuf),从该位移将输出数据带到进程i”。 假设我有sendcounts参数 int sendcounts[7] = {3, 3, 3, 3, 4, 4, 4}; 我的推理方式是,disfs数组应该总是以值0开始,因为第一个条目的位移相对于sendbuf是0,所以在我上面的示例中,disfs应该如下所示: int displs[7] = {0, 3, 6, 9, 13, 17, 2

MPI\u Scatterv()
函数的
disfs
参数被称为“整数数组(长度组大小)。条目i指定位移(相对于sendbuf),从该位移将输出数据带到进程i”。 假设我有
sendcounts
参数

int sendcounts[7] = {3, 3, 3, 3, 4, 4, 4};
我的推理方式是,
disfs
数组应该总是以值0开始,因为第一个条目的位移相对于
sendbuf
是0,所以在我上面的示例中,
disfs
应该如下所示:

int displs[7] = {0, 3, 6, 9, 13, 17, 21};

这是正确的吗?我知道这是一个微不足道的问题,但出于某种原因,网络根本没有帮助。没有好的例子,因此我的问题。

是的,你的推理是正确的-对于连续的数据。
MPI\u Scatterv
中的
位移
参数也允许stRIDE数据,意味着块之间的
sendbuf
中存在未使用的内存间隙


以下是一个示例。官方文档实际上包含良好的信息。

是的,置换为根信息提供了关于发送到特定任务的项目的信息-起始项目的偏移量。因此,在大多数简单情况下(例如,您可以使用
MPI\u散点
,但计数不会平均分配)可根据计数信息立即计算:

displs[0] = 0;              // offsets into the global array
for (size_t i=1; i<comsize; i++)
    displs[i] = displs[i-1] + counts[i-1];

我注意到您正在根列组的
global
中输入值。这样做之后,您不需要将
global
广播到所有列组吗?我这样想是因为如果
global
Scatterv
中使用,那么所有列组不都需要知道
global
中的数据吗匹配的数据类型是一致的。一致对我来说听起来很奇怪,但我不是英语母语。@user7331538,
MPI\u Scatterv
的前四个参数仅由根列使用。其余列组在其接收缓冲区中接收数据块,它们不需要访问
global
(它来自于根)。哦,是的,当然这会让你变得衰老。非常感谢!几天前我发布了一个关于散布问题的相关问题,我真的很想得到一些帮助和评论。如果你有时间的话,如果你能看看@hristoilev,我将不胜感激。给你
displs[0] = globalsize - counts[0];                 
for (size_t i=1; i<comsize; i++)
    displs[i] = displs[i-1] - counts[i];
#include <iostream>
#include <vector>
#include "mpi.h"

int main(int argc, char **argv) {
    const int root = 0;             // the processor with the initial global data

    size_t globalsize;
    std::vector<char> global;       // only root has this

    const size_t localsize = 2;     // most ranks will have 2 items; one will have localsize+1
    char local[localsize+2];        // everyone has this
    int  mynum;                     // how many items 

    MPI_Init(&argc, &argv); 

    int comrank, comsize;
    MPI_Comm_rank(MPI_COMM_WORLD, &comrank);
    MPI_Comm_size(MPI_COMM_WORLD, &comsize);

    // initialize global vector
    if (comrank == root) {
        globalsize = comsize*localsize + 1;
        for (size_t i=0; i<globalsize; i++) 
            global.push_back('a'+i);
    }

    // initialize local
    for (size_t i=0; i<localsize+1; i++) 
        local[i] = '-';
    local[localsize+1] = '\0';

    int counts[comsize];        // how many pieces of data everyone has
    for (size_t i=0; i<comsize; i++)
        counts[i] = localsize;
    counts[comsize-1]++;

    mynum = counts[comrank];
    int displs[comsize];

    if (comrank == 0) 
        std::cout << "In forward order" << std::endl;

    displs[0] = 0;              // offsets into the global array
    for (size_t i=1; i<comsize; i++)
        displs[i] = displs[i-1] + counts[i-1];

    MPI_Scatterv(global.data(), counts, displs, MPI_CHAR, // For root: proc i gets counts[i] MPI_CHARAs from displs[i] 
                 local, mynum, MPI_CHAR,                  // I'm receiving mynum MPI_CHARs into local */
                 root, MPI_COMM_WORLD);                   // Task (root, MPI_COMM_WORLD) is the root

    local[mynum] = '\0';
    std::cout << comrank << " " << local << std::endl;

    std::cout.flush();
    if (comrank == 0) 
        std::cout << "In reverse order" << std::endl;

    displs[0] = globalsize - counts[0];                 
    for (size_t i=1; i<comsize; i++)
        displs[i] = displs[i-1] - counts[i];

    MPI_Scatterv(global.data(), counts, displs, MPI_CHAR, // For root: proc i gets counts[i] MPI_CHARAs from displs[i] 
                 local, mynum, MPI_CHAR,                  // I'm receiving mynum MPI_CHARs into local */
                 root, MPI_COMM_WORLD);                   // Task (root, MPI_COMM_WORLD) is the root

    local[mynum] = '\0';
    std::cout << comrank << " " << local << std::endl;

    MPI_Finalize();
}
In forward order
0 ab
1 cd
2 ef
3 ghi

In reverse order
0 hi
1 fg
2 de
3 abc