1030f984aSJacob Faibussowitsch #include <petsc/private/deviceimpl.h> /*I "petscdevice.h" I*/ 2030f984aSJacob Faibussowitsch #include "objpool.hpp" 3030f984aSJacob Faibussowitsch 4030f984aSJacob Faibussowitsch /* Define the allocator */ 5030f984aSJacob Faibussowitsch struct PetscDeviceContextAllocator : Petsc::Allocator<PetscDeviceContext> 6030f984aSJacob Faibussowitsch { 7030f984aSJacob Faibussowitsch static PetscInt PetscDeviceContextID; 8030f984aSJacob Faibussowitsch 9030f984aSJacob Faibussowitsch PETSC_NODISCARD PetscErrorCode create(PetscDeviceContext *dctx) noexcept 10030f984aSJacob Faibussowitsch { 11030f984aSJacob Faibussowitsch PetscDeviceContext dc; 12030f984aSJacob Faibussowitsch PetscErrorCode ierr; 13030f984aSJacob Faibussowitsch 14030f984aSJacob Faibussowitsch PetscFunctionBegin; 15030f984aSJacob Faibussowitsch ierr = PetscNew(&dc);CHKERRQ(ierr); 16030f984aSJacob Faibussowitsch dc->id = PetscDeviceContextID++; 17030f984aSJacob Faibussowitsch dc->idle = PETSC_TRUE; 18030f984aSJacob Faibussowitsch dc->streamType = PETSC_STREAM_DEFAULT_BLOCKING; 19030f984aSJacob Faibussowitsch *dctx = dc; 20030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 21030f984aSJacob Faibussowitsch } 22030f984aSJacob Faibussowitsch 23030f984aSJacob Faibussowitsch PETSC_NODISCARD PetscErrorCode destroy(PetscDeviceContext &dctx) const noexcept 24030f984aSJacob Faibussowitsch { 25030f984aSJacob Faibussowitsch PetscErrorCode ierr; 26030f984aSJacob Faibussowitsch 27030f984aSJacob Faibussowitsch PetscFunctionBegin; 28030f984aSJacob Faibussowitsch if (PetscUnlikelyDebug(dctx->numChildren)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Device context still has %D un-restored children, must call PetscDeviceContextRestore() on all children before destroying",dctx->numChildren); 29030f984aSJacob Faibussowitsch if (dctx->ops->destroy) {ierr = (*dctx->ops->destroy)(dctx);CHKERRQ(ierr);} 30030f984aSJacob Faibussowitsch ierr = PetscDeviceDestroy(&dctx->device);CHKERRQ(ierr); 31030f984aSJacob Faibussowitsch ierr = PetscFree(dctx->childIDs);CHKERRQ(ierr); 32030f984aSJacob Faibussowitsch ierr = PetscFree(dctx);CHKERRQ(ierr); 33030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 34030f984aSJacob Faibussowitsch } 35030f984aSJacob Faibussowitsch 36030f984aSJacob Faibussowitsch PETSC_NODISCARD PetscErrorCode reset(PetscDeviceContext &dctx) const noexcept 37030f984aSJacob Faibussowitsch { 38030f984aSJacob Faibussowitsch PetscErrorCode ierr; 39030f984aSJacob Faibussowitsch 40030f984aSJacob Faibussowitsch PetscFunctionBegin; 41030f984aSJacob Faibussowitsch /* don't deallocate the child array, rather just zero it out */ 42030f984aSJacob Faibussowitsch ierr = PetscArrayzero(dctx->childIDs,dctx->maxNumChildren);CHKERRQ(ierr); 43030f984aSJacob Faibussowitsch dctx->setup = PETSC_FALSE; 44030f984aSJacob Faibussowitsch dctx->numChildren = 0; 45030f984aSJacob Faibussowitsch dctx->idle = PETSC_TRUE; 46030f984aSJacob Faibussowitsch dctx->streamType = PETSC_STREAM_DEFAULT_BLOCKING; 47030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 48030f984aSJacob Faibussowitsch } 49030f984aSJacob Faibussowitsch 50030f984aSJacob Faibussowitsch PETSC_NODISCARD PetscErrorCode finalize(void) noexcept 51030f984aSJacob Faibussowitsch { 52030f984aSJacob Faibussowitsch PetscFunctionBegin; 53030f984aSJacob Faibussowitsch PetscDeviceContextID = 0; 54030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 55030f984aSJacob Faibussowitsch } 56030f984aSJacob Faibussowitsch }; 57030f984aSJacob Faibussowitsch PetscInt PetscDeviceContextAllocator::PetscDeviceContextID = 0; 58030f984aSJacob Faibussowitsch 59030f984aSJacob Faibussowitsch static Petsc::ObjectPool<PetscDeviceContext,PetscDeviceContextAllocator> contextPool; 60030f984aSJacob Faibussowitsch 61030f984aSJacob Faibussowitsch /*@C 62030f984aSJacob Faibussowitsch PetscDeviceContextCreate - Creates a PetscDeviceContext 63030f984aSJacob Faibussowitsch 64030f984aSJacob Faibussowitsch Not Collective, Asynchronous 65030f984aSJacob Faibussowitsch 6601d2d390SJose E. Roman Output Paramemter: 67030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext 68030f984aSJacob Faibussowitsch 69030f984aSJacob Faibussowitsch Notes: 70030f984aSJacob Faibussowitsch Unlike almost every other PETSc class it is advised that most users use 71030f984aSJacob Faibussowitsch PetscDeviceContextDuplicate() rather than this routine to create new contexts. Contexts 72030f984aSJacob Faibussowitsch of different types are incompatible with one another; using 73030f984aSJacob Faibussowitsch PetscDeviceContextDuplicate() ensures compatible types. 74030f984aSJacob Faibussowitsch 75030f984aSJacob Faibussowitsch Level: beginner 76030f984aSJacob Faibussowitsch 77030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextDuplicate(), PetscDeviceContextSetDevice(), 785181c4f9SJacob Faibussowitsch PetscDeviceContextSetStreamType(), PetscDeviceContextSetUp(), 795181c4f9SJacob Faibussowitsch PetscDeviceContextSetFromOptions(), PetscDeviceContextDestroy() 80030f984aSJacob Faibussowitsch @*/ 81030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextCreate(PetscDeviceContext *dctx) 82030f984aSJacob Faibussowitsch { 83030f984aSJacob Faibussowitsch PetscErrorCode ierr; 84030f984aSJacob Faibussowitsch 85030f984aSJacob Faibussowitsch PetscFunctionBegin; 86030f984aSJacob Faibussowitsch PetscValidPointer(dctx,1); 87030f984aSJacob Faibussowitsch ierr = PetscDeviceInitializePackage();CHKERRQ(ierr); 88030f984aSJacob Faibussowitsch ierr = contextPool.get(*dctx);CHKERRQ(ierr); 89030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 90030f984aSJacob Faibussowitsch } 91030f984aSJacob Faibussowitsch 92030f984aSJacob Faibussowitsch /*@C 93030f984aSJacob Faibussowitsch PetscDeviceContextDestroy - Frees a PetscDeviceContext 94030f984aSJacob Faibussowitsch 95030f984aSJacob Faibussowitsch Not Collective, Asynchronous 96030f984aSJacob Faibussowitsch 97030f984aSJacob Faibussowitsch Input Parameters: 98030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext 99030f984aSJacob Faibussowitsch 100030f984aSJacob Faibussowitsch Notes: 101030f984aSJacob Faibussowitsch No implicit synchronization occurs due to this routine, all resources are released completely asynchronously 102030f984aSJacob Faibussowitsch w.r.t. the host. If one needs to guarantee access to the data produced on this contexts stream one should perform the 103030f984aSJacob Faibussowitsch appropriate synchronization before calling this routine. 104030f984aSJacob Faibussowitsch 105030f984aSJacob Faibussowitsch Developer Notes: 106030f984aSJacob Faibussowitsch The context is never actually "destroyed", only returned to an ever growing pool of 107030f984aSJacob Faibussowitsch contexts. There are currently no safeguards on the size of the pool, this should perhaps 108030f984aSJacob Faibussowitsch be implemented. 109030f984aSJacob Faibussowitsch 110030f984aSJacob Faibussowitsch Level: beginner 111030f984aSJacob Faibussowitsch 112030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextCreate(), PetscDeviceContextSetDevice(), PetscDeviceContextSetUp(), PetscDeviceContextSynchronize() 113030f984aSJacob Faibussowitsch @*/ 114030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextDestroy(PetscDeviceContext *dctx) 115030f984aSJacob Faibussowitsch { 116030f984aSJacob Faibussowitsch PetscErrorCode ierr; 117030f984aSJacob Faibussowitsch 118030f984aSJacob Faibussowitsch PetscFunctionBegin; 119030f984aSJacob Faibussowitsch if (!*dctx) PetscFunctionReturn(0); 120030f984aSJacob Faibussowitsch /* use move assignment whenever possible */ 121030f984aSJacob Faibussowitsch ierr = contextPool.reclaim(std::move(*dctx));CHKERRQ(ierr); 122030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 123030f984aSJacob Faibussowitsch } 124030f984aSJacob Faibussowitsch 125030f984aSJacob Faibussowitsch /*@C 126030f984aSJacob Faibussowitsch PetscDeviceContextSetStreamType - Set the implementation type of the underlying stream for a PetscDeviceContext 127030f984aSJacob Faibussowitsch 128030f984aSJacob Faibussowitsch Not Collective, Asynchronous 129030f984aSJacob Faibussowitsch 13001d2d390SJose E. Roman Input Parameters: 131030f984aSJacob Faibussowitsch + dctx - The PetscDeviceContext 132030f984aSJacob Faibussowitsch - type - The PetscStreamType 133030f984aSJacob Faibussowitsch 134030f984aSJacob Faibussowitsch Notes: 135030f984aSJacob Faibussowitsch See PetscStreamType in include/petscdevicetypes.h for more information on the available 136030f984aSJacob Faibussowitsch types and their interactions. If the PetscDeviceContext was previously set up and stream 137030f984aSJacob Faibussowitsch type was changed, you must call PetscDeviceContextSetUp() again after this routine. 138030f984aSJacob Faibussowitsch 139030f984aSJacob Faibussowitsch Level: intermediate 140030f984aSJacob Faibussowitsch 1415181c4f9SJacob Faibussowitsch .seealso: PetscDeviceContextGetStreamType(), PetscDeviceContextCreate(), PetscDeviceContextSetUp(), PetscDeviceContextSetFromOptions() 142030f984aSJacob Faibussowitsch @*/ 143030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextSetStreamType(PetscDeviceContext dctx, PetscStreamType type) 144030f984aSJacob Faibussowitsch { 145030f984aSJacob Faibussowitsch PetscFunctionBegin; 146030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 147030f984aSJacob Faibussowitsch PetscValidStreamType(type,2); 148030f984aSJacob Faibussowitsch /* only need to do complex swapping if the object has already been setup */ 149030f984aSJacob Faibussowitsch if (dctx->setup && (dctx->streamType != type)) { 150030f984aSJacob Faibussowitsch PetscErrorCode ierr; 151030f984aSJacob Faibussowitsch 152030f984aSJacob Faibussowitsch ierr = (*dctx->ops->changestreamtype)(dctx,type);CHKERRQ(ierr); 153030f984aSJacob Faibussowitsch dctx->setup = PETSC_FALSE; 154030f984aSJacob Faibussowitsch } 155030f984aSJacob Faibussowitsch dctx->streamType = type; 156030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 157030f984aSJacob Faibussowitsch } 158030f984aSJacob Faibussowitsch 159030f984aSJacob Faibussowitsch /*@C 160030f984aSJacob Faibussowitsch PetscDeviceContextGetStreamType - Get the implementation type of the underlying stream for a PetscDeviceContext 161030f984aSJacob Faibussowitsch 162030f984aSJacob Faibussowitsch Not Collective, Asynchronous 163030f984aSJacob Faibussowitsch 16401d2d390SJose E. Roman Input Parameter: 165030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext 166030f984aSJacob Faibussowitsch 167030f984aSJacob Faibussowitsch Output Parameter: 168030f984aSJacob Faibussowitsch . type - The PetscStreamType 169030f984aSJacob Faibussowitsch 170030f984aSJacob Faibussowitsch Notes: 171030f984aSJacob Faibussowitsch See PetscStreamType in include/petscdevicetypes.h for more information on the available types and their interactions 172030f984aSJacob Faibussowitsch 173030f984aSJacob Faibussowitsch Level: intermediate 174030f984aSJacob Faibussowitsch 1755181c4f9SJacob Faibussowitsch .seealso: PetscDeviceContextSetStreamType(), PetscDeviceContextCreate(), PetscDeviceContextSetFromOptions() 176030f984aSJacob Faibussowitsch @*/ 177030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextGetStreamType(PetscDeviceContext dctx, PetscStreamType *type) 178030f984aSJacob Faibussowitsch { 179030f984aSJacob Faibussowitsch PetscFunctionBegin; 180030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 181030f984aSJacob Faibussowitsch PetscValidIntPointer(type,2); 182030f984aSJacob Faibussowitsch *type = dctx->streamType; 183030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 184030f984aSJacob Faibussowitsch } 185030f984aSJacob Faibussowitsch 186030f984aSJacob Faibussowitsch /*@C 187030f984aSJacob Faibussowitsch PetscDeviceContextSetDevice - Set the underlying device for the PetscDeviceContext 188030f984aSJacob Faibussowitsch 189030f984aSJacob Faibussowitsch Not Collective, Possibly Synchronous 190030f984aSJacob Faibussowitsch 19101d2d390SJose E. Roman Input Parameters: 192030f984aSJacob Faibussowitsch + dctx - The PetscDeviceContext 193030f984aSJacob Faibussowitsch - device - The PetscDevice 194030f984aSJacob Faibussowitsch 195030f984aSJacob Faibussowitsch Notes: 196030f984aSJacob Faibussowitsch This routine is effectively PetscDeviceContext's "set-type" (so every PetscDeviceContext 197030f984aSJacob Faibussowitsch must also have an attached PetscDevice). Unlike the usual set-type semantics, it is 198030f984aSJacob Faibussowitsch not stricly necessary to set a contexts device to enable usage, any created device 199030f984aSJacob Faibussowitsch contexts will always come equipped with the "default" device. 200030f984aSJacob Faibussowitsch 2015181c4f9SJacob Faibussowitsch This routine may initialize the backend device and incur synchronization. 2025181c4f9SJacob Faibussowitsch 203030f984aSJacob Faibussowitsch Level: intermediate 204030f984aSJacob Faibussowitsch 2055181c4f9SJacob Faibussowitsch .seealso: PetscDeviceCreate(), PetscDeviceConfigure(), PetscDeviceContextGetDevice() 206030f984aSJacob Faibussowitsch @*/ 207030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextSetDevice(PetscDeviceContext dctx, PetscDevice device) 208030f984aSJacob Faibussowitsch { 209030f984aSJacob Faibussowitsch PetscErrorCode ierr; 210030f984aSJacob Faibussowitsch 211030f984aSJacob Faibussowitsch PetscFunctionBegin; 212030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 213030f984aSJacob Faibussowitsch PetscValidDevice(device,2); 214030f984aSJacob Faibussowitsch if (dctx->device == device) PetscFunctionReturn(0); 215030f984aSJacob Faibussowitsch ierr = PetscDeviceDestroy(&dctx->device);CHKERRQ(ierr); 216030f984aSJacob Faibussowitsch ierr = PetscMemzero(dctx->ops,sizeof(*dctx->ops));CHKERRQ(ierr); 217030f984aSJacob Faibussowitsch ierr = (*device->ops->createcontext)(dctx);CHKERRQ(ierr); 218030f984aSJacob Faibussowitsch dctx->device = PetscDeviceReference(device); 219030f984aSJacob Faibussowitsch dctx->setup = PETSC_FALSE; 220030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 221030f984aSJacob Faibussowitsch } 222030f984aSJacob Faibussowitsch 223030f984aSJacob Faibussowitsch /*@C 224030f984aSJacob Faibussowitsch PetscDeviceContextGetDevice - Get the underlying PetscDevice for a PetscDeviceContext 225030f984aSJacob Faibussowitsch 226030f984aSJacob Faibussowitsch Not Collective, Asynchronous 227030f984aSJacob Faibussowitsch 228030f984aSJacob Faibussowitsch Input Parameter: 229030f984aSJacob Faibussowitsch . dctx - the PetscDeviceContext 230030f984aSJacob Faibussowitsch 231030f984aSJacob Faibussowitsch Output Parameter: 232030f984aSJacob Faibussowitsch . device - The PetscDevice 233030f984aSJacob Faibussowitsch 234030f984aSJacob Faibussowitsch Notes: 235030f984aSJacob Faibussowitsch This is a borrowed reference, the user should not destroy the device. 236030f984aSJacob Faibussowitsch 237*a375dbeeSPatrick Sanan Level: intermediate 238*a375dbeeSPatrick Sanan 239030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextSetDevice(), PetscDevice 240030f984aSJacob Faibussowitsch @*/ 241030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextGetDevice(PetscDeviceContext dctx, PetscDevice *device) 242030f984aSJacob Faibussowitsch { 243030f984aSJacob Faibussowitsch PetscFunctionBegin; 244030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 245030f984aSJacob Faibussowitsch PetscValidPointer(device,2); 246030f984aSJacob Faibussowitsch *device = dctx->device; 247030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 248030f984aSJacob Faibussowitsch } 249030f984aSJacob Faibussowitsch 250030f984aSJacob Faibussowitsch /*@C 251030f984aSJacob Faibussowitsch PetscDeviceContextSetUp - Prepares a PetscDeviceContext for use 252030f984aSJacob Faibussowitsch 253030f984aSJacob Faibussowitsch Not Collective, Asynchronous 254030f984aSJacob Faibussowitsch 25501d2d390SJose E. Roman Input Parameter: 256030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext 257030f984aSJacob Faibussowitsch 258030f984aSJacob Faibussowitsch Developer Notes: 259030f984aSJacob Faibussowitsch This routine is usually the stage where a PetscDeviceContext acquires device-side data structures such as streams, 260030f984aSJacob Faibussowitsch events, and (possibly) handles. 261030f984aSJacob Faibussowitsch 262030f984aSJacob Faibussowitsch Level: beginner 263030f984aSJacob Faibussowitsch 2645181c4f9SJacob Faibussowitsch .seealso: PetscDeviceContextCreate(), PetscDeviceContextSetDevice(), PetscDeviceContextDestroy(), PetscDeviceContextSetFromOptions() 265030f984aSJacob Faibussowitsch @*/ 266030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextSetUp(PetscDeviceContext dctx) 267030f984aSJacob Faibussowitsch { 268030f984aSJacob Faibussowitsch PetscErrorCode ierr; 269030f984aSJacob Faibussowitsch 270030f984aSJacob Faibussowitsch PetscFunctionBegin; 271030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 272030f984aSJacob Faibussowitsch if (!dctx->device) { 273030f984aSJacob Faibussowitsch ierr = PetscInfo2(NULL,"PetscDeviceContext %d did not have an explicitly attached PetscDevice, using default with type %s\n",dctx->id,PetscDeviceKinds[PETSC_DEVICE_DEFAULT]);CHKERRQ(ierr); 274030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetDevice(dctx,PetscDeviceDefault_Internal());CHKERRQ(ierr); 275030f984aSJacob Faibussowitsch } 276030f984aSJacob Faibussowitsch if (dctx->setup) PetscFunctionReturn(0); 277030f984aSJacob Faibussowitsch ierr = (*dctx->ops->setup)(dctx);CHKERRQ(ierr); 278030f984aSJacob Faibussowitsch dctx->setup = PETSC_TRUE; 279030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 280030f984aSJacob Faibussowitsch } 281030f984aSJacob Faibussowitsch 282030f984aSJacob Faibussowitsch /*@C 283030f984aSJacob Faibussowitsch PetscDeviceContextDuplicate - Duplicates a PetscDeviceContext object 284030f984aSJacob Faibussowitsch 285030f984aSJacob Faibussowitsch Not Collective, Asynchronous 286030f984aSJacob Faibussowitsch 287030f984aSJacob Faibussowitsch Input Parameter: 288030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext to duplicate 289030f984aSJacob Faibussowitsch 290030f984aSJacob Faibussowitsch Output Paramter: 291030f984aSJacob Faibussowitsch . strmdup - The duplicated PetscDeviceContext 292030f984aSJacob Faibussowitsch 293030f984aSJacob Faibussowitsch Notes: 294030f984aSJacob Faibussowitsch This is a shorthand method for creating a PetscDeviceContext with the exact same 295030f984aSJacob Faibussowitsch settings as another. Note however that the duplicated PetscDeviceContext does not "share" 296030f984aSJacob Faibussowitsch any of the underlying data with the original, (including its current stream-state) they 297030f984aSJacob Faibussowitsch are completely separate objects. 298030f984aSJacob Faibussowitsch 299030f984aSJacob Faibussowitsch Level: beginner 300030f984aSJacob Faibussowitsch 301030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextCreate(), PetscDeviceContextSetDevice(), PetscDeviceContextSetStreamType() 302030f984aSJacob Faibussowitsch @*/ 303030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextDuplicate(PetscDeviceContext dctx, PetscDeviceContext *dctxdup) 304030f984aSJacob Faibussowitsch { 305030f984aSJacob Faibussowitsch PetscErrorCode ierr; 306030f984aSJacob Faibussowitsch 307030f984aSJacob Faibussowitsch PetscFunctionBegin; 308030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 309030f984aSJacob Faibussowitsch PetscValidPointer(dctxdup,2); 310030f984aSJacob Faibussowitsch ierr = PetscDeviceContextCreate(dctxdup);CHKERRQ(ierr); 311030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetDevice(*dctxdup,dctx->device);CHKERRQ(ierr); 312030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetStreamType(*dctxdup,dctx->streamType);CHKERRQ(ierr); 313030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetUp(*dctxdup);CHKERRQ(ierr); 314030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 315030f984aSJacob Faibussowitsch } 316030f984aSJacob Faibussowitsch 317030f984aSJacob Faibussowitsch /*@C 318030f984aSJacob Faibussowitsch PetscDeviceContextQueryIdle - Returns whether or not a PetscDeviceContext is idle 319030f984aSJacob Faibussowitsch 320030f984aSJacob Faibussowitsch Not Collective, Asynchronous 321030f984aSJacob Faibussowitsch 322030f984aSJacob Faibussowitsch Input Parameter: 323030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext object 324030f984aSJacob Faibussowitsch 325030f984aSJacob Faibussowitsch Output Parameter: 326030f984aSJacob Faibussowitsch . idle - PETSC_TRUE if PetscDeviceContext has NO work, PETSC_FALSE if it has work 327030f984aSJacob Faibussowitsch 328030f984aSJacob Faibussowitsch Notes: 329030f984aSJacob Faibussowitsch This routine only refers a singular context and does NOT take any of its children into account. That is, if dctx is 330030f984aSJacob Faibussowitsch idle but has dependents who do have work, this routine still returns PETSC_TRUE. 331030f984aSJacob Faibussowitsch 332030f984aSJacob Faibussowitsch Results of PetscDeviceContextQueryIdle() are cached on return, allowing this function to be called repeatedly in an 333030f984aSJacob Faibussowitsch efficient manner. When debug mode is enabled this cache is verified on every call to 334030f984aSJacob Faibussowitsch this routine, but is blindly believed when debugging is disabled. 335030f984aSJacob Faibussowitsch 336030f984aSJacob Faibussowitsch Level: intermediate 337030f984aSJacob Faibussowitsch 338030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextCreate(), PetscDeviceContextWaitForContext(), PetscDeviceContextFork() 339030f984aSJacob Faibussowitsch @*/ 340030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextQueryIdle(PetscDeviceContext dctx, PetscBool *idle) 341030f984aSJacob Faibussowitsch { 342030f984aSJacob Faibussowitsch PetscErrorCode ierr; 343030f984aSJacob Faibussowitsch 344030f984aSJacob Faibussowitsch PetscFunctionBegin; 345030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 346030f984aSJacob Faibussowitsch PetscValidBoolPointer(idle,2); 347030f984aSJacob Faibussowitsch if (dctx->idle) { 348030f984aSJacob Faibussowitsch *idle = PETSC_TRUE; 349030f984aSJacob Faibussowitsch ierr = PetscDeviceContextValidateIdle_Internal(dctx);CHKERRQ(ierr); 350030f984aSJacob Faibussowitsch } else { 351030f984aSJacob Faibussowitsch ierr = (*dctx->ops->query)(dctx,idle);CHKERRQ(ierr); 352030f984aSJacob Faibussowitsch dctx->idle = *idle; 353030f984aSJacob Faibussowitsch } 354030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 355030f984aSJacob Faibussowitsch } 356030f984aSJacob Faibussowitsch 357030f984aSJacob Faibussowitsch /*@C 358030f984aSJacob Faibussowitsch PetscDeviceContextWaitForContext - Make one context wait for another context to finish 359030f984aSJacob Faibussowitsch 360030f984aSJacob Faibussowitsch Not Collective, Asynchronous 361030f984aSJacob Faibussowitsch 362030f984aSJacob Faibussowitsch Input Parameters: 363030f984aSJacob Faibussowitsch + dctxa - The PetscDeviceContext object that is waiting 364030f984aSJacob Faibussowitsch - dctxb - The PetscDeviceContext object that is being waited on 365030f984aSJacob Faibussowitsch 366030f984aSJacob Faibussowitsch Notes: 367030f984aSJacob Faibussowitsch Serializes two PetscDeviceContexts. This routine uses only the state of dctxb at the moment this routine was 368030f984aSJacob Faibussowitsch called, so any future work queued will not affect dctxa. It is safe to pass the same context to both arguments. 369030f984aSJacob Faibussowitsch 370030f984aSJacob Faibussowitsch Level: beginner 371030f984aSJacob Faibussowitsch 372030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextCreate(), PetscDeviceContextQueryIdle(), PetscDeviceContextJoin() 373030f984aSJacob Faibussowitsch @*/ 374030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextWaitForContext(PetscDeviceContext dctxa, PetscDeviceContext dctxb) 375030f984aSJacob Faibussowitsch { 376030f984aSJacob Faibussowitsch PetscErrorCode ierr; 377030f984aSJacob Faibussowitsch 378030f984aSJacob Faibussowitsch PetscFunctionBegin; 379030f984aSJacob Faibussowitsch PetscCheckCompatibleDeviceContexts(dctxa,1,dctxb,2); 380030f984aSJacob Faibussowitsch if (dctxa == dctxb) PetscFunctionReturn(0); 381030f984aSJacob Faibussowitsch if (dctxb->idle) { 382030f984aSJacob Faibussowitsch /* No need to do the extra function lookup and event record if the stream were waiting on isn't doing anything */ 383030f984aSJacob Faibussowitsch ierr = PetscDeviceContextValidateIdle_Internal(dctxb);CHKERRQ(ierr); 384030f984aSJacob Faibussowitsch } else { 385030f984aSJacob Faibussowitsch ierr = (*dctxa->ops->waitforctx)(dctxa,dctxb);CHKERRQ(ierr); 386030f984aSJacob Faibussowitsch } 387030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 388030f984aSJacob Faibussowitsch } 389030f984aSJacob Faibussowitsch 390030f984aSJacob Faibussowitsch /*@C 391030f984aSJacob Faibussowitsch PetscDeviceContextFork - Create a set of dependent child contexts from a parent context 392030f984aSJacob Faibussowitsch 393030f984aSJacob Faibussowitsch Not Collective, Asynchronous 394030f984aSJacob Faibussowitsch 395030f984aSJacob Faibussowitsch Input Parameters: 396030f984aSJacob Faibussowitsch + dctx - The parent PetscDeviceContext 397030f984aSJacob Faibussowitsch - n - The number of children to create 398030f984aSJacob Faibussowitsch 399030f984aSJacob Faibussowitsch Output Parameter: 400030f984aSJacob Faibussowitsch . dsub - The created child context(s) 401030f984aSJacob Faibussowitsch 402030f984aSJacob Faibussowitsch Notes: 403030f984aSJacob Faibussowitsch This routine creates n edges of a DAG from a source node which are causally dependent on the source node, meaning 404030f984aSJacob Faibussowitsch that work queued on child contexts will not start until the parent context finishes its work. This accounts for work 405030f984aSJacob Faibussowitsch queued on the parent up until calling this function, any subsequent work enqueued on the parent has no effect on the children. 406030f984aSJacob Faibussowitsch 407030f984aSJacob Faibussowitsch Any children created with this routine have their lifetimes bounded by the parent. That is, the parent context expects 408030f984aSJacob Faibussowitsch to free all of it's children (and ONLY its children) before itself is freed. 409030f984aSJacob Faibussowitsch 410030f984aSJacob Faibussowitsch DAG representation: 411030f984aSJacob Faibussowitsch .vb 412030f984aSJacob Faibussowitsch time -> 413030f984aSJacob Faibussowitsch 414030f984aSJacob Faibussowitsch -> dctx \----> dctx ------> 415030f984aSJacob Faibussowitsch \---> dsub[0] ---> 416030f984aSJacob Faibussowitsch \--> ... -------> 417030f984aSJacob Faibussowitsch \-> dsub[n-1] -> 418030f984aSJacob Faibussowitsch .ve 419030f984aSJacob Faibussowitsch 420030f984aSJacob Faibussowitsch Level: intermediate 421030f984aSJacob Faibussowitsch 422030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextJoin(), PetscDeviceContextSynchronize(), PetscDeviceContextQueryIdle() 423030f984aSJacob Faibussowitsch @*/ 424030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextFork(PetscDeviceContext dctx, PetscInt n, PetscDeviceContext **dsub) 425030f984aSJacob Faibussowitsch { 426030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 427030f984aSJacob Faibussowitsch const PetscInt nBefore = n; 428030f984aSJacob Faibussowitsch static std::string idList; 429030f984aSJacob Faibussowitsch #endif 430030f984aSJacob Faibussowitsch PetscDeviceContext *dsubTmp = nullptr; 431030f984aSJacob Faibussowitsch PetscInt i = 0; 432030f984aSJacob Faibussowitsch PetscErrorCode ierr; 433030f984aSJacob Faibussowitsch 434030f984aSJacob Faibussowitsch PetscFunctionBegin; 435030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 436030f984aSJacob Faibussowitsch PetscValidPointer(dsub,3); 437030f984aSJacob Faibussowitsch if (PetscUnlikelyDebug(n < 0)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of contexts requested %D < 0",n); 438030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 439030f984aSJacob Faibussowitsch /* reserve 4 chars per id, 2 for number and 2 for ', ' separator */ 440030f984aSJacob Faibussowitsch idList.reserve(4*n); 441030f984aSJacob Faibussowitsch #endif 442030f984aSJacob Faibussowitsch /* update child totals */ 443030f984aSJacob Faibussowitsch dctx->numChildren += n; 444030f984aSJacob Faibussowitsch /* now to find out if we have room */ 445030f984aSJacob Faibussowitsch if (dctx->numChildren > dctx->maxNumChildren) { 446030f984aSJacob Faibussowitsch /* no room, either from having too many kids or not having any */ 447030f984aSJacob Faibussowitsch if (dctx->childIDs) { 448030f984aSJacob Faibussowitsch /* have existing children, must reallocate them */ 449030f984aSJacob Faibussowitsch ierr = PetscRealloc(dctx->numChildren*sizeof(*dctx->childIDs),&dctx->childIDs);CHKERRQ(ierr); 450030f984aSJacob Faibussowitsch /* clear the extra memory since realloc doesn't do it for us */ 451030f984aSJacob Faibussowitsch ierr = PetscArrayzero((dctx->childIDs)+(dctx->maxNumChildren),(dctx->numChildren)-(dctx->maxNumChildren));CHKERRQ(ierr); 452030f984aSJacob Faibussowitsch } else { 453030f984aSJacob Faibussowitsch /* have no children */ 454030f984aSJacob Faibussowitsch ierr = PetscCalloc1(dctx->numChildren,&dctx->childIDs);CHKERRQ(ierr); 455030f984aSJacob Faibussowitsch } 456030f984aSJacob Faibussowitsch /* update total number of children */ 457030f984aSJacob Faibussowitsch dctx->maxNumChildren = dctx->numChildren; 458030f984aSJacob Faibussowitsch } 459030f984aSJacob Faibussowitsch ierr = PetscMalloc1(n,&dsubTmp);CHKERRQ(ierr); 460030f984aSJacob Faibussowitsch while (n) { 461030f984aSJacob Faibussowitsch /* empty child slot */ 462030f984aSJacob Faibussowitsch if (!(dctx->childIDs[i])) { 463030f984aSJacob Faibussowitsch /* create the child context in the image of its parent */ 464030f984aSJacob Faibussowitsch ierr = PetscDeviceContextDuplicate(dctx,dsubTmp+i);CHKERRQ(ierr); 465030f984aSJacob Faibussowitsch ierr = PetscDeviceContextWaitForContext(dsubTmp[i],dctx);CHKERRQ(ierr); 466030f984aSJacob Faibussowitsch /* register the child with its parent */ 467030f984aSJacob Faibussowitsch dctx->childIDs[i] = dsubTmp[i]->id; 468030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 469030f984aSJacob Faibussowitsch idList += std::to_string(dsubTmp[i]->id); 470030f984aSJacob Faibussowitsch if (n != 1) idList += ", "; 471030f984aSJacob Faibussowitsch #endif 472030f984aSJacob Faibussowitsch --n; 473030f984aSJacob Faibussowitsch } 474030f984aSJacob Faibussowitsch ++i; 475030f984aSJacob Faibussowitsch } 476030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 477030f984aSJacob Faibussowitsch ierr = PetscInfo3(NULL,"Forked %D children from parent %D with IDs: %s\n",nBefore,dctx->id,idList.c_str());CHKERRQ(ierr); 478030f984aSJacob Faibussowitsch /* resets the size but doesn't deallocate the memory */ 479030f984aSJacob Faibussowitsch idList.clear(); 480030f984aSJacob Faibussowitsch #endif 481030f984aSJacob Faibussowitsch /* pass the children back to caller */ 482030f984aSJacob Faibussowitsch *dsub = dsubTmp; 483030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 484030f984aSJacob Faibussowitsch } 485030f984aSJacob Faibussowitsch 486030f984aSJacob Faibussowitsch /*@C 4875181c4f9SJacob Faibussowitsch PetscDeviceContextJoin - Converge a set of child contexts 488030f984aSJacob Faibussowitsch 489030f984aSJacob Faibussowitsch Not Collective, Asynchronous 490030f984aSJacob Faibussowitsch 491030f984aSJacob Faibussowitsch Input Parameters: 492030f984aSJacob Faibussowitsch + dctx - A PetscDeviceContext to converge on 493030f984aSJacob Faibussowitsch . n - The number of sub contexts to converge 494030f984aSJacob Faibussowitsch . joinMode - The type of join to perform 495030f984aSJacob Faibussowitsch - dsub - The sub contexts to converge 496030f984aSJacob Faibussowitsch 497030f984aSJacob Faibussowitsch Notes: 498030f984aSJacob Faibussowitsch If PetscDeviceContextFork() creates n edges from a source node which all depend on the 499030f984aSJacob Faibussowitsch source node, then this routine is the exact mirror. That is, it creates a node 500030f984aSJacob Faibussowitsch (represented in dctx) which recieves n edges (and optionally destroys them) which is 501030f984aSJacob Faibussowitsch dependent on the completion of all incoming edges. 502030f984aSJacob Faibussowitsch 503030f984aSJacob Faibussowitsch If joinMode is PETSC_DEVICE_CONTEXT_JOIN_DESTROY all contexts in dsub will be destroyed 504030f984aSJacob Faibussowitsch by this routine. Thus all sub contexts must have been created with the dctx passed to 505030f984aSJacob Faibussowitsch this routine. 506030f984aSJacob Faibussowitsch 507030f984aSJacob Faibussowitsch if joinMode is PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC dctx waits for all sub contexts but the 508030f984aSJacob Faibussowitsch sub contexts do not wait for one another afterwards. 509030f984aSJacob Faibussowitsch 510030f984aSJacob Faibussowitsch If joinMode is PETSC_DEVICE_CONTEXT_JOIN_SYNC all sub contexts will additionally 511030f984aSJacob Faibussowitsch wait on dctx after converging. This has the effect of "synchronizing" the outgoing 512030f984aSJacob Faibussowitsch edges. 513030f984aSJacob Faibussowitsch 514030f984aSJacob Faibussowitsch DAG representations: 515030f984aSJacob Faibussowitsch If joinMode is PETSC_DEVICE_CONTEXT_JOIN_DESTROY 516030f984aSJacob Faibussowitsch .vb 517030f984aSJacob Faibussowitsch time -> 518030f984aSJacob Faibussowitsch 519030f984aSJacob Faibussowitsch -> dctx ---------/- dctx -> 520030f984aSJacob Faibussowitsch -> dsub[0] -----/ 521030f984aSJacob Faibussowitsch -> ... -------/ 522030f984aSJacob Faibussowitsch -> dsub[n-1] -/ 523030f984aSJacob Faibussowitsch .ve 524030f984aSJacob Faibussowitsch If joinMode is PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC 525030f984aSJacob Faibussowitsch .vb 526030f984aSJacob Faibussowitsch time -> 527030f984aSJacob Faibussowitsch 528030f984aSJacob Faibussowitsch -> dctx ---------/- dctx -> 529030f984aSJacob Faibussowitsch -> dsub[0] -----/---------> 530030f984aSJacob Faibussowitsch -> ... -------/----------> 531030f984aSJacob Faibussowitsch -> dsub[n-1] -/-----------> 532030f984aSJacob Faibussowitsch .ve 533030f984aSJacob Faibussowitsch If joinMode is PETSC_DEVICE_CONTEXT_JOIN_SYNC 534030f984aSJacob Faibussowitsch .vb 535030f984aSJacob Faibussowitsch time -> 536030f984aSJacob Faibussowitsch 537030f984aSJacob Faibussowitsch -> dctx ---------/- dctx -\----> dctx ------> 538030f984aSJacob Faibussowitsch -> dsub[0] -----/ \---> dsub[0] ---> 539030f984aSJacob Faibussowitsch -> ... -------/ \--> ... -------> 540030f984aSJacob Faibussowitsch -> dsub[n-1] -/ \-> dsub[n-1] -> 541030f984aSJacob Faibussowitsch .ve 542030f984aSJacob Faibussowitsch 543030f984aSJacob Faibussowitsch Level: intermediate 544030f984aSJacob Faibussowitsch 545030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextFork(), PetscDeviceContextSynchronize(), PetscDeviceContextJoinMode 546030f984aSJacob Faibussowitsch @*/ 547030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextJoin(PetscDeviceContext dctx, PetscInt n, PetscDeviceContextJoinMode joinMode, PetscDeviceContext **dsub) 548030f984aSJacob Faibussowitsch { 549030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 550030f984aSJacob Faibussowitsch static std::string idList; 551030f984aSJacob Faibussowitsch #endif 552030f984aSJacob Faibussowitsch PetscErrorCode ierr; 553030f984aSJacob Faibussowitsch 554030f984aSJacob Faibussowitsch PetscFunctionBegin; 555030f984aSJacob Faibussowitsch /* validity of dctx is checked in the wait-for loop */ 556030f984aSJacob Faibussowitsch PetscValidPointer(dsub,4); 557030f984aSJacob Faibussowitsch if (PetscUnlikelyDebug(n < 0)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of contexts merged %D < 0",n); 558030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 559030f984aSJacob Faibussowitsch /* reserve 4 chars per id, 2 for number and 2 for ', ' separator */ 560030f984aSJacob Faibussowitsch idList.reserve(4*n); 561030f984aSJacob Faibussowitsch #endif 562030f984aSJacob Faibussowitsch /* first dctx waits on all the incoming edges */ 563030f984aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 564030f984aSJacob Faibussowitsch PetscCheckCompatibleDeviceContexts(dctx,1,(*dsub)[i],4); 565030f984aSJacob Faibussowitsch ierr = PetscDeviceContextWaitForContext(dctx,(*dsub)[i]);CHKERRQ(ierr); 566030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 567030f984aSJacob Faibussowitsch idList += std::to_string((*dsub)[i]->id); 568030f984aSJacob Faibussowitsch if (i+1 < n) idList += ", "; 569030f984aSJacob Faibussowitsch #endif 570030f984aSJacob Faibussowitsch } 571030f984aSJacob Faibussowitsch 572030f984aSJacob Faibussowitsch /* now we handle the aftermath */ 573030f984aSJacob Faibussowitsch switch (joinMode) { 574030f984aSJacob Faibussowitsch case PETSC_DEVICE_CONTEXT_JOIN_DESTROY: 575030f984aSJacob Faibussowitsch { 576030f984aSJacob Faibussowitsch PetscInt j = 0; 577030f984aSJacob Faibussowitsch 578030f984aSJacob Faibussowitsch if (PetscUnlikelyDebug(n > dctx->numChildren)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy %D children of a parent context that only has %D children, likely trying to restore to wrong parent",n,dctx->numChildren); 579030f984aSJacob Faibussowitsch /* update child count while it's still fresh in memory */ 580030f984aSJacob Faibussowitsch dctx->numChildren -= n; 581030f984aSJacob Faibussowitsch for (PetscInt i = 0; i < dctx->maxNumChildren; ++i) { 582030f984aSJacob Faibussowitsch if (dctx->childIDs[i] && (dctx->childIDs[i] == (*dsub)[j]->id)) { 583030f984aSJacob Faibussowitsch /* child is one of ours, can destroy it */ 584030f984aSJacob Faibussowitsch ierr = PetscDeviceContextDestroy((*dsub)+j);CHKERRQ(ierr); 585030f984aSJacob Faibussowitsch /* reset the child slot */ 586030f984aSJacob Faibussowitsch dctx->childIDs[i] = 0; 587030f984aSJacob Faibussowitsch if (++j == n) break; 588030f984aSJacob Faibussowitsch } 589030f984aSJacob Faibussowitsch } 590030f984aSJacob Faibussowitsch /* gone through the loop but did not find every child, if this triggers (or well, doesn't) on perf-builds we leak the remaining contexts memory */ 591030f984aSJacob Faibussowitsch if (PetscUnlikelyDebug(j != n)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"%D contexts still remain after destroy, this may be because you are trying to restore to the wrong parent context, or the device contexts are not in the same order as they were checked out out in.",n-j); 592030f984aSJacob Faibussowitsch ierr = PetscFree(*dsub);CHKERRQ(ierr); 593030f984aSJacob Faibussowitsch } 594030f984aSJacob Faibussowitsch break; 595030f984aSJacob Faibussowitsch case PETSC_DEVICE_CONTEXT_JOIN_SYNC: 596030f984aSJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 597030f984aSJacob Faibussowitsch ierr = PetscDeviceContextWaitForContext((*dsub)[i],dctx);CHKERRQ(ierr); 598030f984aSJacob Faibussowitsch } 599030f984aSJacob Faibussowitsch case PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC: 600030f984aSJacob Faibussowitsch break; 601030f984aSJacob Faibussowitsch default: 602030f984aSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown PetscDeviceContextJoinMode given"); 603030f984aSJacob Faibussowitsch } 604030f984aSJacob Faibussowitsch 605030f984aSJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) && defined(PETSC_USE_INFO) 606030f984aSJacob Faibussowitsch ierr = PetscInfo4(NULL,"Joined %D ctxs to ctx %D, mode %s with IDs: %s\n",n,dctx->id,PetscDeviceContextJoinModes[joinMode],idList.c_str());CHKERRQ(ierr); 607030f984aSJacob Faibussowitsch idList.clear(); 608030f984aSJacob Faibussowitsch #endif 609030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 610030f984aSJacob Faibussowitsch } 611030f984aSJacob Faibussowitsch 612030f984aSJacob Faibussowitsch /*@C 6135181c4f9SJacob Faibussowitsch PetscDeviceContextSynchronize - Block the host until all work queued on or associated with a PetscDeviceContext has finished 614030f984aSJacob Faibussowitsch 615030f984aSJacob Faibussowitsch Not Collective, Synchronous 616030f984aSJacob Faibussowitsch 617030f984aSJacob Faibussowitsch Input Parameters: 618030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext to synchronize 619030f984aSJacob Faibussowitsch 620030f984aSJacob Faibussowitsch Level: beginner 621030f984aSJacob Faibussowitsch 622030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextFork(), PetscDeviceContextJoin(), PetscDeviceContextQueryIdle() 623030f984aSJacob Faibussowitsch @*/ 624030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextSynchronize(PetscDeviceContext dctx) 625030f984aSJacob Faibussowitsch { 626030f984aSJacob Faibussowitsch PetscErrorCode ierr; 627030f984aSJacob Faibussowitsch 628030f984aSJacob Faibussowitsch PetscFunctionBegin; 629030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 630030f984aSJacob Faibussowitsch /* if it isn't setup there is nothing to sync on */ 631030f984aSJacob Faibussowitsch if (dctx->setup) {ierr = (*dctx->ops->synchronize)(dctx);CHKERRQ(ierr);} 632030f984aSJacob Faibussowitsch dctx->idle = PETSC_TRUE; 633030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 634030f984aSJacob Faibussowitsch } 635030f984aSJacob Faibussowitsch 636030f984aSJacob Faibussowitsch static PetscDeviceContext globalContext = nullptr; 637030f984aSJacob Faibussowitsch static PetscBool globalContextSetup = PETSC_FALSE; 638030f984aSJacob Faibussowitsch static PetscStreamType defaultStreamType = PETSC_STREAM_DEFAULT_BLOCKING; 639030f984aSJacob Faibussowitsch 640030f984aSJacob Faibussowitsch /* automatically registered to PetscFinalize() when first context is instantiated, do not 641030f984aSJacob Faibussowitsch call */ 642030f984aSJacob Faibussowitsch static PetscErrorCode PetscDeviceContextDestroyGlobalContext_Private(void) 643030f984aSJacob Faibussowitsch { 644030f984aSJacob Faibussowitsch PetscErrorCode ierr; 645030f984aSJacob Faibussowitsch 646030f984aSJacob Faibussowitsch PetscFunctionBegin; 647030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSynchronize(globalContext);CHKERRQ(ierr); 648030f984aSJacob Faibussowitsch ierr = PetscDeviceContextDestroy(&globalContext);CHKERRQ(ierr); 649030f984aSJacob Faibussowitsch /* reset everything to defaults */ 650030f984aSJacob Faibussowitsch defaultStreamType = PETSC_STREAM_DEFAULT_BLOCKING; 651030f984aSJacob Faibussowitsch globalContextSetup = PETSC_FALSE; 652030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 653030f984aSJacob Faibussowitsch } 654030f984aSJacob Faibussowitsch 655030f984aSJacob Faibussowitsch /* creates and initializes the root context in PetscInitialize() but does not call 656030f984aSJacob Faibussowitsch SetUp() as the user may wish to change types after PetscInitialize() */ 657030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextInitializeRootContext_Internal(MPI_Comm comm, const char prefix[]) 658030f984aSJacob Faibussowitsch { 659030f984aSJacob Faibussowitsch PetscErrorCode ierr; 660030f984aSJacob Faibussowitsch 661030f984aSJacob Faibussowitsch PetscFunctionBegin; 662030f984aSJacob Faibussowitsch ierr = PetscInfo1(NULL,"Initializing root PetscDeviceContext with PetscDeviceKind %s\n",PetscDeviceKinds[PETSC_DEVICE_DEFAULT]);CHKERRQ(ierr); 663030f984aSJacob Faibussowitsch ierr = PetscDeviceContextCreate(&globalContext);CHKERRQ(ierr); 664030f984aSJacob Faibussowitsch if (PetscUnlikelyDebug(globalContext->id != 0)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"The root current PetscDeviceContext should have id = 0, however it has id = %D",globalContext->id); 665030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetDevice(globalContext,PetscDeviceDefault_Internal());CHKERRQ(ierr); 666030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetStreamType(globalContext,defaultStreamType);CHKERRQ(ierr); 667030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetFromOptions(comm,prefix,globalContext);CHKERRQ(ierr); 668030f984aSJacob Faibussowitsch ierr = PetscRegisterFinalize(PetscDeviceContextDestroyGlobalContext_Private);CHKERRQ(ierr); 669030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 670030f984aSJacob Faibussowitsch } 671030f984aSJacob Faibussowitsch 672030f984aSJacob Faibussowitsch /*@C 6735181c4f9SJacob Faibussowitsch PetscDeviceContextGetCurrentContext - Get the current active PetscDeviceContext 674030f984aSJacob Faibussowitsch 675030f984aSJacob Faibussowitsch Not Collective, Asynchronous 676030f984aSJacob Faibussowitsch 677030f984aSJacob Faibussowitsch Output Parameter: 678030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext 679030f984aSJacob Faibussowitsch 680030f984aSJacob Faibussowitsch Notes: 681030f984aSJacob Faibussowitsch The user generally should not destroy contexts retrieved with this routine unless they themselves have created 682030f984aSJacob Faibussowitsch them. There exists no protection against destroying the root context. 683030f984aSJacob Faibussowitsch 684030f984aSJacob Faibussowitsch Developer Notes: 685030f984aSJacob Faibussowitsch This routine creates the "root" context the first time it is called, registering its 686030f984aSJacob Faibussowitsch destructor to PetscFinalize(). The root context is synchronized before being destroyed. 687030f984aSJacob Faibussowitsch 688030f984aSJacob Faibussowitsch Level: beginner 689030f984aSJacob Faibussowitsch 690030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextSetCurrentContext(), PetscDeviceContextFork(), 691030f984aSJacob Faibussowitsch PetscDeviceContextJoin(), PetscDeviceContextCreate() 692030f984aSJacob Faibussowitsch @*/ 693030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextGetCurrentContext(PetscDeviceContext *dctx) 694030f984aSJacob Faibussowitsch { 695030f984aSJacob Faibussowitsch PetscFunctionBegin; 696030f984aSJacob Faibussowitsch PetscValidPointer(dctx,1); 697030f984aSJacob Faibussowitsch if (PetscUnlikely(!globalContextSetup)) { 698030f984aSJacob Faibussowitsch PetscErrorCode ierr; 699030f984aSJacob Faibussowitsch 700030f984aSJacob Faibussowitsch /* if there is no available device backend, PetscDeviceInitializePackage() will fire a 701030f984aSJacob Faibussowitsch PETSC_ERR_SUP_SYS error. */ 702030f984aSJacob Faibussowitsch ierr = PetscDeviceInitializePackage();CHKERRQ(ierr); 703030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetUp(globalContext);CHKERRQ(ierr); 704030f984aSJacob Faibussowitsch globalContextSetup = PETSC_TRUE; 705030f984aSJacob Faibussowitsch } 706030f984aSJacob Faibussowitsch *dctx = globalContext; 707030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 708030f984aSJacob Faibussowitsch } 709030f984aSJacob Faibussowitsch 710030f984aSJacob Faibussowitsch /*@C 7115181c4f9SJacob Faibussowitsch PetscDeviceContextSetCurrentContext - Set the current active PetscDeviceContext 712030f984aSJacob Faibussowitsch 713030f984aSJacob Faibussowitsch Not Collective, Asynchronous 714030f984aSJacob Faibussowitsch 715030f984aSJacob Faibussowitsch Input Parameter: 716030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext 717030f984aSJacob Faibussowitsch 718030f984aSJacob Faibussowitsch Notes: 719030f984aSJacob Faibussowitsch The old context is not stored in any way by this routine; if one is overriding a context that they themselves do not 720030f984aSJacob Faibussowitsch control, one should take care to temporarily store it by calling PetscDeviceContextGetCurrentContext() before calling 721030f984aSJacob Faibussowitsch this routine. 722030f984aSJacob Faibussowitsch 723030f984aSJacob Faibussowitsch Level: beginner 724030f984aSJacob Faibussowitsch 725030f984aSJacob Faibussowitsch .seealso: PetscDeviceContextGetCurrentContext(), PetscDeviceContextFork(), 726030f984aSJacob Faibussowitsch PetscDeviceContextJoin(), PetscDeviceContextCreate() 727030f984aSJacob Faibussowitsch @*/ 728030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextSetCurrentContext(PetscDeviceContext dctx) 729030f984aSJacob Faibussowitsch { 730030f984aSJacob Faibussowitsch PetscErrorCode ierr; 731030f984aSJacob Faibussowitsch 732030f984aSJacob Faibussowitsch PetscFunctionBegin; 733030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,1); 734030f984aSJacob Faibussowitsch globalContext = dctx; 735030f984aSJacob Faibussowitsch ierr = PetscInfo1(NULL,"Set global device context id %D\n",dctx->id);CHKERRQ(ierr); 736030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 737030f984aSJacob Faibussowitsch } 738030f984aSJacob Faibussowitsch 739030f984aSJacob Faibussowitsch /*@C 740030f984aSJacob Faibussowitsch PetscDeviceContextSetFromOptions - Configure a PetscDeviceContext from the options database 741030f984aSJacob Faibussowitsch 742030f984aSJacob Faibussowitsch Collective on comm, Asynchronous 743030f984aSJacob Faibussowitsch 744030f984aSJacob Faibussowitsch Input Parameters: 745030f984aSJacob Faibussowitsch + comm - MPI communicator on which to query the options database 746030f984aSJacob Faibussowitsch . prefix - prefix to prepend to all options database queries, NULL if not needed 747030f984aSJacob Faibussowitsch - dctx - The PetscDeviceContext to configure 748030f984aSJacob Faibussowitsch 749030f984aSJacob Faibussowitsch Output Parameter: 750030f984aSJacob Faibussowitsch . dctx - The PetscDeviceContext 751030f984aSJacob Faibussowitsch 752030f984aSJacob Faibussowitsch Options Database: 75397bb3fdcSJose E. Roman + -device_context_device_kind - the kind of PetscDevice to attach by default - PetscDeviceKind 75497bb3fdcSJose E. Roman - -device_context_stream_type - type of stream to create inside the PetscDeviceContext - 755030f984aSJacob Faibussowitsch PetscDeviceContextSetStreamType() 756030f984aSJacob Faibussowitsch 757030f984aSJacob Faibussowitsch Level: beginner 758030f984aSJacob Faibussowitsch 7595181c4f9SJacob Faibussowitsch .seealso: PetscDeviceContextSetStreamType(), PetscDeviceContextSetDevice() 760030f984aSJacob Faibussowitsch @*/ 761030f984aSJacob Faibussowitsch PetscErrorCode PetscDeviceContextSetFromOptions(MPI_Comm comm, const char prefix[], PetscDeviceContext dctx) 762030f984aSJacob Faibussowitsch { 763030f984aSJacob Faibussowitsch PetscBool flag; 764030f984aSJacob Faibussowitsch PetscInt stype,dkind; 765030f984aSJacob Faibussowitsch PetscErrorCode ierr; 766030f984aSJacob Faibussowitsch 767030f984aSJacob Faibussowitsch PetscFunctionBegin; 768030f984aSJacob Faibussowitsch if (prefix) {PetscValidCharPointer(prefix,2);} 769030f984aSJacob Faibussowitsch PetscValidDeviceContext(dctx,3); 770030f984aSJacob Faibussowitsch ierr = PetscOptionsBegin(comm,prefix,"PetscDeviceContext Options","Sys");CHKERRQ(ierr); 771030f984aSJacob Faibussowitsch ierr = PetscOptionsEList("-device_context_device_kind","Underlying PetscDevice","PetscDeviceContextSetDevice",PetscDeviceKinds+1,PETSC_DEVICE_MAX-1,dctx->device ? PetscDeviceKinds[dctx->device->kind] : PetscDeviceKinds[PETSC_DEVICE_DEFAULT],&dkind,&flag);CHKERRQ(ierr); 772030f984aSJacob Faibussowitsch if (flag) { 773030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetDevice(dctx,PetscDeviceDefaultKind_Internal(static_cast<PetscDeviceKind>(dkind+1)));CHKERRQ(ierr); 774030f984aSJacob Faibussowitsch } 775030f984aSJacob Faibussowitsch ierr = PetscOptionsEList("-device_context_stream_type","PetscDeviceContext PetscStreamType","PetscDeviceContextSetStreamType",PetscStreamTypes,3,PetscStreamTypes[dctx->streamType],&stype,&flag);CHKERRQ(ierr); 776030f984aSJacob Faibussowitsch if (flag) { 777030f984aSJacob Faibussowitsch ierr = PetscDeviceContextSetStreamType(dctx,static_cast<PetscStreamType>(stype));CHKERRQ(ierr); 778030f984aSJacob Faibussowitsch } 779030f984aSJacob Faibussowitsch ierr = PetscOptionsEnd();CHKERRQ(ierr); 780030f984aSJacob Faibussowitsch PetscFunctionReturn(0); 781030f984aSJacob Faibussowitsch } 782