难以理解 C 中的 MPI 散点和聚集
difficulty understanding MPI scatter and gather in C
我正在尝试学习使用 MPI。下面是我测试 MPI 分散和聚集的简单程序。我不明白它是如何工作的以及为什么会产生结果
1 2 3 4 4 5 6 7 8 9 10 11
而不是预期
1 2 3 4 5 6 7 8 9 10 11 12
文档和我能找到的所有示例都太complicated/poorly 措辞让我无法理解。我只想将一个数组分散到 3 个进程中,并为每个进程中的每个值加一个。或者,我会很高兴看到一个二维数组是如何逐行发送到每个进程并且每一行都被简单地处理的。
int main(int argc, char **argv) {
int rank; // my process ID
int size = 3; // number of processes/nodes
MPI_Status status;
MPI_Init(&argc, &argv); // start MPI
MPI_Comm_size(MPI_COMM_WORLD, &size); // initialize MPI
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
unsigned char inData[12]; // data returned after being "processed"
unsigned char outData[12]; // buffer for receiving data
unsigned long datasize = 12; // size of data to process
unsigned char testData[12]; // data to be processed
if (rank == 0) {
// initialize data
for (int i = 0; i < datasize; i++) {
testData[i] = i;
outData[i] = 0;
inData[i] = 0;
}
}
// scatter the data to the processes
// I am not clear about the numbers sent in and out
MPI_Scatter(&testData, 12, MPI_UNSIGNED_CHAR, &outData,
12, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
// process data
for (int i = 0; i < 4; i++) { outData[i] = outData[i] + 1; }
MPI_Barrier(MPI_COMM_WORLD);
// gather processed data
MPI_Gather(&outData, 12, MPI_UNSIGNED_CHAR, &inData,
12, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
//print processed data from root
if (rank == 0) {
for (int i = 0; i < 12; i++) {
printf("\n%d", inData[i]);
}
MPI_Finalize();
}
return 0;
}
虽然你的主要错误是使用 12
而不是 4
,但让我们一步一步来。
// int size = 3; // number of processes/nodes
int size;
...
MPI_Comm_size(MPI_COMM_WORLD, &size); // initialize MPI
assert(size == 3);
将 size
设置为 3
没有意义。该值将被 MPI_Comm_size
覆盖为实际进程数。此数字取决于您 运行 您的 MPI 应用程序(例如 mpirun -np 3
)。
//unsigned char outData[12]; // buffer for receiving data
unsigned char outData[4];
我们有 12 个元素和 3 个进程,每个进程 4 个元素。因此,outData
.
有 4 个元素就足够了
outData[i] = 0;
inData[i] = 0;
将这些缓冲区清零没有意义,它们将被覆盖。
// scatter the data to the processes
// I am not clear about the numbers sent in and out
MPI_Scatter(&testData, 4 /*12*/, MPI_UNSIGNED_CHAR, &outData,
4 /*12*/, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
我们每个进程有 4 个元素,所以数量应该是 4,而不是 12。
MPI_Barrier(MPI_COMM_WORLD);
这里不需要障碍。
MPI_Gather(&outData, 4 /*12*/, MPI_UNSIGNED_CHAR, &inData,
4 /*12*/, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
同样的故事,4
而不是 12
。
MPI_Finalize();
这应该被所有进程调用。
我正在尝试学习使用 MPI。下面是我测试 MPI 分散和聚集的简单程序。我不明白它是如何工作的以及为什么会产生结果
1 2 3 4 4 5 6 7 8 9 10 11
而不是预期
1 2 3 4 5 6 7 8 9 10 11 12
文档和我能找到的所有示例都太complicated/poorly 措辞让我无法理解。我只想将一个数组分散到 3 个进程中,并为每个进程中的每个值加一个。或者,我会很高兴看到一个二维数组是如何逐行发送到每个进程并且每一行都被简单地处理的。
int main(int argc, char **argv) {
int rank; // my process ID
int size = 3; // number of processes/nodes
MPI_Status status;
MPI_Init(&argc, &argv); // start MPI
MPI_Comm_size(MPI_COMM_WORLD, &size); // initialize MPI
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
unsigned char inData[12]; // data returned after being "processed"
unsigned char outData[12]; // buffer for receiving data
unsigned long datasize = 12; // size of data to process
unsigned char testData[12]; // data to be processed
if (rank == 0) {
// initialize data
for (int i = 0; i < datasize; i++) {
testData[i] = i;
outData[i] = 0;
inData[i] = 0;
}
}
// scatter the data to the processes
// I am not clear about the numbers sent in and out
MPI_Scatter(&testData, 12, MPI_UNSIGNED_CHAR, &outData,
12, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
// process data
for (int i = 0; i < 4; i++) { outData[i] = outData[i] + 1; }
MPI_Barrier(MPI_COMM_WORLD);
// gather processed data
MPI_Gather(&outData, 12, MPI_UNSIGNED_CHAR, &inData,
12, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
//print processed data from root
if (rank == 0) {
for (int i = 0; i < 12; i++) {
printf("\n%d", inData[i]);
}
MPI_Finalize();
}
return 0;
}
虽然你的主要错误是使用 12
而不是 4
,但让我们一步一步来。
// int size = 3; // number of processes/nodes
int size;
...
MPI_Comm_size(MPI_COMM_WORLD, &size); // initialize MPI
assert(size == 3);
将 size
设置为 3
没有意义。该值将被 MPI_Comm_size
覆盖为实际进程数。此数字取决于您 运行 您的 MPI 应用程序(例如 mpirun -np 3
)。
//unsigned char outData[12]; // buffer for receiving data
unsigned char outData[4];
我们有 12 个元素和 3 个进程,每个进程 4 个元素。因此,outData
.
outData[i] = 0;
inData[i] = 0;
将这些缓冲区清零没有意义,它们将被覆盖。
// scatter the data to the processes
// I am not clear about the numbers sent in and out
MPI_Scatter(&testData, 4 /*12*/, MPI_UNSIGNED_CHAR, &outData,
4 /*12*/, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
我们每个进程有 4 个元素,所以数量应该是 4,而不是 12。
MPI_Barrier(MPI_COMM_WORLD);
这里不需要障碍。
MPI_Gather(&outData, 4 /*12*/, MPI_UNSIGNED_CHAR, &inData,
4 /*12*/, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD);
同样的故事,4
而不是 12
。
MPI_Finalize();
这应该被所有进程调用。