Boost MPI send and recv

本文探讨了一种使用Boost库在多个进程间高效分发数据的方法,通过创建并操作自定义类实例,实现了数据在分布式计算环境中的平滑传递。详细介绍了如何构建数据结构、利用Boost库的功能以及优化数据分发过程,旨在提高并行计算任务的效率。
#include "stdafx.h"
#include <boost/mpi.hpp>
#include <iostream>
#include <vector>
#include "VecAndMatrix.h"
namespace mpi = boost::mpi;

class cPoint
{
private:
 friend class boost::serialization::access;

template<class Archive>
 void serialize(Archive &ar, const unsigned int version)
 {
   ar & x;
   ar & y;
   ar & x;
   ar & m;
 }

public:
 double x,y,z;
 double m;
 cPoint(){;};
 cPoint(double xt,double yt,double zt,double mt):x(xt),y(yt),z(zt),m(mt){;};
};

int main(int argc, char *argv[])   {
  mpi::environment env(argc, argv);
  mpi::communicator world;

  int size = world.size();
  int num = int(100*1.0/size);

  if(world.rank() == 0) {
    std::vector<cPoint> point;
    for(int i=0;i<10;i++){point.push_back(cPoint(i, i, i,5));};

    std::vector<cPoint> *vs = &point;
    for(int i=1;i<world.size();i++){world.send(i, 100, vs,1);};


  }
  else {
    std::vector<cPoint> point;
    std::vector<cPoint> *vr = &point;
    world.recv(0, 100, vr,1);

    for(int i=0;i<point.size(); i++) {
        std::cout<<world.rank()<<'\t'<<point[i].x<<'\t'<<point[i].x<<'\t'<<point[i].x<<'\t'<<point[i].m<<std::endl;}
  }

  return 0;
}

以上程序将根进程的一个vector发送给其他所有进程。vector中的元素是cPoint类。以上程序利用了指针,也可以直接用vector,只需将发送接收做如下修改,功能完全相同:

for(int i=1;i<world.size();i++){world.send(i, 100, point);};
world.recv(0, 100, point);

注意此格式只有三个参数。(boost 根据参数进行函数重载)。
template void send(int dest, int tag, const T & value) const;
(Send data to another process.(发送数据到另外一个进程)
This routine executes a potentially blocking send with tag tag to the process with rank dest. It can be received by the destination process with a matching recv call.

template
void send(int dest, int tag, const T * values, int n) const;
Send an array of values to another process.(发送一个数组到另外一个进程,必须要用一个匹配的数组接受调用接收)。

参数:
dest
The process rank of the remote process to which the data will be sent.
n
The number of values stored in the array. The destination process must call receive with at least this many elements to correctly receive the message.
tag
The tag that will be associated with this message. Tags may be any integer between zero and an implementation-defined upper limit. This limit is accessible via environment::max_tag().
values
The array of values that will be transmitted to the receiver. The type T of these values must be mapped to an MPI data type.

要用此函数,数组元素必须是 MPI数据类型,所以应该不能用此函数发送上面的 VECTOR, 但上面的程序在n=1时候能够正确执行,n=2时候不行。

如果有一个vector,想把其中元素平均分给其他进程:

#include "stdafx.h"
#include <boost/mpi.hpp>
#include <iostream>
#include <vector>
#include "VecAndMatrix.h"
namespace mpi = boost::mpi;



int main(int argc, char *argv[])   {
  mpi::environment env(argc, argv);
  mpi::communicator world;
  int tag = 99;
  std::vector<double> v;

  for(int i=0;i<10;i++)v.push_back(i);

 if (world.rank() == 0) {
    int load = v.size()/world.size();
    int start = load+v.size()%world.size();

for (int i = 1; i < world.size(); ++i){
     std::vector<double> to_send (v.begin()+start,v.begin()+start+load);
     world.send(i,tag,to_send);
     start+=load;}
 }
 else {
 std::vector<double> v;
 world.recv(0,tag,v);

 for(int i=0;i<v.size();i++){
     std::cout<<world.rank()<<'\t'<<i<<'\t'<<v[i]<<std::endl;}
}
}

以上程序将10个元素分给n个进程。

<think>首先,用户的问题是关于在Windows系统下设置MPI线程参数的方法。我需要基于提供的引用内容来回答这个问题。 回顾引用: - 引用[1]:讨论MPI标准中的线程支持级别。指出MPICH2在Windows和Unix上都支持MPI_THREAD_MULTIPLE级别,允许任何用户线程随时调用MPI。实现需要线程锁定机制。 - 引用[2]:展示了一个运行结果,使用了多线程MPI,涉及消息发送和接收。提到了标准阻塞接收发送方式。 - 引用[3]:关于Python使用mpi4py进行分布式计算,适合参数化任务。 - 引用[4]:说明在Windows下编译Boost的参数,涉及bjam命令。 用户的上一个问题可能是隐含的,但从当前消息看,用户直接询问Windows系统下设置MPI线程参数的方法。系统级指令提醒我参考用户上一次的问题和我的回答,但我没有之前的上下文,所以专注于当前查询。 关键点是设置MPI线程参数。引用[1]提到线程支持级别,这是核心: - MPI定义了线程级别:MPI_THREAD_SINGLE、MPI_THREAD_FUNNELED、MPI_THREAD_SERIALIZED、MPI_THREAD_MULTIPLE。 - 用户可以向MPI实现请求特定级别的线程支持。 - 引用[1]提到MPICH2支持MPI_THREAD_MULTIPLE在Windows上。 所以,设置MPI线程参数的方法应该涉及如何在程序中初始化MPI时指定线程级别。 在MPI编程中,设置线程参数通常通过调用MPI_Init_thread()函数,而不是标准的MPI_Init()。MPI_Init_thread()允许指定所需的线程支持级别。 步骤: 1. 在程序中包含MPI头文件。 2. 使用MPI_Init_thread()初始化MPI,传入参数如MPI_THREAD_MULTIPLE。 3. MPI实现会返回实际提供的级别;用户可以检查是否支持所需的级别。 引用[4]是关于编译Boost的,似乎不直接相关。引用[2]和[3]涉及MPI使用,但不针对线程参数设置。 用户指定Windows系统,所以需要Windows特定的信息。引用[1]提到MPICH2支持MPI_THREAD_MULTIPLE在Windows上,所以我可以聚焦于MPICH实现。 编译Boost的引用[4]可能暗示用户在使用Boost.MPI或类似,但用户查询是MPI线程参数,不是编译参数。 综合: - 方法:在代码中调用MPI_Init_thread()。 - 使用MPICH或其他MPI实现时,在Windows上支持。 - 示例代码片段可能有帮助。 系统指令要求: - 使用中文回答。 - 行内数学表达式用$...$,但这里可能不需要数学。 - 独立公式用$$...$$,但在文本中可能不适用。 - LaTeX语法正确。 - 生成相关问题。 - 引用段落末尾添加引用标识。 回答结构: - 清晰解释方法。 - 提供示例代码(如果需要)。 - 引用相关引用。 - 结束时生成相关问题。 可能的示例代码: 在C或C++中: ```c #include <mpi.h> int main(int argc, char **argv) { int provided; MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); // 检查provided是否>=所需级别 if (provided < MPI_THREAD_MULTIPLE) { // 处理不支持的情况 } // ... MPI代码 ... MPI_Finalize(); return 0; } ``` 在Python中使用mpi4py(引用[3]提到): ```python from mpi4py import MPI import threading # 初始化MPI comm = MPI.COMM_WORLD if comm.Get_attr(MPI.THREAD_MULTIPLE) is None: # 检查线程支持,但初始化可能隐含 # 在mpi4py中,使用MPI.Init_thread() provided = MPI.Init_thread(MPI.THREAD_MULTIPLE) if provided < MPI.THREAD_MULTIPLE: raise RuntimeError("Thread support level not sufficient") # 然后可以使用多线程 ``` 在mpi4py中,MPI.Init_thread()可用。 用户提到Windows,所以确保兼容性:MPICH或MS-MPI在Windows上都支持。 结束生成相关问题。 引用标识: - 当提到线程支持级别时,引用[1]。 - 如果提到消息传递,引用[2]。 - 如果提到Python,引用[3]。 现在,构建回答。 </think>在Windows系统下设置MPI线程参数的方法主要涉及在MPI程序中初始化线程支持级别,并通过编译和运行时配置来实现。以下是详细的步骤和说明,基于MPI标准(如MPICH2或MS-MPI)的实现: ### 1. **理解MPI线程支持级别** MPI标准定义了四种线程支持级别[^1]: - `MPI_THREAD_SINGLE`:仅主线程可调用MPI函数。 - `MPI_THREAD_FUNNELED`:多线程中,仅主线程可调用MPI函数。 - `MPI_THREAD_SERIALIZED`:多线程可调用MPI函数,但需序列化访问。 - `MPI_THREAD_MULTIPLE`:任何线程可随时调用MPI函数(需线程锁机制)。 在Windows上,MPICH2等实现支持`MPI_THREAD_MULTIPLE`级别[^1],允许高度并行化。 ### 2. **在代码中设置线程参数** 使用`MPI_Init_thread()`函数初始化MPI时指定所需线程级别。示例代码如下(以C语言为例): ```c #include <mpi.h> int main(int argc, char **argv) { int provided; // 实际提供的线程级别 // 请求 MPI_THREAD_MULTIPLE 级别 MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); // 检查实际支持级别 if (provided < MPI_THREAD_MULTIPLE) { // 处理不支持的情况,如降级或报错 } // ... 多线程MPI代码(例如创建线程调用MPI_Send/Recv)... MPI_Finalize(); return 0; } ``` - **关键参数**:`MPI_THREAD_MULTIPLE`请求最高级别线程安全。 - **返回值检查**:`provided`变量返回实际支持的级别,需验证是否满足需求。 - **Python实现(使用mpi4py)**[^3]: ```python from mpi4py import MPI provided = MPI.Init_thread(MPI.THREAD_MULTIPLE) if provided < MPI.THREAD_MULTIPLE: print("警告:线程支持级别不足") # ... 后续多线程并行任务 ... ``` ### 3. **Windows系统下的编译配置** - **MPI库选择**:推荐使用MPICH2或MS-MPI(Microsoft MPI),两者均支持Windows且兼容`MPI_THREAD_MULTIPLE`[^1]。 - **编译命令**:需链接线程安全的MPI库。例如,使用Visual Studio编译器时: ```bash cl /O2 my_mpi_program.c /I "C:\MPI\include" /link /LIBPATH:"C:\MPI\lib" msmpi.lib ``` - **Boost.MPI(如需额外库支持)**[^4]: - 编译Boost时启用MPI线程安全: ```bash bjam install --with-mpi threadapi=win32 link=static runtime-link=shared toolset=msvc ``` - 参数说明:`threadapi=win32`确保Windows线程模型兼容,`link=static`减少依赖。 ### 4. **运行时注意事项** - **线程锁定**:在`MPI_THREAD_MULTIPLE`级别下,MPI内部使用锁机制保证线程安全,开发者无需额外加锁[^1]。 - **消息传递**:多线程中推荐使用阻塞通信(如`MPI_Send`和`MPI_Recv`)以避免竞态[^2]。 - **调试**:启用MPI调试模式检测线程冲突: ```bash mpiexec -n 4 my_program.exe ``` ### 5. **验证线程支持** 运行程序后,检查: - 日志输出实际线程级别(如打印`provided`值)。 - 使用多线程发送/接收消息验证功能[^2],例如开启4线程时进程间通信正常。 通过以上方法,可在Windows系统中高效设置MPI线程参数,实现多线程并行计算。如需参数化任务(如批量测试不同参数),可结合Python mpi4py简化开发[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值