我想举一个例子,展示如何使用MPI_Type_create_subarray
为大型矩阵构建二维循环分布。
我知道这MPI_Type_create_darray
会给我二维循环分布,但它与SCALAPACK
过程网格不兼容。
我会使用MPI_Type_create_subarray
矩阵进行二维块循环分布并将其传递给SCALAPACK
例程。
我可以举个例子吗?
我想举一个例子,展示如何使用MPI_Type_create_subarray
为大型矩阵构建二维循环分布。
我知道这MPI_Type_create_darray
会给我二维循环分布,但它与SCALAPACK
过程网格不兼容。
我会使用MPI_Type_create_subarray
矩阵进行二维块循环分布并将其传递给SCALAPACK
例程。
我可以举个例子吗?
你的问题至少有两个部分。以下部分将讨论这两个组成部分,但将两者的集成留给您。下面两节中包含的示例代码以及下面 ScaLapack 链接中提供的解释应该提供一些指导......
来自DeinoMPI:
以下示例代码说明了 MPI_Type_create_subarray。
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
int myrank;
MPI_Status status;
MPI_Datatype subarray;
int array[9] = { -1, 1, 2, 3, -2, -3, -4, -5, -6 };
int array_size[] = {9};
int array_subsize[] = {3};
int array_start[] = {1};
int i;
MPI_Init(&argc, &argv);
/* Create a subarray datatype */
MPI_Type_create_subarray(1, array_size, array_subsize, array_start, MPI_ORDER_C, MPI_INT, &subarray);
MPI_Type_commit(&subarray);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (myrank == 0)
{
MPI_Send(array, 1, subarray, 1, 123, MPI_COMM_WORLD);
}
else if (myrank == 1)
{
for (i=0; i<9; i++)
array[i] = 0;
MPI_Recv(array, 1, subarray, 0, 123, MPI_COMM_WORLD, &status);
for (i=0; i<9; i++)
printf("array[%d] = %d\n", i, array[i]);
fflush(stdout);
}
MPI_Finalize();
return 0;
}
不幸的是,没有用于 ScaLAPACK 或 PBLAS 的 C 接口。所有参数都应该通过引用传递到例程和函数中,您还可以定义常量(i_one 表示 1,i_negone 表示 -1,d_two 表示 2.0E+0 等)以传递到例程中.矩阵应该存储为一维数组(A[ i + lda*j ],而不是 A[i][j])
要在您的程序中调用 ScaLAPACK 例程,您应该首先通过 BLACS 例程初始化网格(BLACS 就足够了)。其次,您应该将矩阵分布在进程网格上(块循环二维分布)。您可以通过 pdgeadd_PBLAS 例程来执行此操作。该例程计算两个矩阵 A、B 的和:B:=alpha A+beta B)。矩阵可以有不同的分布,特别是矩阵A只能由一个进程拥有,因此,设置 alpha=1, beta=0 您可以简单地将非分布式矩阵 A 复制到分布式矩阵 B 中。
第三,为矩阵B调用pdgeqrf_。在ScaLAPACK部分代码的最后,您可以在一个进程上收集结果(只需通过pdgeadd_将分布式矩阵复制到本地)。最后,通过 blacs_gridexit_ 和 blacs_exit_ 关闭网格。
毕竟,使用 ScaLAPACK 的程序应该包含以下内容:
void main(){
// Useful constants
const int i_one = 1, i_negone = -1, i_zero = 0;
const double zero=0.0E+0, one=1.0E+0;
... (See the rest of code in linked location above...)