2017-02-07 21 views
-1

私はここで多くの同様のスレッドを見ましたが、私の問題は、私のプログラムが実際には異なる設定で実行されていることです。例えばMPIエラー:(セグメンテーションフォールト:11)

:私のマトリックスは、2つのコアの1024x1024

ある:エラー4 11

、8、16等が正常に動作します。

マトリックス2048x2048:任意のコア設定について

:エラー11

私はこれがなぜ起こるか、各プロセスが計算する2048 /(総プロセス)X 2028行列を取っている理解していません。そしてそれは正しく働くはずです。

これは私が私の行列を宣言する方法です:

int temp[wp][hp]; 

のために受け取る:

rc = MPI_Recv(&temp[0][0], wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status); 

して送信用:私はそれを得ることはありません

rc = MPI_Send(&temp[0][0], wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD); 

、それがあるべきワーキング。ポインタが関係しているのではないかと思いますか?

+1

CおよびC++は、 2つの異なる言語。 'wp'や' hp'が変数ならば、これは: 'int temp [wp] [hp];'は法的なC++ではありません。 – PaulMcKenzie

+3

また、 '2048 * 2048 * sizeof(int)' - それが何であるか、配列がローカルであるかグローバルに宣言されているかを考慮してください。それがローカルの場合。あなたはスタックを吹き飛ばしているかもしれません。 – PaulMcKenzie

+1

@PaulMcKenzieそれはCです、あなたは正しいです。私は、あなたがグローバルに、あるいはローカルで何を意味するのかよく分かりません。 '' temp''はmain()の中で宣言され、すべてのプロセスにアクセス可能です。 8つのプロセスがあれば、この行列は256x2048でなければなりません。最後の行列は '' im''と呼ばれ、2048x2048で、すべてのプロセスにもアクセス可能ですが、実際にはマスタープロセスだけが最後に使用します。 –

答えて

2

私はその後、私は

rc = MPI_Recv(temp, wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status); 

rc = MPI_Send(temp, wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD); 

と私は配列を使用して終わりだし、他の行を変更しますmalloc関数

int *temp =(int*)malloc(wp * hp * sizeof(int)); 

を持つ配列を作成します、私はそれを解放する。

free(temp) 

コメント欄に既に記載されているように、配列をあなたの方法で割り当てることは、合法的ではありません。++。

編集:

あなたは、配列の二次元にアクセスしたい場合は、ここではそのためのパターンは次のとおりです。

temp[rowToAccess * numberOfColumns + columnToAcess] 
+0

入力いただきありがとうございます!私は今これを得ています: ''エラー:添え字付きの値は配列、ポインタ、またはベクトルではありません '' '' im [k] [l] = temp [cnt] [l]; '' –

+1

@MpkRoes基本的には1次元の「配列」にアクセスするために2次元の配列構文を使用しています(実際には配列ではありませんが、引数のためにそれを呼びましょう)。したがって、 '[] []'構文を保持したい場合は、2D配列を動的に作成しなければなりません。これは、プログラミングボード上のクイックアンサーより良い 'C'ブックが良い場所です。 – PaulMcKenzie

+1

@MpkRoes - 答えは基本的に正しいです。唯一の問題は、2次元配列を作成するために 'malloc'を使う必要があるため、2D配列の構文' [] [] 'を使うことです。興味があれば私は答えを投稿した。 – PaulMcKenzie

0

与えられた答えは基本的に問題のランダウンです - あなたはおそらく以上のものスタック空間を使用して配列を格納し、スタック用に予約されたメモリを使い果たします。

このように、ソリューションは動的にアレイを作成することです。ここで

は、動的に2次元配列を作成する例です:

#include <stdlib.h> 
//... 
int** create2DArray(unsigned nrows, unsigned ncols) 
{ 
    unsigned i; 
    int** ptr = malloc(nrows * sizeof(int*)); // allocate pointers to rows 
    if (ptr != NULL) 
    { 
     int* pool = malloc(nrows * ncols * sizeof(int)); // allocate pool of memory 
     if (pool != NULL) 
     { 
      for (i = 0; i < nrows; ++i, pool += ncols) 
       ptr[i] = pool; // point the row pointers into the pool 
     } 
     else 
     { 
      free(ptr); 
      ptr = NULL; 
     } 
    } 
    return ptr; 
} 

void delete2DArray(int** arr) 
{ 
    free(arr[0]); // remove the pool 
    free(arr);  // remove the pointers 
} 

int main() 
{ 
    int **temp = create2DArray(2048, 2048); 
    if (temp != NULL) 
    { 
     temp[0][0] = 10; // for example you can use it like a 2D array 
     delete2DArray(temp); // free the memory 
    } 
} 

これは、本質的にメモリを使用すると、int temp[2048][2048]を使用して作成しようとしたのと同様の連続2次元配列、が、この時間を作成します。スタックではなくヒープから取得されます。

2次元配列のように、[][]の構文を使用できます。

どのように動作するのか詳しくはわかりませんが、ロジックに従うだけで十分です。

+0

ええと、このようなすべての配列を割り当てるのはいいのですか? –

+0

あなたの配列が大きくなく、コンパイル時に次元がわかっている場合は、メモリを 'free()'するという問題があるので、これを行うことはお勧めできません。そうしないとメモリリークが発生します。動的に配列を作成する必要がある場合にのみ、配列を動的に作成する必要があります。その理由は、1)実行時まで配列のサイズが不明である、または2)スタックが大きすぎるためです。 – PaulMcKenzie

+0

私はこのようなすべての行列をやった。それはコンパイルする。私は元の投稿と同じように '' send''と '' recv''を使用します。それ以外の場合はすべてのエラーが発生します。しかし、計算は正確ではありません。何が起こっているのか分かりません。 –

0

したがって、これらの問題だった:@PaulMcKenzieと@Alexで示すように

1)、私は動的にメモリを割り当てる必要がありました。さて問題は、私は

rc = MPI_Send(temp, wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD); 

または

rc = MPI_Recv(temp, wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status); 

@Alexが提案されているよう

を使用した場合、その後、私のプログラムが何らかの理由でクラッシュするということでした。だから私の最初の &temp[0][0]が正しい。

2)第二の問題は、だった私は、fwriteのを使用して、この配列を保存しましたが、uは動的配列を持っている場合、あなたはこのようにそれを行う必要があること:

for (int i = 0; i < w; i++){ 
for (int j = 0; j < h; j++){ 
    fwrite(&im[i][j], sizeof(int), 1, yourfilename); 
} 
} 

乾杯のみんな