如何使用 MPI 分散和收集数组
How to use MPI scatter and gather with array
我是MPI新手,用C语言写了下面的程序。我不想使用指针,而是想如下所示设置我的数组。我的第一个数组元素读取正确,之后,它不会读取数组元素。你能告诉我这是否不是使用分散和收集的正确方法
以下是我得到的结果:
$ mpicc test.c -o test
$ mpirun -np 4 test
1. Processor 0 has data 0 1 2 3
2. Processor 0 has data 0
3. Processor 0 doubling the data, now has 5
2. Processor 1 has data 32767
3. Processor 1 doubling the data, now has 5
2. Processor 2 has data -437713961
3. Processor 2 doubling the data, now has 5
2. Processor 3 has data 60
3. Processor 3 doubling the data, now has 5
4. Processor 0 has data: 5 1 2 3
正确的结果应该是:
$ mpicc test.c -o test
$ mpirun -np 4 test
1. Processor 0 has data 0 1 2 3
2. Processor 0 has data 0
3. Processor 0 doubling the data, now has 5
2. Processor 1 has data 1
3. Processor 1 doubling the data, now has 5
2. Processor 2 has data 2
3. Processor 2 doubling the data, now has 5
2. Processor 3 has data 3
3. Processor 3 doubling the data, now has 5
4. Processor 0 has data: 5 5 5 5
如有任何帮助,我们将不胜感激。以下代码 运行 使用 4 个处理器:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int globaldata[4]; /*wants to declare array this way*/
int localdata[4]; /*without using pointers*/
int i;
if (rank == 0) {
for (i = 0; i < size; i++)
globaldata[i] = i;
printf("1. Processor %d has data: ", rank);
for (i = 0; i < size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("2. Processor %d has data %d\n", rank, localdata[rank]);
localdata[rank]= 5;
printf("3. Processor %d now has %d\n", rank, localdata[rank]);
MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("4. Processor %d has data: ", rank);
for (i = 0; i < size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Finalize();
return 0;
}
你的设置和散点图原则上没问题。你的问题出在打印上,因为你在这里误解了 scatter/gather 的细节。
分散 4 元素数组时,每个进程仅获取一个元素(如您使用 MPI_Scatter call()
的第 2 个和第 5 个参数定义的那样)。此元素存储在本地数组的 0 索引中。它实际上是一个标量。
一般来说,你可能会分散很大的数组,每个进程可能仍然需要处理一个很大的本地数组。在这些情况下,必须正确计算 全局指数 和 局部指数 .
假设以下玩具问题:您想将数组 [1 2 3 4 5 6] 分散到两个进程。 Proc0 应该有 [1 2 3] 部分,Proc1 应该有 [4 5 6] 部分。在这种情况下,全局数组的大小为 6,局部数组的大小为 3。Proc0 获取全局元素 0、1、2 并将它们分配给其局部 0、1、2。Proc1 获取全局元素 3、4 , 5 并将它们分配给它的本地 0, 1, 2.
当您了解 MPI_Scatterv 时,您可能会更好地理解这个概念,它不会为每个进程假定相同数量的局部元素。
您的代码版本似乎有效:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int globaldata[4];/*wants to declare array this way*/
int localdata;/*without using pointers*/
int i;
if (rank == 0) {
for (i=0; i<size; i++)
globaldata[i] = i;
printf("1. Processor %d has data: ", rank);
for (i=0; i<size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("2. Processor %d has data %d\n", rank, localdata);
localdata= 5;
printf("3. Processor %d now has %d\n", rank, localdata);
MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("4. Processor %d has data: ", rank);
for (i=0; i<size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Finalize();
return 0;
}
享受学习 MPI 吧! :-)
我是MPI新手,用C语言写了下面的程序。我不想使用指针,而是想如下所示设置我的数组。我的第一个数组元素读取正确,之后,它不会读取数组元素。你能告诉我这是否不是使用分散和收集的正确方法
以下是我得到的结果:
$ mpicc test.c -o test
$ mpirun -np 4 test
1. Processor 0 has data 0 1 2 3
2. Processor 0 has data 0
3. Processor 0 doubling the data, now has 5
2. Processor 1 has data 32767
3. Processor 1 doubling the data, now has 5
2. Processor 2 has data -437713961
3. Processor 2 doubling the data, now has 5
2. Processor 3 has data 60
3. Processor 3 doubling the data, now has 5
4. Processor 0 has data: 5 1 2 3
正确的结果应该是:
$ mpicc test.c -o test
$ mpirun -np 4 test
1. Processor 0 has data 0 1 2 3
2. Processor 0 has data 0
3. Processor 0 doubling the data, now has 5
2. Processor 1 has data 1
3. Processor 1 doubling the data, now has 5
2. Processor 2 has data 2
3. Processor 2 doubling the data, now has 5
2. Processor 3 has data 3
3. Processor 3 doubling the data, now has 5
4. Processor 0 has data: 5 5 5 5
如有任何帮助,我们将不胜感激。以下代码 运行 使用 4 个处理器:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int globaldata[4]; /*wants to declare array this way*/
int localdata[4]; /*without using pointers*/
int i;
if (rank == 0) {
for (i = 0; i < size; i++)
globaldata[i] = i;
printf("1. Processor %d has data: ", rank);
for (i = 0; i < size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("2. Processor %d has data %d\n", rank, localdata[rank]);
localdata[rank]= 5;
printf("3. Processor %d now has %d\n", rank, localdata[rank]);
MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("4. Processor %d has data: ", rank);
for (i = 0; i < size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Finalize();
return 0;
}
你的设置和散点图原则上没问题。你的问题出在打印上,因为你在这里误解了 scatter/gather 的细节。
分散 4 元素数组时,每个进程仅获取一个元素(如您使用 MPI_Scatter call()
的第 2 个和第 5 个参数定义的那样)。此元素存储在本地数组的 0 索引中。它实际上是一个标量。
一般来说,你可能会分散很大的数组,每个进程可能仍然需要处理一个很大的本地数组。在这些情况下,必须正确计算 全局指数 和 局部指数 .
假设以下玩具问题:您想将数组 [1 2 3 4 5 6] 分散到两个进程。 Proc0 应该有 [1 2 3] 部分,Proc1 应该有 [4 5 6] 部分。在这种情况下,全局数组的大小为 6,局部数组的大小为 3。Proc0 获取全局元素 0、1、2 并将它们分配给其局部 0、1、2。Proc1 获取全局元素 3、4 , 5 并将它们分配给它的本地 0, 1, 2.
当您了解 MPI_Scatterv 时,您可能会更好地理解这个概念,它不会为每个进程假定相同数量的局部元素。
您的代码版本似乎有效:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int globaldata[4];/*wants to declare array this way*/
int localdata;/*without using pointers*/
int i;
if (rank == 0) {
for (i=0; i<size; i++)
globaldata[i] = i;
printf("1. Processor %d has data: ", rank);
for (i=0; i<size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("2. Processor %d has data %d\n", rank, localdata);
localdata= 5;
printf("3. Processor %d now has %d\n", rank, localdata);
MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("4. Processor %d has data: ", rank);
for (i=0; i<size; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Finalize();
return 0;
}
享受学习 MPI 吧! :-)