我已经编写了单个Xeon Phi节点的代码(其上有61个内核)。我有两个文件。我在调用任何其他mpi调用之前调用了MPI_Init(2)。我找到了ntasks,排名也使用mpi调用。我还包括了所有必需的库。我仍然得到一个错误。你能帮帮我吗?
在档案1中:
int buffsize;
int *sendbuff,**recvbuff,buffsum;
int *shareRegion;
shareRegion = (int*)gInit(MPI_COMM_WORLD, buffsize, ntasks); /* gInit is in file 2 */
buffsize=atoi(argv[1]);
sendbuff=(int *)malloc(sizeof(int)*buffsize);
if( taskid == 0 ){
recvbuff=(int **)malloc(sizeof(int *)*ntasks);
recvbuff[0]=(int *)malloc(sizeof(int)*ntasks*buffsize);
for(i=1;i<ntasks;i++)recvbuff[i]=recvbuff[i-1]+buffsize;
}
else{
recvbuff=(int **)malloc(sizeof(int *)*1);
recvbuff[0]=(int *)malloc(sizeof(int)*1);
}
for(i=0;i<buffsize;i++){
sendbuff[i]=1;
MPI_Barrier(MPI_COMM_WORLD);
call(sendbuff, buffsize, shareRegion, recvbuff[0],buffsize,taskid,ntasks);
在文件2中:
void* gInit( MPI_Comm comm, int size, int num_proc)
{
int share_mem = shm_open("share_region", O_CREAT|O_RDWR,0666 );
if( share_mem == -1)
return NULL;
int rank;
MPI_Comm_rank(comm,&rank);
if( ftruncate( share_mem, sizeof(int)*size*num_proc) == -1 )
return NULL;
int* shared = mmap(NULL, sizeof(int)*size*num_proc, PROT_WRITE | PROT_READ, MAP_SHARED, share_mem, 0);
if(shared == (void*)-1)
printf("error in mem allocation (mmap)\n");
*(shared+(rank)) = 0
MPI_Barrier(MPI_COMM_WORLD);
return shared;
}
void call(int *sendbuff, int sendcount, volatile int *sharedRegion, int **recvbuff, int recvcount, int rank, int size)
{
int i=0;
int k,j;
j=rank*sendcount;
for(i=0;i<sendcount;i++)
{
sharedRegion[j] = sendbuff[i];
j++;
}
if( rank == 0)
for(k=0;k<size;k++)
for(i=0;i<sendcount;i++)
{
j=0;
recvbuff[k][i] = sharedRegion[j];
j++;
}
}
然后我在这个recvbuff上的文件1中做了一些计算。 使用sharedRegion变量时出现此分段错误。
答案 0 :(得分:1)
MPI 代表消息传递范例。这意味着,流程(排名)是隔离的,通常在分布式计算机上运行。它们通过显式通信消息进行通信,最近的版本也允许单方面但仍然明确的数据传输。您不能假设共享内存可用于进程。看看任何MPI教程,看看如何使用MPI。
由于您未指定正在运行的机器类型,因此任何进一步的建议都纯属推测。如果您实际上在共享内存计算机上,则可能需要使用真正的共享内存范例,例如OpenMP的。
答案 1 :(得分:0)
虽然可以将MPI限制为仅使用一台机器并具有共享内存(参见RMA章节,特别是在MPI-3中),但如果您只使用一台机器,则更容易使用其他一些范例
但是,如果您要使用多个节点并在一个节点上拥有多个排名(例如多核流程),那么可能值得一看MPI-3 RMA以了解它如何帮助您具有本地共享内存和远程内存访问。关于这个主题有很多论文,但由于它们是如此新颖,所以还没有很多好的教程。你需要挖掘一下才能找到对你有用的东西。
答案 2 :(得分:0)
这两行的顺序:
shareRegion = (int*)gInit(MPI_COMM_WORLD, buffsize, ntasks); /* gInit is in file 2 */
buffsize=atoi(argv[1]);
建议buffsize
在调用gInit
之前和之后可能有不同的值。如果在调用buffsize
时,程序的第一个参数中传递的gInit
大于其初始值,则稍后将发生越界内存访问并导致分段错误。
提示:从调试器内部(例如mpirun
)运行您的代码作为MPI单例(例如,没有gdb
)或更改限制,以便在出现错误时转储核心(例如使用{{ 1}})然后用调试器检查核心文件。使用调试信息进行编译(例如,将ulimit -c unlimited
添加到编译器选项中)在这种情况下会有很多帮助。