【发布时间】:2021-09-22 22:17:16
【问题描述】:
我的主要问题是如何将自定义类型/结构的成员与通过 MPI_Win_allocate_shared(size,disp,...,&baseptr, &win) 分配的成员相关联。感谢 C 或 fortran 的帮助!下面我包含了我想在 C 和 fortran 中做的事情的草图。
C中的一个例子大致如下:
struct MyStruct{
int * ptr_int;
double * ptr_dble;
};
main(){
int n1,n2,n3;
struct * data;
// I am looking to use MPI to allocate a struct equivalent to the following:
// data = calloc(n3,sizeof(struct MyStruct))
// for (int i=0;i<n3;i++) {
// data[i].ptr_int = calloc(n1,sizeof(int));
// data[i].ptr_dble = calloc(n2,sizeof(double));}
int w_size,w_rank;
MPI_Init(NULL,NULL);
MPI_Comm_size(MPI_COMM_WORLD,&w_size);
MPI_Comm_rank(MPI_COMM_WORLD,&w_rank);
MPI_Win win;
MPI_Aint size;
void * baseptr;
if (w_rank==0){
size = n3*(sizeof(int)*n1 + sizeof(double)*n2);
MPI_Win_allocate_shared(size,1,MPI_INFO_NULL,MPI_COMM_WORLD,&baseptr,&win);
// Question: how to associate struct * data with win, baseptr?
// Can &win then be initialized by calling data[i].ptr_int[j] = ...?
}else{
MPI_Win_shared_query(...);
// Question: again, how to associated struct * data with win, baseptr?
}
}
等价于fortran的一个例子如下:
type MyStruct
integer, allocatable :: ptr_int(:)
real, allocatable :: ptr_dble(:)
end type
program main
implicit none
use mpi
integer :: n1,n2,n3
type(MyStruct), allocatable :: data
integer :: w_rank, w_size, ierr
call mpi_init(ierr)
call mpi_comm_size(mpi_comm_world,w_size,ierr)
call mpi_comm_rank(mpi_comm_world,w_rank,ierr)
MPI_Win MPI_Win
MPI_Aint size
if (w_rank==0) then
size = n3*(sizeof(int)*n1 + sizeof(double)*n2)
call mpi_win_allocate_shared(size,1,MPI_INFO_NULL,MPI_COMM_WORLD,baseptr,win)
! Question: how to associate data with win, baseptr?
! Can win then be initialized by calling data(i)%ptr_int(j) = ...?
else
call mpi_win_shared_query(...);
! Question: again, how to associated type(mystruct) data with win, baseptr?
endif
end program main
【问题讨论】:
-
看看 MPI_Winn_allocate_shared 上的 openmpi 页面,我看到“MPI_Win_allocate_shared 是由 comm 组中的所有进程执行的集体调用” - 你只有一个进程调用它。它继续说“可以使用函数 MPI_Win_shared_query 查询其他进程的基本指针。”所以我从来没有这样做过,但在我看来 win_allocate_shared 为您提供了窗口所有 procs 的句柄,然后查询将进程特定指针作为 void * 返回。
-
另外请注意,我希望您不想从远程进程访问 calloc 分配的内存。指针将是仅在分配进程空间中有意义的地址 - 谁知道它们将指向另一个进程的位置。
-
最后我看到 Fortran 标记已被删除 - 如果您对 Fortran 解决方案感到满意,我建议您编辑问题以明确说明并重新添加 Fortran 标记。