使用MPI派生的数据类型

使用MPI派生的数据类型,mpi,derived-types,Mpi,Derived Types,阅读之后,我仍然想知道发送C/C++结构数据的最佳方式。事实上,我已经决定使用派生类型,但我遇到了问题 紧接着MPI_Init(…),我在一个单独的文件(MPI_NewTypes.cpp/h)中编写了一个函数,基本上用于提交新的数据类型。以下是一个快照: int loop_counter; msgInstallP InstallPStruct; MPI_Datatype MPI_MSGINSTALLP; MPI_Datatype type[4] = {MPI_INT, M

阅读之后,我仍然想知道发送C/C++结构数据的最佳方式。事实上,我已经决定使用派生类型,但我遇到了问题

紧接着
MPI_Init(…)
,我在一个单独的文件(MPI_NewTypes.cpp/h)中编写了一个函数,基本上用于提交新的数据类型。以下是一个快照:

int loop_counter;
    msgInstallP InstallPStruct;
    MPI_Datatype MPI_MSGINSTALLP;
    MPI_Datatype type[4] = {MPI_INT, MPI_INT, MPI_INT, MPI_CHAR};
    int blocklen[4] = {
                        sizeof(InstallPStruct.type),
                        sizeof(InstallPStruct.location),
                        sizeof(InstallPStruct.processID),
                        sizeof(InstallPStruct.name)
                      };

    MPI_Aint     disp[4];
    int          base;
    MPI_Address( &InstallPStruct,                disp);
    MPI_Address( &InstallPStruct.location,       disp+1);
    MPI_Address( &InstallPStruct.processID,      disp+2);
    MPI_Address( &InstallPStruct.name,           disp+3);
    base = disp[0];

    for (loop_counter=0; loop_counter < 4; loop_counter++)
      {
        disp[loop_counter] = disp[loop_counter] - base;
      }

    MPI_Type_struct(
                    4, /*count of elements */
                    blocklen, /* array_of_blocklengths */
                    disp, /* array_of_displacements */
                    type, /* array_of_types */
                    &MPI_MSGINSTALLP /* newtype */
                    );

    MPI_Type_commit( &MPI_MSGINSTALLP);
这里,
Add_MPI_Types()
是提交新数据类型的函数,驻留在MPI_NewTypes.cpp/h文件(已显示)中

run(…)
函数也在另一个文件中定义,该文件实际上尝试执行MPI发送/接收:

  msgInstallP InstallPMessage;
  InstallPMessage = *(msgInstallP*)Data;
  //Add_MPI_msgInstallP_Type();
  MPI_Ssend(
            (void*)&InstallPMessage,             /* Payload */
            sizeof(msgInstallP),                 /* size of the payload */
            MPI_MSGINSTALLP,                      /* MPI Data type */
            InstallPMessage.location,             /* location to which the message is being sent */
            InstallPMessage.type,                 /* Tag */
            MPI_COMM_WORLD                        /* Communicator */
            );
其中,msgInstallP是一种C/C++结构类型(在MPI中它的等价物是MPI_msgInstallP)。MPI\u MSGINSTALLP.h除了函数
Add\u MPI\u Types()
的接口声明外,不包含任何内容


如果需要更多详细信息,请告诉我。

这肯定是一个范围问题
MPI\u MSGINSTALLP
只是一个类型为
MPI\u Datatype
的普通旧变量,而不是一个特殊的文本,一旦提交就可以在任何地方使用(这基本上就是您尝试使用它的方式)。由于该变量在
Add\u MPI\u Types()
中是临时变量,因此在调用
run()
时,该变量早已不存在

就我个人而言,我会在
run()
中移动
MPI\u MSGINSTALLP
的声明,在
add\u MPI\u Types()
的参数中添加一个
MPI\u数据类型&
,并将
MPI\u MSGINSTALLP
传递给它,因此
run()
看起来如下:

msgInstallP InstallPMessage;
InstallPMessage = *(msgInstallP*)Data;
MPI_Datatype MPI_MSGINSTALLP;
Add_MPI_Types(MPI_MSGINSTALLP);
//Add_MPI_msgInstallP_Type();
MPI_Ssend(
            (void*)&InstallPMessage,             /* Payload */
            sizeof(msgInstallP),                 /* size of the payload */
            MPI_MSGINSTALLP,                      /* MPI Data type */
            InstallPMessage.location,             /* location to which the message is being sent */
            InstallPMessage.type,                 /* Tag */
            MPI_COMM_WORLD                        /* Communicator */
            );

这绝对是一个范围问题
MPI\u MSGINSTALLP
只是一个类型为
MPI\u Datatype
的普通旧变量,而不是一个特殊的文本,一旦提交就可以在任何地方使用(这基本上就是您尝试使用它的方式)。由于该变量在
Add\u MPI\u Types()
中是临时变量,因此在调用
run()
时,该变量早已不存在

就我个人而言,我会在
run()
中移动
MPI\u MSGINSTALLP
的声明,在
add\u MPI\u Types()
的参数中添加一个
MPI\u数据类型&
,并将
MPI\u MSGINSTALLP
传递给它,因此
run()
看起来如下:

msgInstallP InstallPMessage;
InstallPMessage = *(msgInstallP*)Data;
MPI_Datatype MPI_MSGINSTALLP;
Add_MPI_Types(MPI_MSGINSTALLP);
//Add_MPI_msgInstallP_Type();
MPI_Ssend(
            (void*)&InstallPMessage,             /* Payload */
            sizeof(msgInstallP),                 /* size of the payload */
            MPI_MSGINSTALLP,                      /* MPI Data type */
            InstallPMessage.location,             /* location to which the message is being sent */
            InstallPMessage.type,                 /* Tag */
            MPI_COMM_WORLD                        /* Communicator */
            );

你能给出一个实际消息传递代码的例子吗?它看起来确实像一个范围问题,如果没有上下文,调试起来相当困难。:)你能给出一个实际消息传递代码的例子吗?它看起来确实像一个范围问题,如果没有上下文,调试起来相当困难。:)这是一个很好的答案,我可以做到。但是,问题在于可行性。我希望我可以进行一个函数调用,并提交新的数据类型,然后在项目中的任何地方重用它,这恰好是相当大的。我做了更多的阅读,如果我理解正确的话,每次使用新的数据类型时,都需要提交,然后释放。因此,如果我在不同的文件作用域中以并行线程进行几十次发送和接收,它将很快变得丑陋。您只需要定义和提交一次数据类型,只要它的类型映射仍然正确(即,它不表示在通信之间变化的动态数据结构),就可以重用它
MPI_MSGINSTALLP
看起来是静态的,所以您需要做的就是确保它在任何地方都可见。例如,将
MPI\u MSGINSTALLP
的定义和对
Add\u MPI\u Types(MPI\u MSGINSTALLP)
的调用移动到程序的开头,并将对
MPI\u MSGINSTALLP
的引用传递给任何需要它的函数。或者冒风险,使其全球化。:)谢谢。当我有时间的时候,我会再试一次。现在,我绕过了MPI_包和MPI_解包的混乱。这是一个很好的答案,我可以让它工作。但是,问题在于可行性。我希望我可以进行一个函数调用,并提交新的数据类型,然后在项目中的任何地方重用它,这恰好是相当大的。我做了更多的阅读,如果我理解正确的话,每次使用新的数据类型时,都需要提交,然后释放。因此,如果我在不同的文件作用域中以并行线程进行几十次发送和接收,它将很快变得丑陋。您只需要定义和提交一次数据类型,只要它的类型映射仍然正确(即,它不表示在通信之间变化的动态数据结构),就可以重用它
MPI_MSGINSTALLP
看起来是静态的,所以您需要做的就是确保它在任何地方都可见。例如,将
MPI\u MSGINSTALLP
的定义和对
Add\u MPI\u Types(MPI\u MSGINSTALLP)
的调用移动到程序的开头,并将对
MPI\u MSGINSTALLP
的引用传递给任何需要它的函数。或者冒风险,使其全球化。:)谢谢。当我有时间的时候,我会再试一次。现在,我绕过了MPI_包和MPI_解包的混乱局面。