xref: /petsc/src/sys/objects/device/tests/ex8.c (revision 21e3ffae2f3b73c0bd738cf6d0a809700fc04bb0)
1 static const char help[] = "Tests PetscDeviceContextSetDevice.\n\n";
2 
3 #include "petscdevicetestcommon.h"
4 
5 int main(int argc, char *argv[])
6 {
7   PetscDeviceContext dctx   = NULL;
8   PetscDevice        device = NULL, other_device = NULL;
9 
10   PetscFunctionBeginUser;
11   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
12 
13   PetscCall(PetscDeviceContextCreate(&dctx));
14   PetscCall(AssertDeviceContextExists(dctx));
15 
16   PetscCall(PetscDeviceCreate(PETSC_DEVICE_DEFAULT(), PETSC_DECIDE, &device));
17   PetscCall(PetscDeviceConfigure(device));
18   PetscCall(PetscDeviceView(device, NULL));
19 
20   PetscCall(PetscDeviceContextSetDevice(dctx, device));
21   PetscCall(PetscDeviceContextGetDevice(dctx, &other_device));
22   PetscCall(AssertPetscDevicesValidAndEqual(device, other_device, "PetscDevice after setdevice() does not match original PetscDevice"));
23   // output here should be a duplicate of output above
24   PetscCall(PetscDeviceView(other_device, NULL));
25 
26   // setup, test that this doesn't clobber the device
27   PetscCall(PetscDeviceContextSetUp(dctx));
28   PetscCall(PetscDeviceContextGetDevice(dctx, &other_device));
29   PetscCall(AssertPetscDevicesValidAndEqual(device, other_device, "PetscDevice after setdevice() does not match original PetscDevice"));
30   // once again output of this view should not change anything
31   PetscCall(PetscDeviceView(other_device, NULL));
32 
33   PetscCall(PetscDeviceContextView(dctx, NULL));
34   PetscCall(PetscDeviceContextDestroy(&dctx));
35 
36   // while we have destroyed the device context (which should decrement the PetscDevice's
37   // refcount), we still hold a reference ourselves. Check that it remains valid
38   PetscCall(PetscDeviceView(device, NULL));
39   PetscCall(PetscDeviceContextCreate(&dctx));
40   // PetscDeviceContext secretly keeps the device reference alive until the device context
41   // itself is recycled. So create a new context here such that PetscDeviceDestroy() is called
42   PetscCall(PetscDeviceView(device, NULL));
43 
44   // setup will attach the default device
45   PetscCall(PetscDeviceContextSetUp(dctx));
46   // check that it has, the attached device should not be equal to ours
47   PetscCall(PetscDeviceContextGetDevice(dctx, &other_device));
48   // None C++ builds have dummy devices (NULL)
49   if (PetscDefined(HAVE_CXX)) PetscCheck(device != other_device, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContext still has old PetscDevice attached after being recycled!");
50 
51   PetscCall(PetscDeviceContextDestroy(&dctx));
52   PetscCall(PetscDeviceDestroy(&device));
53 
54   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n"));
55   PetscCall(PetscFinalize());
56   return 0;
57 }
58 
59 /*TEST
60 
61   testset:
62     requires: cxx
63     args: -device_enable {{lazy eager}}
64     test:
65       requires: !device
66       suffix: host_no_device
67     test:
68       requires: device
69       args: -default_device_type host
70       suffix: host_with_device
71     test:
72       requires: cuda
73       args: -default_device_type cuda
74       suffix: cuda
75     test:
76       requires: hip
77       args: -default_device_type hip
78       suffix: hip
79     test:
80       requires: sycl
81       args: -default_device_type sycl
82       suffix: sycl
83 
84   testset:
85     requires: !cxx
86     output_file: ./output/ExitSuccess.out
87     suffix: no_cxx
88 
89 TEST*/
90