xref: /petsc/include/petscdevice.h (revision a4af0ceea8a251db97ee0dc5c0d52d4adf50264a)
1030f984aSJacob Faibussowitsch #if !defined(PETSCDEVICE_H)
2030f984aSJacob Faibussowitsch #define PETSCDEVICE_H
3030f984aSJacob Faibussowitsch 
4030f984aSJacob Faibussowitsch #include <petscsys.h>
5030f984aSJacob Faibussowitsch #include <petscdevicetypes.h>
6*a4af0ceeSJacob Faibussowitsch #include <petscpkg_version.h>
7030f984aSJacob Faibussowitsch 
8030f984aSJacob Faibussowitsch #if PetscDefined(HAVE_CUDA)
9030f984aSJacob Faibussowitsch #include <cuda.h>
10030f984aSJacob Faibussowitsch #include <cuda_runtime.h>
11030f984aSJacob Faibussowitsch #include <cublas_v2.h>
12030f984aSJacob Faibussowitsch #include <cusolverDn.h>
13030f984aSJacob Faibussowitsch #include <cusolverSp.h>
14030f984aSJacob Faibussowitsch #include <cufft.h>
15030f984aSJacob Faibussowitsch 
16030f984aSJacob Faibussowitsch /* cuBLAS does not have cublasGetErrorName(). We create one on our own. */
17030f984aSJacob Faibussowitsch PETSC_EXTERN const char* PetscCUBLASGetErrorName(cublasStatus_t); /* PETSC_EXTERN since it is exposed by the CHKERRCUBLAS macro */
18030f984aSJacob Faibussowitsch PETSC_EXTERN const char* PetscCUSolverGetErrorName(cusolverStatus_t);
19030f984aSJacob Faibussowitsch PETSC_EXTERN const char* PetscCUFFTGetErrorName(cufftResult);
20030f984aSJacob Faibussowitsch 
21*a4af0ceeSJacob Faibussowitsch /* REMOVE ME */
22*a4af0ceeSJacob Faibussowitsch #define WaitForCUDA() cudaDeviceSynchronize()
23030f984aSJacob Faibussowitsch 
24030f984aSJacob Faibussowitsch /* CUDART_VERSION = 1000 x major + 10 x minor version */
25030f984aSJacob Faibussowitsch 
26030f984aSJacob Faibussowitsch /* Could not find exactly which CUDART_VERSION introduced cudaGetErrorName. At least it was in CUDA 8.0 (Sep. 2016) */
27*a4af0ceeSJacob Faibussowitsch #if PETSC_PKG_CUDA_VERSION_GE(8,0,0)
28*a4af0ceeSJacob Faibussowitsch #define CHKERRCUDA(cerr) do {                                           \
29*a4af0ceeSJacob Faibussowitsch     const cudaError_t _p_cuda_err__ = cerr;                             \
30*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_cuda_err__ != cudaSuccess)) {                  \
31*a4af0ceeSJacob Faibussowitsch       const char *name  = cudaGetErrorName(_p_cuda_err__);              \
32*a4af0ceeSJacob Faibussowitsch       const char *descr = cudaGetErrorString(_p_cuda_err__);            \
33030f984aSJacob Faibussowitsch       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_GPU,"cuda error %d (%s) : %s", \
34*a4af0ceeSJacob Faibussowitsch                (PetscErrorCode)_p_cuda_err__,name,descr);               \
35030f984aSJacob Faibussowitsch     }                                                                   \
36030f984aSJacob Faibussowitsch   } while (0)
37*a4af0ceeSJacob Faibussowitsch #else /* PETSC_PKG_CUDA_VERSION_GE(8,0,0) */
38*a4af0ceeSJacob Faibussowitsch #define CHKERRCUDA(cerr) do {                                   \
39*a4af0ceeSJacob Faibussowitsch     const cudaError_t _p_cuda_err__ = cerr;                     \
40*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_cuda_err__ != cudaSuccess)) {          \
41*a4af0ceeSJacob Faibussowitsch       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_GPU,"cuda error %d",   \
42*a4af0ceeSJacob Faibussowitsch                (PetscErrorCode)_p_cuda_err__);                  \
43*a4af0ceeSJacob Faibussowitsch     }                                                           \
44*a4af0ceeSJacob Faibussowitsch   } while (0)
45*a4af0ceeSJacob Faibussowitsch #endif /* PETSC_PKG_CUDA_VERSION_GE(8,0,0) */
46030f984aSJacob Faibussowitsch 
47*a4af0ceeSJacob Faibussowitsch #define CHKERRCUBLAS(stat)   do {                                       \
48*a4af0ceeSJacob Faibussowitsch     const cublasStatus_t _p_cublas_stat__ = stat;                       \
49*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_cublas_stat__ != CUBLAS_STATUS_SUCCESS)) {     \
50*a4af0ceeSJacob Faibussowitsch       const char *name = PetscCUBLASGetErrorName(_p_cublas_stat__);     \
51*a4af0ceeSJacob Faibussowitsch       if (((_p_cublas_stat__ == CUBLAS_STATUS_NOT_INITIALIZED) ||       \
52*a4af0ceeSJacob Faibussowitsch            (_p_cublas_stat__ == CUBLAS_STATUS_ALLOC_FAILED))   &&       \
53*a4af0ceeSJacob Faibussowitsch           PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {                  \
54*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_GPU_RESOURCE,                \
55*a4af0ceeSJacob Faibussowitsch                  "cuBLAS error %d (%s). "                               \
56*a4af0ceeSJacob Faibussowitsch                  "Reports not initialized or alloc failed; "            \
57*a4af0ceeSJacob Faibussowitsch                  "this indicates the GPU may have run out resources",   \
58*a4af0ceeSJacob Faibussowitsch                  (PetscErrorCode)_p_cublas_stat__,name);                \
59*a4af0ceeSJacob Faibussowitsch       } else {                                                          \
60*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_GPU,"cuBLAS error %d (%s)",  \
61*a4af0ceeSJacob Faibussowitsch                  (PetscErrorCode)_p_cublas_stat__,name);                \
62*a4af0ceeSJacob Faibussowitsch       }                                                                 \
63030f984aSJacob Faibussowitsch     }                                                                   \
64030f984aSJacob Faibussowitsch   } while (0)
65030f984aSJacob Faibussowitsch 
66*a4af0ceeSJacob Faibussowitsch #define CHKERRCUSOLVER(stat) do {                                       \
67*a4af0ceeSJacob Faibussowitsch     const cusolverStatus_t _p_cusolver_stat__ = stat;                   \
68*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_cusolver_stat__ != CUSOLVER_STATUS_SUCCESS)) { \
69*a4af0ceeSJacob Faibussowitsch       const char *name = PetscCUSolverGetErrorName(_p_cusolver_stat__); \
70*a4af0ceeSJacob Faibussowitsch       if (((_p_cusolver_stat__ == CUSOLVER_STATUS_NOT_INITIALIZED) ||   \
71*a4af0ceeSJacob Faibussowitsch            (_p_cusolver_stat__ == CUSOLVER_STATUS_ALLOC_FAILED)    ||   \
72*a4af0ceeSJacob Faibussowitsch            (_p_cusolver_stat__ == CUSOLVER_STATUS_INTERNAL_ERROR)) &&   \
73*a4af0ceeSJacob Faibussowitsch           PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {                  \
74*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_GPU_RESOURCE,                \
75*a4af0ceeSJacob Faibussowitsch                  "cuSolver error %d (%s). "                             \
76*a4af0ceeSJacob Faibussowitsch                  "This indicates the GPU may have run out resources",   \
77*a4af0ceeSJacob Faibussowitsch                  (PetscErrorCode)_p_cusolver_stat__,name);              \
78*a4af0ceeSJacob Faibussowitsch       } else {                                                          \
79*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_GPU,                         \
80*a4af0ceeSJacob Faibussowitsch                  "cuSolver error %d (%s)",                              \
81*a4af0ceeSJacob Faibussowitsch                  (PetscErrorCode)_p_cusolver_stat__,name);              \
82*a4af0ceeSJacob Faibussowitsch       }                                                                 \
83030f984aSJacob Faibussowitsch     }                                                                   \
84030f984aSJacob Faibussowitsch   } while (0)
85030f984aSJacob Faibussowitsch 
86*a4af0ceeSJacob Faibussowitsch #define CHKERRCUFFT(res)     do {                                       \
87*a4af0ceeSJacob Faibussowitsch     const cufftResult_t _p_cufft_stat__ = res;                          \
88*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_cufft_stat__ != CUFFT_SUCCESS)) {              \
89*a4af0ceeSJacob Faibussowitsch       const char *name = PetscCUFFTGetErrorName(_p_cufft_stat__);       \
90*a4af0ceeSJacob Faibussowitsch       if (((_p_cufft_stat__ == CUFFT_SETUP_FAILED)  ||                  \
91*a4af0ceeSJacob Faibussowitsch            (_p_cufft_stat__ == CUFFT_ALLOC_FAILED)) &&                  \
92*a4af0ceeSJacob Faibussowitsch           PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {                  \
93*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_GPU_RESOURCE,                \
94*a4af0ceeSJacob Faibussowitsch                  "cuFFT error %d (%s). "                                \
95*a4af0ceeSJacob Faibussowitsch                  "Reports not initialized or alloc failed; "            \
96*a4af0ceeSJacob Faibussowitsch                  "this indicates the GPU has run out resources",        \
97*a4af0ceeSJacob Faibussowitsch                  (PetscErrorCode)_p_cufft_stat__,name);                 \
98*a4af0ceeSJacob Faibussowitsch       } else {                                                          \
99*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_GPU,                         \
100*a4af0ceeSJacob Faibussowitsch                  "cuFFT error %d (%s)",                                 \
101*a4af0ceeSJacob Faibussowitsch                  (PetscErrorCode)_p_cufft_stat__,name);                 \
102*a4af0ceeSJacob Faibussowitsch       }                                                                 \
103*a4af0ceeSJacob Faibussowitsch     }                                                                   \
104*a4af0ceeSJacob Faibussowitsch   } while (0)
105*a4af0ceeSJacob Faibussowitsch 
106*a4af0ceeSJacob Faibussowitsch #define CHKERRCURAND(stat)   do {                                       \
107*a4af0ceeSJacob Faibussowitsch     const curandStatus_t _p_curand_stat__ = stat;                       \
108*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_curand_stat__ != CURAND_STATUS_SUCCESS)) {     \
109*a4af0ceeSJacob Faibussowitsch       if (((_p_curand_stat__ == CURAND_STATUS_INITIALIZATION_FAILED) || \
110*a4af0ceeSJacob Faibussowitsch            (_p_curand_stat__ == CURAND_STATUS_ALLOCATION_FAILED))    && \
111*a4af0ceeSJacob Faibussowitsch           PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {                  \
112*a4af0ceeSJacob Faibussowitsch         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_GPU_RESOURCE,                \
113*a4af0ceeSJacob Faibussowitsch                  "cuRAND error %d. "                                    \
114*a4af0ceeSJacob Faibussowitsch                  "Reports not initialized or alloc failed; "            \
115*a4af0ceeSJacob Faibussowitsch                  "this indicates the GPU has run out resources",        \
116*a4af0ceeSJacob Faibussowitsch                  (PetscErrorCode)_p_curand_stat__);                     \
117*a4af0ceeSJacob Faibussowitsch       } else {                                                          \
118*a4af0ceeSJacob Faibussowitsch         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_GPU,                         \
119*a4af0ceeSJacob Faibussowitsch                  "cuRand error %d",(PetscErrorCode)_p_curand_stat__);   \
120*a4af0ceeSJacob Faibussowitsch       }                                                                 \
121030f984aSJacob Faibussowitsch     }                                                                   \
122030f984aSJacob Faibussowitsch   } while (0)
123030f984aSJacob Faibussowitsch 
124030f984aSJacob Faibussowitsch PETSC_EXTERN cudaStream_t   PetscDefaultCudaStream; /* The default stream used by PETSc */
125030f984aSJacob Faibussowitsch 
126030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscCUBLASGetHandle(cublasHandle_t*);
127030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscCUSOLVERDnGetHandle(cusolverDnHandle_t*);
128030f984aSJacob Faibussowitsch #endif /* PetscDefined(HAVE_CUDA) */
129030f984aSJacob Faibussowitsch 
130030f984aSJacob Faibussowitsch #if PetscDefined(HAVE_HIP)
131030f984aSJacob Faibussowitsch #include <hip/hip_runtime.h>
132030f984aSJacob Faibussowitsch #include <hipblas.h>
133030f984aSJacob Faibussowitsch #if defined(__HIP_PLATFORM_NVCC__)
134030f984aSJacob Faibussowitsch #include <cusolverDn.h>
135030f984aSJacob Faibussowitsch #else /* __HIP_PLATFORM_HCC__ */
136030f984aSJacob Faibussowitsch #include <rocsolver.h>
137030f984aSJacob Faibussowitsch #endif /* __HIP_PLATFORM_NVCC__ */
138030f984aSJacob Faibussowitsch 
139*a4af0ceeSJacob Faibussowitsch /* REMOVE ME */
140*a4af0ceeSJacob Faibussowitsch #define WaitForHIP() hipDeviceSynchronize()
141030f984aSJacob Faibussowitsch 
142030f984aSJacob Faibussowitsch /* hipBLAS does not have hipblasGetErrorName(). We create one on our own. */
143030f984aSJacob Faibussowitsch PETSC_EXTERN const char* PetscHIPBLASGetErrorName(hipblasStatus_t); /* PETSC_EXTERN since it is exposed by the CHKERRHIPBLAS macro */
144030f984aSJacob Faibussowitsch 
145*a4af0ceeSJacob Faibussowitsch #define CHKERRHIP(cerr)     do {                                        \
146*a4af0ceeSJacob Faibussowitsch     const hipError_t _p_hip_err__ = cerr;                               \
147*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_hip_err__ != hipSuccess)) {                    \
148*a4af0ceeSJacob Faibussowitsch       const char *name  = hipGetErrorName(_p_hip_err__);                \
149*a4af0ceeSJacob Faibussowitsch       const char *descr = hipGetErrorString(_p_hip_err__);              \
150*a4af0ceeSJacob Faibussowitsch       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_GPU,"hip error %d (%s) : %s",  \
151*a4af0ceeSJacob Faibussowitsch                (PetscErrorCode)_p_hip_err__,name,descr);                \
152030f984aSJacob Faibussowitsch     }                                                                   \
153030f984aSJacob Faibussowitsch   } while (0)
154030f984aSJacob Faibussowitsch 
155*a4af0ceeSJacob Faibussowitsch #define CHKERRHIPBLAS(stat) do {                                        \
156*a4af0ceeSJacob Faibussowitsch     const hipblasStatus_t _p_hipblas_stat__ = stat;                     \
157*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_hipblas_stat__ != HIPBLAS_STATUS_SUCCESS)) {   \
158*a4af0ceeSJacob Faibussowitsch       const char *name = PetscHIPBLASGetErrorName(_p_hipblas_stat__);   \
159*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_GPU,"hipBLAS error %d (%s)",   \
160*a4af0ceeSJacob Faibussowitsch                (PetscErrorCode)_p_hipblas_stat__,name);                 \
161030f984aSJacob Faibussowitsch     }                                                                   \
162030f984aSJacob Faibussowitsch   } while (0)
163030f984aSJacob Faibussowitsch 
164030f984aSJacob Faibussowitsch /* TODO: SEK:  Need to figure out the hipsolver issues */
165*a4af0ceeSJacob Faibussowitsch #define CHKERRHIPSOLVER(stat) do {                                      \
166*a4af0ceeSJacob Faibussowitsch     const hipsolverStatus_t _p_hipsolver_stat__ = stat;                 \
167*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(_p_hipsolver_stat__ /* != HIPSOLVER_STATUS_SUCCESS */)) { \
168*a4af0ceeSJacob Faibussowitsch       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_GPU,"HIPSOLVER error %d",      \
169*a4af0ceeSJacob Faibussowitsch                (PetscErrorCode)_p_hipsolver_stat__);                    \
170030f984aSJacob Faibussowitsch     }                                                                   \
171030f984aSJacob Faibussowitsch   } while (0)
172030f984aSJacob Faibussowitsch 
173030f984aSJacob Faibussowitsch /* hipSolver does not exist yet so we work around it
174030f984aSJacob Faibussowitsch    rocSOLVER users rocBLAS for the handle
175030f984aSJacob Faibussowitsch  * */
176030f984aSJacob Faibussowitsch #if defined(__HIP_PLATFORM_NVCC__)
177030f984aSJacob Faibussowitsch typedef cusolverDnHandle_t hipsolverHandle_t;
178030f984aSJacob Faibussowitsch typedef cusolverStatus_t   hipsolverStatus_t;
179030f984aSJacob Faibussowitsch 
180030f984aSJacob Faibussowitsch /* Alias hipsolverDestroy to cusolverDnDestroy */
181030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverDestroy(hipsolverHandle_t *hipsolverhandle)
182030f984aSJacob Faibussowitsch {
183030f984aSJacob Faibussowitsch   return cusolverDnDestroy(hipsolverhandle)
184030f984aSJacob Faibussowitsch }
185030f984aSJacob Faibussowitsch 
186030f984aSJacob Faibussowitsch /* Alias hipsolverCreate to cusolverDnCreate */
187030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverCreate(hipsolverHandle_t *hipsolverhandle)
188030f984aSJacob Faibussowitsch {
189030f984aSJacob Faibussowitsch   return cusolverDnCreate(hipsolverhandle)
190030f984aSJacob Faibussowitsch }
191030f984aSJacob Faibussowitsch 
192030f984aSJacob Faibussowitsch /* Alias hipsolverGetStream to cusolverDnGetStream */
193030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverGetStream(hipsolverHandle_t handle, hipStream_t *stream)
194030f984aSJacob Faibussowitsch {
195030f984aSJacob Faibussowitsch   return cusolverDnGetStream(handle,stream);
196030f984aSJacob Faibussowitsch }
197030f984aSJacob Faibussowitsch 
198030f984aSJacob Faibussowitsch /* Alias hipsolverSetStream to cusolverDnSetStream */
199030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverSetStream(hipsolverHandle_t handle, hipStream_t stream)
200030f984aSJacob Faibussowitsch {
201030f984aSJacob Faibussowitsch   return cusolveDnSetStream(handle,stream);
202030f984aSJacob Faibussowitsch }
203030f984aSJacob Faibussowitsch #else /* __HIP_PLATFORM_HCC__ */
204030f984aSJacob Faibussowitsch typedef rocblas_handle hipsolverHandle_t;
205030f984aSJacob Faibussowitsch typedef rocblas_status hipsolverStatus_t;
206030f984aSJacob Faibussowitsch 
207030f984aSJacob Faibussowitsch /* Alias hipsolverDestroy to rocblas_destroy_handle */
208030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverDestroy(hipsolverHandle_t  hipsolverhandle)
209030f984aSJacob Faibussowitsch {
210030f984aSJacob Faibussowitsch   return rocblas_destroy_handle(hipsolverhandle);
211030f984aSJacob Faibussowitsch }
212030f984aSJacob Faibussowitsch 
213030f984aSJacob Faibussowitsch /* Alias hipsolverCreate to rocblas_destroy_handle */
214030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverCreate(hipsolverHandle_t *hipsolverhandle)
215030f984aSJacob Faibussowitsch {
216030f984aSJacob Faibussowitsch   return rocblas_create_handle(hipsolverhandle);
217030f984aSJacob Faibussowitsch }
218030f984aSJacob Faibussowitsch 
219030f984aSJacob Faibussowitsch /* Alias hipsolverGetStream to rocblas_get_stream */
220030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverGetStream(hipsolverHandle_t handle, hipStream_t *stream)
221030f984aSJacob Faibussowitsch {
222030f984aSJacob Faibussowitsch   return rocblas_get_stream(handle,stream);
223030f984aSJacob Faibussowitsch }
224030f984aSJacob Faibussowitsch 
225030f984aSJacob Faibussowitsch /* Alias hipsolverSetStream to rocblas_set_stream */
226030f984aSJacob Faibussowitsch PETSC_STATIC_INLINE hipsolverStatus_t hipsolverSetStream(hipsolverHandle_t handle, hipStream_t stream)
227030f984aSJacob Faibussowitsch {
228030f984aSJacob Faibussowitsch   return rocblas_set_stream(handle,stream);
229030f984aSJacob Faibussowitsch }
230030f984aSJacob Faibussowitsch #endif /* __HIP_PLATFORM_NVCC__ */
231030f984aSJacob Faibussowitsch PETSC_EXTERN hipStream_t    PetscDefaultHipStream; /* The default stream used by PETSc */
232030f984aSJacob Faibussowitsch 
233030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscHIPBLASGetHandle(hipblasHandle_t*);
234030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscHIPSOLVERGetHandle(hipsolverHandle_t*);
235030f984aSJacob Faibussowitsch #endif /* PetscDefined(HAVE_HIP) */
236030f984aSJacob Faibussowitsch 
237030f984aSJacob Faibussowitsch /* Cannot use the device context api without C++11 */
238030f984aSJacob Faibussowitsch #if PetscDefined(HAVE_CXX_DIALECT_CXX11)
239030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceInitializePackage(void);
240030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceFinalizePackage(void);
241030f984aSJacob Faibussowitsch 
242030f984aSJacob Faibussowitsch /* PetscDevice */
243*a4af0ceeSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceInitialize(PetscDeviceType);
244*a4af0ceeSJacob Faibussowitsch PETSC_EXTERN PetscBool      PetscDeviceInitialized(PetscDeviceType);
245*a4af0ceeSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceCreate(PetscDeviceType,PetscInt,PetscDevice*);
246030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceConfigure(PetscDevice);
247*a4af0ceeSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceView(PetscDevice,PetscViewer);
248030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceDestroy(PetscDevice*);
249030f984aSJacob Faibussowitsch 
250030f984aSJacob Faibussowitsch /* PetscDeviceContext */
251030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextCreate(PetscDeviceContext*);
252030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextDestroy(PetscDeviceContext*);
253030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetDevice(PetscDeviceContext,PetscDevice);
254030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextGetDevice(PetscDeviceContext,PetscDevice*);
255030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetStreamType(PetscDeviceContext,PetscStreamType);
256030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextGetStreamType(PetscDeviceContext,PetscStreamType*);
257030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetUp(PetscDeviceContext);
258030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextDuplicate(PetscDeviceContext,PetscDeviceContext*);
259030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextQueryIdle(PetscDeviceContext,PetscBool*);
260030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextWaitForContext(PetscDeviceContext,PetscDeviceContext);
261030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextFork(PetscDeviceContext,PetscInt,PetscDeviceContext**);
262030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextJoin(PetscDeviceContext,PetscInt,PetscDeviceContextJoinMode,PetscDeviceContext**);
263030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSynchronize(PetscDeviceContext);
264030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextGetCurrentContext(PetscDeviceContext*);
265030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetCurrentContext(PetscDeviceContext);
266030f984aSJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDeviceContextSetFromOptions(MPI_Comm,const char[],PetscDeviceContext);
267030f984aSJacob Faibussowitsch #endif /* PetscDefined(HAVE_CXX_DIALECT_CXX11) */
268030f984aSJacob Faibussowitsch #endif /* PETSCDEVICE_H */
269