标签: mpi-rma

使用MPI_Put的异步有限差分格式

Donzis&Aditya的一篇论文表明,有可能使用可能在模板上有延迟的有限差分方案.这是什么意思?FD方案可能用于解决热方程和读取(或简化它)

u[t+1,i] = u[t,i] + c (u[t,i-1]-u[t,i+1])
Run Code Online (Sandbox Code Playgroud)

意思是,下一个时间步的值取决于同一位置的值及其前一时间步的邻居.

通过将(在我们的示例中为1D)域分割到不同的处理器上,可以容易地将该问题平行化.但是,在计算处理器的边界节点时我们需要通信,因为该元素u[t,i+-1]仅在另一个处理器上可用.

问题在下图中说明,该图取自引用的论文.

在此输入图像描述

MPI实现可能使用MPI_SendMPI_Recv进行同步计算.由于计算本身相当容易,因此通信可能成为可能的瓶颈.

该论文给出了该问题的解决方案:

尽管它可能是较早时间步长的值,但只需获取可用的边界音符而不是同步过程.然后该方法仍然收敛(在某些假设下)

对于我的工作,我想实现异步MPI案例(这不是本文的一部分).同步部件使用MPI_Send并且MPI_Recv工作正常.我将内存扩展了两个元素作为相邻元素的ghost单元格,并通过发送和接收发送所需的值.下面的代码基本上是上图的实现,并且在计算之前的每个时间步骤期间执行.

MPI_Send(&u[NpP],1,MPI_DOUBLE,RIGHT,rank,MPI_COMM_WORLD);
MPI_Recv(&u[0],1,MPI_DOUBLE,LEFT,LEFT,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

MPI_Send(&u[1],1,MPI_DOUBLE,LEFT,rank,MPI_COMM_WORLD);
MPI_Recv(&u[NpP+1],1,MPI_DOUBLE,RIGHT,RIGHT,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
Run Code Online (Sandbox Code Playgroud)

现在,我绝不是MPI专家.我想,这MPI_Put可能是我需要的异步情况和阅读一点,我想出了以下实现.

在时间循环之前:

MPI_Win win;
double *boundary;
MPI_Alloc_mem(sizeof(double) * 2, MPI_INFO_NULL, &boundary);
MPI_Info info;
MPI_Info_create(&info);
MPI_Info_set(info,"no_locks","true");
MPI_Win_create(boundary, 2*sizeof(double), sizeof(double), info, MPI_COMM_WORLD, &win);
Run Code Online (Sandbox Code Playgroud)

在时间循环内:

MPI_Put(&u[1],1,MPI_DOUBLE,LEFT,1,1,MPI_DOUBLE,win);
MPI_Put(&u[NpP],1,MPI_DOUBLE,RIGHT,0,1,MPI_DOUBLE,win);
MPI_Win_fence(0,win);
u[0] = boundary[0];
u[NpP+1] = boundary[1];
Run Code Online (Sandbox Code Playgroud)

它将所需的元素放在窗口中,即boundary(具有两个元素的数组)在相邻的处理器上u[0]u[NpP+1]boundary数组本身获取值.这个实现工作正常,我得到了相同的结果MPI_Send/Recv.但是,由于我还在使用MPI_Win_fence,这并不是真正的异步,据我所知,这确保了同步.

问题是:如果我取出MPI_Win_fence里面的值boundary永远不会更新并保持初始值.我的理解是,如果没有MPI_Win_fence …

c parallel-processing asynchronous mpi mpi-rma

9
推荐指数
1
解决办法
612
查看次数

创建一个在MPI进程中保持同步的计数器

我在使用基本通信和组MPI2方法方面有相当多的经验,并且使用MPI进行了相当多的令人尴尬的并行仿真工作.到目前为止,我已经构建了我的代码,以便有一个调度节点和一堆工作节点.调度节点具有将与模拟器一起运行的参数文件列表.它使用参数文件为每个工作节点播种.工作节点运行其模拟,然后请求调度节点提供的另一个参数文件.运行所有参数文件后,调度节点会在关闭自身之前关闭每个工作节点.

参数文件通常命名为"Par_N.txt",其中N是标识整数(例如,-N = 1-1000).所以我在想,如果我可以创建一个计数器,并且可以在所有节点上同步这个计数器,我就可以省去调度节点,并使系统更简单一些.理论上这听起来很简单,在实践中我怀疑它有点困难,因为我需要确保计数器在被改变时被锁定等等.并且认为可能存在MPI的内置方式处理这个(事情.有什么想法吗?我在想这个吗?

c++ count mpi thread-safety mpi-rma

6
推荐指数
1
解决办法
3002
查看次数

使用MPI-2的RMA函数在Fortran程序中进行分段错误

只要包含MPI_GET调用,以下简短的Fortran90程序就会崩溃.等级1尝试从等级0读取值并在MPI_WIN_UNLOCK中挂起.排名0尝试在MPI_BARRIER中发生崩溃并出现分段错误.

我反复检查命令的语法,但它们似乎是正确的.C/C++中的类似代码在同一系统上运行.

我正在使用OpenMPI 1.4.3和gfortran 4.4.5.

PROGRAM mpitest
USE mpi
IMPLICIT NONE

INTEGER :: ierr, npe, rnk, win
INTEGER (KIND=MPI_ADDRESS_KIND) lowerbound, sizeofreal
REAL :: val = 1.0, oval = 2.0

CALL MPI_INIT( ierr )
CALL MPI_COMM_RANK( MPI_COMM_WORLD, rnk, ierr )
CALL MPI_COMM_SIZE( MPI_COMM_WORLD, npe, ierr )

CALL MPI_TYPE_GET_EXTENT(MPI_REAL, lowerbound, sizeofreal, ierr)

CALL MPI_WIN_CREATE(val, sizeofreal, sizeofreal, MPI_INFO_NULL, MPI_COMM_WORLD, win, ierr)

IF( rnk .EQ. 1 ) THEN
   CALL MPI_WIN_LOCK( MPI_LOCK_SHARED, 0, 0, win, ierr )
   CALL MPI_GET( oval, 1, MPI_REAL, 0, 0, 1, …
Run Code Online (Sandbox Code Playgroud)

fortran mpi mpi-rma

5
推荐指数
1
解决办法
1121
查看次数

MPI:如何正确使用 MPI_Win_allocate_shared

我想在进程之间使用共享内存。我尝试了 MPI_Win_allocate_shared 但当我执行程序时它给了我一个奇怪的错误:

文件./src/mpid/ch3/include/mpid_rma_shm.h第 592 行断言失败:local_target_rank >= 0 internal ABORT

这是我的来源:

    # include <stdlib.h>
    # include <stdio.h>
    # include <time.h>
    
    # include "mpi.h"
    
    int main ( int argc, char *argv[] );
    void pt(int t[], int s);
    
    int main ( int argc, char *argv[] )
    {
        int rank, size, shared_elem = 0, i;
        MPI_Init ( &argc, &argv );
        MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
        MPI_Comm_size ( MPI_COMM_WORLD, &size );
        MPI_Win win;
        int *shared;
        
        if (rank == 0) shared_elem = …
Run Code Online (Sandbox Code Playgroud)

mpi mpi-rma

3
推荐指数
1
解决办法
5125
查看次数