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