MPI使用C ++中的向量属性发送结构体 [英] MPI send struct with a vector property in C++

查看:485
本文介绍了MPI使用C ++中的向量属性发送结构体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想发送一个具有向量属性的结构。

I want to send a struct that has a vector property.

typedef struct {
    int id;
    vector<int> neighbors;
} Node;

我知道我必须创建一个MPI派生的数据类型,如这个答案,但我不知道如何做我的情况下,我有一个向量在结构。

I know i have to create an MPI derived datatype as in this answer, but i don't know how to do it in my case, where i have a vector in the struct.

推荐答案

我不喜欢导入库只是做这个简单的事情的想法。所以这里是我做的:

I didn't like the idea of importing a library just to do this simple thing. So here is what i did:

我认为没有理由让MPI知道对象的底层结构。所以我可以只手动将其转换为缓冲区数组,并且由于接收器知道是期望一个Node结构,可以在另一侧重新创建对象。所以最初我定义了一个 MPI_Contiguous 数据类型并发送:

I thought that there is no reason to have the MPI know anything about the underlying structure of the object. So i could just manually convert it to a buffer array and since the receiver knows that is expecting a Node struct, can recreate the object on the other side. So initially i defined an MPI_Contiguous datatype and send it:

int size = (int) ((node.second.neighbors.size() + 1) * sizeof(int *));

MPI_Datatype datatype;
MPI_Type_contiguous(size, MPI_BYTE, &datatype);
MPI_Type_commit(&datatype);

MPI_Isend(&buffer, 1, datatype, proc_rank, TAG_DATA, MPI_COMM_WORLD, &request); 

这是一个更通用的解决方案并起作用。

This is a more general solution and worked.

但是因为结构包含 int 向量< int> ,我决定创建一个int缓冲第一个元素为 node.id ,并重置为 node.neighbors 。另一方面,使用 MPI_Iprobe (或同步 MPI_Probe )和 MPI_Get_count i可以重新创建Node结构体。下面是代码:

But since the struct contains an int and a vector<int>, i decided to create an int buffer with the first element as the node.id and the reset as the node.neighbors. And on the other side using MPI_Iprobe (or synchronous MPI_Probe) and MPI_Get_count i can recreate the Node struct. Here is the code:

int *seriealizeNode(Node node) {
    //allocate buffer array
    int *s = new int[node.neighbors.size() + 1];
    //set the first element = Node.id
    s[0] = node.id;
    //set the rest elements to be the vector elements
    for (int i = 0; i < node.neighbors.size(); ++i) {
        s[i + 1] = node.neighbors[i];
    }
    return s;
}

Node deseriealizeNode(int buffer[], int size) {
    Node node;
    //get the Node.id
    node.id = buffer[0];
    //get the vector elements
    for (int i = 1; i < size; ++i) {
        node.neighbors.push_back(buffer[i]);
    }
    return node;
}

我认为必须有更高效/更快的方式将节点转换为int [],反之亦然。

I think that there must be a more efficient/faster way for converting the Node to int[] and vice versa. I would like if someone could offer some tips.

然后在发件人端:

while (some_condition){

    ...

    //if there is a pending request wait for it to finish and then free the buffer
    if (request != MPI_REQUEST_NULL) {
        MPI_Wait(&request, &status);
        free(send_buffer);
    }

    // now send the node data
    send_buffer = seriealizeNode(node.second);
    int buffer_size = (int) (node.second.neighbors.size() + 1);
    MPI_Isend(send_buffer, buffer_size, MPI_INT, proc, TAG_DATA, MPI_COMM_WORLD, &request);

    ...
}

int count = 0;
MPI_Iprobe(MPI_ANY_SOURCE, TAG_DATA, MPI_COMM_WORLD, &flag, &status);
if (flag) {
    MPI_Get_count(&status, MPI_INT, &count);
    int *s = new int[count];
    MPI_Recv(s, count, MPI_INT, MPI_ANY_SOURCE, TAG_DATA, MPI_COMM_WORLD, &status);
    Node node = deseriealizeNode(s, count);
    free(s);
    //my logic

}

预期。

这篇关于MPI使用C ++中的向量属性发送结构体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆