c++ - std::vector 作为 MPI 非阻塞函数的输入缓冲区

标签 c++ vector mpi

TLDR:如果您的非阻塞 MPI 点对点或 RMA 函数的输入缓冲区是一个 vector ,那么在某些时候指向底层元素的指针将失效(在 vector 插入时),导致如果通信操作未完成,内存损坏问题。

考虑这个函数,我必须将输入数据复制到一个 vector 中,然后再将其传递给 MPI_Issend(或任何非阻塞发送):

    void TaggedIssend(int tag, int target, int count, const long* data)
    {
        // data
        const long msgq_size = msgQ_data_.size();
        for (int i = 0; i < count; i++)
            msgQ_data_.push_back(data[i]);

        // request
        const long req_size = msgQ_reqs_.size();
        msgQ_reqs_.push_back(MPI_REQUEST_NULL);

        MPI_Issend(&msgQ_data_[msgq_size], count, MPI_LONG, 
                target, tag, comm_, &msgQ_reqs_[req_size]);
    }

在某一时刻,msgQ_data_msgQ_reqs_ 将被移动(复制到新位置),此时如果发送未完成,则程序会崩溃(段错误会出现在看似奇怪的地方,并且 MPI_Request 对象在测试时可能会变得无效,仅举几个问题)。尽管我在这个特定问题中使用了 std::vector,但动态调整数组大小也会出现同样的问题。这就是为什么 MPI 通信函数的输入缓冲区类型是 const void*

问题:我有兴趣了解安全使用动态调整大小的数组作为 MPI 非阻塞函数的输入缓冲区的技术。我目前正在将传出数据推送到一个固定大小的缓冲区中,当它已满时,我会一次性发出所有发送,并在重新使用缓冲区之前完成它们。谁能提出更好的选择? 我在这里使用 MPI_Issend 的原因是因为我的发送发生在一个 while 循环内,我可以测试所有发送以完成通信(测试与 MPI_Issend 关联的请求仅当匹配的接收被发布时才会返回 true),并用它来跳出循环。

最佳答案

I am interested to know the techniques to safely use a dynamically resizing array as an input buffer to MPI nonblocking functions.

使用std::vector::reserve分配足够的内存空间。然后,如果您将 push_back 放入该 vector 中,则可以保证在保留容量未满之前不会重新分配。这个解决方案有点脆弱,但如果您事先知道最大 vector 大小,它就会奏效。

或者,您也可以使用 MPI_Bsend 发送,例如,使用一些递增的 tag 参数,然后将此标签发回以测试是否已收到数据。

关于c++ - std::vector 作为 MPI 非阻塞函数的输入缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48590393/

相关文章:

c++ - 设备浏览问题

C++ std::vector 问题

arrays - 将特定元胞数组元素转换为数组

c++ - 如何设置 "discrete_distribution"c++的 vector

c++ - Boost MPI 的 Autoconf 宏?

c++ - 如何在 MPI 中使用多维 STL vector

c++ - 获取指向映射 C++ 中结构的指针

c++如何在不使用返回的情况下从函数中获取数据?

c - 最大数数据类型 MPI

c++ - A*搜索两种可能性