MPI调用C++程序

转自http://cnscott.blog.163.com/blog/static/6404570200910941649875/

在运行MPI程序时,有时候需要让并行运算过程中的多个实例共享同一个文件。前提是你安装了MPICH2或者Open MPI,并使用mpicc (for C)和mpicxx(for C++)进行编译。方法如下:

//C Version
#include "mpi.h"
#include ***

MPI_Init(&argc,&argv); //MPI初始化

int rank,size;
MPI_Comm_rank(MPI_COMM_WORLD,&rank); //获得线程序号
MPI_Comm_size(MPI_COMM_WORLD,&size); //获得线程数目

int length=FileName.length();
char t[length+1];
memset(t,0,length+1);
strcpy(t,FileName.c_str());

MPI_File fh;
MPI_Status status;
MPI_File_open(MPI_COMM_WORLD, t, MPI_MODE_CREATE | MPI_MODE_RDWR,
MPI_INFO_NULL, &fh); //以读写方式创建共享文件

stringstream str;
str << "Test of a string stream from thread " << rank << " of " << size << "."<< endl;
int nints=str.str().length();
char buf[nints+1];
memset(buf,0,nints+1);
strcpy(buf,str.str().c_str());

MPI_File_write_shared(fh, buf, nints, MPI_CHAR, &status); //以共享方式将buf内容写入文件
MPI_File_close(&fh); //关闭文件

MPI_Finalize(); //终止MPI

("*** glibc detected *** free(): invalid pointer": 在使用new操作符时要多分配一个存储空间,因为在拷贝字符串时会有一个'\0'的尾巴,这往往会导致delete时产生错误)

程序的多个线程共享文件指针,以阻塞方式操作同一个文件。经过两天的摸索,终于在Geant4中成功地进行了应用。
//C++ Version
#include "mpi.h"
#include ***

//MPI初始化
//MPI::Init(argc,argv);
MPI::Init_thread(argc, argv, MPI::THREAD_MULTIPLE);

int rank,size;
rank = MPI::COMM_WORLD.Get_rank(); //获得线程序号
size = MPI::COMM_WORLD.Get_size(); //获得线程数目

int length=FileName.length();
char t[length+1];
memset(t,0,length+1);
strcpy(t,FileName.c_str());

MPI::File dataFile=MPI::File::Open(MPI::COMM_WORLD,tName,MPI::MODE_CREATE | MPI::MODE_RDWR, MPI::INFO_NULL); //以读写方式创建共享文件

stringstream str;
str << "Test of a string stream from thread " << rank << " of " << size << "."<< endl;
int nints=str.str().length();
char buf[nints+1];
memset(buf,0,nints+1);
strcpy(buf,str.str().c_str());

dataFile.Write_shared(buf, nints, MPI::CHAR); //以共享方式将buf内容写入文件
dataFile.Close(); //关闭文件

MPI::Finalize(); //终止MPI

============================================================================

下面是函数(C)的参考:(以下摘自http://www.ycrc.com.cn/qinghua/03/content/catalog.htm)
MPI_FILE_OPEN(comm, filename, amode, info, fh)
IN   comm    组内通信域
IN   filename  将打开的文件名
IN   amode    打开方式
IN   info    传递给运行时的信息
OUT   fh     返回的文件句柄
int MPI_File_open(MPI_Comm comm, char * filename, int amode, MPI_Info info,
      MPI_File * fh)
MPI_FILE_OPEN(COMM,FILENAME, AMODE, INFO, FH,IERROR)
 CHARACTER *(*) FILENAME
 INTEGER COMM, AMODE, INFO, FH, IERROR
   MPI_FILE_OPEN是一个组调用,即通信域comm中的所有进程都必须按给定的文件名filename来执行它,各进程使用的文件名 filename要相同,给定的打开方式amode也要相同,但是各进程传递给运行时的信息info可以互不相同。该调用返回一个文件句柄fh,以后各进 程对文件的具体操作都是通过文件句柄fh来实现的。
  根据用途的不同,打开方式可以是如下所示的任何9种方式之一。
文件打开方式

打开方式 含义
MPI_MODE_RDONLY 只读
MPI_MODE_RDWR 读写
MPI_MODE_WRONLY 只写
MPI_MODE_CREATE 若文件不存在则创建
MPI_MODE_EXCL 创建不存在的新文件,若存在则错
MPI_MODE_DELETE_ON_CLOSE 关闭时删除
MPI_MODE_UNIQUE_OPEN 不能并发打开
MPI_MODE_SEQUENTIAL 文件只能顺序存取
MPI_MODE_APPEND 追加方式打开,初始文件指针指向文件尾
MPI_FILE_CLOSE(fh)
INOUT   fh    前面打开的文件句柄
int MPI_File_close(MPI_File * fh)
MPI_FILE_CLOSE(FH,IERROR)
  INTEGER FH, IERROR

  MPI_FILE_CLOSE关闭前面已经打开的与句柄fh相联系的文件,它也是一个组调用,即所有打开该文件的进程,也必须都执行关闭操作。这里虽然没有明确指出通信域或进程组,但是,文件句柄fh已包含了进程组的信息。

MPI_FILE_DELETE(filename, info)
IN   filename    将删除的文件名
IN   info      传递给运行时的信息
int MPI_File_delete(char * filename, MPI_Info info)
MPI_FILE_DELETE(FILENAME, INFO, IERROR)
  CHARACTER *(*) FILENAME
  INTEGER INFO, IERROR

MPI_FILE_DELETE删除指定的文件filename。


MPI_FILE_READ_SHARED(fh, buf,count,datatype,status)
INOUT  fh    共享文件句柄
OUT   buf    读取数据存放的缓冲区
IN    count   读取数据的个数
IN    datatype 读取数据的数据类型
OUT   status  返回的状态信息
int MPI_File_read_shared(MPI_File fh, void * buf, int count, MPI_Datatype datatype,
   MPI_Status * status)
MPI_FILE_READ_SHARED(FH, BUF, COUNT,DATATYPE, STATUS,IERROR)
  <type> BUF(*)
  INTEGER FH, COUNT, DATATYPE, STATUS(MPI_STATUS_SIZE), IERROR
   MPI_FILE_READ_SHARED从句柄fh对应的共享文件中读取count个数据类型为datatype的数据,放到buf中,返回的状态是 status。这一调用使用的文件指针是共享指针,即该读取操作完成后,共享指针自动移到下一个数据单元的位置,其它进程再对该共享文件进行操作时,文件 指针的位置是本调用完成后指针移动过的位置。

MPI_FILE_WRITE_SHARED(fh, buf,count,datatype,status)
INOUT  fh    共享文件句柄
IN    buf    写入数据存放的缓冲区
IN    count   写入数据的个数
IN    datatype 写入数据的数据类型
OUT   status  返回的状态信息
int MPI_File_write_shared(MPI_File fh, void * buf, int count, MPI_Datatype datatype,
    MPI_Status * status)
MPI_FILE_WRITE_SHARED(FH, BUF, COUNT,DATATYPE, STATUS,IERROR)
  <type> BUF(*)
  INTEGER FH, COUNT, DATATYPE, STATUS(MPI_STATUS_SIZE), IERROR

   MPI_FILE_WRITE_SHARED向句柄fh对应的共享文件中写入数据,数据存放在buf中,共count个,数据类型为datatype。 返回的状态信息是status。MPI_FILE_WRITE_SHARED调用和MPI_FILE_READ_SHARED一样,写入位置是共享文件指 针对应的位置,该写入操作完成后,共享文件指针自动指向下一个数据单元的位置,指针的移动在所有的进程中都会体现出来,本写入操作完成后,其它进程对共享 文件的操作是在本操作完成后指针所在的位置开始的。

MPI_FILE_IREAD_SHARED(fh, buf,count,datatype,request)
INOUT  fh    共享文件句柄
OUT   buf    读取数据存放的缓冲区
IN   count   读取数据的个数
IN   datatype 读取数据的数据类型
OUT   request  非阻塞读取完成对象
int MPI_File_iread_shared(MPI_File fh, void * buf, int count, MPI_Datatype datatype,
  MPI_Request * request)
MPI_FILE_IREAD_SHARED(FH, BUF, COUNT,DATATYPE, REQUEST,IERROR)
  <type> BUF(*)
  INTEGER FH, COUNT, DATATYPE, REQUEST, IERROR
  MPI_FILE_IREAD_SHARED与MPI_FILE_READ_SHARED一样,也是从句柄fh对应的共享文件中读取count个数据 类型为datatype的数据,存放到buf中,但是这一调用和MPI_FILE_READ_SHARED不同之处就在于它是非阻塞调用,它不必等到文件 读取完成就可以立即返回,而文件读取的最终完成是通过使用本调用返回的非阻塞读取完成对象request执行MPI_WAIT实现的。
MPI_FILE_IWRITE_SHARED(fh, buf,count,datatype,request)
INOUT  fh    共享文件句柄
IN    buf    写入数据存放的缓冲区
IN    count   写入数据个数
IN    datatype 写入数据类型
OUT   request  非阻塞写入完成对象
int MPI_File_iwrite_shared(MPI_File fh, void * buf, int count, MPI_Datatype datatype,
MPI_Request * request)
MPI_FILE_IWRITE_SHARED(FH, BUF, COUNT,DATATYPE, REQUEST,IERROR)
  <type> BUF(*)
  INTEGER FH, COUNT, DATATYPE, REQUEST, IERROR

   MPI_FILE_IWRITE_SHARED向句柄fh对应的共享文件中写入存放在buf中的数据,写入数据的个数是count个,写入数据的数据类 型是datatype。该调用执行后立即返回,不必等到写入操作完成,返回的非阻塞写入完成对象是request,写入操作的最终完成是通过对 request调用MPI_WAIT实现的。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值