Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何发送和接收可变长度(取决于处理器)std::vector<;myStruct>;使用MPI_C++_Struct_Mpi_Stdvector - Fatal编程技术网

C++ 如何发送和接收可变长度(取决于处理器)std::vector<;myStruct>;使用MPI

C++ 如何发送和接收可变长度(取决于处理器)std::vector<;myStruct>;使用MPI,c++,struct,mpi,stdvector,C++,Struct,Mpi,Stdvector,每个处理器上都有一个自定义结构向量。这些向量都是不同大小的。我正在努力从处理器0上的处理器1到N接收数据 我已尝试实施所附幻灯片第31-33页上的建议,其中发送和接收std::vector。我还实现了MPI_注册和MPI_注销 我正在osx上编译和运行这段代码 #包括 #包括 #包括 #包括 #包括 #包括 结构蟹爪 { 蟹爪():com(),number(),weight(),crossing_count(),com0_id(){} ///////// 蟹爪( 向量c, int n, 双w,

每个处理器上都有一个自定义结构向量。这些向量都是不同大小的。我正在努力从处理器0上的处理器1到N接收数据

我已尝试实施所附幻灯片第31-33页上的建议,其中发送和接收std::vector。我还实现了MPI_注册和MPI_注销

我正在osx上编译和运行这段代码

#包括
#包括
#包括
#包括
#包括
#包括
结构蟹爪
{
蟹爪():com(),number(),weight(),crossing_count(),com0_id(){}
/////////
蟹爪(
向量c,
int n,
双w,
std::矢量cc,
整数id
):com(c)、数字(n)、重量(w)、交叉计数(cc)、com0_id(id){}
std::vector com=std::vector(3);
整数;
双倍重量;
标准::向量交叉计数=标准::向量(3);
int com0_id;
};
MPI\u数据类型寄存器\u MPI\u类型(蟹爪)//常量&)
{
constexpr std::size\t num\u members=5;
整数长度[num_成员]={3,1,1,3,1};
MPI维护偏移量[成员数]={
偏移量(蟹爪,com),//矢量(双倍)
偏移量(蟹爪,数字),//int
偏移量(蟹爪,重量),//双
偏移量(蟹爪,交叉计数),//向量(双精度)
偏移量(蟹爪,com0\U id)//int
};
MPI_数据类型[num_members]={MPI_DOUBLE,MPI_INT,MPI_DOUBLE,MPI_DOUBLE,MPI_INT};
MPI_数据类型;
MPI类型结构(成员数、长度、偏移量、类型和类型);
MPI_类型_提交(&Type);
返回类型;
}
作废注销器\u mpi\u类型(mpi\u数据类型)
{
无MPI类型(类型和类型);
}
int main(
int argc,
字符*argv[]
)
{
MPI_Init(&argc,&argv);
int mpi处理器;mpi通信大小(mpi通信世界和mpi处理器);
int mpi_my_id;mpi_Comm_rank(mpi_Comm_WORLD和mpi_my_id);
常量int mpi_主id=0;
向量h;双j=mpi\u my\u id;
对于(int i=0;i<(2*mpi_my_id+1);+i)
{
螃蟹爪h_1;
标准:向量h_-com(3,0.);
h_com[0]=((i+1)/20.*2*j)/(i+1);
h_com[1]=((i+1)/20.*2*j)/(i+1);
h_com[2]=((i+1)/20.*2*j)/(i+1);
j/=0.5;
标准:向量交叉计数(3,0);
h_1.com=h_com;
h_1.number=i*mpi_my_id+1;
h_1.重量=j*0.3;
h_1.交叉计数=交叉计数;
h_1.com0_id=mpi_my_id;
h、 推回(h_1);
}
MPI_屏障(MPI_通信世界);
/*为struct crab_claw创建一个类型*/
std::载体存储;
MPI_数据类型=寄存器_MPI_类型(h[0]);
如果(mpi\U我的\U id!=mpi\U主\U id)
{
int tag=mpi\u my\u id;
无符号长度=h.size();
const int destination=mpi_master_id;
MPI_发送(
&长度,
1.
MPI_未签名,
目的地,
标记+mpi处理器,
MPI_通讯世界
);
如果(长度!=0)
{
MPI_发送(
h、 数据(),
长度,
类型,
目的地,
mpi_我的id,
MPI_通讯世界
);
}
}
MPI_屏障(MPI_通信世界);
如果(mpi\U我的\U id==mpi\U主\U id)
{
对于(int j=0;jSTD::尽管对MPI了解不多,但是这里显然有一个非常基本的误解:C++向量是什么,以及它们是如何工作的。不能不注意到,<代码>偏移量< /C> >对于<代码> STD::向量< /代码>以及一个普通的<代码>双< /代码>,完全是相同的。这是不对的。在<代码> STD::vector重复>,我不重复,在向量本身是“代码>结构代码< /代码>的一部分时,我不重复告诉你向量的实际值。C++没有这样的工作。这看起来是一个C C++库,没有关于C++类的线索,它们是如何工作的,它们是什么。嗨,山姆,我很感激你的回答。我确实是新T。o偏移量。但是在MPI和附加链接中,它被强调(我相信)偏移量指的是容器中元素的数量,这是我认为应该正确处理的。数组可能会解决问题,因为向量指向数组,并且在结构中传递向量会将指针埋得更深一层吗?如果您对我的无知/无能有其他评论的话关于我的代码结构到底有什么错误,我将不胜感激。@samvarshavchikt“附加链接”告诉您需要对
std::vector
s执行什么操作。这与您在所示代码中执行的操作不同。您是否看到代码中的
std::vector
s与链接中名为“处理std::vector”的一章之间的联系?您认为这两者之间可能有联系吗?所示代码的哪一部分实现了“附加链接”中该章中给出的说明?您似乎忽略了嵌套
std::vector
对象的意义。您不能将
std::vector
策略用于
std::vector
,而
std::vector
本身就很重要。在这种情况下,嵌套结构
com
交叉计数
似乎是硬编码的长度3,例如在
寄存器中_
#include <mpi.h>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
#include <cstddef>

struct crab_claw
{
    crab_claw()  : com(), number(), weight(), crossing_count(), com0_id() {}
    /////////
    crab_claw(
             std::vector<double> c,
             int n,
             double w,
             std::vector<double> cc,
             int id
             ) : com( c ), number( n ), weight( w ), crossing_count( cc ), com0_id( id ) {}
    std::vector<double> com = std::vector<double>(3);
    int number;
    double weight;
    std::vector<double> crossing_count = std::vector<double>(3);
    int com0_id;
};

MPI_Datatype register_mpi_type(crab_claw)// const&)
{
    constexpr std::size_t num_members = 5;
    int lengths[num_members] = {3,1,1,3,1};

    MPI_Aint offsets[num_members] =  {
                                      offsetof(crab_claw, com), //vector (of doubles)
                                      offsetof(crab_claw, number),     //int
                                      offsetof(crab_claw, weight),     //double
                                      offsetof(crab_claw, crossing_count),       //vector (of doubles)
                                      offsetof(crab_claw, com0_id)  //int
                                      };

    MPI_Datatype types[num_members] = { MPI_DOUBLE, MPI_INT, MPI_DOUBLE, MPI_DOUBLE, MPI_INT };
    MPI_Datatype type;
    MPI_Type_struct(num_members, lengths, offsets, types, &type);
    MPI_Type_commit(&type);
    return type;
}

void deregister_mpi_type(MPI_Datatype type)
{
    MPI_Type_free(&type);
}

int main(
         int argc,
         char* argv[]
         )
{
    MPI_Init(&argc, &argv);
    int mpi_nprocessors;  MPI_Comm_size(MPI_COMM_WORLD, &mpi_nprocessors);
    int mpi_my_id;        MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_id);
    const int mpi_master_id = 0;

    std::vector<crab_claw> h; double j = mpi_my_id;

    for(int i = 0; i < (2*mpi_my_id+1); ++i)
    {
        crab_claw h_1;
        std::vector<double> h_com(3,0.);
        h_com[0] = ((i+1)/20. * 2*j)/(i+1);
        h_com[1] = ((i+1)/20. * 2*j)/(i+1);
        h_com[2] = ((i+1)/20. * 2*j)/(i+1);
        j /= 0.5;
        std::vector<double> crossing_count(3,0.);

        h_1.com            = h_com;
        h_1.number         = i*mpi_my_id+1;
        h_1.weight         = j*0.3;
        h_1.crossing_count = crossing_count;
        h_1.com0_id        = mpi_my_id;
        h.push_back(h_1);
    }

    MPI_Barrier(MPI_COMM_WORLD);
    /* create a type for struct crab_claw */

    std::vector<crab_claw> storage;

    MPI_Datatype type = register_mpi_type(h[0]);
    if (mpi_my_id != mpi_master_id)
    {
        int       tag    = mpi_my_id;
        unsigned length = h.size();
        const int destination = mpi_master_id;
        MPI_Send(
                 &length,
                 1,
                 MPI_UNSIGNED,
                 destination,
                 tag+mpi_nprocessors,
                 MPI_COMM_WORLD
                 );

        if(length != 0)
        {
            MPI_Send(
                     h.data(),
                     length,
                     type,
                     destination,
                     mpi_my_id,
                     MPI_COMM_WORLD
                     );
        }
    }

    MPI_Barrier(MPI_COMM_WORLD);
    if (mpi_my_id == mpi_master_id)
    {
        for(int j = 0; j < mpi_nprocessors; ++j)
        {
            if(j == 0)
            {
                storage.insert(storage.end(), h.begin(), h.end());

                std::cout << "inert insert" << '\n';
            }

            if(j > 0)
            {
                unsigned length;
                MPI_Status s;

                MPI_Recv(
                         &length,
                         1,
                         MPI_UNSIGNED,
                         j,
                         j+mpi_nprocessors,
                         MPI_COMM_WORLD,
                         &s
                         );

                std::vector<crab_claw> rec;

                //std::cout << "MPIMYID " << mpi_my_id << " LENGTH OF RECEIVED OBJ " << length << " j " << j << '\n';

                if (length != 0)
                {
                    h.resize(length);
                    MPI_Recv(
                             h.data(),
                             length,
                             type,
                             j,
                             j,
                             MPI_COMM_WORLD,
                             &s
                             );


                    std::cout << "SIZE() " << h.size() << " MY MPI ID " << mpi_my_id << " h[0].number " << h[0].weight << '\n';


                //storage.insert(storage.end(), h.begin(), h.end());

                } else
                {
                    h.clear();
                }

            }
        }
    }


    //std::cout << mpi_my_id << '\n';
    MPI_Finalize();
    return 0;
}