多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并未接收到数据。

作业运行脚本


暂无数据
您好!您不能使用hipMemcpy进行进程间通讯,hipMemcpy只能在1个进程地址空间内使用。不同的进程具有不同的虚拟地址空间,一般来说无法从一个进程访问其他进程的虚拟地址空间。
节点间通讯需要首先把DCU上的数据拷贝到CPU主存,然后用MPI函数发送到通讯进程的CPU主存,然后再从CPU主存拷贝到DCU。
如果在同一个节点内,节点间通讯也可以尝试hipIpc系列的函数,和MPI没有关系。