Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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
C MPI_散射-发送二维阵列的列_C_Mpi - Fatal编程技术网

C MPI_散射-发送二维阵列的列

C MPI_散射-发送二维阵列的列,c,mpi,C,Mpi,我想将2D数组的列发送到单独的进程。我现在有一个完整的2d阵列,我被MPI_散射所困扰。如何将整列作为字段发送 谢谢 编辑: 我有数组-浮点a[100][101] 我已尝试通过以下方式发送阵列: float send; MPI_Scatter ((void *)a, n, MPI_FLOAT,(void *)&send , 1, MPI_INT,0, MPI_COMM_WORLD); 编辑2: 我制作了新的类型_向量: MPI_Datatype newt

我想将2D数组的列发送到单独的进程。我现在有一个完整的2d阵列,我被MPI_散射所困扰。如何将整列作为字段发送

谢谢

编辑:

我有数组-浮点a[100][101]

我已尝试通过以下方式发送阵列:

float send;
MPI_Scatter ((void *)a, n, MPI_FLOAT,(void *)&send  , 1, MPI_INT,0, MPI_COMM_WORLD);
编辑2:

我制作了新的类型_向量:

               MPI_Datatype newtype;

               MPI_Type_vector(n,       /* # column elements */
                   1,           /* 1 column only */
                   n+1,         /* skip n+1 elements */
                   MPI_FLOAT,       /* elements are float */
                   &newtype);       /* MPI derived datatype */

               MPI_Type_commit(&newtype);

现在我正试图将它发送到我的其他进程。矩阵由浮点数填充,我的矩阵是nxn+1,因为测试是n=5,所以它是矩阵5x6。什么样的分散调用会起作用,我应该从其他进程的角度采取什么方法?我的意思是,如何获得通过分散发送的数据?

分散尝试以相等的比例发送它必须发送的数据。不幸的是,C中的数据是按行存储的,而不是按列存储的。因此,您的调用将导致分散获取n个元素,然后发送每个进程m=n/(进程数)浮点

解决此问题的常用方法是创建新的MPI向量数据类型(请参阅函数MPI_Type_vector),在该数据类型中,您将能够克服C数组的行数据存储问题(因为您可以定义向量中元素之间的跨距,这正好是一行的长度)


我还没有用这种方式使用带有向量的散布,所以我不确定这是否有助于调用散布,但至少您能够轻松地按列访问数据。然后,通过使用循环将这些数据传递给相应的进程将是一种简单的方法,这有很多问题,但主要问题是内存布局。在由
a
表示的内存位置上,没有一个
float
:只有
float*
s指向内存中其他位置的各种
float
数组。因为这些数组不一定是连续的,所以不能在它们上使用

最简单的解决方案是将矩阵存储在单个阵列中:

float a[100*101];
并按主顺序填写。然后像这样散开:

MPI_Scatter(a, 100*101, MPI_FLOAT, send, 10*101, MPI_FLOAT, 0, MPI_COMM_WORLD);

这是假设您分散在10个进程之间,
send
被定义为每个进程中的
float[10*101]
。请注意,在您发布的代码中,Scatter的参数4-6肯定有缺陷。如果
send
是一个数组,那么您不需要传递
&send
(出于同样的原因,您不需要在第一个参数中传递
&a
),并且您希望将收到的数据项的数量和类型与发送的数据项相匹配。

这与此问题非常相似:。问题是,列在内存中不是连续的,所以您必须四处游荡

在C语言中,由于缺少真正的多维数组,所以在内存布局上必须小心一点。我相信在C语言中,静态声明的数组

float a[nrows][ncols]
将在内存中连续,因此您现在应该没事了。但是,请注意,一旦进入动态分配,情况就不再是这样了;您必须一次分配所有数据,以确保获得连续的数据,例如

float **floatalloc2d(int n, int m) {
    float *data = (float *)malloc(n*m*sizeof(float));
    float **array = (float **)calloc(n*sizeof(float *));
    for (int i=0; i<n; i++)
        array[i] = &(data[i*m]);

    return array;
}

float floatfree2d(float **array) {
    free(array[0]);
    free(array);
    return;
}

/* ... */
float **a;
nrows = 3;
ncols = 2;
a = floatalloc2d(nrows,ncols);
我会做你想做的。注意,接收进程将具有与发送进程不同的类型,因为它们存储的列数较少;因此元素之间的跨距更小

最后,你现在可以分散注意力了

MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if (rank == 0) {
    a = floatalloc2d(nrows,ncols);
    sendptr = &(a[0][0]);
} else {
    sendptr = NULL;
}
int ncolsperproc = ncols/size;  /* we're assuming this divides evenly */
b = floatalloc(nrows, ncolsperproc);

MPI_Datatype acol, acoltype, bcol, bcoltype;

if (rank == 0) {
    MPI_Type_vector(nrows,    
               1,                  
               ncols,         
               MPI_FLOAT,       
               &acol);       

     MPI_Type_commit(&acol);
     MPI_Type_create_resized(acol, 0, 1*sizeof(float), &acoltype);
}
MPI_Type_vector(nrows,    
               1,                  
               ncolsperproc,         
               MPI_FLOAT,       
               &bcol);       

MPI_Type_commit(&bcol);
MPI_Type_create_resized(bcol, 0, 1*sizeof(float), &bcoltype);
MPI_Type_commit(&bcoltype);

MPI_Scatter (sendptr, ncolsperproc, acoltype, &(b[0][0]), ncolsperproc, bcoltype, 0, MPI_COMM_WORLD);

您的数组是如何定义的,您如何调用Scatter?谢谢您的评论,但我将使用colums进行一些计算,所以不可能有[100*101]字段。您好,请参阅我的edit2。我已经创建了新的MPI_类型_向量,但现在我很困惑,如何将正确的值传递给散点,甚至发送。。。你能帮我吗?谢谢你这么长的回复!我一定要去尝尝。与此同时,我在思考我的整个问题。我在做平行高斯消去法。因此,在开始时,我想发送到所有其他进程列,用于计算pivot。但现在我把整个矩阵发送给所有人,所以我有点希望整个矩阵会更好。。。进程将在行之间进行计数,所以我认为在所有进程上都有矩阵是有用的。
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if (rank == 0) {
    a = floatalloc2d(nrows,ncols);
    sendptr = &(a[0][0]);
} else {
    sendptr = NULL;
}
int ncolsperproc = ncols/size;  /* we're assuming this divides evenly */
b = floatalloc(nrows, ncolsperproc);

MPI_Datatype acol, acoltype, bcol, bcoltype;

if (rank == 0) {
    MPI_Type_vector(nrows,    
               1,                  
               ncols,         
               MPI_FLOAT,       
               &acol);       

     MPI_Type_commit(&acol);
     MPI_Type_create_resized(acol, 0, 1*sizeof(float), &acoltype);
}
MPI_Type_vector(nrows,    
               1,                  
               ncolsperproc,         
               MPI_FLOAT,       
               &bcol);       

MPI_Type_commit(&bcol);
MPI_Type_create_resized(bcol, 0, 1*sizeof(float), &bcoltype);
MPI_Type_commit(&bcoltype);

MPI_Scatter (sendptr, ncolsperproc, acoltype, &(b[0][0]), ncolsperproc, bcoltype, 0, MPI_COMM_WORLD);