cuDeviceCanAccessPeer(...) 和 cuDeviceGetP2PAttribute(..., CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED, ...) 有什么区别?

What's the difference between cuDeviceCanAccessPeer(...) and cuDeviceGetP2PAttribute(..., CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED, ...)?

我无法访问多 GPU 系统来对此进行测试,但在 cuda.h 中我发现了两件看起来非常相似的事情。第一个是函数

    CUresult CUDAAPI cuDeviceCanAccessPeer(int *canAccessPeer, CUdevice dev, CUdevice peerDev);

描述为

Returns in *canAccessPeer a value of 1 if contexts on dev are capable of directly accessing memory from contexts on peerDev and 0 otherwise. If direct access of peerDev from dev is possible, then access may be enabled on two specific contexts by calling ::cuCtxEnablePeerAccess().

第二个是

    CUresult CUDAAPI cuDeviceGetP2PAttribute(int* value, CUdevice_P2PAttribute attrib, CUdevice srcDevice, CUdevice dstDevice);

描述为

Returns in *value the value of the requested attribute attrib of the link between srcDevice and dstDevice. The supported attributes are:

::CU_DEVICE_P2P_ATTRIBUTE_PERFORMANCE_RANK: A relative value indicating the performance of the link between two devices.

::CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED P2:1` if P2P Access is enable.

::CU_DEVICE_P2P_ATTRIBUTE_NATIVE_ATOMIC_SUPPORTED: 1 if Atomic operations over the link are supported.

名称 CU_DEVICE_ATTRUBUTE_ACCESS_SUPPORTED 表明调用 cuDeviceCanAccessPeer 与使用 cuDeviceGetP2PAttributeattrib 设置为 ::CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED P2P 相同,但描述“1 如果启用 P2P 访问”让我感到困惑。

它们真的一样吗,还是第二个应该测试link是否已经激活?

我不相信他们是一样的。

  • cuDeviceCanAccessPeer returns 两个设备之间是否可能进行 P2P 访问。
  • cuDeviceGetP2PAttributereturns 两台设备之间是否启用P2P 访问。

如果没有事先成功调用 cuCtxEnablePeerAccesscuDeviceGetP2PAttribute 在查询 CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED 属性时应该 return false,即使 cuDeviceCanAccessPeer return是真的。

请注意,我目前也无法访问支持 P2P 的系统来检查这一点。