1*0e6b6b59SJacob Faibussowitsch #ifndef PETSCDEVICE_HIP_H 2*0e6b6b59SJacob Faibussowitsch #define PETSCDEVICE_HIP_H 3*0e6b6b59SJacob Faibussowitsch 4*0e6b6b59SJacob Faibussowitsch #include <petscdevice.h> 5*0e6b6b59SJacob Faibussowitsch #include <petscpkg_version.h> 6*0e6b6b59SJacob Faibussowitsch 7*0e6b6b59SJacob Faibussowitsch #if defined(__HCC__) || (defined(__clang__) && defined(__HIP__)) 8*0e6b6b59SJacob Faibussowitsch #define PETSC_USING_HCC 1 9*0e6b6b59SJacob Faibussowitsch #endif 10*0e6b6b59SJacob Faibussowitsch 11*0e6b6b59SJacob Faibussowitsch #if PetscDefined(HAVE_HIP) 12*0e6b6b59SJacob Faibussowitsch #include <hip/hip_runtime.h> 13*0e6b6b59SJacob Faibussowitsch 14*0e6b6b59SJacob Faibussowitsch #if PETSC_PKG_HIP_VERSION_GE(5, 2, 0) 15*0e6b6b59SJacob Faibussowitsch #include <hipblas/hipblas.h> 16*0e6b6b59SJacob Faibussowitsch #else 17*0e6b6b59SJacob Faibussowitsch #include <hipblas.h> 18*0e6b6b59SJacob Faibussowitsch #endif 19*0e6b6b59SJacob Faibussowitsch 20*0e6b6b59SJacob Faibussowitsch #if defined(__HIP_PLATFORM_NVCC__) 21*0e6b6b59SJacob Faibussowitsch #include <cusolverDn.h> 22*0e6b6b59SJacob Faibussowitsch #else // __HIP_PLATFORM_HCC__ 23*0e6b6b59SJacob Faibussowitsch #if PETSC_PKG_HIP_VERSION_GE(5, 2, 0) 24*0e6b6b59SJacob Faibussowitsch #include <rocsolver/rocsolver.h> 25*0e6b6b59SJacob Faibussowitsch #else 26*0e6b6b59SJacob Faibussowitsch #include <rocsolver.h> 27*0e6b6b59SJacob Faibussowitsch #endif 28*0e6b6b59SJacob Faibussowitsch #endif // __HIP_PLATFORM_NVCC__ 29*0e6b6b59SJacob Faibussowitsch #include <hip/hip_complex.h> // for hipComplex, hipDoubleComplex 30*0e6b6b59SJacob Faibussowitsch 31*0e6b6b59SJacob Faibussowitsch // REMOVE ME 32*0e6b6b59SJacob Faibussowitsch #define WaitForHIP() hipDeviceSynchronize() 33*0e6b6b59SJacob Faibussowitsch 34*0e6b6b59SJacob Faibussowitsch /* hipBLAS does not have hipblasGetErrorName(). We create one on our own. */ 35*0e6b6b59SJacob Faibussowitsch PETSC_EXTERN const char *PetscHIPBLASGetErrorName(hipblasStatus_t); /* PETSC_EXTERN since it is exposed by the CHKERRHIPBLAS macro */ 36*0e6b6b59SJacob Faibussowitsch 37*0e6b6b59SJacob Faibussowitsch #define PetscCallHIP(...) \ 38*0e6b6b59SJacob Faibussowitsch do { \ 39*0e6b6b59SJacob Faibussowitsch const hipError_t _p_hip_err__ = __VA_ARGS__; \ 40*0e6b6b59SJacob Faibussowitsch if (PetscUnlikely(_p_hip_err__ != hipSuccess)) { \ 41*0e6b6b59SJacob Faibussowitsch const char *name = hipGetErrorName(_p_hip_err__); \ 42*0e6b6b59SJacob Faibussowitsch const char *descr = hipGetErrorString(_p_hip_err__); \ 43*0e6b6b59SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_GPU, "hip error %d (%s) : %s", (PetscErrorCode)_p_hip_err__, name, descr); \ 44*0e6b6b59SJacob Faibussowitsch } \ 45*0e6b6b59SJacob Faibussowitsch } while (0) 46*0e6b6b59SJacob Faibussowitsch #define CHKERRHIP(...) PetscCallHIP(__VA_ARGS__) 47*0e6b6b59SJacob Faibussowitsch 48*0e6b6b59SJacob Faibussowitsch #define PetscCallHIPBLAS(...) \ 49*0e6b6b59SJacob Faibussowitsch do { \ 50*0e6b6b59SJacob Faibussowitsch const hipblasStatus_t _p_hipblas_stat__ = __VA_ARGS__; \ 51*0e6b6b59SJacob Faibussowitsch if (PetscUnlikely(_p_hipblas_stat__ != HIPBLAS_STATUS_SUCCESS)) { \ 52*0e6b6b59SJacob Faibussowitsch const char *name = PetscHIPBLASGetErrorName(_p_hipblas_stat__); \ 53*0e6b6b59SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_GPU, "hipBLAS error %d (%s)", (PetscErrorCode)_p_hipblas_stat__, name); \ 54*0e6b6b59SJacob Faibussowitsch } \ 55*0e6b6b59SJacob Faibussowitsch } while (0) 56*0e6b6b59SJacob Faibussowitsch #define CHKERRHIPBLAS(...) PetscCallHIPBLAS(__VA_ARGS__) 57*0e6b6b59SJacob Faibussowitsch 58*0e6b6b59SJacob Faibussowitsch /* TODO: SEK: Need to figure out the hipsolver issues */ 59*0e6b6b59SJacob Faibussowitsch #define PetscCallHIPSOLVER(...) \ 60*0e6b6b59SJacob Faibussowitsch do { \ 61*0e6b6b59SJacob Faibussowitsch const hipsolverStatus_t _p_hipsolver_stat__ = __VA_ARGS__; \ 62*0e6b6b59SJacob Faibussowitsch PetscCheck(!_p_hipsolver_stat__, PETSC_COMM_SELF, PETSC_ERR_GPU, "HIPSOLVER error %d", (PetscErrorCode)_p_hipsolver_stat__); \ 63*0e6b6b59SJacob Faibussowitsch } while (0) 64*0e6b6b59SJacob Faibussowitsch #define CHKERRHIPSOLVER(...) PetscCallHIPSOLVER(__VA_ARGS__) 65*0e6b6b59SJacob Faibussowitsch 66*0e6b6b59SJacob Faibussowitsch /* hipSolver does not exist yet so we work around it 67*0e6b6b59SJacob Faibussowitsch rocSOLVER users rocBLAS for the handle 68*0e6b6b59SJacob Faibussowitsch * */ 69*0e6b6b59SJacob Faibussowitsch #if defined(__HIP_PLATFORM_NVCC__) 70*0e6b6b59SJacob Faibussowitsch typedef cusolverDnHandle_t hipsolverHandle_t; 71*0e6b6b59SJacob Faibussowitsch typedef cusolverStatus_t hipsolverStatus_t; 72*0e6b6b59SJacob Faibussowitsch 73*0e6b6b59SJacob Faibussowitsch /* Alias hipsolverDestroy to cusolverDnDestroy */ 74*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverDestroy(hipsolverHandle_t *hipsolverhandle) { 75*0e6b6b59SJacob Faibussowitsch return cusolverDnDestroy(hipsolverhandle); 76*0e6b6b59SJacob Faibussowitsch } 77*0e6b6b59SJacob Faibussowitsch 78*0e6b6b59SJacob Faibussowitsch /* Alias hipsolverCreate to cusolverDnCreate */ 79*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverCreate(hipsolverHandle_t *hipsolverhandle) { 80*0e6b6b59SJacob Faibussowitsch return cusolverDnCreate(hipsolverhandle); 81*0e6b6b59SJacob Faibussowitsch } 82*0e6b6b59SJacob Faibussowitsch 83*0e6b6b59SJacob Faibussowitsch /* Alias hipsolverGetStream to cusolverDnGetStream */ 84*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverGetStream(hipsolverHandle_t handle, hipStream_t *stream) { 85*0e6b6b59SJacob Faibussowitsch return cusolverDnGetStream(handle, stream); 86*0e6b6b59SJacob Faibussowitsch } 87*0e6b6b59SJacob Faibussowitsch 88*0e6b6b59SJacob Faibussowitsch /* Alias hipsolverSetStream to cusolverDnSetStream */ 89*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverSetStream(hipsolverHandle_t handle, hipStream_t stream) { 90*0e6b6b59SJacob Faibussowitsch return cusolveDnSetStream(handle, stream); 91*0e6b6b59SJacob Faibussowitsch } 92*0e6b6b59SJacob Faibussowitsch #else /* __HIP_PLATFORM_HCC__ */ 93*0e6b6b59SJacob Faibussowitsch typedef rocblas_handle hipsolverHandle_t; 94*0e6b6b59SJacob Faibussowitsch typedef rocblas_status hipsolverStatus_t; 95*0e6b6b59SJacob Faibussowitsch 96*0e6b6b59SJacob Faibussowitsch /* Alias hipsolverDestroy to rocblas_destroy_handle */ 97*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverDestroy(hipsolverHandle_t hipsolverhandle) { 98*0e6b6b59SJacob Faibussowitsch return rocblas_destroy_handle(hipsolverhandle); 99*0e6b6b59SJacob Faibussowitsch } 100*0e6b6b59SJacob Faibussowitsch 101*0e6b6b59SJacob Faibussowitsch /* Alias hipsolverCreate to rocblas_destroy_handle */ 102*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverCreate(hipsolverHandle_t *hipsolverhandle) { 103*0e6b6b59SJacob Faibussowitsch return rocblas_create_handle(hipsolverhandle); 104*0e6b6b59SJacob Faibussowitsch } 105*0e6b6b59SJacob Faibussowitsch 106*0e6b6b59SJacob Faibussowitsch // Alias hipsolverGetStream to rocblas_get_stream 107*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverGetStream(hipsolverHandle_t handle, hipStream_t *stream) { 108*0e6b6b59SJacob Faibussowitsch return rocblas_get_stream(handle, stream); 109*0e6b6b59SJacob Faibussowitsch } 110*0e6b6b59SJacob Faibussowitsch 111*0e6b6b59SJacob Faibussowitsch // Alias hipsolverSetStream to rocblas_set_stream 112*0e6b6b59SJacob Faibussowitsch static inline hipsolverStatus_t hipsolverSetStream(hipsolverHandle_t handle, hipStream_t stream) { 113*0e6b6b59SJacob Faibussowitsch return rocblas_set_stream(handle, stream); 114*0e6b6b59SJacob Faibussowitsch } 115*0e6b6b59SJacob Faibussowitsch #endif // __HIP_PLATFORM_NVCC__ 116*0e6b6b59SJacob Faibussowitsch 117*0e6b6b59SJacob Faibussowitsch // REMOVE ME 118*0e6b6b59SJacob Faibussowitsch PETSC_EXTERN hipStream_t PetscDefaultHipStream; // The default stream used by PETSc 119*0e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscHIPBLASGetHandle(hipblasHandle_t *); 120*0e6b6b59SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscHIPSOLVERGetHandle(hipsolverHandle_t *); 121*0e6b6b59SJacob Faibussowitsch 122*0e6b6b59SJacob Faibussowitsch #endif // PETSC_HAVE_HIP 123*0e6b6b59SJacob Faibussowitsch 124*0e6b6b59SJacob Faibussowitsch // these can also be defined in petscdevice_cuda.h 125*0e6b6b59SJacob Faibussowitsch #ifndef PETSC_DEVICE_DEFINED_DECLS_PRIVATE 126*0e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_DEFINED_DECLS_PRIVATE 127*0e6b6b59SJacob Faibussowitsch #if PetscDefined(USING_HCC) 128*0e6b6b59SJacob Faibussowitsch #define PETSC_HOST_DECL __host__ 129*0e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_DECL __device__ 130*0e6b6b59SJacob Faibussowitsch #define PETSC_KERNEL_DECL __global__ 131*0e6b6b59SJacob Faibussowitsch #define PETSC_SHAREDMEM_DECL __shared__ 132*0e6b6b59SJacob Faibussowitsch #define PETSC_FORCEINLINE __forceinline__ 133*0e6b6b59SJacob Faibussowitsch #define PETSC_CONSTMEM_DECL __constant__ 134*0e6b6b59SJacob Faibussowitsch #else 135*0e6b6b59SJacob Faibussowitsch #define PETSC_HOST_DECL 136*0e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_DECL 137*0e6b6b59SJacob Faibussowitsch #define PETSC_KERNEL_DECL 138*0e6b6b59SJacob Faibussowitsch #define PETSC_SHAREDMEM_DECL 139*0e6b6b59SJacob Faibussowitsch #define PETSC_FORCEINLINE inline 140*0e6b6b59SJacob Faibussowitsch #define PETSC_CONSTMEM_DECL 141*0e6b6b59SJacob Faibussowitsch #endif // PETSC_USING_NVCC 142*0e6b6b59SJacob Faibussowitsch 143*0e6b6b59SJacob Faibussowitsch #define PETSC_HOSTDEVICE_DECL PETSC_HOST_DECL PETSC_DEVICE_DECL 144*0e6b6b59SJacob Faibussowitsch #define PETSC_DEVICE_INLINE_DECL PETSC_DEVICE_DECL PETSC_FORCEINLINE 145*0e6b6b59SJacob Faibussowitsch #define PETSC_HOSTDEVICE_INLINE_DECL PETSC_HOSTDEVICE_DECL PETSC_FORCEINLINE 146*0e6b6b59SJacob Faibussowitsch #endif // PETSC_DEVICE_DEFINED_DECLS_PRIVATE 147*0e6b6b59SJacob Faibussowitsch 148*0e6b6b59SJacob Faibussowitsch #endif // PETSCDEVICE_HIP_H 149