1

私は多くの説明を検索しましたが、どうすればこの状況を行うことができるかを理解できなかったと思います. 私はそのようなことをしたい: マスター プロセッサを使用して、動的な 2D 配列を作成しています。それから私はしたいです。

1- この配列を他のプロセッサに送信します。そして、各プロセッサはこの 2D 配列を出力し、この配列の一部を他のプロセッサに送信します。そして、各プロセッサは自分の部分を画面に出力します。

例えば; 私は 2D 配列 11*11 と 4 つのプロセッサを持っています。ランク0がマスター。他の人は奴隷です。最初の状況では、すべての配列をランク 1、ランク 2、およびランク 3 に送りたいと考えています。2 番目の状況では、行をスレーブに共有したいと考えています。11/3 = 3. したがって、ランク 1 は 3 行、ランク 2 は 3 行、ランク 3 は 5 行になります。

これが私のコードです:

int processorID;  
int numberOfProcessors;  


int main(int argc, char* argv[]){

    MPI_Init(&argc, &argv);  
    MPI_Comm_size(MPI_COMM_WORLD ,&numberOfProcessors);  
    MPI_Comm_rank(MPI_COMM_WORLD ,&processorID);

    double **array;

    if(MASTER){
        array = (double**) malloc(11*sizeof(double *));
        for(i=0; i<11; i++){
            array[i] =  (double *) malloc(11*sizeof(double));
        }

        for(i=0; i<11; i++){
            for(j=0; j<11; j++){
                array[i][j] = i*j;
            }

        }
    }
    MPI_Bcast(array, 11*11, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    if(SLAVE){
        for(i=0; i<11; i++){
            for(j=0; j<11; j++){
                printf("%f ", array[i][j]);
            }

        }
    }

    MPI_Finalize();  
    return 0;  
}

これらのリンクによると; MPI_B 動的な 2 次元配列をキャストします。配列を次のように作成する必要があります。

if (MASTER){

    array = (double**) malloc(121*sizeof(double))

        for(i=0; i<11; i++){
            for(j=0; j<11; j++){
                array[i][j] = i*j;  // this is not working.
            }
        }
}

しかし、これを行うと、配列内の各メンバーを初期化できません。内部 for ループが機能していません。私はそれを解決する方法を見つけることができませんでした。

2 番目の質問については、 MPI を使用して C で 2D 配列のブロックを送信するこのリンクをたどりました。if(SLAVE)の中を変える必要があると思います。スレーブ プロセッサごとに 2D サブアレイを作成する必要があります。そして、MPI_Scatterv を使用する必要があります。しかし、私は完全には理解できませんでした。

int main() {

    ...
    ...

    MPI_Scatterv() // what must be here?
    if(SLAVE){
        if(processorID = numberOfProcessor-1){
            subArray = (double**) malloc(5*sizeof(double *)); // beacuse number of row for last processor is 5
            for(i=0; i<11; i++){
                array[i] =  (double *) malloc(11*sizeof(double));
            }
        }
        else {
            subArray = (double**) malloc(3*sizeof(double *));
            for(i=0; i<11; i++){
                array[i] =  (double *) malloc(11*sizeof(double));
            }
        }
    }
}
4

2 に答える 2

1

各行ポインターは別のノードのアドレス空間に移植できないため、ポインターの配列 (誤って「2D 配列」と呼んでいるもの) を使用することはできません。

線形メモリ割り当てで 2D 配列を作成するために引用したコードは完全に正しいです。ループが次のようになるように、そのメモリを行優先順でインデックス付けするだけです。

double* array = (double*) malloc(121*sizeof(double)); 
if (MASTER){
    for(i=0; i<11; i++){
        for(j=0; j<11; j++){
            array[j+i*11] = i*j;  // row major indexing here
        }
    }
}

/* Scatter code follows */

この種の配列を複数のノードに安全に分散させることができます。

于 2013-01-12T11:10:31.113 に答える
1

C には実際には多次元配列はありません。値を通常の 1D バッファーに格納し、1D 値から正しいインデックスを計算することをお勧めします。そのようです:

double* data = (double*)malloc(sizeof(double)*11*11);

// Now, to access data[i][j], simply do:
data[j + i*11] = ...; // this "maps" 2D indices into 1D

これにより、階層化に関するすべての問題がmalloc回避され、MPI API に簡単に渡すことができます。

于 2013-01-12T11:11:33.747 に答える