CUDA Fortran:多 GPU 编程和内存分配

计算科学 正则 高性能计算 显卡 库达
2021-12-24 08:39:47

我正在编写一个程序,该程序应该使用 CUDA Fortran 在单个节点上使用多个 GPU。尽管我浏览了Portland Group CUDA Fortran Reference,但我仍然不清楚如何在我的情况下进行内存分配。

我正在尝试在多个 GPU 之间拆分模拟域,以便 GPU 共享负载。我有一些限制:

  • 由于使用的分区算法,该字段可能不会完全均匀地分割。因此,给定的 GPU 设备通常最终会得到与其同类设备略有不同的阵列。

  • 代码必须是可扩展的。有些机器可能只有一个 GPU 可用,而其他机器可能有两个、三个、我们的四个 GPU,基于 PCI 端口等。

  • 该字段足够大,我宁愿没有字段变量的简单副本,因为这会将我的字段大小限制为理想场景的 1/N,其中 N 是连接到节点的 GPU 数量。

我尝试遵循在 MPI 中实现时使用的过程,假设每个 GPU 保留一个单独的符号表(分布式内存假设),因此可以单独分配,并使用类似于此的方法:

  program multiGPU
  implicit none
  doubleprecision, allocatable, device :: fieldVAR(:)
  integer, parameter :: NGPUS=3 ! For the sake of this example
  integer :: istat, i, fieldsizes(NGPUS)

  ! field size assigned to each GPU, which would be done through
  ! some partitioning algorithm. Arbitrary assignment here:
  fieldsizes(1)=300
  fieldsizes(2)=400
  fieldsizes(3)=350

  do i=1, NGPUS
      istat= cudaSetDevice(i-1)
      allocate(fieldVAR(fieldsizes(i)))
      !
      !  Assign initial values etc.
      !
  end do
  end program multiGPU

因为在 MPI 中,每个进程都有一个单独的符号表,所有进程唯一的共同点是环境变量,例如带有 MPI_* 前缀的环境变量但是,这种策略似乎不起作用,因为程序似乎与最新版本一起使用分配完成,因此表明即使有两个单独的单元,它们也保留一个符号表,可能是由于具有相同的主机代码。

我想知道是否有比硬编码“GPU1_fieldvar”和“GPU2_fieldvar”更好的方法来分割模拟域。

1个回答

我不确定这是否更适合 StackOverflow,但可以。

最好的方法是创建一个新类型,其中包含该特定 GPU 的可分配数组。

查看 Portland Group 的这篇文章,描述如何使用 CUDA Fortran 进行多 GPU 计算。