C语言中使用MPI添加数组
Adding an array using MPI in C language
我对 MPI 编程还很陌生。在下面的代码中,我尝试使用流程 1 添加前 3 个元素,使用流程 2 添加最后 3 个元素。结果应显示前三个元素为 Sum is 11
,后三个元素为 Sum is 18
。我看到我的问题的原因是在第 2 级(进程 2)它读取 arr[3] 作为数组的第一个元素。我真的很迷惑为什么它不能在第 2 位正确读取数组的第 3 个元素
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int tag2 = 1;
int tag1 = 2;
int arr[7] = { 6,2,3,9,4,5};
printf ("\n--Current Rank: %d\n", world_rank);
int index;
int source = 0;
int dest;
if (world_rank == 0)
{
printf("* Rank 0 excecuting");
index = 0;
dest = 1;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr, 2, MPI_INT, dest, tag2, MPI_COMM_WORLD);
index = 3;
dest = 2;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr, 1, MPI_INT, dest, tag2, MPI_COMM_WORLD);
}
else
{
int sum = 0;
int i;
MPI_Recv(&index, 1, MPI_INT, source, tag1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&arr[index], 20, MPI_INT, source, tag2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("At Rank: %d index is: %d\n", world_rank, index);
for(i = index; i<=index+2; i++)
{
printf("i: %d and arr[i]: %d\n", i, arr[i]);
sum = arr[i]+sum;
}
printf("\n Sum is: %d and arr[3]: %d\n", sum, arr[3]);
}
MPI_Finalize();
}
使用命令得到的结果:mpirun -np 3 test1
--Current Rank: 0
--Current Rank: 1
At Rank: 1 index is: 0
i: 0 and arr[i]: 6
i: 1 and arr[i]: 2
i: 2 and arr[i]: 3
Sum is: 11 and arr[3]: 9 //here it shows the correct value of 3rd array element
--Current Rank: 2
At Rank: 2 index is: 3
i: 3 and arr[i]: 6 //Error happens here
i: 4 and arr[i]: 4
i: 5 and arr[i]: 5
Sum is: 15 and arr[3]: 6 //Show the wrong array value for 3rd element
* Rank 0 excecuting
嗯,代码按照您的要求执行...
index = 3;
dest = 2;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr, 1, MPI_INT, dest, tag2, MPI_COMM_WORLD);
也许你想要更多:
index = 3;
dest = 2;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr[index], 3, MPI_INT, dest, tag2, MPI_COMM_WORLD);
而其他索引是 "valid" 的事实是因为初始分配...
这段代码还有一些问题:
int arr[7] = { 6,2,3,9,4,5};
:也许更确切地说 int arr[] = {6,2,3,9,4,5};
MPI_Send(&arr, 2, MPI_INT, dest, tag2, MPI_COMM_WORLD);
应该是 MPI_Send(&arr[index], 3, MPI_INT, dest, tag2, MPI_COMM_WORLD);
虽然我不太确定这是你打算做的。
MPI_Recv(&arr[index], 20, MPI_INT, source, tag2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
:这个20
是从哪里来的?不应该是3
吗?
希望这对你有意义。
我是 MPI 新手。但这就是我对 MPI 的了解。如果我错了请纠正我。
通常排名为 0 的进程从其他进程接收消息并打印结果或者它会进行必要的计算(在这种情况下添加它接收到的两个值)
所有其他进程完成他们的工作并将其发送给进程 0。
在这种情况下不需要标签,因为这只涉及简单的计算。
所以这个解决方案可以像这样简化。
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]){
int world_rank,world_size, i;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int arr[6] = {6,2,3,9,4,5};
printf ("Current Rank: %d\n", world_rank);
int total = 0;
if(world_rank != 0){//if the rank is not 0, calculate the partial sum
int tempTotal = 0;
for(i = 0; i < 3; i++){
tempTotal += arr[(world_rank -1)* 3 + i];
}
printf("* Rank %d sending value %d\n",world_rank, tempTotal);
MPI_Send(&tempTotal, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);//send the partial sum to process 0
printf("* Rank %d value sent\n", world_rank);
}else{
printf("RANK 0 receiving values:\n");
int temp;
for(i = 1; i < world_size; i++){
MPI_Recv(&temp, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);//receive partial sums from other processes
printf("Received value %d from rank %d\n", temp, i);
total += temp;//add the partial sum to total
}
printf("Sum of the array = %d\n", total);//after all partial sums arrive, print the total
}
MPI_Finalize();
}
要运行代码:
mpicc mpi.c -o mpi
mpirun -np 3 ./mpi
希望对您有所帮助。
我对 MPI 编程还很陌生。在下面的代码中,我尝试使用流程 1 添加前 3 个元素,使用流程 2 添加最后 3 个元素。结果应显示前三个元素为 Sum is 11
,后三个元素为 Sum is 18
。我看到我的问题的原因是在第 2 级(进程 2)它读取 arr[3] 作为数组的第一个元素。我真的很迷惑为什么它不能在第 2 位正确读取数组的第 3 个元素
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int tag2 = 1;
int tag1 = 2;
int arr[7] = { 6,2,3,9,4,5};
printf ("\n--Current Rank: %d\n", world_rank);
int index;
int source = 0;
int dest;
if (world_rank == 0)
{
printf("* Rank 0 excecuting");
index = 0;
dest = 1;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr, 2, MPI_INT, dest, tag2, MPI_COMM_WORLD);
index = 3;
dest = 2;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr, 1, MPI_INT, dest, tag2, MPI_COMM_WORLD);
}
else
{
int sum = 0;
int i;
MPI_Recv(&index, 1, MPI_INT, source, tag1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&arr[index], 20, MPI_INT, source, tag2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("At Rank: %d index is: %d\n", world_rank, index);
for(i = index; i<=index+2; i++)
{
printf("i: %d and arr[i]: %d\n", i, arr[i]);
sum = arr[i]+sum;
}
printf("\n Sum is: %d and arr[3]: %d\n", sum, arr[3]);
}
MPI_Finalize();
}
使用命令得到的结果:mpirun -np 3 test1
--Current Rank: 0
--Current Rank: 1
At Rank: 1 index is: 0
i: 0 and arr[i]: 6
i: 1 and arr[i]: 2
i: 2 and arr[i]: 3
Sum is: 11 and arr[3]: 9 //here it shows the correct value of 3rd array element
--Current Rank: 2
At Rank: 2 index is: 3
i: 3 and arr[i]: 6 //Error happens here
i: 4 and arr[i]: 4
i: 5 and arr[i]: 5
Sum is: 15 and arr[3]: 6 //Show the wrong array value for 3rd element
* Rank 0 excecuting
嗯,代码按照您的要求执行...
index = 3;
dest = 2;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr, 1, MPI_INT, dest, tag2, MPI_COMM_WORLD);
也许你想要更多:
index = 3;
dest = 2;
MPI_Send(&index, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
MPI_Send(&arr[index], 3, MPI_INT, dest, tag2, MPI_COMM_WORLD);
而其他索引是 "valid" 的事实是因为初始分配...
这段代码还有一些问题:
int arr[7] = { 6,2,3,9,4,5};
:也许更确切地说int arr[] = {6,2,3,9,4,5};
MPI_Send(&arr, 2, MPI_INT, dest, tag2, MPI_COMM_WORLD);
应该是MPI_Send(&arr[index], 3, MPI_INT, dest, tag2, MPI_COMM_WORLD);
虽然我不太确定这是你打算做的。MPI_Recv(&arr[index], 20, MPI_INT, source, tag2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
:这个20
是从哪里来的?不应该是3
吗?
希望这对你有意义。
我是 MPI 新手。但这就是我对 MPI 的了解。如果我错了请纠正我。
通常排名为 0 的进程从其他进程接收消息并打印结果或者它会进行必要的计算(在这种情况下添加它接收到的两个值)
所有其他进程完成他们的工作并将其发送给进程 0。
在这种情况下不需要标签,因为这只涉及简单的计算。
所以这个解决方案可以像这样简化。
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]){
int world_rank,world_size, i;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int arr[6] = {6,2,3,9,4,5};
printf ("Current Rank: %d\n", world_rank);
int total = 0;
if(world_rank != 0){//if the rank is not 0, calculate the partial sum
int tempTotal = 0;
for(i = 0; i < 3; i++){
tempTotal += arr[(world_rank -1)* 3 + i];
}
printf("* Rank %d sending value %d\n",world_rank, tempTotal);
MPI_Send(&tempTotal, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);//send the partial sum to process 0
printf("* Rank %d value sent\n", world_rank);
}else{
printf("RANK 0 receiving values:\n");
int temp;
for(i = 1; i < world_size; i++){
MPI_Recv(&temp, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);//receive partial sums from other processes
printf("Received value %d from rank %d\n", temp, i);
total += temp;//add the partial sum to total
}
printf("Sum of the array = %d\n", total);//after all partial sums arrive, print the total
}
MPI_Finalize();
}
要运行代码:
mpicc mpi.c -o mpi
mpirun -np 3 ./mpi
希望对您有所帮助。