10e6b6b59SJacob Faibussowitsch #ifndef PETSCDEVICE_HIP_H 20e6b6b59SJacob Faibussowitsch #define PETSCDEVICE_HIP_H 30e6b6b59SJacob Faibussowitsch 40e6b6b59SJacob Faibussowitsch #include <petscdevice.h> 50e6b6b59SJacob Faibussowitsch #include <petscpkg_version.h> 60e6b6b59SJacob Faibussowitsch 70e6b6b59SJacob Faibussowitsch #if defined(__HCC__) || (defined(__clang__) && defined(__HIP__)) 80e6b6b59SJacob Faibussowitsch #define PETSC_USING_HCC 1 90e6b6b59SJacob Faibussowitsch #endif 100e6b6b59SJacob Faibussowitsch 110e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_HIP) 120e6b6b59SJacob Faibussowitsch #include <hip/hip_runtime.h> 130e6b6b59SJacob Faibussowitsch 140e6b6b59SJacob Faibussowitsch #if PETSC_PKG_HIP_VERSION_GE(5, 2, 0) 150e6b6b59SJacob Faibussowitsch #include <hipblas/hipblas.h> 16*47d993e7Ssuyashtn #include <hipsparse/hipsparse.h> 170e6b6b59SJacob Faibussowitsch #else 180e6b6b59SJacob Faibussowitsch #include <hipblas.h> 19*47d993e7Ssuyashtn #include <hipsparse.h> 200e6b6b59SJacob Faibussowitsch #endif 210e6b6b59SJacob Faibussowitsch 220e6b6b59SJacob Faibussowitsch #if defined(__HIP_PLATFORM_NVCC__) 230e6b6b59SJacob Faibussowitsch #include <cusolverDn.h> 240e6b6b59SJacob Faibussowitsch #else // __HIP_PLATFORM_HCC__ 250e6b6b59SJacob Faibussowitsch #if PETSC_PKG_HIP_VERSION_GE(5, 2, 0) 26*47d993e7Ssuyashtn #include <hipsolver/hipsolver.h> 270e6b6b59SJacob Faibussowitsch #else 28*47d993e7Ssuyashtn #include <hipsolver.h> 290e6b6b59SJacob Faibussowitsch #endif 300e6b6b59SJacob Faibussowitsch #endif // __HIP_PLATFORM_NVCC__ 310e6b6b59SJacob Faibussowitsch #include <hip/hip_complex.h> // for hipComplex, hipDoubleComplex 320e6b6b59SJacob Faibussowitsch 330e6b6b59SJacob Faibussowitsch // REMOVE ME 340e6b6b59SJacob Faibussowitsch #define WaitForHIP() hipDeviceSynchronize() 350e6b6b59SJacob Faibussowitsch 36*47d993e7Ssuyashtn /* hipBLAS, hipSPARSE and hipSolver does not have hip*GetErrorName(). We create one on our own. */ 370e6b6b59SJacob Faibussowitsch PETSC_EXTERN const char *PetscHIPBLASGetErrorName(hipblasStatus_t); /* PETSC_EXTERN since it is exposed by the CHKERRHIPBLAS macro */ 38*47d993e7Ssuyashtn PETSC_EXTERN const char *PetscHIPSPARSEGetErrorName(hipsparseStatus_t); /* PETSC_EXTERN since it is exposed by the CHKERRHIPSPARSE macro */ 39*47d993e7Ssuyashtn PETSC_EXTERN const char *PetscHIPSolverGetErrorName(hipsolverStatus_t); /* PETSC_EXTERN since it is exposed by the CHKERRHIPSOLVER macro */ 400e6b6b59SJacob Faibussowitsch 410e6b6b59SJacob Faibussowitsch #define PetscCallHIP(...) \ 420e6b6b59SJacob Faibussowitsch do { \ 430e6b6b59SJacob Faibussowitsch const hipError_t _p_hip_err__ = __VA_ARGS__; \ 440e6b6b59SJacob Faibussowitsch if (PetscUnlikely(_p_hip_err__ != hipSuccess)) { \ 450e6b6b59SJacob Faibussowitsch const char *name = hipGetErrorName(_p_hip_err__); \ 460e6b6b59SJacob Faibussowitsch const char *descr = hipGetErrorString(_p_hip_err__); \ 470e6b6b59SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_GPU, "hip error %d (%s) : %s", (PetscErrorCode)_p_hip_err__, name, descr); \ 480e6b6b59SJacob Faibussowitsch } \ 490e6b6b59SJacob Faibussowitsch } while (0) 500e6b6b59SJacob Faibussowitsch #define CHKERRHIP(...) PetscCallHIP(__VA_ARGS__) 510e6b6b59SJacob Faibussowitsch 52*47d993e7Ssuyashtn #define PetscHIPCheckLaunch \ 53*47d993e7Ssuyashtn do { \ 54*47d993e7Ssuyashtn /* Check synchronous errors, i.e. pre-launch */ \ 55*47d993e7Ssuyashtn PetscCallHIP(hipGetLastError()); \ 56*47d993e7Ssuyashtn /* Check asynchronous errors, i.e. kernel failed (ULF) */ \ 57*47d993e7Ssuyashtn PetscCallHIP(hipDeviceSynchronize()); \ 58*47d993e7Ssuyashtn } while (0) 59*47d993e7Ssuyashtn 600e6b6b59SJacob Faibussowitsch #define PetscCallHIPBLAS(...) \ 610e6b6b59SJacob Faibussowitsch do { \ 620e6b6b59SJacob Faibussowitsch const hipblasStatus_t _p_hipblas_stat__ = __VA_ARGS__; \ 630e6b6b59SJacob Faibussowitsch if (PetscUnlikely(_p_hipblas_stat__ != HIPBLAS_STATUS_SUCCESS)) { \ 640e6b6b59SJacob Faibussowitsch const char *name = PetscHIPBLASGetErrorName(_p_hipblas_stat__); \ 650e6b6b59SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_GPU, "hipBLAS error %d (%s)", (PetscErrorCode)_p_hipblas_stat__, name); \ 660e6b6b59SJacob Faibussowitsch } \ 670e6b6b59SJacob Faibussowitsch } while (0) 680e6b6b59SJacob Faibussowitsch #define CHKERRHIPBLAS(...) PetscCallHIPBLAS(__VA_ARGS__) 690e6b6b59SJacob Faibussowitsch 70*47d993e7Ssuyashtn #if PETSC_PKG_HIP_VERSION_GE(4, 5, 0) 71*47d993e7Ssuyashtn /* HIPSPARSE & HIPSOLVER have better functionality with ROCm-4.5 or newer */ 72*47d993e7Ssuyashtn #define PetscCallHIPSPARSE(...) \ 73*47d993e7Ssuyashtn do { \ 74*47d993e7Ssuyashtn const hipsparseStatus_t _p_hipsparse_stat__ = __VA_ARGS__; \ 75*47d993e7Ssuyashtn if (PetscUnlikely(_p_hipsparse_stat__ != HIPSPARSE_STATUS_SUCCESS)) { \ 76*47d993e7Ssuyashtn const char *name = PetscHIPSPARSEGetErrorName(_p_hipsparse_stat__); \ 77*47d993e7Ssuyashtn PetscCheck((_p_hipsparse_stat__ != HIPSPARSE_STATUS_NOT_INITIALIZED) && (_p_hipsparse_stat__ != HIPSPARSE_STATUS_ALLOC_FAILED), PETSC_COMM_SELF, PETSC_ERR_GPU_RESOURCE, "hipSPARSE errorcode %d (%s): Reports not initialized or alloc failed; this indicates the GPU has run out resources", (int)_p_hipsparse_stat__, name); \ 78*47d993e7Ssuyashtn SETERRQ(PETSC_COMM_SELF, PETSC_ERR_GPU, "hipSPARSE errorcode %d (%s)", (int)_p_hipsparse_stat__, name); \ 79*47d993e7Ssuyashtn } \ 80*47d993e7Ssuyashtn } while (0) 81*47d993e7Ssuyashtn #define CHKERRHIPSPARSE(...) PetscCallHIPSPARSE(__VA_ARGS__) 82*47d993e7Ssuyashtn 830e6b6b59SJacob Faibussowitsch #define PetscCallHIPSOLVER(...) \ 840e6b6b59SJacob Faibussowitsch do { \ 850e6b6b59SJacob Faibussowitsch const hipsolverStatus_t _p_hipsolver_stat__ = __VA_ARGS__; \ 86*47d993e7Ssuyashtn if (PetscUnlikely(_p_hipsolver_stat__ != HIPSOLVER_STATUS_SUCCESS)) { \ 87*47d993e7Ssuyashtn const char *name = PetscHIPSolverGetErrorName(_p_hipsolver_stat__); \ 88*47d993e7Ssuyashtn if (((_p_hipsolver_stat__ == HIPSOLVER_STATUS_NOT_INITIALIZED) || (_p_hipsolver_stat__ == HIPSOLVER_STATUS_ALLOC_FAILED) || (_p_hipsolver_stat__ == HIPSOLVER_STATUS_INTERNAL_ERROR)) && PetscDeviceInitialized(PETSC_DEVICE_HIP)) { \ 89*47d993e7Ssuyashtn SETERRQ(PETSC_COMM_SELF, PETSC_ERR_GPU_RESOURCE, \ 90*47d993e7Ssuyashtn "hipSolver error %d (%s). " \ 91*47d993e7Ssuyashtn "This indicates the GPU may have run out resources", \ 92*47d993e7Ssuyashtn (PetscErrorCode)_p_hipsolver_stat__, name); \ 93*47d993e7Ssuyashtn } else { \ 94*47d993e7Ssuyashtn SETERRQ(PETSC_COMM_SELF, PETSC_ERR_GPU, "hipSolver error %d (%s)", (PetscErrorCode)_p_hipsolver_stat__, name); \ 95*47d993e7Ssuyashtn } \ 96*47d993e7Ssuyashtn } \ 970e6b6b59SJacob Faibussowitsch } while (0) 980e6b6b59SJacob Faibussowitsch #define CHKERRHIPSOLVER(...) PetscCallHIPSOLVER(__VA_ARGS__) 990e6b6b59SJacob Faibussowitsch 100*47d993e7Ssuyashtn #else /* PETSC_PKG_HIP_VERSION_GE(4,5,0) */ 1010e6b6b59SJacob Faibussowitsch /* hipSolver does not exist yet so we work around it 1020e6b6b59SJacob Faibussowitsch rocSOLVER users rocBLAS for the handle 1030e6b6b59SJacob Faibussowitsch * */ 1040e6b6b59SJacob Faibussowitsch #if defined(__HIP_PLATFORM_NVCC__) 105*47d993e7Ssuyashtn #include <cusolverDn.h> 1060e6b6b59SJacob Faibussowitsch typedef cusolverDnHandle_t hipsolverHandle_t; 1070e6b6b59SJacob Faibussowitsch typedef cusolverStatus_t hipsolverStatus_t; 1080e6b6b59SJacob Faibussowitsch 1090e6b6b59SJacob Faibussowitsch /* Alias hipsolverDestroy to cusolverDnDestroy */ 110d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverDestroy(hipsolverHandle_t *hipsolverhandle) 111d71ae5a4SJacob Faibussowitsch { 1120e6b6b59SJacob Faibussowitsch return cusolverDnDestroy(hipsolverhandle); 1130e6b6b59SJacob Faibussowitsch } 1140e6b6b59SJacob Faibussowitsch 1150e6b6b59SJacob Faibussowitsch /* Alias hipsolverCreate to cusolverDnCreate */ 116d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverCreate(hipsolverHandle_t *hipsolverhandle) 117d71ae5a4SJacob Faibussowitsch { 1180e6b6b59SJacob Faibussowitsch return cusolverDnCreate(hipsolverhandle); 1190e6b6b59SJacob Faibussowitsch } 1200e6b6b59SJacob Faibussowitsch 1210e6b6b59SJacob Faibussowitsch /* Alias hipsolverGetStream to cusolverDnGetStream */ 122d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverGetStream(hipsolverHandle_t handle, hipStream_t *stream) 123d71ae5a4SJacob Faibussowitsch { 1240e6b6b59SJacob Faibussowitsch return cusolverDnGetStream(handle, stream); 1250e6b6b59SJacob Faibussowitsch } 1260e6b6b59SJacob Faibussowitsch 1270e6b6b59SJacob Faibussowitsch /* Alias hipsolverSetStream to cusolverDnSetStream */ 128d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverSetStream(hipsolverHandle_t handle, hipStream_t stream) 129d71ae5a4SJacob Faibussowitsch { 1300e6b6b59SJacob Faibussowitsch return cusolveDnSetStream(handle, stream); 1310e6b6b59SJacob Faibussowitsch } 1320e6b6b59SJacob Faibussowitsch #else /* __HIP_PLATFORM_HCC__ */ 133*47d993e7Ssuyashtn #include <rocsolver.h> 134*47d993e7Ssuyashtn #include <rocblas.h> 1350e6b6b59SJacob Faibussowitsch typedef rocblas_handle hipsolverHandle_t; 1360e6b6b59SJacob Faibussowitsch typedef rocblas_status hipsolverStatus_t; 1370e6b6b59SJacob Faibussowitsch 1380e6b6b59SJacob Faibussowitsch /* Alias hipsolverDestroy to rocblas_destroy_handle */ 139d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverDestroy(hipsolverHandle_t hipsolverhandle) 140d71ae5a4SJacob Faibussowitsch { 1410e6b6b59SJacob Faibussowitsch return rocblas_destroy_handle(hipsolverhandle); 1420e6b6b59SJacob Faibussowitsch } 1430e6b6b59SJacob Faibussowitsch 1440e6b6b59SJacob Faibussowitsch /* Alias hipsolverCreate to rocblas_destroy_handle */ 145d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverCreate(hipsolverHandle_t *hipsolverhandle) 146d71ae5a4SJacob Faibussowitsch { 1470e6b6b59SJacob Faibussowitsch return rocblas_create_handle(hipsolverhandle); 1480e6b6b59SJacob Faibussowitsch } 1490e6b6b59SJacob Faibussowitsch 1500e6b6b59SJacob Faibussowitsch // Alias hipsolverGetStream to rocblas_get_stream 151d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverGetStream(hipsolverHandle_t handle, hipStream_t *stream) 152d71ae5a4SJacob Faibussowitsch { 1530e6b6b59SJacob Faibussowitsch return rocblas_get_stream(handle, stream); 1540e6b6b59SJacob Faibussowitsch } 1550e6b6b59SJacob Faibussowitsch 1560e6b6b59SJacob Faibussowitsch // Alias hipsolverSetStream to rocblas_set_stream 157d71ae5a4SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverSetStream(hipsolverHandle_t handle, hipStream_t stream) 158d71ae5a4SJacob Faibussowitsch { 1590e6b6b59SJacob Faibussowitsch return rocblas_set_stream(handle, stream); 1600e6b6b59SJacob Faibussowitsch } 1610e6b6b59SJacob Faibussowitsch #endif // __HIP_PLATFORM_NVCC__ 162*47d993e7Ssuyashtn #endif /* PETSC_PKG_HIP_VERSION_GE(4,5,0) */ 1630e6b6b59SJacob Faibussowitsch // REMOVE ME 1640e6b6b59SJacob Faibussowitsch PETSC_EXTERN hipStream_t PetscDefaultHipStream; // The default stream used by PETSc 1650e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscHIPBLASGetHandle(hipblasHandle_t *); 1660e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscHIPSOLVERGetHandle(hipsolverHandle_t *); 1670e6b6b59SJacob Faibussowitsch 1680e6b6b59SJacob Faibussowitsch #endif // PETSC_HAVE_HIP 1690e6b6b59SJacob Faibussowitsch 1700e6b6b59SJacob Faibussowitsch // these can also be defined in petscdevice_cuda.h 1710e6b6b59SJacob Faibussowitsch #ifndef PETSC_DEVICE_DEFINED_DECLS_PRIVATE 1720e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_DEFINED_DECLS_PRIVATE 1730e6b6b59SJacob Faibussowitsch #if PetscDefined(USING_HCC) 1740e6b6b59SJacob Faibussowitsch #define PETSC_HOST_DECL __host__ 1750e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_DECL __device__ 1760e6b6b59SJacob Faibussowitsch #define PETSC_KERNEL_DECL __global__ 1770e6b6b59SJacob Faibussowitsch #define PETSC_SHAREDMEM_DECL __shared__ 1780e6b6b59SJacob Faibussowitsch #define PETSC_FORCEINLINE __forceinline__ 1790e6b6b59SJacob Faibussowitsch #define PETSC_CONSTMEM_DECL __constant__ 1800e6b6b59SJacob Faibussowitsch #else 1810e6b6b59SJacob Faibussowitsch #define PETSC_HOST_DECL 1820e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_DECL 1830e6b6b59SJacob Faibussowitsch #define PETSC_KERNEL_DECL 1840e6b6b59SJacob Faibussowitsch #define PETSC_SHAREDMEM_DECL 1850e6b6b59SJacob Faibussowitsch #define PETSC_FORCEINLINE inline 1860e6b6b59SJacob Faibussowitsch #define PETSC_CONSTMEM_DECL 1870e6b6b59SJacob Faibussowitsch #endif // PETSC_USING_NVCC 1880e6b6b59SJacob Faibussowitsch 1890e6b6b59SJacob Faibussowitsch #define PETSC_HOSTDEVICE_DECL PETSC_HOST_DECL PETSC_DEVICE_DECL 1900e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_INLINE_DECL PETSC_DEVICE_DECL PETSC_FORCEINLINE 1910e6b6b59SJacob Faibussowitsch #define PETSC_HOSTDEVICE_INLINE_DECL PETSC_HOSTDEVICE_DECL PETSC_FORCEINLINE 1920e6b6b59SJacob Faibussowitsch #endif // PETSC_DEVICE_DEFINED_DECLS_PRIVATE 1930e6b6b59SJacob Faibussowitsch 1940e6b6b59SJacob Faibussowitsch #endif // PETSCDEVICE_HIP_H 195