【问题标题】:MPI_Type_create_subarray and MPI_SendMPI_Type_create_subarray 和 MPI_Send
【发布时间】:2011-07-31 19:27:42
【问题描述】:

这是我在 stackoverflow 中的第一个问题。我有两个进程,一个根 0 和一个从属 1。从属分配一个二维数组 (CHUNK_ROWS+2,CHUNK_COLUMNS+2) 并希望发送一个 [CHUNK_ROWS][CHUNK_COLUMNS] 子数组。 Root 分配一个二维数组 (ROWS,COLUMNS) 并从 ddd[0][0] 接收想要存储的子数组并打印它。结果我错了..为什么? 我知道这是一个无意义的代码,但它只是一个简单的程序,可以帮助我完成更复杂的项目。 代码如下:

#include <mpi.h>
#include <iostream>
using namespace std;

#define ROWS 10
#define COLUMNS 10
#define CHUNK_ROWS 5
#define CHUNK_COLUMNS 5
#define TAG 0

int** alloca_matrice(int righe, int colonne)
{
int** matrice=NULL;
int i;

// per allocare la matrice devo fare in questo modo al fine di avere le righe contigue in memoria
// e poter così utilizzare il tipo 'colonna' che definisco con MPI_Type_Vector()
matrice = (int **)malloc(righe * sizeof(int*));

if(matrice != NULL){
    matrice[0] = (int *)malloc(righe*colonne*sizeof(int));
    if(matrice[0]!=NULL)
        for(i=1; i<righe; i++)
            matrice[i] = matrice[0]+i*colonne;
    else{
        free(matrice);
        matrice = NULL;
    }
}
else{
    matrice = NULL;
}
return matrice;
}


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

int my_id, numprocs,length,i,j;
int ndims, sizes[2],subsizes[2],starts[2];
int** DEBUG_CH;
int** ddd;
char name[BUFSIZ];
MPI_Datatype subarray;
MPI_Status status;
MPI_Init(&argc, &argv) ;                    // Chiamata obbligatoria di inizializzazione    
MPI_Comm_rank(MPI_COMM_WORLD, &my_id) ;     // Ottiene l'identificativo del processo
MPI_Comm_size(MPI_COMM_WORLD, &numprocs) ;  // Ottiene quanti processi sono attivi
MPI_Get_processor_name(name, &length);      // Il nome del nodo dove il processo ? in esecuzione



if(my_id==1){
    //creo una sottomatrice ripulita dalle ghost cells
    ndims=2;
    sizes[0] = CHUNK_ROWS+2;
    sizes[1] = CHUNK_COLUMNS+2;
    subsizes[0] = CHUNK_ROWS;
    subsizes[1] = CHUNK_COLUMNS;
    starts[0] = 1;
    starts[1] = 1;
    MPI_Type_create_subarray(ndims,sizes,subsizes,starts,MPI_ORDER_C,MPI_INT,&subarray);
    MPI_Type_commit(&subarray);

    DEBUG_CH = alloca_matrice(CHUNK_ROWS+2,CHUNK_COLUMNS+2);
    for(i=0; i<CHUNK_ROWS+2; i++){
        for(j=0; j<CHUNK_COLUMNS+2; j++){
            if(i==0 || i==CHUNK_ROWS+1 || j==0 || j==CHUNK_COLUMNS+1)
                DEBUG_CH[i][j] = 5;
            else
                DEBUG_CH[i][j] = 1;
        }
    }
    MPI_Send(DEBUG_CH,1,subarray,0,TAG,MPI_COMM_WORLD);
    MPI_Type_free(&subarray);
}
if(my_id==0){
    //creo una sottomatrice ripulita dalle ghost cells
    ndims=2;
    sizes[0] = ROWS;
    sizes[1] = COLUMNS;
    subsizes[0] = CHUNK_ROWS;
    subsizes[1] = CHUNK_COLUMNS;
    starts[0] = 0;
    starts[1] = 0;
    MPI_Type_create_subarray(ndims,sizes,subsizes,starts,MPI_ORDER_C,MPI_INT,&subarray);
    MPI_Type_commit(&subarray);

    ddd = alloca_matrice(ROWS,COLUMNS);
    MPI_Recv(ddd[0],1,subarray,1,TAG,MPI_COMM_WORLD,&status);
    MPI_Type_free(&subarray);
    for(i=0; i<CHUNK_ROWS; i++){
        for(j=0; j<CHUNK_COLUMNS; j++){
            printf("%d ",ddd[i][j]);
        }
        printf("\n");
    }
}
MPI_Finalize();                             // Chiusura di MPI.
return 0;
}

提前致谢。

【问题讨论】:

    标签: c mpi parallel-processing


    【解决方案1】:

    恭喜你,你的代码几乎是完美的,在 MPI_Send 中只有一个愚蠢的错误,而你在 MPI_Recv 中是正确的。

    对于发送,你有

    MPI_Send(DEBUG_CH,1,subarray,0,TAG,MPI_COMM_WORLD);
    

    而对于 Recv,你有

    MPI_Recv(ddd[0],1,subarray,1,TAG,MPI_COMM_WORLD,&status);
    

    第二个是对的。您需要发送一个指向数据开始位置的指针;这不是 DEBUG_CH,它是一个指向 ints 的指针,而是 &(DEBUG_CH[0][0]),或者等效的 DEBUG_CH[0],就像你对 ddd 所做的那样。

    【讨论】:

    • 谢谢乔纳森。有用!现在我用类似的问题编辑了我的问题。也许这不是使用 stackoverflow 的正确方法。我正在努力学习。
    • 将其作为第二个帖子可能会更好,因为现在这是一个完全不同的问题。
    猜你喜欢
    • 2011-07-31
    • 2011-11-11
    • 2012-10-31
    • 2014-04-17
    • 2011-01-24
    • 2011-07-18
    • 2017-10-25
    • 1970-01-01
    • 2019-07-08
    相关资源
    最近更新 更多