MPI_Scatter : 散点特征矩阵

MPI_Scatter : Scatter Eigen Matrix

我正在尝试使用以下特征矩阵实现 MPI_Scatter:

// get pointer to samples
double *X = prob.x;
// map the samples into the matrix object
MatrixXd globaldata = Map<MatrixXd>(X, dims, nsmp);
MatrixXd localdata;
int size, rank;

MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (rank == 0) {
    printf("Processor %d has data before Scatter \n", rank);
    cout << globaldata<<endl<<endl;
}

MPI_Scatter(globaldata.data(), 1, MPI_DOUBLE, &localdata, 1, MPI_DOUBLE, 0,
        MPI_COMM_WORLD);

printf("Processor %d has data \n", rank);
cout << localdata << endl;

MatrixXd globaldata 的输出是:

        -1         -1         -1         -1
 -0.997455  -0.996032  -0.998472  -0.996154
  -0.94402  -0.912698  -0.966387  -0.915385
 -0.974555  -0.960317  -0.984721  -0.961538
  -0.46056 -0.0753968  -0.676089   0.423077
         1          1          1          1

然后我尝试使用

分散本征矩阵 gloaldata
MPI_Scatter(globaldata.data(), 1, MPI_DOUBLE, &localdata, 1, MPI_DOUBLE, 0,
            MPI_COMM_WORLD);

但是我认为以上内容不正确。我如何逐列散布上述特征矩阵,以便当我 运行 mpirun -np 4 ./mpitest 例如我看到特征矩阵的每一列映射到每个进程或如果 np 为 2 则 2 映射到每个进程? send_datatype 和 recv_datatype 是否正确,即 MPI_DOUBLE?

在MPI_Scatter中,计数(您的值为 1)是发送到每个进程的元素数。要在 "size" 个进程之间均匀分布矩阵,您需要将计数设置为 16/大小(对于您的 4x4 矩阵示例)。

这依赖于矩阵中的所有数据都存储为一个连续的内存块 - 您需要检查 MatrixXd 类型的情况,尽管我猜它是真的。

同样,散点是分布行还是列取决于您的存储顺序。对于标准 C 数组,在 4 个进程中,您将向每个进程发送单独的行,而不是一列。但是,Eigen 似乎默认为列主要存储(Fortran 的标准但不是 C 的标准),这意味着您要发送整个列。

您需要为接收缓冲区分配space。简单地将变量定义为 double * 不会保留任何存储空间,因此您会收到错误消息。我认为您的原始示例也是如此 - 定义了 localdata 但看起来没有分配存储空间 space。

要使代码正常工作,您可以尝试:

double X1[24]; // This is more storage than you need but its safe
...
MPI_Scatter(X, 4,MPI_DOUBLE, X1, 4, MPI_DOUBLE, 0, MPI_COMM_WORLD)

虽然错误发生在MPI_Scatter,我认为问题的根源在于指针和分配数组之间存在一些混淆。