Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MPI#u Scatterv不';行不通_C_Mpi - Fatal编程技术网

MPI#u Scatterv不';行不通

MPI#u Scatterv不';行不通,c,mpi,C,Mpi,我用C/MPI编写了一个程序,只需将一个NxN矩阵拆分成子矩阵(行),然后用例程MPI_Scatterv将其分配给所有进程。维度N不一定是进程数的倍数。我决定多给一些进程一行,这些进程等于DIM%大小。代码如下:;它不起作用,我不明白为什么。错误消息如下所示: 作业已中止: 等级:节点:退出代码[:错误消息] 0:PACI:-1073741819:进程0已退出,但未调用finalize #include <mpi.h> #include <stdio.h> #includ

我用C/MPI编写了一个程序,只需将一个NxN矩阵拆分成子矩阵(行),然后用例程MPI_Scatterv将其分配给所有进程。维度N不一定是进程数的倍数。我决定多给一些进程一行,这些进程等于DIM%大小。代码如下:;它不起作用,我不明白为什么。错误消息如下所示: 作业已中止: 等级:节点:退出代码[:错误消息] 0:PACI:-1073741819:进程0已退出,但未调用finalize

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define DIM 4
#define ROOT 0

float **alloc (int, int);
void init (float **, int, int);
void print (float **, int, int);

int main(int argc, char *argv[])
{
    int rank,               
    size,               
    dimrecv,
    i;                  
    int *sendcount = NULL, *displs = NULL;
    float **matrix, **recvbuf;  

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    dimrecv = (int)(DIM / size);
    if(rank < (DIM % size))
        dimrecv += 1 ;
    recvbuf = alloc(dimrecv, DIM); 

    if (rank == ROOT) 
    {
        matrix = alloc(DIM, DIM);
        init(matrix, DIM, DIM);
        sendcount = (int*)calloc(size, sizeof(int));
        displs = (int*)calloc(size, sizeof(int));
        int total = 0;
        printf("MATRIX %d x %d", DIM, DIM);
        print(matrix, DIM, DIM);

        displs[0] = 0;
        for (i = 0; i < size; i++)
        {
            if (i < DIM % size)
                sendcount[i] = (ceil((float)DIM/size))*DIM;
            else
                sendcount[i] = (floor((float)DIM/size))*DIM;
            total += sendcount[i];
            if (i + 1 < size)
                displs[i + 1] = total;
        }
    }
MPI_Scatterv(&(matrix[0][0]), sendcount, displs, MPI_FLOAT,
             recvbuf, dimrecv*DIM, MPI_FLOAT, ROOT, MPI_COMM_WORLD);

printf("\n\n");

for(i = 0; i< size; i++)
{
    MPI_Barrier(MPI_COMM_WORLD);
    if (i == rank)
    {
        printf("SUBMATRIX P%d", i);
        print(recvbuf, dimrecv, DIM);
    }
}

free(matrix[0]);
free(matrix);
free(recvbuf[0]);
free(recvbuf);
/* quit */
MPI_Finalize();
return 0;
}

float **alloc(int rows, int cols)
{
    int i;
    float *num_elem = (float *)calloc(rows*cols, sizeof(float));
    float **matrix= (float **)calloc(rows, sizeof(float*));
    for (i=0; i<rows; i++)
        matrix[i] = &(num_elem[cols*i]);

    return matrix;
}

void init (float **matrix, int rows, int cols)
{
    int i, j;
    srand(time(NULL));
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++)
            matrix[i][j] = 1 + (rand() % 5);
    }
}

void print (float **matrix, int rows, int cols)
{
int i, j;
for (i = 0; i < rows; i++) {
        printf("\n");
        for (j = 0; j < cols; j++)
            printf("%.1f ", matrix[i][j]);
    }
}
#包括
#包括
#包括
#包括
#包括
#定义尺寸4
#定义根0
浮动**分配(整数,整数);
void init(float**,int,int);
无效打印(浮动**,整数,整数);
int main(int argc,char*argv[])
{
整数级,
大小,
dimrecv,
我
int*sendcount=NULL,*disfs=NULL;
浮点**矩阵,**recvbuf;
MPI_Init(&argc,&argv);
MPI通信等级(MPI通信世界和等级);
MPI_通信大小(MPI_通信世界和大小);
dimrecv=(整数)(尺寸/大小);
if(等级<(尺寸百分比))
dimrecv+=1;
recvbuf=alloc(dimrecv,DIM);
if(秩==根)
{
矩阵=alloc(尺寸,尺寸);
init(矩阵,DIM,DIM);
sendcount=(int*)calloc(size,sizeof(int));
disfs=(int*)calloc(size,sizeof(int));
int-total=0;
printf(“矩阵%d x%d”,尺寸,尺寸);
打印(矩阵、DIM、DIM);
显示[0]=0;
对于(i=0;i对于(i=0;i您需要更加小心哪个进程/列组分配内存,哪个进程/列组因此释放内存

在当前的实现中,您需要
rank==ROOT
来分配和初始化
矩阵
sendcount
disfs
。您需要每个列组分配和初始化
sendcount
disfs
(否则,当他们各自输入
MPI_Scatterv
时,他们如何知道他们将接收到什么?)。最后,他们还需要分配但不初始化
recvbuf
。此缓冲区的初始化在
MPI_Scatterv
例程内部进行

[旁注:从技术上讲,您不需要让每个列组初始化
sendcount
disfs
,尽管这肯定是最快的。如果只有
rank==ROOT
进程知道如何计算这些值,那么在进入
MPI\u Scatterv
例行程序。]

当然,您还必须确保只有正确的列组才能释放之前分配的正确内存

这在静态初始化中起作用的原因是,当您最初静态定义数组时,每个列组“分配”了内存。假设您这样做很幼稚,您以前可能在该实现中使用了多余的内存(因为,如上所述,并非每个列组都需要为您使用的每个矩阵/数组分配内存)


希望这能有所帮助。

感谢Nose的建议。不过,该程序运行不正常。修改后的代码如下:

...
MPI_Bcast(sendcount, 4, MPI_INT, ROOT, MPI_COMM_WORLD);
MPI_Bcast(displs, 4, MPI_INT, ROOT, MPI_COMM_WORLD);

MPI_Scatterv(&(matrix[0][0]), sendcount, displs, MPI_FLOAT,
             recvbuf, dimrecv*DIM, MPI_FLOAT, ROOT, MPI_COMM_WORLD);

printf("\n\n");
for(i = 0; i< size; i++)
{
    MPI_Barrier(MPI_COMM_WORLD);
    if (i == rank)
    {
        printf("SUBMATRIX P%d", i);
        print(recvbuf, dimrecv, DIM);
    }
}
if (rank == ROOT) {
    for (i=0; i<DIM; i++)
        free(matrix[i]);
    free(matrix);
}
for(i=0; i<dimrecv; i++)
    free(recvbuf[i]);
free(recvbuf);
free(sendcount);
free(recvbuf);
。。。
MPI_Bcast(发送计数,4,MPI_INT,根,MPI_COMM_WORLD);
MPI_Bcast(显示,4,MPI_INT,根,MPI_COMM_WORLD);
MPI_散射(&(矩阵[0][0])、发送计数、显示、MPI_浮点、,
recvbuf、dimrecv*DIM、MPI_浮点、根、MPI_COMM_WORLD);
printf(“\n\n”);
对于(i=0;i对于(i=0;只有秩0为
sendcount
disfs
分配了任何内存。您需要首先让其他秩为这些指针分配内存,然后
MPI\u Broadcast
它们应该具有的值(并由秩0计算)。作为旁注,通常认为将
malloc
calloc
和co的结果进行转换是不好的形式。