如何使用 mpi scatter 修复“矢量下标超出范围”?

Posted

技术标签:

【中文标题】如何使用 mpi scatter 修复“矢量下标超出范围”?【英文标题】:How to fix "vector subscript out of range" using mpi scatter? 【发布时间】:2019-09-10 22:16:11 【问题描述】:

问题在于我对 boost MPI 包装器如何工作的误解。 我正在使用 Microsoft MPI 实现。 在这段代码中,我试图将std::vector 分散到进程中,但得到一个调试断言vector subscript out of range 错误。

这段代码是我使用 boost 包装器和 Microsoft MPI 实现超排序算法的引导程序。

我尝试了来自 boost 库的示例,但得到了相同的断言。 我还尝试将<vector><boost/serialization/vector> 都包含在内,但没有帮助。 我使用 boost 1.70 和最新版本的 Microsoft MPI 在 Windows 10 上运行我的程序。

#pragma once

#include <boost/mpi.hpp>
#include <boost/mpi/collectives.hpp>
#include <boost/serialization/vector.hpp>

#include "qsort.hpp"
#include "utils.hpp"

namespace algo 
namespace mpi_extension 

namespace mpi = boost::mpi;

void hyperqsort_v1(int argc, char* argv[]) 
    mpi::environment env(argc, argv);
    mpi::communicator world;
    int value = 0;
    int recv_value = 0;

    std::vector<int> unsorted_list5, 3, 6, 2, 9, 1, 10, 7;
    auto distribuion_number = unsorted_list.size() / world.size();
    std::vector<std::vector<int>> unsorted_dist_list;
    if(0 == world.rank()) 
        for(size_t j = 0; j < world.size(); ++j) 
            for(size_t k = 0 + j; k < distribuion_number + j; ++k) 
                unsorted_dist_list[j].push_back(unsorted_list[j + k]);
            
        

    
    std::vector<int> recv_vector;
    recv_vector.resize(distribuion_number);
    mpi::scatter(
        world, unsorted_dist_list, recv_vector, 0);


 // namespace mpi_extension
 // namespace algo

qsort.hpp - qsort 算法的顺序实现

我希望通信器中的所有进程都有自己的未排序列表。

我只能在调试版本中产生这个错误

【问题讨论】:

我只能在调试版本中产生此错误我认为这是因为在发布模式下不存在越界检查。你还有一些错误。 第一步是让你的调试器告诉你哪一行包含越界访问。 【参考方案1】:

您只会在调试版本中遇到该错误,因为 Microsoft 编译器仅在调试版本中包含该检查。发布版本中仍然存在问题。

如果world.rank() 为零,当您在unsorted_dist_list[j] 中使用unsorted_dist_list 时,它将是一个空向量。至少,您应该添加

unsorted_dist_list.resize(world.size());

for (size_t j = 0; 循环之前。

如果world.rank() 不为零,则unsorted_dist_list 在传递给mpi::scatter 时将为空。

【讨论】:

感谢您的回答,但我自己制定了解决方案。【参考方案2】:

正确的方法是使用 std::vector::data() 来获取第一个元素的地址。 可能它仅适用于 Microsoft MPI 实现。

没有上升调试断言的示例: mpiexec -n 4

mpi::environment env;
mpi::communicator world;

std::vector<int> unsorted_list11, 36, 44, 50, 53, 67, 86, 95;
std::vector<int> list;
list.resize(2);

mpi::scatter(world, unsorted_list.data(), list.data(), 2, 0);

【讨论】:

以上是关于如何使用 mpi scatter 修复“矢量下标超出范围”?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 MPI_Scatter 和 MPI_Gather 计算多个进程的平均值?

如何从 C 中使用 MPI_Scatter 和 MPI_Gather?

如何在 MPI_Scatter 的数组中分散多个变量

使用 MPI_Send 和 MPI_Recv 实现 MPI_Scatter 的问题

将 MPI_Scatter 与 MPI_Type_vector 一起使用时列的意外分布

C 中的 MPI_Scatter 结构