xref: /petsc/src/sys/objects/device/tests/ex8.c (revision f9fea11e2c44c506c9f9a3f6998afbe8a760174b)
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   /* basic creation and destruction */
14   PetscCall(PetscDeviceContextCreate(&dctx));
15   PetscCall(AssertDeviceContextExists(dctx));
16 
17   PetscCall(PetscDeviceCreate(PETSC_DEVICE_DEFAULT(), PETSC_DECIDE, &device));
18   PetscCall(PetscDeviceConfigure(device));
19   PetscCall(PetscDeviceView(device, NULL));
20 
21   PetscCall(PetscDeviceContextSetDevice(dctx, device));
22   PetscCall(PetscDeviceContextGetDevice(dctx, &other_device));
23   PetscCall(AssertPetscDevicesValidAndEqual(device, other_device, "PetscDevice after setdevice() does not match original PetscDevice"));
24   // output here should be a duplicate of output above
25   PetscCall(PetscDeviceView(other_device, NULL));
26 
27   // setup, test that this doesn't clobber the device
28   PetscCall(PetscDeviceContextSetUp(dctx));
29   PetscCall(PetscDeviceContextGetDevice(dctx, &other_device));
30   PetscCall(AssertPetscDevicesValidAndEqual(device, other_device, "PetscDevice after setdevice() does not match original PetscDevice"));
31   // once again output of this view should not change anything
32   PetscCall(PetscDeviceView(other_device, NULL));
33 
34   PetscCall(PetscDeviceContextView(dctx, NULL));
35   PetscCall(PetscDeviceContextDestroy(&dctx));
36 
37   // while we have destroyed the device context (which should decrement the PetscDevice's
38   // refcount), we still hold a reference ourselves. Check that it remains valid
39   PetscCall(PetscDeviceView(device, NULL));
40   PetscCall(PetscDeviceContextCreate(&dctx));
41   // PetscDeviceContext secretly keeps the device reference alive until the device context
42   // itself is recycled. So create a new context here such that PetscDeviceDestroy() is called
43   PetscCall(PetscDeviceView(device, NULL));
44 
45   // setup will attach the default device
46   PetscCall(PetscDeviceContextSetUp(dctx));
47   // check that it has, the attached device should not be equal to ours
48   PetscCall(PetscDeviceContextGetDevice(dctx, &other_device));
49   // None C++ builds have dummy devices (NULL)
50   if (PetscDefined(HAVE_CXX)) PetscCheck(device != other_device, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContext still has old PetscDevice attached after being recycled!");
51 
52   PetscCall(PetscDeviceContextDestroy(&dctx));
53   PetscCall(PetscDeviceDestroy(&device));
54 
55   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n"));
56   PetscCall(PetscFinalize());
57   return 0;
58 }
59 
60 /*TEST
61 
62  testset:
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 TEST*/
85