首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MPI_Scatter分段故障

MPI_Scatter分段故障
EN

Stack Overflow用户
提问于 2011-03-29 00:25:16
回答 2查看 2.4K关注 0票数 0

我正在编写一个并行排序程序来学习MPI,并且我在使用MPI_Scatter时遇到了问题。每次我尝试运行时,都会得到以下结果:

代码语言:javascript
复制
reading input
Scattering input
_pmii_daemon(SIGCHLD): [NID 00012] PE 0 exit signal Segmentation fault
[NID 00012] 2011-03-28 10:12:56 Apid 23655: initiated application termination

简单地看一下其他问题并不能真正回答为什么我会遇到麻烦--数组是连续的,所以我应该不会遇到非连续内存访问的问题,而且我以正确的顺序传递了正确的指针。有谁有什么想法吗?

下面是源代码-它是为一个特定的数字指定的,因为我还不想处理变量输入和排名大小。

代码语言:javascript
复制
#include <mpi.h>

#include <iostream>
using std::endl;

using std::cout;

#include <fstream>
using std::ifstream;
using std::ofstream;
#include <algorithm>
using std::sort;

#define SIZEOF_INPUT 10000000
#define NUMTHREADS 100
#define SIZEOF_SUBARRAY SIZEOF_INPUT/NUMTHREADS

int main(int argc, char** argv){
    MPI_Init(&argc, &argv);

    int input[SIZEOF_INPUT];
    int tempbuf[SIZEOF_SUBARRAY];

    int myRank;
    MPI_Comm_rank(MPI_COMM_WORLD, &myRank);

    /*
            Read input from file
    */
    if(myRank == 0){
            cout << "reading input" << endl;
            ifstream in(argv[1]);
            for(int i = 0; i < SIZEOF_INPUT; ++i)
                    in >> input[i];
            cout << "Scattering input" << endl;
    }

    // Scatter, Sort, and Gather again    
    MPI_Scatter(input,SIZEOF_INPUT,MPI_INT,tempbuf,SIZEOF_SUBARRAY,MPI_INT,0,MPI_COMM_WORLD);
    cout << "Rank " << myRank << "Sorting" << endl;
    sort(tempbuf,tempbuf+SIZEOF_SUBARRAY);
    MPI_Gather(tempbuf,SIZEOF_SUBARRAY,MPI_INT,input,SIZEOF_INPUT,MPI_INT,0,MPI_COMM_WORLD);

    if(myRank == 0){
            cout << "Sorting final output" << endl;
            // I'm doing a multi-queue merge here using tricky pointer games

            //list of iterators representing things in the queue
            int* iterators[NUMTHREADS];
            //The ends of those iterators
            int* ends[NUMTHREADS];

            //Set up iterators and ends
            for(int i = 0; i < NUMTHREADS; ++i){
                    iterators[i] = input + (i*SIZEOF_SUBARRAY);
                    ends[i] = iterators[i] + SIZEOF_SUBARRAY;
            }

            ofstream out(argv[2]);
            int ULTRA_MAX = SIZEOF_INPUT + 1;
            int* ULTRA_MAX_POINTER = &ULTRA_MAX;
            while(true){
                    int** curr_min = &ULTRA_MAX_POINTER;
                    for(int i = 0 ; i < NUMTHREADS; ++i)
                            if(iterators[i] < ends[i] && *iterators[i] < **curr_min)
                                    curr_min = &iterators[i];

                    if(curr_min == &ULTRA_MAX_POINTER) break;

                    out << **curr_min << endl;
                    ++(*curr_min);
            }
    }

    MPI_Finalize();
}

任何帮助都将不胜感激。向你致敬,扎克

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-29 02:54:10

哈哈!我花了一段时间才看到这个。

诀窍在于,在MPI_Scatter中,sendcount是发送到每个进程的数量,而不是总数。gather也是如此;它是从每个数据库接收的数量。也就是说,它类似于带有计数的MPI_Scatterv;计数是针对每个进程的,但在本例中,它被假定是相同的。

所以这就是

代码语言:javascript
复制
MPI_Scatter(input,SIZEOF_SUBARRAY,MPI_INT,tempbuf,SIZEOF_SUBARRAY,MPI_INT,0,MPI_COMM_WORLD);
cout << "Rank " << myRank << "Sorting" << endl;
MPI_Gather(tempbuf,SIZEOF_SUBARRAY,MPI_INT,input,SIZEOF_SUBARRAY,MPI_INT,0,MPI_COMM_WORLD);

这对我很有效。

另外,在堆栈上分配像这样的大型数组时要小心;我知道这只是一个示例问题,但对我来说,这马上就会导致崩溃。动态地做它

代码语言:javascript
复制
int *input = new int[SIZEOF_INPUT];
int *tempbuf = new int[SIZEOF_SUBARRAY];
//....
delete [] input;
delete [] tempbuf;

解决了这个问题。

票数 3
EN

Stack Overflow用户

发布于 2011-03-29 00:43:18

代码语言:javascript
复制
int* iterators[NUMTHREADS];
//The ends of those iterators
int* ends[NUMTHREADS];

//Set up iterators and ends
 for(int i = 0; i < NUMTHREADS; ++i){
       iterators[i] = input + (i*SIZEOF_SUBARRAY); // problem
       ends[i] = iterators[i] + SIZEOF_SUBARRAY;   // problem
 }

这两个iterators and ends都是整数指针数组,没有指向任何地方或垃圾。但是在for循环中,试图保持这些值就好像它们指向某个位置,这会导致分段错误。程序应该首先分配内存,迭代器可以指向,然后应该将值保持在它们所指向的位置。

代码语言:javascript
复制
for( int i=0 ; i < NUMTHREADS; ++i )
{
     iterators[i] = new int; 
     end[i] = new int ; 
}
// Now do the earlier operation which caused problem

由于程序管理资源(即从new获取),因此当不再需要时,它应该使用delete[]将资源返回到免费存储。使用std::vector而不是自己管理资源,这非常容易。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5462046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档