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,我认为问题的根源在于指针和分配数组之间存在一些混淆。
我正在尝试使用以下特征矩阵实现 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
然后我尝试使用
分散本征矩阵 gloaldataMPI_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,我认为问题的根源在于指针和分配数组之间存在一些混淆。