1
运行时
MPI+HIP混合编程数据传输问题
2023-05-08 19:26:36
92

多DCU编程DCU间数据传输可以直接通过hipMemcpy进行D2D传输,并且不需要显式设置设备,只需设备内存地址即可传输。现在我想用MPI+HIP编程,在一个节点上开4个进程,每个进程使用一个DCU,想在每个设备直接通信,虽然可以通过MPI函数直接进行通信,但是我想用hipMemcpy D2D的方式进行数据传输,理论上只需要把每个设备内存的地址传递给其他进程即可调用hipMemcpy进行通信,但是我在测试的时候发现无法通过这种方式通信,请问这是什么原因?

#include <stdio.h>
#include <mpi.h>
#include <hip/hip_runtime.h>
#include "hip.h"
#include <iostream>

__global__ void iPrint(int *d_b)
{
  int tid = blockIdx.x * blockDim.x + threadIdx.x;
  printf("((%d))\t", d_b[tid]);
}

__global__ void aaa(int *d_a, int *d_b)
{
    int tid = blockIdx.x * blockDim.x + threadIdx.x;
    d_b[tid] = d_a[tid] * 2;
}

int main(int argc, char **argv)
{
  int myrank, nprocs, ndcus, ilen;
  char processor[100];
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
  MPI_Get_processor_name(processor, &ilen);
  hipGetDeviceCount(&ndcus);
  printf("myrank:%d,node:%s,ndcus:%d\n", myrank, processor, ndcus);
  MPI_Barrier(MPI_COMM_WORLD);

  int *a, *d_a, *d_b;
  a = (int *)malloc(100 * sizeof(int));
  for (int i = 0; i < 100; ++i)
    a[i] = myrank + 100;

  hipSetDevice(myrank);
  hipMalloc(&d_a, 100 * sizeof(int));
  hipMalloc(&d_b, 100 * sizeof(int));
  // 打印地址
  std::cout << myrank << "\t" << d_b << std::endl;
  hipMemcpy(d_a, a, 100 * sizeof(int), hipMemcpyHostToDevice);

  aaa<<<1, 100>>>(d_a, d_b);
  int **d_des = (int **)malloc(4 * sizeof(int *));

  MPI_Gather(&d_b, 1, MPI_UNSIGNED_LONG, d_des, 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
  MPI_Bcast(d_des, ndcus, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);

  if (myrank == 3)
  {
    for (int i = 0; i < 4; ++i)
      std::cout << d_des[i] << "\t";
    std::cout << std::endl;
    hipMemcpy(d_des[1], d_b, 100 * sizeof(int), hipMemcpyDeviceToDevice);
  }
  MPI_Barrier(MPI_COMM_WORLD);

  if (myrank == 1)
  {
    hipMemcpy(a, d_b, 100 * sizeof(int), hipMemcpyDeviceToHost);
    std::cout << myrank << ":";
    for (int i = 0; i < 5; ++i)
      std::cout << a[i] << "\t";
    std::cout << std::endl;
  }
  MPI_Barrier(MPI_COMM_WORLD);
  free(a);
  hipFree(d_a);
  hipFree(d_b);
  MPI_Finalize();
  return 0;
}

代码中是通过把所有进程的d_b地址传递给其他进程,再进行设备数据传输。现在让3号进程DCU上的d_b发送给1号进程,但是一号进程的DCU并未接收到数据。

attachmentId-image.png

作业运行脚本

attachmentId-image.png

全部评论(1)
只看楼主
网
网友zRCyFD
1楼

您好!您不能使用hipMemcpy进行进程间通讯,hipMemcpy只能在1个进程地址空间内使用。不同的进程具有不同的虚拟地址空间,一般来说无法从一个进程访问其他进程的虚拟地址空间。

节点间通讯需要首先把DCU上的数据拷贝到CPU主存,然后用MPI函数发送到通讯进程的CPU主存,然后再从CPU主存拷贝到DCU。

如果在同一个节点内,节点间通讯也可以尝试hipIpc系列的函数,和MPI没有关系。
2023/5/9
没有更多内容了
--
楼主
Level.1
0 帖子
楼主热帖
暂无数据