我是MPI的新手,这个应用程序涉及MPI_Bcast和MPI_Scatter的实现。要求首先是root应该使用MPI_Bcast向节点广播分区的大小,然后将每个数组的部分分散到节点。我的根工作正常,但节点没有接收到数组的值,因此平均值的计算是偏斜的。下面是我到目前为止的代码
/** includes **/
#include <iostream>
#include <mpi.h>
// function that will implement the coordinator job of this application
void coordinator(int world_size) {
std::cout << " coordinator rank [0] starting " << std::endl;
// generate 100000 random integers and store them in an array
int values[40];
for (unsigned int i = 0; i < 40; i++){
values[i] = rand() % 10;
std::cout << values[i] << ", ";
if (i % 10 == 9) std::cout << std::endl;
}
// determine the size of each partition by dividing 100000 by the world size
// it is impertative that the world_size divides this evenly
int partition_size = 40 / world_size;
std::cout << " coordinator rank [0] partition size is " << partition_size << "\n" << std::endl;
// broadcast the partition size to each node so they can setup up memory as appropriate
MPI_Bcast(&partition_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
std::cout << " coordinator rank [0] broadcasted partition size\n" << std::endl;
// generate an average for our partition
int total = 0;
for (unsigned int i = 0; i < (40 / world_size); i++)
total += values[i];
float average = (float)total / (40 / world_size);
std::cout << " coordinator rank [0] average is " << average << "\n" << std::endl;
// call a reduce operation to get the total average and then divide that by the world size
float total_average = 0;
MPI_Reduce(&average, &total_average, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
std::cout << " total average is " << total_average / world_size << std::endl;
}
// function that will implement the participant job of this applicaiton
void participant(int world_rank, int world_size) {
std::cout << " participant rank [" << world_rank << "] starting" << std::endl;
// get the partition size from the root and allocate memory as necessary
int partition_size = 0;
MPI_Bcast(&partition_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
std::cout << " participant rank [" << world_rank << "] recieved partition size of " <<
partition_size << std::endl;
// allocate the memory for our partition
int *partition = new int[partition_size];
// generate an average for our partition
int total = 0;
for (unsigned int i = 0; i < partition_size; i++)
total += partition[i];
float average = (float)total / partition_size;
std::cout << " participant rank [" << world_rank << "] average is " << average << std::endl;
// call a reduce operation to get the total average and then divide that by the world size
float total_average = 0;
MPI_Reduce(&average, &total_average, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
// as we are finished with the memory we should free it
delete partition;
}
int main(int argc, char** argv) {
// initialise the MPI library
MPI_Init(NULL, NULL);
// determine the world size
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// determine our rank in the world
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
// print out the rank and size
std::cout << " rank [" << world_rank << "] size [" << world_size << "]" << std::endl;
// if we have a rank of zero then we are the coordinator. if not we are a participant
// in the task
if (world_rank == 0){
coordinator(world_size);
}
else{
participant(world_rank, world_size);
}
int *values = new int[40];
int *partition_size = new int[40 / world_size];
// run the scatter operation and then display the contents of all 4 nodes
MPI_Scatter(values, 40 / world_size, MPI_INT, partition_size, 40 / world_size,
MPI_INT, 0, MPI_COMM_WORLD);
std::cout << "rank " << world_rank << " partition: ";
for (unsigned int i = 0; i < 40 / world_size; i++)
std::cout << partition_size[i] << ", ";
std::cout << std::endl;
// finalise the MPI library
MPI_Finalize();
}
这是我在运行代码后获得的内容
我需要得到这个
1,7,4,0,9,4,8,8,2,4,
5,5,1,7,1,1,5,2,7,6,
1,4,2,3,2,2,1,6,8,5,
7,6,1,8,9,2,7,9,5,4,
但我得到了这个
排名0分区:-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,
排名3分区:-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,
排名2分区:-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,
排名1分区:-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,
答案 0 :(得分:1)
您散布了一系列未初始化数据:
int *values = new int[40];
int *partition_size = new int[40 / world_size];
// values is never initialised
MPI_Scatter(values, 40 / world_size, MPI_INT, partition_size, 40 / world_size,
MPI_INT, 0, MPI_COMM_WORLD);
-842150451
是0xCDCDCDCD
,Microsoft CRT在调试模式下使用该值填充新分配的内存(在发布模式下,内存内容将在分配后保留原样。)
您必须将MPI_Scatter
的调用放在相应的协调员/参与者功能中。