@@ -1663,8 +1663,56 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy2D(
1663
1663
UR_CHECK_ERROR (RetImplEvent->start ());
1664
1664
}
1665
1665
1666
+ // There is an issue with hipMemcpy2D* when hipMemcpyDefault is used, which
1667
+ // makes the HIP runtime not correctly derive the copy kind (direction) for
1668
+ // the copies since ROCm 5.6.0+. See: https://github.com/ROCm/clr/issues/40
1669
+ #if HIP_VERSION >= 50600000
1670
+ hipPointerAttribute_t srcAttribs{};
1671
+ hipPointerAttribute_t dstAttribs{};
1672
+
1673
+ bool srcIsSystemAlloc{false };
1674
+ bool dstIsSystemAlloc{false };
1675
+
1676
+ hipError_t hipRes{};
1677
+ // hipErrorInvalidValue returned from hipPointerGetAttributes for a non-null
1678
+ // pointer refers to an OS-allocation, hence pageable host memory. However,
1679
+ // this means we cannot rely on the attributes result, hence we mark system
1680
+ // pageable memory allocation manually as host memory. The HIP runtime can
1681
+ // handle the registering/unregistering of the memory as long as the right
1682
+ // copy-kind (direction) is provided to hipMemcpy2DAsync for this case.
1683
+ hipRes = hipPointerGetAttributes (&srcAttribs, (const void *)pSrc);
1684
+ if (hipRes == hipErrorInvalidValue && pSrc)
1685
+ srcIsSystemAlloc = true ;
1686
+ hipRes = hipPointerGetAttributes (&dstAttribs, (const void *)pDst);
1687
+ if (hipRes == hipErrorInvalidValue && pDst)
1688
+ dstIsSystemAlloc = true ;
1689
+
1690
+ const unsigned int srcMemType{srcAttribs.memoryType };
1691
+ const unsigned int dstMemType{dstAttribs.memoryType };
1692
+
1693
+ const bool srcIsHost{(srcMemType == hipMemoryTypeHost) || srcIsSystemAlloc};
1694
+ const bool srcIsDevice{srcMemType == hipMemoryTypeDevice};
1695
+ const bool dstIsHost{(dstMemType == hipMemoryTypeHost) || dstIsSystemAlloc};
1696
+ const bool dstIsDevice{dstMemType == hipMemoryTypeDevice};
1697
+
1698
+ unsigned int cpyKind{};
1699
+ if (srcIsHost && dstIsHost)
1700
+ cpyKind = hipMemcpyHostToHost;
1701
+ else if (srcIsHost && dstIsDevice)
1702
+ cpyKind = hipMemcpyHostToDevice;
1703
+ else if (srcIsDevice && dstIsHost)
1704
+ cpyKind = hipMemcpyDeviceToHost;
1705
+ else if (srcIsDevice && dstIsDevice)
1706
+ cpyKind = hipMemcpyDeviceToDevice;
1707
+ else
1708
+ cpyKind = hipMemcpyDefault;
1709
+
1710
+ UR_CHECK_ERROR (hipMemcpy2DAsync (pDst, dstPitch, pSrc, srcPitch, width,
1711
+ height, (hipMemcpyKind)cpyKind, HIPStream));
1712
+ #else
1666
1713
UR_CHECK_ERROR (hipMemcpy2DAsync (pDst, dstPitch, pSrc, srcPitch, width,
1667
1714
height, hipMemcpyDefault, HIPStream));
1715
+ #endif
1668
1716
1669
1717
if (phEvent) {
1670
1718
UR_CHECK_ERROR (RetImplEvent->record ());
0 commit comments