Device之间的数据传输
Atlas 200/300/500 推理产品上,当前版本不支持该功能。
注意点说明:
- 可使用aclrtDeviceCanAccessPeer接口查询两个Device之间是否支持内存复制,若支持,需调用两次aclrtDeviceEnablePeerAccess接口使能两个Device之间的内存复制功能(例如,调用一次aclrtDeviceEnablePeerAccess接口使能Device 0到Device 1的内存复制,再调用一次aclrtDeviceEnablePeerAccess接口使能Device 1到Device 0的内存复制),再调用aclrtMemcpy接口(同步接口)或aclrtMemcpyAsync接口(异步接口)通过内存复制的方式实现数据传输。
- 当前仅支持同一个PCIe Switch内Device之间的内存复制。
- 仅支持同一个进程内、线程间的Device之间的内存复制,不支持不同进程间Device之间的内存复制。
调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。
int main(int argc, const char *argv[])
{
// AscendCL初始化
auto ret = aclInit(NULL);
int32_t canAccessPeer = 0;
// 查询Device 0和Device 1之间是否支持内存复制
ret = aclrtDeviceCanAccessPeer(&canAccessPeer, 0, 1);
// 1表示支持内存复制
if (canAccessPeer == 1) {
// ************************************************************
// Device 0 操作
ret = aclrtSetDevice(0);
// 使能当前Device(Device 0)到指定Device(Device 1)的内存复制
ret = aclrtDeviceEnablePeerAccess(1, 0);
void *dev0;
ret = aclrtMalloc(&dev0, 10, ACL_MEM_MALLOC_HUGE_FIRST_P2P);
ret = aclrtMemset(dev0, 10, 1, 10);
ret = aclrtResetDevice(0);
// ************************************************************
// Device 1 操作
ret = aclrtSetDevice(1);
// 使能当前Device(Device 1)到指定Device(Device 0)的内存复制
ret = aclrtDeviceEnablePeerAccess(0, 0);
void *dev1;
ret = aclrtMalloc(&dev1, 10, ACL_MEM_MALLOC_HUGE_FIRST_P2P);
ret = aclrtMemset(dev1, 10, 0, 10);
// 执行复制,将Device 0上的内存数据复制到Device 1上
ret = aclrtMemcpy(dev1, 10, dev0, 10, ACL_MEMCPY_DEVICE_TO_DEVICE);
ret = aclrtResetDevice(1);
// ************************************************************
printf("P2P copy success\n");
} else {
printf("current device doesn't support p2p feature\n");
}
// AscendCL去初始化
aclFinalize();
return 0;
}父主题: 数据传输