diff --git a/projects/clr/hipamd/include/hip/hcc_detail/hip_runtime_api.h b/projects/clr/hipamd/include/hip/hcc_detail/hip_runtime_api.h index 3ab43ea64d..87b4df3275 100644 --- a/projects/clr/hipamd/include/hip/hcc_detail/hip_runtime_api.h +++ b/projects/clr/hipamd/include/hip/hcc_detail/hip_runtime_api.h @@ -61,7 +61,7 @@ typedef struct ihipStream_t *hipStream_t; #define hipIpcMemLazyEnablePeerAccess 0 -typedef struct ihipIpcMemHandle *hipIpcMemHandle_t; +typedef struct ihipIpcMemHandle_t *hipIpcMemHandle_t; //TODO: IPC event handle currently unsupported struct ihipIpcEventHandle_t; @@ -1822,19 +1822,19 @@ hipError_t hipProfilerStop(); * @brief Gets an interprocess memory handle for an existing device memory * allocation * - * Takes a pointer to the base of an existing device memory allocation created - * with hipMalloc and exports it for use in another process. This is a + * Takes a pointer to the base of an existing device memory allocation created + * with hipMalloc and exports it for use in another process. This is a * lightweight operation and may be called multiple times on an allocation - * without adverse effects. + * without adverse effects. * * If a region of memory is freed with hipFree and a subsequent call * to hipMalloc returns memory with the same device address, * hipIpcGetMemHandle will return a unique handle for the - * new memory. + * new memory. * * @param handle - Pointer to user allocated hipIpcMemHandle to return * the handle in. - * @param devPtr - Base pointer to previously allocated device memory + * @param devPtr - Base pointer to previously allocated device memory * * @returns * hipSuccess, @@ -1850,14 +1850,14 @@ extern __host__ hipError_t hipIpcGetMemHandle(hipIpcMemHandle_t *handle, void *d * and returns a device pointer usable in the local process. * * Maps memory exported from another process with hipIpcGetMemHandle into - * the current device address space. For contexts on different devices + * the current device address space. For contexts on different devices * hipIpcOpenMemHandle can attempt to enable peer access between the - * devices as if the user called hipDeviceEnablePeerAccess. This behavior is - * controlled by the hipIpcMemLazyEnablePeerAccess flag. + * devices as if the user called hipDeviceEnablePeerAccess. This behavior is + * controlled by the hipIpcMemLazyEnablePeerAccess flag. * hipDeviceCanAccessPeer can determine if a mapping is possible. * * Contexts that may open hipIpcMemHandles are restricted in the following way. - * hipIpcMemHandles from each device in a given process may only be opened + * hipIpcMemHandles from each device in a given process may only be opened * by one context per device per other process. * * Memory returned from hipIpcOpenMemHandle must be freed with @@ -1866,7 +1866,7 @@ extern __host__ hipError_t hipIpcGetMemHandle(hipIpcMemHandle_t *handle, void *d * Calling hipFree on an exported memory region before calling * hipIpcCloseMemHandle in the importing context will result in undefined * behavior. - * + * * @param devPtr - Returned device pointer * @param handle - hipIpcMemHandle to open * @param flags - Flags for this operation. Must be specified as hipIpcMemLazyEnablePeerAccess @@ -1877,15 +1877,16 @@ extern __host__ hipError_t hipIpcGetMemHandle(hipIpcMemHandle_t *handle, void *d * hipErrorInvalidResourceHandle, * hipErrorTooManyPeers * - * @note No guarantees are made about the address returned in @p *devPtr. + * @note No guarantees are made about the address returned in @p *devPtr. * In particular, multiple processes may not receive the same address for the same @p handle. * */ -extern __host__ hipError_t hipIpcOpenMemHandle(void **devPtr, hipIpcMemHandle_t handle, unsigned int flags); +extern __host__ hipError_t hipIpcOpenMemHandle(void **devPtr, + hipIpcMemHandle_t handle, unsigned int flags); /** * @brief Close memory mapped with hipIpcOpenMemHandle - * + * * Unmaps memory returnd by hipIpcOpenMemHandle. The original allocation * in the exporting process as well as imported mappings in other processes * will be unaffected. @@ -1894,7 +1895,7 @@ extern __host__ hipError_t hipIpcOpenMemHandle(void **devPtr, hipIpcMemHandle_t * last mapping using them. * * @param devPtr - Device pointer returned by hipIpcOpenMemHandle - * + * * @returns * hipSuccess, * hipErrorMapBufferObjectFailed, diff --git a/projects/clr/hipamd/include/hip/hip_runtime_api.h b/projects/clr/hipamd/include/hip/hip_runtime_api.h index 5a8dd44e61..a45a1ee27e 100644 --- a/projects/clr/hipamd/include/hip/hip_runtime_api.h +++ b/projects/clr/hipamd/include/hip/hip_runtime_api.h @@ -210,6 +210,7 @@ typedef enum hipError_t { hipErrorRuntimeOther = 1053, ///< HSA runtime call other than memory returned error. Typically not seen in production systems. hipErrorHostMemoryAlreadyRegistered = 1061, ///< Produced when trying to lock a page-locked memory. hipErrorHostMemoryNotRegistered = 1062, ///< Produced when trying to unlock a non-page-locked memory. + hipErrorMapBufferObjectFailed = 1071, ///< Produced when the IPC memory attach failed from ROCr. hipErrorTbd ///< Marker that more error codes are needed. } hipError_t; diff --git a/projects/clr/hipamd/src/hip_hcc.h b/projects/clr/hipamd/src/hip_hcc.h index cd099f026c..82290bc489 100644 --- a/projects/clr/hipamd/src/hip_hcc.h +++ b/projects/clr/hipamd/src/hip_hcc.h @@ -372,10 +372,12 @@ struct LockedBase { * HIP IPC Handle Size */ #define HIP_IPC_HANDLE_SIZE 64 -struct __HIP_DEVICE__ ihipIpcMemHandle +class ihipIpcMemHandle_t { - volatile hsa_amd_ipc_memory_t handle; ///< ipc memory handle on ROCr +public: + hsa_amd_ipc_memory_t ipc_handle; ///< ipc memory handle on ROCr char reserved[HIP_IPC_HANDLE_SIZE]; + size_t psize; }; class ihipFunction_t{ diff --git a/projects/clr/hipamd/src/hip_memory.cpp b/projects/clr/hipamd/src/hip_memory.cpp index 9a09c5ff70..f2ab6d19a0 100644 --- a/projects/clr/hipamd/src/hip_memory.cpp +++ b/projects/clr/hipamd/src/hip_memory.cpp @@ -1031,27 +1031,67 @@ hipError_t hipMemGetAddressRange ( hipDeviceptr_t* pbase, size_t* psize, hipDevi *pbase = amPointerInfo._devicePointer; *psize = amPointerInfo._sizeBytes; } - hipStatus = hipErrorInvalidDevicePointer; + else + hipStatus = hipErrorInvalidDevicePointer; return hipStatus; } //TODO: IPC implementaiton: -hipError_t hipIpcOpenMemHandle(void** devPtr, hipIpcMemHandle_t handle, unsigned int flags){ - // HIP_INIT_API ( devPtr, handle.handle , flags); - hipError_t hipStatus = hipSuccess; - return hipStatus; -} hipError_t hipIpcGetMemHandle(hipIpcMemHandle_t* handle, void* devPtr){ HIP_INIT_API ( handle, devPtr); hipError_t hipStatus = hipSuccess; + // Get the size of allocated pointer + size_t psize; + hc::accelerator acc; + hc::AmPointerInfo amPointerInfo( NULL , NULL , 0 , acc , 0 , 0 ); + am_status_t status = hc::am_memtracker_getinfo( &amPointerInfo , devPtr ); + if (status == AM_SUCCESS) { + psize = (size_t)amPointerInfo._sizeBytes; + } + else + hipStatus = hipErrorInvalidResourceHandle; + + // Save the size of the pointer to hipIpcMemHandle + (*handle)->psize = psize; + + // Create HSA ipc memory + hsa_status_t hsa_status = + hsa_amd_ipc_memory_create(devPtr, psize, &(*handle)->ipc_handle); + if(hsa_status!= HSA_STATUS_SUCCESS) + hipStatus = hipErrorMemoryAllocation; + + return hipStatus; +} + +hipError_t hipIpcOpenMemHandle(void** devPtr, hipIpcMemHandle_t handle, unsigned int flags){ +// HIP_INIT_API ( devPtr, handle.handle , flags); + hipError_t hipStatus = hipSuccess; + + // Get the current device agent. + hc::accelerator acc; + hsa_agent_t *agent = static_cast(acc.get_hsa_agent()); + if(!agent) + return hipErrorInvalidResourceHandle; + + //Attach ipc memory + hsa_status_t hsa_status = + hsa_amd_ipc_memory_attach(&handle->ipc_handle, handle->psize, 1, agent, devPtr); + if(hsa_status != HSA_STATUS_SUCCESS) + hipStatus = hipErrorMapBufferObjectFailed; + return hipStatus; } hipError_t hipIpcCloseMemHandle(void *devPtr){ HIP_INIT_API ( devPtr ); hipError_t hipStatus = hipSuccess; + + hsa_status_t hsa_status = + hsa_amd_ipc_memory_detach(devPtr); + if(hsa_status != HSA_STATUS_SUCCESS) + return hipErrorInvalidResourceHandle; return hipStatus; }