static const char help[] = "Tests PetscDeviceContextSetDevice.\n\n"; #include "petscdevicetestcommon.h" int main(int argc, char *argv[]) { PetscDeviceContext dctx = NULL; PetscDevice device = NULL, other_device = NULL; PetscFunctionBeginUser; PetscCall(PetscInitialize(&argc, &argv, NULL, help)); PetscCall(PetscDeviceContextCreate(&dctx)); PetscCall(AssertDeviceContextExists(dctx)); PetscCall(PetscDeviceCreate(PETSC_DEVICE_DEFAULT(), PETSC_DECIDE, &device)); PetscCall(PetscDeviceConfigure(device)); PetscCall(PetscDeviceView(device, NULL)); PetscCall(PetscDeviceContextSetDevice(dctx, device)); PetscCall(PetscDeviceContextGetDevice(dctx, &other_device)); PetscCall(AssertPetscDevicesValidAndEqual(device, other_device, "PetscDevice after setdevice() does not match original PetscDevice")); // output here should be a duplicate of output above PetscCall(PetscDeviceView(other_device, NULL)); // setup, test that this doesn't clobber the device PetscCall(PetscDeviceContextSetUp(dctx)); PetscCall(PetscDeviceContextGetDevice(dctx, &other_device)); PetscCall(AssertPetscDevicesValidAndEqual(device, other_device, "PetscDevice after setdevice() does not match original PetscDevice")); // once again output of this view should not change anything PetscCall(PetscDeviceView(other_device, NULL)); PetscCall(PetscDeviceContextView(dctx, NULL)); PetscCall(PetscDeviceContextDestroy(&dctx)); // while we have destroyed the device context (which should decrement the PetscDevice's // refcount), we still hold a reference ourselves. Check that it remains valid PetscCall(PetscDeviceView(device, NULL)); PetscCall(PetscDeviceContextCreate(&dctx)); // PetscDeviceContext secretly keeps the device reference alive until the device context // itself is recycled. So create a new context here such that PetscDeviceDestroy() is called PetscCall(PetscDeviceView(device, NULL)); // setup will attach the default device PetscCall(PetscDeviceContextSetUp(dctx)); // check that it has, the attached device should not be equal to ours PetscCall(PetscDeviceContextGetDevice(dctx, &other_device)); // None C++ builds have dummy devices (NULL) if (PetscDefined(DEVICELANGUAGE_CXX)) PetscCheck(device != other_device, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContext still has old PetscDevice attached after being recycled!"); PetscCall(PetscDeviceContextDestroy(&dctx)); PetscCall(PetscDeviceDestroy(&device)); PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n")); PetscCall(PetscFinalize()); return 0; } /*TEST testset: requires: defined(PETSC_DEVICELANGUAGE_CXX) args: -device_enable {{lazy eager}} test: requires: !device suffix: host_no_device test: requires: device args: -default_device_type host suffix: host_with_device test: requires: cuda args: -default_device_type cuda suffix: cuda test: requires: hip args: -default_device_type hip suffix: hip test: requires: sycl args: -default_device_type sycl suffix: sycl testset: requires: !defined(PETSC_DEVICELANGUAGE_CXX) output_file: output/ExitSuccess.out suffix: no_cxx TEST*/