MPI从站发送数据,但只有四分之一是正确的

问题描述 投票:0回答:1

我改变了我的问题,因为我不能问另一个问题,从哪个变量发送和接收的问题到下面的问题。希望这是一个更合适的问题。

我正在尝试收集在我的处理器中分割的数据,但只有四分之一的数据正确回收。我正在为每个处理器分配(num loops)/(num procs)循环次数(用户被迫使用整数个处理器来进行迭代次数)。在使用5个处理器和200次迭代时,每个从站都可以正确计算所有40个值,但不知何故只有四分之一的值能够正确地返回到主站。我将它扩展到400次迭代,仍然只有四分之一使它正确地回到了主人。我想知道我是否需要等待或确定它从一个处理器读取到下一个处理器?代码的MPI部分在下面,删除了所有数学。

#define MASTER 0
MPI_Init(NULL,NULL);
MPI_Status status;
int rank,size,name_len;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Get_processor_name(processor_name, &name_len);

chunksize = (NumEnergies / size);    
if (rank == MASTER)
{
    offset = chunksize;
    for (dest=1; dest<size; dest++)
    {
        MPI_Send(&offset, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
        offset = offset + chunksize;
    }

    //master does its calcs for CrossSections and DiffCrossSections

    for (int i=1; i<size; i++)
    {
        source = i;
        MPI_Recv(&offset, 1, MPI_INT, source, tag1, MPI_COMM_WORLD, &status);
        MPI_Recv(&CrossSections[offset][1], chunksize, MPI_DOUBLE, source, tag2, MPI_COMM_WORLD, &status);

        MPI_Recv(&DiffCrossSections[0][offset+1], (181)*chunksize, MPI_DOUBLE, source, tag3, MPI_COMM_WORLD, &status);
    }
}


if (rank > MASTER)
{
    /* Receive my portion of array from the master task */
    source = MASTER;
    MPI_Recv(&offset, 1, MPI_INT, source, tag1, MPI_COMM_WORLD, &status);

    std::cout<<"Processor: "<<processor_name<<"   rank:"<<rank<<"  Energies="<<CrossSections[offset][0]<<" - "<<CrossSections[offset+chunksize-1][0]<<std::endl;

    /* Each task does its part of the work */

    /* Send task results back to the master task */
    dest = MASTER;
    MPI_Send(&offset, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
    MPI_Send(&CrossSections[offset][1], chunksize, MPI_DOUBLE, dest, tag2, MPI_COMM_WORLD);
    MPI_Send(&DiffCrossSections[0][offset+1], (181)*chunksize, MPI_DOUBLE, dest, tag3, MPI_COMM_WORLD);
}

MPI_Finalize();

我读出了每个从站中的值,并且所有值都是正确的,尽管当然是乱七八糟的。其中3/4发送回0,这是我初始化矢量。所以,看起来他们只是保持他们的初始值,而不是实际上被发送垃圾。关于什么可能导致它仅正确返回四分之一值的任何提示?每次都是四分之一,它不会改变。

谢谢!

multithreading multidimensional-array vector parallel-processing mpi
1个回答
0
投票

我认为问题在于send如何通过分配给向量的内存。当我使用1D缓冲区传递结果时,它工作正常,这让我觉得我想传递的数据并不是在连续的内存块中。因此,在分配向量时可能会反转索引会使我想要访问的内存连续。但是,也许我拥有它的方式是一种“有序对”的安排,而不是我真正想要的那种。我将不得不为DiffCrossSections做同样的事情。

编辑:我在其初始化中转换了CrossSections和DiffCrossSections,并解决了这个问题。所以,它似乎确实是我在内存中发送的数据我认为是连续但不是。

std::vector<std::vector<double > > DiffCrossSections (NumEnergies+1,std::vector<double>(181,0.0));
std::vector< std::vector<double > > CrossSections (2, std::vector<double> (NumEnergies,0.0));

#define MASTER 0
MPI_Init(NULL,NULL);
MPI_Status status;
int rank,size,name_len;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Get_processor_name(processor_name, &name_len);

chunksize = (NumEnergies / size);    
if (rank == MASTER)
{
    offset = chunksize;
    for (dest=1; dest<size; dest++)
    {
        MPI_Send(&offset, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
        offset = offset + chunksize;
    }

    //master does its calcs for CrossSections and DiffCrossSections

    for (int i=1; i<size; i++)
    {
        source = i;
        MPI_Recv(&offset, 1, MPI_INT, source, tag1, MPI_COMM_WORLD, &status);
        MPI_Recv(&CorssSections[1][offset], chunksize, MPI_DOUBLE, source, tag2, MPI_COMM_WORLD, &status);

        MPI_Recv(&DiffCrossSections[offset+1][0], (181)*chunksize, MPI_DOUBLE, source, tag3, MPI_COMM_WORLD, &status);
    }
}


if (rank > MASTER)
{
    /* Receive my portion of array from the master task */
    source = MASTER;
    MPI_Recv(&offset, 1, MPI_INT, source, tag1, MPI_COMM_WORLD, &status);

    std::cout<<"Processor: "<<processor_name<<"   rank:"<<rank<<"  Energies="<<CrossSections[0][offset]<<" - "<<CrossSections[0][offset+chunksize-1]<<std::endl;

    /* Each task does its part of the work */

    /* Send task results back to the master task */
    dest = MASTER;
    MPI_Send(&offset, 1, MPI_INT, dest, tag1, MPI_COMM_WORLD);
    MPI_Send(&CrossSections[1][offset], chunksize, MPI_DOUBLE, dest, tag2, MPI_COMM_WORLD);
    MPI_Send(&DiffCrossSections[offset+1][0], (181)*chunksize, MPI_DOUBLE, dest, tag3, MPI_COMM_WORLD);
}

MPI_Finalize();
© www.soinside.com 2019 - 2024. All rights reserved.