跨卡aclrtmemcpy失败,报错 507899
收藏回复举报
跨卡aclrtmemcpy失败,报错 507899
t('forum.solved') 已解决
新人帖
发表于2025-07-07 21:11:47
0 查看

源码如下

 // 跨设备复制,使用P2P直接访问,并增加健壮性检查

        int32_t original_device_id = -1;

        aclrtGetDevice(&original_device_id);

        // --- 1. 检查并双向启用P2P访问 ---

        int32_t can_access_peer = 0;

        // 检查 src -> dst

        ret = aclrtDeviceCanAccessPeer(&can_access_peer, src_gpu_id, dst_gpu_id);

        if (ret != ACL_SUCCESS || can_access_peer == 0) {

            fprintf(stderr, "[CAM %d] P2P access from src %d to dst %d is NOT supported (ret=%d, can_access=%d).\n", i, src_gpu_id, dst_gpu_id, ret, can_access_peer);

            aclrtSetDevice(original_device_id);

            return -1;

        }

        // 检查 dst -> src

        ret = aclrtDeviceCanAccessPeer(&can_access_peer, dst_gpu_id, src_gpu_id);

        if (ret != ACL_SUCCESS || can_access_peer == 0) {

            fprintf(stderr, "[CAM %d] P2P access from dst %d to src %d is NOT supported (ret=%d, can_access=%d).\n", i, dst_gpu_id, src_gpu_id, ret, can_access_peer);

            aclrtSetDevice(original_device_id);

            return -1;

        }

       

        // 在源设备上使能对目标设备的访问

        aclrtSetDevice(src_gpu_id);

        ret = aclrtDeviceEnablePeerAccess(dst_gpu_id, 0);

        if (ret != ACL_SUCCESS && ret != ACL_ERROR_REPEAT_INITIALIZE) {

            fprintf(stderr, "[CAM %d] Enabling P2P from src %d to dst %d failed: %d\n", i, src_gpu_id, dst_gpu_id, ret);

            aclrtSetDevice(original_device_id);

            return ret;

        }

       

        // 在目标设备上使能对源设备的访问

        aclrtSetDevice(dst_gpu_id);

        ret = aclrtDeviceEnablePeerAccess(src_gpu_id, 0);

        if (ret != ACL_SUCCESS && ret != ACL_ERROR_REPEAT_INITIALIZE) {

            fprintf(stderr, "[CAM %d] Enabling P2P from dst %d to src %d failed: %d\n", i, dst_gpu_id, src_gpu_id, ret);

            aclrtSetDevice(original_device_id);

            return ret;

        }

        // --- 2. 在目标设备上分配临时中转内存 ---

        y_size = camCtx->pool_stitch_scale_NV12_frm_array[frm_index]->linesize[0] * camCtx->pool_stitch_scale_NV12_frm_array[frm_index]->height;

        uv_size = camCtx->pool_stitch_scale_NV12_frm_array[frm_index]->linesize[1] * camCtx->pool_stitch_scale_NV12_frm_array[frm_index]->height / 2;

        size_t total_size = y_size + uv_size;

        void* temp_device_buffer = nullptr;

       

        aclrtSetDevice(dst_gpu_id); // 确保在目标设备上分配

        ret = aclrtMalloc(&temp_device_buffer, total_size, ACL_MEM_MALLOC_HUGE_FIRST);

        if (ret != ACL_SUCCESS) {

            fprintf(stderr, "[CAM %d] Failed to allocate temporary device buffer on device %d, size %zu. ret=%d\n", i, dst_gpu_id, total_size, ret);

            aclrtSetDevice(original_device_id);

            return ret;

        }

        // --- 3. 从源设备上下文发起P2P复制,数据写入目标设备的临时内存 ---

        aclrtSetDevice(src_gpu_id);

        // Y平面

        ret = aclrtMemcpy(temp_device_buffer, y_size, camCtx->pool_stitch_scale_NV12_frm_array[frm_index]->data[0], y_size, ACL_MEMCPY_DEVICE_TO_DEVICE);

        if (ret != ACL_SUCCESS) {

            fprintf(stderr, "[CAM %d] Failed P2P copy Y-plane from src %d to temp buffer on dst %d: %d\n", i, src_gpu_id, dst_gpu_id, ret);

            aclrtSetDevice(dst_gpu_id);

            aclrtFree(temp_device_buffer);

            aclrtSetDevice(original_device_id);

            return ret;

        }

备注:camCtx->pool_stitch_scale_NV12_frm_array 是分配在device上的ffmpeg AVFrame硬件帧

拷贝 y平面的时候就出错, 但是如果我从host往device侧memcpy就成功。跨卡的device_to_device就失败。

我双向检查了 aclrtDeviceCanAccessPeer 和 aclrtDeviceEnablePeerAccess , 然后aclrtSetDevice都成功,没有任何报错。

我看文档中写到 aclrtDeviceCanAccessPeer的约束,会不会是我的BIOS相关设置没有打开?

约束说明

  • 仅支持物理机和容器场景;
  • 仅支持同一个PCIe Switch内Device之间的内存复制。AI Server场景下,虽然是跨PCIe Switch,但也支持Device之间的内存复制。
  • 仅支持同一个物理机或容器内的Device之间的内存复制操作;
  • 仅支持同一个进程内、线程间的Device之间的内存复制,不支持不同进程间Device之间的内存复制。
  • Host的相关端口要已使能(例如Host BIOS等),同一个PCIe Switch内Device之间的拷贝才能端到端可用。

请帮忙看下,没有分析到具体的原因.

我的设备型号是6卡300V Pro, CANN8.0 ,npu-smi 24.1.0.1  

我要发帖子