Actual source code: ex13.cxx
1: static const char help[] = "Test CUPM two-dimensional memory operations on a delayed device context.\n";
3: #include <petsc/private/cupminterface.hpp>
5: using Petsc::device::cupm::DeviceType;
7: template <DeviceType T>
8: struct TestMemory2D : Petsc::device::cupm::impl::Interface<T> {
9: PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(T);
11: static PetscErrorCode Run(PetscDeviceContext dctx)
12: {
13: const PetscInt width = 3, height = 2, src_pitch = 7, dst_pitch = 5;
14: const auto dtod = cupmMemcpyDeviceToDevice;
15: unsigned char *src, *dst, *result;
16: void *handle;
17: cupmStream_t stream;
19: PetscFunctionBeginUser;
20: PetscCall(PetscDeviceContextGetStreamHandle(dctx, &handle));
21: stream = *static_cast<cupmStream_t *>(handle);
22: PetscCall(PetscDeviceMalloc(dctx, PETSC_MEMTYPE_DEVICE, src_pitch * height, PETSC_DECIDE, &src));
23: PetscCall(PetscDeviceMalloc(dctx, PETSC_MEMTYPE_DEVICE, dst_pitch * height, PETSC_DECIDE, &dst));
24: PetscCall(PetscDeviceMalloc(dctx, PETSC_MEMTYPE_HOST, dst_pitch * height, PETSC_DECIDE, &result));
25: for (PetscInt op = 0; op < 2; ++op) {
26: PetscCall(PetscDeviceMemset(dctx, src, 1, src_pitch * height));
27: PetscCall(PetscDeviceMemset(dctx, dst, 7, dst_pitch * height));
28: PetscCall(PetscDeviceContextSynchronize(dctx));
29: PetscCall(PetscDeviceContextDelay(dctx, 0.1));
30: if (op) {
31: PetscCall(PetscDeviceMemset(dctx, dst, 2, dst_pitch * height));
32: PetscCallCUPM(cupmMemset2DAsync(dst, dst_pitch, 0, width, height, stream));
33: } else {
34: PetscCall(PetscDeviceMemset(dctx, src, 2, src_pitch * height));
35: PetscCallCUPM(cupmMemcpy2DAsync(dst, dst_pitch, src, src_pitch, width, height, dtod, stream));
36: }
37: // Drain misplaced default-stream work before the delayed producer can overwrite its result.
38: PetscCall(PetscDeviceContextSynchronize(PetscDeviceContextDefault));
39: PetscCall(PetscDeviceContextSynchronize(dctx));
40: PetscCall(PetscDeviceArrayCopy(dctx, result, dst, dst_pitch * height));
41: PetscCall(PetscDeviceContextSynchronize(dctx));
42: for (PetscInt j = 0; j < height; ++j) {
43: for (PetscInt i = 0; i < dst_pitch; ++i) {
44: const unsigned char expected = i < width ? (op ? 0 : 2) : (op ? 2 : 7);
46: PetscCheck(result[j * dst_pitch + i] == expected, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Incorrect %s result at row %" PetscInt_FMT ", column %" PetscInt_FMT ": got %u, expected %u", op ? "memset" : "copy", j, i, (unsigned int)result[j * dst_pitch + i], (unsigned int)expected);
47: }
48: }
49: }
50: PetscCall(PetscDeviceFree(dctx, src));
51: PetscCall(PetscDeviceFree(dctx, dst));
52: PetscCall(PetscDeviceFree(dctx, result));
53: PetscCall(PetscDeviceContextSynchronize(dctx));
54: PetscFunctionReturn(PETSC_SUCCESS);
55: }
56: };
58: int main(int argc, char **argv)
59: {
60: PetscDeviceContext current, dctx;
61: PetscDeviceType dtype;
63: PetscFunctionBeginUser;
64: PetscCall(PetscInitialize(&argc, &argv, nullptr, help));
65: PetscCall(PetscDeviceContextGetCurrentContext(¤t));
66: PetscCall(PetscDeviceContextDuplicate(current, &dctx));
67: PetscCall(PetscDeviceContextSetStreamType(dctx, PETSC_STREAM_NONBLOCKING));
68: PetscCall(PetscDeviceContextSetUp(dctx));
69: PetscCall(PetscDeviceContextGetDeviceType(dctx, &dtype));
70: PetscCall(PetscDeviceContextSynchronize(PetscDeviceContextDefault));
71: switch (dtype) {
72: #if PetscDefined(HAVE_CUDA)
73: case PETSC_DEVICE_CUDA:
74: PetscCall(TestMemory2D<DeviceType::CUDA>::Run(dctx));
75: break;
76: #endif
77: #if PetscDefined(HAVE_HIP)
78: case PETSC_DEVICE_HIP:
79: PetscCall(TestMemory2D<DeviceType::HIP>::Run(dctx));
80: break;
81: #endif
82: default:
83: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "This test requires CUDA or HIP");
84: }
85: PetscCall(PetscDeviceContextDestroy(&dctx));
86: PetscCall(PetscFinalize());
87: return 0;
88: }
90: /*TEST
92: build:
93: requires: cxx
95: testset:
96: output_file: output/empty.out
97: test:
98: suffix: cuda
99: requires: cuda
100: args: -default_device_type cuda
101: test:
102: suffix: hip
103: requires: hip
104: args: -default_device_type hip
106: TEST*/