Actual source code: vecseqcupm.hip.cpp

  1: #include "../vecseqcupm.hpp" /*I <petscvec.h> I*/

  3: using namespace Petsc::vec::cupm::impl;

  5: static constexpr auto VecSeq_HIP = VecSeq_CUPM<::Petsc::device::cupm::DeviceType::HIP>{};

  7: PetscErrorCode VecCreate_SeqHIP(Vec v)
  8: {
  9:   PetscFunctionBegin;
 10:   PetscCall(VecSeq_HIP.create(v));
 11:   PetscFunctionReturn(PETSC_SUCCESS);
 12: }

 14: /*@
 15:   VecCreateSeqHIP - Creates a standard, sequential, array-style vector.

 17:   Collective, Possibly Synchronous

 19:   Input Parameters:
 20: + comm - the communicator, must be `PETSC_COMM_SELF`
 21: - n    - the vector length

 23:   Output Parameter:
 24: . v - the vector

 26:   Level: intermediate

 28:   Notes:
 29:   Use `VecDuplicate()` or `VecDuplicateVecs()` to form additional vectors of the same type as an
 30:   existing vector.

 32:   This function may initialize `PetscDevice`, which may incur a device synchronization.

 34: .seealso: [](chapter_vectors), `PetscDeviceInitialize()`, `VecCreate()`, `VecCreateSeq()`, `VecCreateSeqHIPWithArray()`,
 35:           `VecCreateMPI()`, `VecCreateMPIHIP()`, `VecDuplicate()`, `VecDuplicateVecs()`, `VecCreateGhost()`
 36: @*/
 37: PetscErrorCode VecCreateSeqHIP(MPI_Comm comm, PetscInt n, Vec *v)
 38: {
 39:   PetscFunctionBegin;
 40:   PetscCall(VecCreateSeqCUPMAsync(VecSeq_HIP, comm, n, v));
 41:   PetscFunctionReturn(PETSC_SUCCESS);
 42: }

 44: /*@C
 45:   VecCreateSeqHIPWithArrays - Creates a sequential, array-style vector using HIP, where the
 46:   user provides the complete array space to store the vector values.

 48:   Collective, Possibly Synchronous

 50:   Input Parameters:
 51: + comm     - the communicator, must be `PETSC_COMM_SELF`
 52: . bs       - the block size
 53: . n        - the local vector length
 54: . cpuarray - CPU memory where the vector elements are to be stored (or `NULL`)
 55: - gpuarray - GPU memory where the vector elements are to be stored (or `NULL`)

 57:   Output Parameter:
 58: . v - the vector

 60:   Level: intermediate

 62:   Notes:
 63:   If the user-provided array is `NULL`, then `VecHIPPlaceArray()` can be used at a later stage to
 64:   SET the array for storing the vector values. Otherwise, the array must be allocated on the
 65:   device.

 67:   If both cpuarray and gpuarray are provided, the provided arrays must have identical
 68:   values.

 70:   The arrays are NOT freed when the vector is destroyed via `VecDestroy()`. The user must free
 71:   them themselves, but not until the vector is destroyed.

 73:   This function may initialize `PetscDevice`, which may incur a device synchronization.

 75: .seealso: [](chapter_vectors), `PetscDeviceInitialize()`, `VecCreate()`, `VecCreateSeqWithArray()`, `VecCreateSeqHIP()`,
 76:           `VecCreateSeqHIPWithArray()`, `VecCreateMPIHIP()`, `VecCreateMPIHIPWithArray()`,
 77:           `VecCreateMPIHIPWithArrays()`, `VecHIPPlaceArray()`
 78: C@*/
 79: PetscErrorCode VecCreateSeqHIPWithArrays(MPI_Comm comm, PetscInt bs, PetscInt n, const PetscScalar cpuarray[], const PetscScalar gpuarray[], Vec *v)
 80: {
 81:   PetscFunctionBegin;
 82:   PetscCall(VecCreateSeqCUPMWithArraysAsync(VecSeq_HIP, comm, bs, n, cpuarray, gpuarray, v));
 83:   PetscFunctionReturn(PETSC_SUCCESS);
 84: }

 86: /*@C
 87:   VecCreateSeqHIPWithArray - Creates a sequential, array-style vector using HIP, where the
 88:   user provides the device array space to store the vector values.

 90:   Collective, Possibly Synchronous

 92:   Input Parameters:
 93: + comm     - the communicator, must be `PETSC_COMM_SELF`
 94: . bs       - the block size
 95: . n        - the vector length
 96: - gpuarray - GPU memory where the vector elements are to be stored (or NULL)

 98:   Output Parameter:
 99: . v - the vector

101:   Level: intermediate

103:   Notes:
104:   If the user-provided array is `NULL`, then `VecHIPPlaceArray()` can be used at a later stage to
105:   SET the array for storing the vector values. Otherwise, the array must be allocated on the
106:   device.

108:   The array is NOT freed when the vector is destroyed via `VecDestroy()`. The user must free the
109:   array themselves, but not until the vector is destroyed.

111:   Use `VecDuplicate()` or `VecDuplicateVecs()` to form additional vectors of the same type as an
112:   existing vector.

114:   This function may initialize `PetscDevice`, which may incur a device synchronization.

116: .seealso: [](chapter_vectors), `PetscDeviceInitialize()`, `VecCreate()`, `VecCreateSeq()`, `VecCreateSeqWithArray()`,
117:           `VecCreateMPIWithArray()`, `VecCreateSeqHIP()`, `VecCreateMPIHIPWithArray()`, `VecHIPPlaceArray()`,
118:           `VecDuplicate()`, `VecDuplicateVecs()`, `VecCreateGhost()`
119: @*/
120: PetscErrorCode VecCreateSeqHIPWithArray(MPI_Comm comm, PetscInt bs, PetscInt n, const PetscScalar gpuarray[], Vec *v)
121: {
122:   PetscFunctionBegin;
123:   PetscCall(VecCreateSeqHIPWithArrays(comm, bs, n, nullptr, gpuarray, v));
124:   PetscFunctionReturn(PETSC_SUCCESS);
125: }

127: /*@C
128:   VecHIPGetArray - Provides access to the device buffer inside a vector

130:   Asynchronous; No Fortran Support

132:   Input Parameter:
133: . v - the vector

135:   Output Parameter:
136: . a - the device buffer

138:   Level: intermediate

140:   Notes:
141:   This routine has semantics similar to `VecGetArray()`; the returned buffer points to a
142:   consistent view of the vector data. This may involve copying data from the host to the device
143:   if the data on the device is out of date. It is also assumed that the returned buffer is
144:   immediately modified, marking the host data out of date. This is similar to intent(inout) in
145:   fortran.

147:   If the user does require strong memory guarantees, they are encouraged to use
148:   `VecHIPGetArrayRead()` and/or `VecHIPGetArrayWrite()` instead.

150:   The user must call `VecHIPRestoreArray()` when they are finished using the array.

152:   Developer Note:
153:   If the device memory hasn't been allocated previously it will be allocated as part of this
154:   routine.

156: .seealso: [](chapter_vectors), `VecHIPRestoreArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`,
157:           `VecGetArrayRead()`, `VecGetArrayWrite()`
158: @*/
159: PetscErrorCode VecHIPGetArray(Vec v, PetscScalar **a)
160: {
161:   PetscFunctionBegin;
162:   PetscCall(VecCUPMGetArrayAsync(VecSeq_HIP, v, a));
163:   PetscFunctionReturn(PETSC_SUCCESS);
164: }

166: /*@C
167:   VecHIPRestoreArray - Restore a device buffer previously acquired with `VecHIPGetArray()`.

169:   Asynchronous; No Fortran Support

171:   Input Parameters:
172: + v - the vector
173: - a - the device buffer

175:   Level: intermediate

177:   Note:
178:   The restored pointer is invalid after this function returns. This function also marks the
179:   host data as out of date. Subsequent access to the vector data on the host side via
180:   `VecGetArray()` will incur a (synchronous) data transfer.

182: .seealso: [](chapter_vectors), `VecHIPGetArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`,
183:           `VecRestoreArray()`, `VecGetArrayRead()`
184: @*/
185: PetscErrorCode VecHIPRestoreArray(Vec v, PetscScalar **a)
186: {
187:   PetscFunctionBegin;
188:   PetscCall(VecCUPMRestoreArrayAsync(VecSeq_HIP, v, a));
189:   PetscFunctionReturn(PETSC_SUCCESS);
190: }

192: /*@C
193:   VecHIPGetArrayRead - Provides read access to the HIP buffer inside a vector.

195:   Asynchronous; No Fortran Support

197:   Input Parameter:
198: . v - the vector

200:   Output Parameter:
201: . a - the HIP pointer.

203:   Level: intermediate

205:   Notes:
206:   See `VecHIPGetArray()` for data movement semantics of this function.

208:   This function assumes that the user will not modify the vector data. This is analgogous to
209:   intent(in) in Fortran.

211:   The device pointer must be restored by calling `VecHIPRestoreArrayRead()`. If the data on the
212:   host side was previously up to date it will remain so, i.e. data on both the device and the
213:   host is up to date. Accessing data on the host side does not incur a device to host data
214:   transfer.

216: .seealso: [](chapter_vectors), `VecHIPRestoreArrayRead()`, `VecHIPGetArray()`, `VecHIPGetArrayWrite()`, `VecGetArray()`,
217:           `VecGetArrayRead()`
218: @*/
219: PetscErrorCode VecHIPGetArrayRead(Vec v, const PetscScalar **a)
220: {
221:   PetscFunctionBegin;
222:   PetscCall(VecCUPMGetArrayReadAsync(VecSeq_HIP, v, a));
223:   PetscFunctionReturn(PETSC_SUCCESS);
224: }

226: /*@C
227:   VecHIPRestoreArrayRead - Restore a HIP device pointer previously acquired with
228:   `VecHIPGetArrayRead()`.

230:   No Fortran Support

232:   Input Parameters:
233: + v - the vector
234: - a - the HIP device pointer

236:   Level: intermediate

238:   Note:
239:   This routine does not modify the corresponding array on the host in any way. The pointer is
240:   invalid after this function returns.

242: .seealso: [](chapter_vectors), `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecHIPGetArray()`, `VecGetArray()`,
243:           `VecRestoreArray()`, `VecGetArrayRead()`
244: @*/
245: PetscErrorCode VecHIPRestoreArrayRead(Vec v, const PetscScalar **a)
246: {
247:   PetscFunctionBegin;
248:   PetscCall(VecCUPMRestoreArrayReadAsync(VecSeq_HIP, v, a));
249:   PetscFunctionReturn(PETSC_SUCCESS);
250: }

252: /*@C
253:   VecHIPGetArrayWrite - Provides write access to the HIP buffer inside a vector.

255:   No Fortran Support

257:   Input Parameter:
258: . v - the vector

260:   Output Parameter:
261: . a - the HIP pointer

263:   Level: advanced

265:   Notes:
266:   The data pointed to by the device pointer is uninitialized. The user may not read from this
267:   data. Furthermore, the entire array needs to be filled by the user to obtain well-defined
268:   behaviour. The device memory will be allocated by this function if it hasn't been allocated
269:   previously. This is analogous to intent(out) in Fortran.

271:   The device pointer needs to be released with `VecHIPRestoreArrayWrite()`. When the pointer is
272:   released the host data of the vector is marked as out of data. Subsequent access of the host
273:   data with e.g. `VecGetArray()` incurs a device to host data transfer.

275: .seealso: [](chapter_vectors), `VecHIPRestoreArrayWrite()`, `VecHIPGetArray()`, `VecHIPGetArrayRead()`,
276:           `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
277: @*/
278: PetscErrorCode VecHIPGetArrayWrite(Vec v, PetscScalar **a)
279: {
280:   PetscFunctionBegin;
281:   PetscCall(VecCUPMGetArrayWriteAsync(VecSeq_HIP, v, a));
282:   PetscFunctionReturn(PETSC_SUCCESS);
283: }

285: /*@C
286:   VecHIPRestoreArrayWrite - Restore a HIP device pointer previously acquired with
287:   `VecHIPGetArrayWrite()`.

289:   No Fortran Support

291:   Input Parameters:
292: + v - the vector
293: - a - the HIP device pointer.  This pointer is invalid after `VecHIPRestoreArrayWrite()` returns.

295:   Level: intermediate

297:   Note:
298:   Data on the host will be marked as out of date. Subsequent access of the data on the host
299:   side e.g. with `VecGetArray()` will incur a device to host data transfer.

301: .seealso: [](chapter_vectors), `VecHIPGetArrayWrite()`, `VecHIPGetArray()`, `VecHIPGetArrayRead()`,
302:           `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
303: @*/
304: PetscErrorCode VecHIPRestoreArrayWrite(Vec v, PetscScalar **a)
305: {
306:   PetscFunctionBegin;
307:   PetscCall(VecCUPMRestoreArrayWriteAsync(VecSeq_HIP, v, a));
308:   PetscFunctionReturn(PETSC_SUCCESS);
309: }

311: /*@C
312:   VecHIPPlaceArray - Allows one to replace the GPU array in a vector with a GPU array provided
313:   by the user.

315:   Not Collective; No Fortran Support

317:   Input Parameters:
318: + vec - the vector
319: - array - the GPU array

321:   Level: advanced

323:   Notes:
324:   This routine is useful to avoid copying an array into a vector, though you can return to the
325:   original GPU array with a call to `VecHIPResetArray()`.

327:   It is not possible to use `VecHIPPlaceArray()` and `VecPlaceArray()` at the same time on the
328:   same vector.

330:   `vec` does not take ownership of `array` in any way. The user must free `array` themselves
331:   but be careful not to do so before the vector has either been destroyed, had its original
332:   array restored with `VecHIPResetArray()` or permanently replaced with
333:   `VecHIPReplaceArray()`.

335: .seealso: [](chapter_vectors), `VecPlaceArray()`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`,
336:           `VecResetArray()`, `VecHIPResetArray()`, `VecHIPReplaceArray()`
337: @*/
338: PetscErrorCode VecHIPPlaceArray(Vec vin, const PetscScalar a[])
339: {
340:   PetscFunctionBegin;
341:   PetscCall(VecCUPMPlaceArrayAsync(VecSeq_HIP, vin, a));
342:   PetscFunctionReturn(PETSC_SUCCESS);
343: }

345: /*@C
346:   VecHIPReplaceArray - Permanently replace the GPU array in a vector with a GPU array provided
347:   by the user.

349:   Not Collective; No Fortran Support

351:   Input Parameters:
352: + vec   - the vector
353: - array - the GPU array

355:   Level: advanced

357:   Notes:
358:   This is useful to avoid copying a GPU array into a vector.

360:   This frees the memory associated with the old GPU array. The vector takes ownership of the
361:   passed array so it CANNOT be freed by the user. It will be freed when the vector is
362:   destroyed.

364: .seealso: [](chapter_vectors), `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`,
365:           `VecHIPResetArray()`, `VecHIPPlaceArray()`, `VecReplaceArray()`
366: @*/
367: PetscErrorCode VecHIPReplaceArray(Vec vin, const PetscScalar a[])
368: {
369:   PetscFunctionBegin;
370:   PetscCall(VecCUPMReplaceArrayAsync(VecSeq_HIP, vin, a));
371:   PetscFunctionReturn(PETSC_SUCCESS);
372: }

374: /*@C
375:   VecHIPResetArray - Resets a vector to use its default memory.

377:   Not Collective

379:   Input Parameters:
380: . vec - the vector

382:   Level: advanced

384:   Note:
385:   Call this after the use of `VecHIPPlaceArray()`.

387: .seealso: [](chapter_vectors), `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`,
388:           `VecResetArray()`, `VecHIPPlaceArray()`, `VecHIPReplaceArray()`
389: @*/
390: PetscErrorCode VecHIPResetArray(Vec vin)
391: {
392:   PetscFunctionBegin;
393:   PetscCall(VecCUPMResetArrayAsync(VecSeq_HIP, vin));
394:   PetscFunctionReturn(PETSC_SUCCESS);
395: }