Actual source code: vecseqcupm.hip.cpp

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

  4: using namespace ::Petsc::vec::cupm;
  5: using ::Petsc::device::cupm::DeviceType;

  7: template class impl::VecSeq_CUPM<DeviceType::HIP>;

  9: static constexpr auto VecSeq_HIP = impl::VecSeq_CUPM<DeviceType::HIP>{};

 11: PetscErrorCode VecCreate_SeqHIP(Vec v)
 12: {
 13:   PetscFunctionBegin;
 14:   PetscCall(VecSeq_HIP.Create(v));
 15:   PetscFunctionReturn(PETSC_SUCCESS);
 16: }

 18: PetscErrorCode VecConvert_Seq_SeqHIP_inplace(Vec v)
 19: {
 20:   PetscFunctionBegin;
 21:   PetscCall(VecSeq_HIP.Convert_IMPL_IMPLCUPM(v));
 22:   PetscFunctionReturn(PETSC_SUCCESS);
 23: }

 25: // PetscClangLinter pragma disable: -fdoc-internal-linkage
 26: /*@
 27:   VecCreateSeqHIP - Creates a standard, sequential, array-style vector.

 29:   Collective, Possibly Synchronous

 31:   Input Parameters:
 32: + comm - the communicator, must be `PETSC_COMM_SELF`
 33: - n    - the vector length

 35:   Output Parameter:
 36: . v - the vector

 38:   Level: intermediate

 40:   Notes:
 41:   Use `VecDuplicate()` or `VecDuplicateVecs()` to form additional vectors of the same type as an
 42:   existing vector.

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

 46: .seealso: [](ch_vectors), `PetscDeviceInitialize()`, `VecCreate()`, `VecCreateSeq()`, `VecCreateSeqHIPWithArray()`,
 47:           `VecCreateMPI()`, `VecCreateMPIHIP()`, `VecDuplicate()`, `VecDuplicateVecs()`, `VecCreateGhost()`
 48: @*/
 49: PetscErrorCode VecCreateSeqHIP(MPI_Comm comm, PetscInt n, Vec *v)
 50: {
 51:   PetscFunctionBegin;
 52:   PetscCall(VecCreateSeqCUPMAsync<DeviceType::HIP>(comm, n, v));
 53:   PetscFunctionReturn(PETSC_SUCCESS);
 54: }

 56: // PetscClangLinter pragma disable: -fdoc-internal-linkage
 57: /*@C
 58:   VecCreateSeqHIPWithArrays - Creates a sequential, array-style vector using HIP, where the
 59:   user provides the complete array space to store the vector values.

 61:   Collective, Possibly Synchronous

 63:   Input Parameters:
 64: + comm     - the communicator, must be `PETSC_COMM_SELF`
 65: . bs       - the block size
 66: . n        - the local vector length
 67: . cpuarray - CPU memory where the vector elements are to be stored (or `NULL`)
 68: - gpuarray - GPU memory where the vector elements are to be stored (or `NULL`)

 70:   Output Parameter:
 71: . v - the vector

 73:   Level: intermediate

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

 80:   If both `cpuarray` and `gpuarray` are provided, the provided arrays must have identical
 81:   values.

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

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

 88: .seealso: [](ch_vectors), `PetscDeviceInitialize()`, `VecCreate()`, `VecCreateSeqWithArray()`, `VecCreateSeqHIP()`,
 89:           `VecCreateSeqHIPWithArray()`, `VecCreateMPIHIP()`, `VecCreateMPIHIPWithArray()`,
 90:           `VecCreateMPIHIPWithArrays()`, `VecHIPPlaceArray()`
 91: C@*/
 92: PetscErrorCode VecCreateSeqHIPWithArrays(MPI_Comm comm, PetscInt bs, PetscInt n, const PetscScalar cpuarray[], const PetscScalar gpuarray[], Vec *v)
 93: {
 94:   PetscFunctionBegin;
 95:   PetscCall(VecCreateSeqCUPMWithArraysAsync<DeviceType::HIP>(comm, bs, n, cpuarray, gpuarray, v));
 96:   PetscFunctionReturn(PETSC_SUCCESS);
 97: }

 99: // PetscClangLinter pragma disable: -fdoc-internal-linkage
100: /*@C
101:   VecCreateSeqHIPWithArray - Creates a sequential, array-style vector using HIP, where the
102:   user provides the device array space to store the vector values.

104:   Collective, Possibly Synchronous

106:   Input Parameters:
107: + comm     - the communicator, must be `PETSC_COMM_SELF`
108: . bs       - the block size
109: . n        - the vector length
110: - gpuarray - GPU memory where the vector elements are to be stored (or `NULL`)

112:   Output Parameter:
113: . v - the vector

115:   Level: intermediate

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

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

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

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

130: .seealso: [](ch_vectors), `PetscDeviceInitialize()`, `VecCreate()`, `VecCreateSeq()`, `VecCreateSeqWithArray()`,
131:           `VecCreateMPIWithArray()`, `VecCreateSeqHIP()`, `VecCreateMPIHIPWithArray()`, `VecHIPPlaceArray()`,
132:           `VecDuplicate()`, `VecDuplicateVecs()`, `VecCreateGhost()`
133: @*/
134: PetscErrorCode VecCreateSeqHIPWithArray(MPI_Comm comm, PetscInt bs, PetscInt n, const PetscScalar gpuarray[], Vec *v)
135: {
136:   PetscFunctionBegin;
137:   PetscCall(VecCreateSeqHIPWithArrays(comm, bs, n, nullptr, gpuarray, v));
138:   PetscFunctionReturn(PETSC_SUCCESS);
139: }

141: // PetscClangLinter pragma disable: -fdoc-internal-linkage
142: /*@C
143:   VecHIPGetArray - Provides access to the device buffer inside a vector

145:   Not Collective; Asynchronous; No Fortran Support

147:   Input Parameter:
148: . v - the vector

150:   Output Parameter:
151: . a - the device buffer

153:   Level: intermediate

155:   Notes:
156:   This routine has semantics similar to `VecGetArray()`; the returned buffer points to a
157:   consistent view of the vector data. This may involve copying data from the host to the device
158:   if the data on the device is out of date. It is also assumed that the returned buffer is
159:   immediately modified, marking the host data out of date. This is similar to intent(inout) in
160:   Fortran.

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

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

167:   Developer Note:
168:   If the device memory hasn't been allocated previously it will be allocated as part of this
169:   routine.

171: .seealso: [](ch_vectors), `VecHIPRestoreArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`,
172:           `VecGetArrayRead()`, `VecGetArrayWrite()`
173: @*/
174: PetscErrorCode VecHIPGetArray(Vec v, PetscScalar **a)
175: {
176:   PetscFunctionBegin;
177:   PetscCall(VecCUPMGetArrayAsync<DeviceType::HIP>(v, a));
178:   PetscFunctionReturn(PETSC_SUCCESS);
179: }

181: // PetscClangLinter pragma disable: -fdoc-internal-linkage
182: /*@C
183:   VecHIPRestoreArray - Restore a device buffer previously acquired with `VecHIPGetArray()`.

185:   Not Collective; Asynchronous; No Fortran Support

187:   Input Parameters:
188: + v - the vector
189: - a - the device buffer

191:   Level: intermediate

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

198: .seealso: [](ch_vectors), `VecHIPGetArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`,
199:           `VecRestoreArray()`, `VecGetArrayRead()`
200: @*/
201: PetscErrorCode VecHIPRestoreArray(Vec v, PetscScalar **a)
202: {
203:   PetscFunctionBegin;
204:   PetscCall(VecCUPMRestoreArrayAsync<DeviceType::HIP>(v, a));
205:   PetscFunctionReturn(PETSC_SUCCESS);
206: }

208: // PetscClangLinter pragma disable: -fdoc-internal-linkage
209: /*@C
210:   VecHIPGetArrayRead - Provides read access to the HIP buffer inside a vector.

212:   Not Collective; Asynchronous; No Fortran Support

214:   Input Parameter:
215: . v - the vector

217:   Output Parameter:
218: . a - the HIP pointer.

220:   Level: intermediate

222:   Notes:
223:   See `VecHIPGetArray()` for data movement semantics of this function.

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

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

233: .seealso: [](ch_vectors), `VecHIPRestoreArrayRead()`, `VecHIPGetArray()`, `VecHIPGetArrayWrite()`, `VecGetArray()`,
234:           `VecGetArrayRead()`
235: @*/
236: PetscErrorCode VecHIPGetArrayRead(Vec v, const PetscScalar **a)
237: {
238:   PetscFunctionBegin;
239:   PetscCall(VecCUPMGetArrayReadAsync<DeviceType::HIP>(v, a));
240:   PetscFunctionReturn(PETSC_SUCCESS);
241: }

243: // PetscClangLinter pragma disable: -fdoc-internal-linkage
244: /*@C
245:   VecHIPRestoreArrayRead - Restore a HIP device pointer previously acquired with
246:   `VecHIPGetArrayRead()`.

248:   Not Collective; Asynchronous; No Fortran Support

250:   Input Parameters:
251: + v - the vector
252: - a - the HIP device pointer

254:   Level: intermediate

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

260: .seealso: [](ch_vectors), `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecHIPGetArray()`, `VecGetArray()`,
261:           `VecRestoreArray()`, `VecGetArrayRead()`
262: @*/
263: PetscErrorCode VecHIPRestoreArrayRead(Vec v, const PetscScalar **a)
264: {
265:   PetscFunctionBegin;
266:   PetscCall(VecCUPMRestoreArrayReadAsync<DeviceType::HIP>(v, a));
267:   PetscFunctionReturn(PETSC_SUCCESS);
268: }

270: // PetscClangLinter pragma disable: -fdoc-internal-linkage
271: /*@C
272:   VecHIPGetArrayWrite - Provides write access to the HIP buffer inside a vector.

274:    Not Collective; Asynchronous; No Fortran Support

276:   Input Parameter:
277: . v - the vector

279:   Output Parameter:
280: . a - the HIP pointer

282:   Level: advanced

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

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

294: .seealso: [](ch_vectors), `VecHIPRestoreArrayWrite()`, `VecHIPGetArray()`, `VecHIPGetArrayRead()`,
295:           `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
296: @*/
297: PetscErrorCode VecHIPGetArrayWrite(Vec v, PetscScalar **a)
298: {
299:   PetscFunctionBegin;
300:   PetscCall(VecCUPMGetArrayWriteAsync<DeviceType::HIP>(v, a));
301:   PetscFunctionReturn(PETSC_SUCCESS);
302: }

304: // PetscClangLinter pragma disable: -fdoc-internal-linkage
305: /*@C
306:   VecHIPRestoreArrayWrite - Restore a HIP device pointer previously acquired with
307:   `VecHIPGetArrayWrite()`.

309:   Not Collective; Asynchronous; No Fortran Support

311:   Input Parameters:
312: + v - the vector
313: - a - the HIP device pointer.  This pointer is invalid after `VecHIPRestoreArrayWrite()` returns.

315:   Level: intermediate

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

321: .seealso: [](ch_vectors), `VecHIPGetArrayWrite()`, `VecHIPGetArray()`, `VecHIPGetArrayRead()`,
322:           `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
323: @*/
324: PetscErrorCode VecHIPRestoreArrayWrite(Vec v, PetscScalar **a)
325: {
326:   PetscFunctionBegin;
327:   PetscCall(VecCUPMRestoreArrayWriteAsync<DeviceType::HIP>(v, a));
328:   PetscFunctionReturn(PETSC_SUCCESS);
329: }

331: // PetscClangLinter pragma disable: -fdoc-internal-linkage
332: /*@C
333:   VecHIPPlaceArray - Allows one to replace the GPU array in a vector with a GPU array provided
334:   by the user.

336:   Not Collective; Asynchronous; No Fortran Support

338:   Input Parameters:
339: + vec - the vector
340: - array - the GPU array

342:   Level: advanced

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

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

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

356: .seealso: [](ch_vectors), `VecPlaceArray()`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`,
357:           `VecResetArray()`, `VecHIPResetArray()`, `VecHIPReplaceArray()`
358: @*/
359: PetscErrorCode VecHIPPlaceArray(Vec vin, const PetscScalar a[])
360: {
361:   PetscFunctionBegin;
362:   PetscCall(VecCUPMPlaceArrayAsync<DeviceType::HIP>(vin, a));
363:   PetscFunctionReturn(PETSC_SUCCESS);
364: }

366: // PetscClangLinter pragma disable: -fdoc-internal-linkage
367: /*@C
368:   VecHIPReplaceArray - Permanently replace the GPU array in a vector with a GPU array provided
369:   by the user.

371:   Not Collective; No Fortran Support

373:   Input Parameters:
374: + vec   - the vector
375: - array - the GPU array

377:   Level: advanced

379:   Notes:
380:   This is useful to avoid copying a GPU array into a vector.

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

386: .seealso: [](ch_vectors), `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`,
387:           `VecHIPResetArray()`, `VecHIPPlaceArray()`, `VecReplaceArray()`
388: @*/
389: PetscErrorCode VecHIPReplaceArray(Vec vin, const PetscScalar a[])
390: {
391:   PetscFunctionBegin;
392:   PetscCall(VecCUPMReplaceArrayAsync<DeviceType::HIP>(vin, a));
393:   PetscFunctionReturn(PETSC_SUCCESS);
394: }

396: // PetscClangLinter pragma disable: -fdoc-internal-linkage
397: /*@C
398:   VecHIPResetArray - Resets a vector to use its default memory.

400:   Not Collective; No Fortran Support

402:   Input Parameters:
403: . vec - the vector

405:   Level: advanced

407:   Note:
408:   Call this after the use of `VecHIPPlaceArray()`.

410: .seealso: [](ch_vectors), `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`,
411:           `VecResetArray()`, `VecHIPPlaceArray()`, `VecHIPReplaceArray()`
412: @*/
413: PetscErrorCode VecHIPResetArray(Vec vin)
414: {
415:   PetscFunctionBegin;
416:   PetscCall(VecCUPMResetArrayAsync<DeviceType::HIP>(vin));
417:   PetscFunctionReturn(PETSC_SUCCESS);
418: }