1 #ifndef PETSCDEVICE_H 2 #define PETSCDEVICE_H 3 4 #include <petscdevicetypes.h> 5 #include <petscviewertypes.h> 6 7 /* SUBMANSEC = Sys */ 8 9 // REVIEW ME: this should probably go somewhere better, configure-time? 10 #define PETSC_HAVE_HOST 1 11 12 /* logging support */ 13 PETSC_EXTERN PetscClassId PETSC_DEVICE_CLASSID; 14 PETSC_EXTERN PetscClassId PETSC_DEVICE_CONTEXT_CLASSID; 15 16 PETSC_EXTERN PetscErrorCode PetscDeviceInitializePackage(void); 17 PETSC_EXTERN PetscErrorCode PetscDeviceFinalizePackage(void); 18 PETSC_EXTERN PetscErrorCode PetscGetMemType(const void *, PetscMemType *); 19 20 /* PetscDevice */ 21 #if PetscDefined(HAVE_CXX) 22 PETSC_EXTERN PetscErrorCode PetscDeviceCreate(PetscDeviceType, PetscInt, PetscDevice *); 23 PETSC_EXTERN PetscErrorCode PetscDeviceDestroy(PetscDevice *); 24 PETSC_EXTERN PetscErrorCode PetscDeviceConfigure(PetscDevice); 25 PETSC_EXTERN PetscErrorCode PetscDeviceView(PetscDevice, PetscViewer); 26 PETSC_EXTERN PetscErrorCode PetscDeviceGetType(PetscDevice, PetscDeviceType *); 27 PETSC_EXTERN PetscErrorCode PetscDeviceGetDeviceId(PetscDevice, PetscInt *); 28 PETSC_EXTERN PetscDeviceType PETSC_DEVICE_DEFAULT(void); 29 PETSC_EXTERN PetscErrorCode PetscDeviceSetDefaultDeviceType(PetscDeviceType); 30 PETSC_EXTERN PetscErrorCode PetscDeviceInitialize(PetscDeviceType); 31 PETSC_EXTERN PetscBool PetscDeviceInitialized(PetscDeviceType); 32 #else 33 #define PetscDeviceCreate(PetscDeviceType, PetscInt, dev) (*(dev) = PETSC_NULLPTR, 0) 34 #define PetscDeviceDestroy(dev) (*(dev) = PETSC_NULLPTR, 0) 35 #define PetscDeviceConfigure(PetscDevice) 0 36 #define PetscDeviceView(PetscDevice, PetscViewer) 0 37 #define PetscDeviceGetType(PetscDevice, type) (*(type) = PETSC_DEVICE_DEFAULT(), 0) 38 #define PetscDeviceGetDeviceId(PetscDevice, id) (*(id) = 0) 39 #define PETSC_DEVICE_DEFAULT() PETSC_DEVICE_HOST 40 #define PetscDeviceSetDefaultDeviceType(PetscDeviceType) 0 41 #define PetscDeviceInitialize(PetscDeviceType) 0 42 #define PetscDeviceInitialized(dtype) ((dtype) == PETSC_DEVICE_HOST) 43 #endif /* PetscDefined(HAVE_CXX) */ 44 45 /* PetscDeviceContext */ 46 #if PetscDefined(HAVE_CXX) 47 PETSC_EXTERN PetscErrorCode PetscDeviceContextCreate(PetscDeviceContext *); 48 PETSC_EXTERN PetscErrorCode PetscDeviceContextDestroy(PetscDeviceContext *); 49 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetStreamType(PetscDeviceContext, PetscStreamType); 50 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetStreamType(PetscDeviceContext, PetscStreamType *); 51 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetDevice(PetscDeviceContext, PetscDevice); 52 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetDevice(PetscDeviceContext, PetscDevice *); 53 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetDeviceType(PetscDeviceContext, PetscDeviceType *); 54 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetUp(PetscDeviceContext); 55 PETSC_EXTERN PetscErrorCode PetscDeviceContextDuplicate(PetscDeviceContext, PetscDeviceContext *); 56 PETSC_EXTERN PetscErrorCode PetscDeviceContextQueryIdle(PetscDeviceContext, PetscBool *); 57 PETSC_EXTERN PetscErrorCode PetscDeviceContextWaitForContext(PetscDeviceContext, PetscDeviceContext); 58 PETSC_EXTERN PetscErrorCode PetscDeviceContextForkWithStreamType(PetscDeviceContext, PetscStreamType, PetscInt, PetscDeviceContext **); 59 PETSC_EXTERN PetscErrorCode PetscDeviceContextFork(PetscDeviceContext, PetscInt, PetscDeviceContext **); 60 PETSC_EXTERN PetscErrorCode PetscDeviceContextJoin(PetscDeviceContext, PetscInt, PetscDeviceContextJoinMode, PetscDeviceContext **); 61 PETSC_EXTERN PetscErrorCode PetscDeviceContextSynchronize(PetscDeviceContext); 62 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetFromOptions(MPI_Comm, PetscDeviceContext); 63 PETSC_EXTERN PetscErrorCode PetscDeviceContextView(PetscDeviceContext, PetscViewer); 64 PETSC_EXTERN PetscErrorCode PetscDeviceContextViewFromOptions(PetscDeviceContext, PetscObject, PetscViewer); 65 PETSC_EXTERN PetscErrorCode PetscDeviceContextGetCurrentContext(PetscDeviceContext *); 66 PETSC_EXTERN PetscErrorCode PetscDeviceContextSetCurrentContext(PetscDeviceContext); 67 #else 68 #define PetscDeviceContextCreate(dctx) (*(dctx) = PETSC_NULLPTR, 0) 69 #define PetscDeviceContextDestroy(dctx) (*(dctx) = PETSC_NULLPTR, 0) 70 #define PetscDeviceContextSetStreamType(PetscDeviceContext, PetscStreamType) 0 71 #define PetscDeviceContextGetStreamType(PetscDeviceContext, type) (*(type) = PETSC_STREAM_GLOBAL_BLOCKING, 0) 72 #define PetscDeviceContextSetDevice(PetscDeviceContext, PetscDevice) 0 73 #define PetscDeviceContextGetDevice(PetscDeviceContext, device) (*(device) = PETSC_NULLPTR, 0) 74 #define PetscDeviceContextGetDeviceType(PetscDeviceContext, type) (*(type) = PETSC_DEVICE_DEFAULT()) 75 #define PetscDeviceContextSetUp(PetscDeviceContext) 0 76 #define PetscDeviceContextDuplicate(PetscDeviceContextl, PetscDeviceContextr) (*(PetscDeviceContextr) = PETSC_NULLPTR, 0) 77 #define PetscDeviceContextQueryIdle(PetscDeviceContext, idle) (*(idle) = PETSC_TRUE, 0) 78 #define PetscDeviceContextWaitForContext(PetscDeviceContextl, PetscDeviceContextr) 0 79 #define PetscDeviceContextForkWithStreamType(PetscDeviceContextp, PetscStreamType, PetscInt, PetscDeviceContextc) (*(PetscDeviceContextc) = PETSC_NULLPTR, 0) 80 #define PetscDeviceContextFork(PetscDeviceContextp, PetscInt, PetscDeviceContextc) (*(PetscDeviceContextc) = PETSC_NULLPTR, 0) 81 #define PetscDeviceContextJoin(PetscDeviceContextp, PetscInt, PetscDeviceContextJoinMode, PetscDeviceContextc) (*(PetscDeviceContextc) = PETSC_NULLPTR, 0) 82 #define PetscDeviceContextSynchronize(PetscDeviceContext) 0 83 #define PetscDeviceContextSetFromOptions(MPI_Comm, PetscDeviceContext) 0 84 #define PetscDeviceContextView(PetscDeviceContext, PetscViewer) 0 85 #define PetscDeviceContextViewFromOptions(PetscDeviceContext, PetscObject, PetscViewer) 0 86 #define PetscDeviceContextGetCurrentContext(dctx) (*(dctx) = PETSC_NULLPTR, 0) 87 #define PetscDeviceContextSetCurrentContext(PetscDeviceContext) 0 88 #endif /* PetscDefined(HAVE_CXX) */ 89 90 /* memory */ 91 #if PetscDefined(HAVE_CXX) 92 PETSC_EXTERN PetscErrorCode PetscDeviceAllocate(PetscDeviceContext, PetscBool, PetscMemType, size_t, void **PETSC_RESTRICT); 93 PETSC_EXTERN PetscErrorCode PetscDeviceDeallocate(PetscDeviceContext, void *PETSC_RESTRICT); 94 PETSC_EXTERN PetscErrorCode PetscDeviceMemcpy(PetscDeviceContext, void *PETSC_RESTRICT, const void *PETSC_RESTRICT, size_t); 95 PETSC_EXTERN PetscErrorCode PetscDeviceMemset(PetscDeviceContext, void *PETSC_RESTRICT, PetscInt, size_t); 96 #else 97 #include <string.h> // memset() 98 #define PetscDeviceAllocate(PetscDeviceContext, clear, PetscMemType, size, ptr) PetscMallocA(1, (clear), __LINE__, PETSC_FUNCTION_NAME, __FILE__, (size), (ptr)) 99 #define PetscDeviceDeallocate(PetscDeviceContext, ptr) PetscFree((ptr)) 100 #define PetscDeviceMemcpy(PetscDeviceContext, dest, src, size) PetscMemcpy((dest), (src), (size)) 101 #define PetscDeviceMemset(PetscDeviceContext, ptr, v, size) ((void)memset((ptr), (unsigned char)(v), (size)), 0) 102 #endif /* PetscDefined(HAVE_CXX) */ 103 104 /*MC 105 PetscDeviceMalloc - Allocate device-aware memory 106 107 Synopsis: 108 #include <petscdevice.h> 109 PetscErrorCode PetscDeviceMalloc(PetscDeviceContext dctx, PetscMemType mtype, size_t n, Type **ptr) 110 111 Not Collective, Asynchronous, Auto-dependency aware 112 113 Input Parameters: 114 + dctx - The `PetscDeviceContext` used to allocate the memory 115 . mtype - The type of memory to allocate 116 - n - The amount (in elements) to allocate 117 118 Output Parameter: 119 . ptr - The pointer to store the result in 120 121 Notes: 122 See `PetscDeviceAllocate()` for more detailed discussion on usage and async semantics. 123 124 This uses the `sizeof()` of the memory type requested to determine the total memory to be 125 allocated, therefore you should not multiply the number of elements requested by the 126 `sizeof()` the type\: 127 128 .vb 129 PetscInt *arr; 130 131 // correct 132 PetscDeviceMalloc(dctx,PETSC_MEMTYPE_DEVICE,n,&arr); 133 134 // incorrect 135 PetscDeviceMalloc(dctx,PETSC_MEMTYPE_DEVICE,n*sizeof(*arr),&arr); 136 .ve 137 138 This routine falls back to using `PetscMalloc1()` (which is fully synchronous) if PETSc was 139 not configured with device support. The user should note that `mtype` is ignored in this 140 case, as `PetscMalloc1()` allocates only host memory. 141 142 Level: beginner 143 144 .N ASYNC_API 145 146 .seealso: `PetscDeviceFree()`, `PetscDeviceCalloc()`, `PetscDeviceArrayCopy()`, 147 `PetscDeviceArrayZero()`, `PetscDeviceAllocate()`, `PetscDeviceDeallocate()` 148 M*/ 149 #define PetscDeviceMalloc(dctx, mtype, n, ptr) (PetscDefined(HAVE_DEVICE) ? PetscDeviceAllocate((dctx), PETSC_FALSE, (mtype), (size_t)(n) * sizeof(**(ptr)), (void **)(ptr)) : PetscMalloc1((n), (ptr))) 150 151 /*MC 152 PetscDeviceCalloc - Allocate zeroed device-aware memory 153 154 Synopsis: 155 #include <petscdevice.h> 156 PetscErrorCode PetscDeviceCalloc(PetscDeviceContext dctx, PetscMemType mtype, size_t n, Type **ptr) 157 158 Not Collective, Asynchronous, Auto-dependency aware 159 160 Input Parameters: 161 + dctx - The `PetscDeviceContext` used to allocate the memory 162 . mtype - The type of memory to allocate 163 - n - The amount (in elements) to allocate 164 165 Output Parameter: 166 . ptr - The pointer to store the result in 167 168 Notes: 169 Has identical usage to `PetscDeviceMalloc()` except that the memory is zeroed before it is 170 returned. See `PetscDeviceMalloc()` for further discussion. 171 172 This routine falls back to using `PetscCalloc1()` if PETSc was not configured with device 173 support. The user should note that `mtype` is ignored in this case, as `PetscCalloc1()` 174 allocates only host memory. 175 176 Level: beginner 177 178 .N ASYNC_API 179 180 .seealso: `PetscDeviceFree()`, `PetscDeviceMalloc()`, `PetscDeviceArrayCopy()`, 181 `PetscDeviceArrayZero()`, `PetscDeviceAllocate()`, `PetscDeviceDeallocate()` 182 M*/ 183 #define PetscDeviceCalloc(dctx, mtype, n, ptr) (PetscDefined(HAVE_DEVICE) ? PetscDeviceAllocate((dctx), PETSC_TRUE, (mtype), (size_t)(n) * sizeof(**(ptr)), (void **)(ptr)) : PetscCalloc1((n), (ptr))) 184 185 /*MC 186 PetscDeviceFree - Free device-aware memory 187 188 Synopsis: 189 #include <petscdevice.h> 190 PetscErrorCode PetscDeviceFree(PetscDeviceContext dctx, void *ptr) 191 192 Not Collective, Asynchronous, Auto-dependency aware 193 194 Input Parameters: 195 + dctx - The `PetscDeviceContext` used to free the memory 196 - ptr - The pointer to free 197 198 Notes: 199 `ptr` must have been allocated using `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, or 200 `PetscDeviceAllocate()`, or registered with the system using `PetscRegisterMemory()`. 201 202 Automatically sets `ptr` to `PETSC_NULLPTR` on successful deallocation. 203 204 This routine falls back to using `PetscFree()` if PETSc was not configured with device 205 support. The user should note that `PetscFree()` frees only host memory. 206 207 See `PetscDeviceDeallocate()` for more further discussion. 208 209 Level: beginner 210 211 .N ASYNC_API 212 213 .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceDeallocate()` 214 M*/ 215 #define PetscDeviceFree(dctx, ptr) ((ptr) ? (PetscDefined(HAVE_DEVICE) ? (PetscDeviceDeallocate((dctx), (ptr)) || ((ptr) = PETSC_NULLPTR, 0)) : PetscFree(ptr)) : 0) 216 217 /*MC 218 PetscDeviceArrayCopy - Copy memory in a device-aware manner 219 220 Synopsis: 221 #include <petscdevice.h> 222 PetscErrorCode PetscDeviceArrayCopy(PetscDeviceContext dctx, void *PETSC_RESTRICT dest, const void *PETSC_RESTRICT src, size_t n, PetscDeviceCopyMode mode) 223 224 Not Collective, Asynchronous, Auto-dependency aware 225 226 Input Parameters: 227 + dctx - The `PetscDeviceContext` used to copy the memory 228 . dest - The pointer to copy to 229 . src - The pointer to copy from 230 - n - The amount (in elements) to copy 231 232 Notes: 233 Both `dest` and `src` must have been allocated using any of `PetscDeviceMalloc()`, 234 `PetscDeviceCalloc()` or `PetscDeviceAllocate()`, or registered with the system via 235 `PetscDeviceRegisterMemory()`. 236 237 This uses the `sizeof()` of the `src` memory type requested to determine the total memory to 238 be copied, therefore you should not multiply the number of elements by the `sizeof()` the 239 type\: 240 241 .vb 242 PetscInt *to,*from; 243 244 // correct 245 PetscDeviceArrayCopy(dctx,to,from,n,PETSC_DEVICE_COPY_AUTO); 246 247 // incorrect 248 PetscDeviceArrayCopy(dctx,to,from,n*sizeof(*from),PETSC_DEVICE_COPY_AUTO); 249 .ve 250 251 See `PetscDeviceMemcpy()` for further discussion. 252 253 Level: beginner 254 255 .N ASYNC_API 256 257 .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceRegisterMemory()`, 258 `PetscDeviceFree()`, `PetscDeviceArrayZero()`, `PetscDeviceMemcpy()` 259 M*/ 260 #define PetscDeviceArrayCopy(dctx, dest, src, n) ((n) ? (PetscDefined(HAVE_DEVICE) ? PetscDeviceMemcpy((dctx), (dest), (src), (size_t)(n) * sizeof(*(src))) : PetscArraycpy((dest), (src), (n))) : 0) 261 262 /*MC 263 PetscDeviceArrayZero - Zero memory in a device-aware manner 264 265 Synopsis: 266 #include <petscdevice.h> 267 PetscErrorCode PetscDeviceArrayZero(PetscDeviceContext dctx, PetscMemType mtype, void *ptr, size_t n) 268 269 Not Collective, Asynchronous, Auto-dependency aware 270 271 Input Parameters: 272 + dctx - The `PetscDeviceContext` used to zero the memory 273 . ptr - The pointer to the memory 274 - n - The amount (in elements) to zero 275 276 Notes: 277 `ptr` must have been allocated using any of `PetscDeviceMalloc()`, `PetscDeviceCalloc()` or 278 `PetscDeviceAllocate()`, or registered with the system via `PetscDeviceRegisterMemory()`. 279 280 This uses the `sizeof()` of the memory type requested to determine the total memory to be 281 zeroed, therefore you should not multiply the number of elements by the `sizeof()` the type\: 282 283 .vb 284 PetscInt *ptr; 285 286 // correct 287 PetscDeviceArrayZero(dctx,PETSC_MEMTYPE_DEVICE,ptr,n); 288 289 // incorrect 290 PetscDeviceArrayZero(dctx,PETSC_MEMTYPE_DEVICE,ptr,n*sizeof(*ptr)); 291 .ve 292 293 See `PetscDeviceMemset()` for futher discussion. 294 295 Level: beginner 296 297 .N ASYNC_API 298 299 .seealso: `PetscDeviceMalloc()`, `PetscDeviceCalloc()`, `PetscDeviceRegisterMemory()`, 300 `PetscDeviceFree()`, `PetscDeviceArrayCopy()`, `PetscDeviceMemset()` 301 M*/ 302 #define PetscDeviceArrayZero(dctx, ptr, n) ((n) ? (PetscDefined(HAVE_DEVICE) ? PetscDeviceMemset((dctx), (ptr), 0, (size_t)(n) * sizeof(*(ptr))) : PetscArrayzero((ptr), (n))) : 0) 303 304 #endif /* PETSCDEVICE_H */ 305