使用MPI Derived数据类型创建并传递“结构数组”

我正在尝试使用MPI衍生数据类型使用MPI_Type_create_struct编写MPI_Alltoallv。 我找不到任何解决这个问题的例子。 像这样的大多数例子使用单个struct成员执行通信(Send / Recv),而我的目标是结构数组。 以下是一个更简单的测试代码,它尝试对使用DDT创建的结构数组执行MPI_Sendrecv操作:

#include  #include  #include  #include  typedef struct sample{ char str[12]; int count; }my_struct; int main(int argc, char **argv) { int rank, count; my_struct *sbuf = (my_struct *) calloc (sizeof(my_struct),5); my_struct *rbuf = (my_struct *) calloc (sizeof(my_struct),5); int blens[2]; MPI_Aint displs[2]; MPI_Aint baseaddr, addr1, addr2; MPI_Datatype types[2]; MPI_Datatype contigs[5]; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); strcpy(sbuf[0].str,"ACTGCCAATTCG"); sbuf[0].count = 10; strcpy(sbuf[1].str,"ACTGCCCATACG"); sbuf[1].count = 5; strcpy(sbuf[2].str,"ACTGCCAATTTT"); sbuf[2].count = 6; strcpy(sbuf[3].str,"CCTCCCAATTCG"); sbuf[3].count = 12; strcpy(sbuf[4].str,"ACTATGAATTCG"); sbuf[4].count = 8; blens[0] = 12; blens[1] = 1; types[0] = MPI_CHAR; types[1] = MPI_INT; for (int i=0; i<5; i++) { MPI_Get_address ( &sbuf[i], &baseaddr); MPI_Get_address ( &sbuf[i].str, &addr1); MPI_Get_address ( &sbuf[i].count, &addr2); displs[0] = addr1 - baseaddr; displs[1] = addr2 - baseaddr; MPI_Type_create_struct(2, blens, displs, types, &contigs[i]); MPI_Type_commit(&contigs[i]); } /* send to ourself */ MPI_Sendrecv(sbuf, 5, contigs, 0, 0, rbuf, 5, contigs, 0, 0, MPI_COMM_SELF, &status); for (int i=0; i<5; i++) MPI_Type_free(&contigs[i]); MPI_Finalize(); return 0; } 

我在编译时收到以下警告:

  coll.c(53): warning #810: conversion from "MPI_Datatype={int} *" to "MPI_Datatype={int}" may lose significant bits MPI_Sendrecv(sbuf, 5, contigs, 0, 0, ^ coll.c(54): warning #810: conversion from "MPI_Datatype={int} *" to "MPI_Datatype={int}" may lose significant bits rbuf, 5, contigs, 0, 0, 

并在所有进程中观察以下错误:

  Rank 0 [Thu Jun 16 16:19:24 2016] [c0-0c2s9n1] Fatal error in MPI_Sendrecv: Invalid datatype, error stack: MPI_Sendrecv(232): MPI_Sendrecv(sbuf=0x9ac440, scount=5, INVALID DATATYPE, dest=0, stag=0, rbuf=0x9ac4a0, rcount=5, INVALID DATATYPE, src=0, rtag=0, MPI_COMM_SELF, status=0x7fffffff6780) failed 

不确定我做错了什么。 我是否需要进一步使用“MPI_Type_create_resized”来注册“范围”? 如果是这样,引用上述场景的例子确实会有所帮助。

我的主要目标是使用类似的结构数组(大小〜几千)执行“MPI_Alltoallv”。 希望如果我能让SendRecv工作,我可以转到“MPI_Alltoallv”。

任何帮助将受到高度赞赏。

sendtyperecvtype参数需要一个MPI_Datatype类型的参数。 你传递的是这些数组,即MPI_Datatype *

您一次只能使用其中一个数组元素传递给此函数。