问题描述
我正在尝试使用MPI_Type_create_struct使用MPI派生数据类型对MPI_Alltoallv进行编程.我找不到任何解决此特定问题的示例.大多数示例像这样使用一个单一的struct成员,而我的目标是一个struct数组.以下是一个更简单的测试代码,它尝试对使用DDT创建的结构数组执行MPI_Sendrecv操作:
I am trying to program an MPI_Alltoallv using an MPI Derived datatype using MPI_Type_create_struct. I could not find any examples solving this particular problem. Most examples like this perform communication(Send/Recv) using a single struct member, whereas I am targeting an array of structs. Following is a simpler test code that attempts a MPI_Sendrecv operation on an array of structs created using DDT:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <stddef.h>
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;
}
我在编译时收到以下警告:
I get the following warning at compile time:
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,
并在所有过程中观察到以下错误:
And observe the following error across all processes:
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"注册范围"?如果是这样,引用上述情况的示例确实会有所帮助.
Not sure what I am doing wrong. Do i need to further use "MPI_Type_create_resized " to register the "extent"? If so, an example quoting the above scenario would really help.
我的主要目标也是使用类似的结构数组(大小约为数千个)来执行"MPI_Alltoallv".希望如果我能使SendRecv正常工作,我可以继续进行到"MPI_Alltoallv".
Also my main goal is to perform "MPI_Alltoallv" using a similar array of structs (of size ~ several thousands). Hopefully if I can get the SendRecv to work I can move on to "MPI_Alltoallv".
任何帮助将不胜感激.
推荐答案
sendtype
和recvtype
参数需要类型为MPI_Datatype
的参数.您要传递的是这些数组,即MPI_Datatype *
.
The sendtype
and recvtype
parameters expect a parameter of type MPI_Datatype
. What you're passing in is an array of these, i.e. a MPI_Datatype *
.
一次只能使用这些数组元素之一传递给该函数.
You can only use one of these array elements at a time to pass to this function.
这篇关于创建并传达“结构数组".使用MPI衍生的数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!