A OptionalDeviceGuard is an RAII class that sets a device to some value on initialization, and resets the device to its original value on destruction. More...
#include <DeviceGuard.h>
Public Member Functions | |
OptionalDeviceGuard () | |
Create an uninitialized guard. Set the guard later using set_device. | |
OptionalDeviceGuard (Device device) | |
Initialize the guard, setting the current device to the passed Device. | |
OptionalDeviceGuard (optional< Device > device) | |
Initialize the guard if a Device is passed; otherwise leave the guard uninitialized. More... | |
OptionalDeviceGuard (Device device, const impl::DeviceGuardImplInterface *impl) | |
Constructor for testing only. | |
OptionalDeviceGuard (const OptionalDeviceGuard &)=delete | |
Copy is disallowed. | |
OptionalDeviceGuard & | operator= (const OptionalDeviceGuard &)=delete |
OptionalDeviceGuard (OptionalDeviceGuard &&other)=delete | |
Move is disallowed See Note [Explicit initialization of optional fields] and // Note [Move construction for RAII guards is tricky] for rationale. More... | |
OptionalDeviceGuard & | operator= (OptionalDeviceGuard &&other)=delete |
void | reset_device (at::Device device) |
Sets the device to the given one. More... | |
void | reset_device (at::Device device, const impl::DeviceGuardImplInterface *impl) |
For testing only. | |
optional< Device > | original_device () const |
Returns the device that was set at the time the guard was constructed. | |
optional< Device > | current_device () const |
Returns the most recent device that was set using this device guard, either from construction, or via set_device. More... | |
A OptionalDeviceGuard is an RAII class that sets a device to some value on initialization, and resets the device to its original value on destruction.
Morally, a OptionalDeviceGuard is equivalent to optional<DeviceGuard>, but with extra constructors and methods as appropriate.
Besides its obvious use (optionally applying a DeviceGuard), OptionalDeviceGuard is often also used for the following idiom:
OptionalDeviceGuard g; for (const auto& t : tensors) { g.set_device(t.device()); do_something_with(t); }
This usage is marginally more efficient than constructing a DeviceGuard every iteration of the for loop, as it avoids an unnecessary device reset.
Unlike DeviceGuard, a OptionalDeviceGuard may be uninitialized. This occurs when you use the nullary constructor, or pass a nullopt to the constructor. Uninitialized OptionalDeviceGuards do nothing; they do not know what the original device was and they do not reset on destruction. This is why original_device() and current_device() return optional<Device> rather than Device (as they do in DeviceGuard), and also is why we didn't just provide OptionalDeviceGuard by default and hide DeviceGuard from users.
The semantics of an OptionalDeviceGuard are exactly explained by thinking of it as an optional<DeviceGuard>. In particular, an initialized OptionalDeviceGuard doesn't restore device to its value at construction; it restores device to its value at initialization. So if you have the program:
setDevice(1); OptionalDeviceGuard g; setDevice(2); g.set_device(3); // initializes!
On destruction, g will reset device to 2, rather than 1.
An uninitialized OptionalDeviceGuard is distinct from a (initialized) DeviceGuard whose original_device_ and current_device_ match, since the DeviceGuard will still reset the device to original_device_.
Definition at line 119 of file DeviceGuard.h.
Initialize the guard if a Device is passed; otherwise leave the guard uninitialized.
Definition at line 129 of file DeviceGuard.h.
|
delete |
Move is disallowed See Note [Explicit initialization of optional fields] and // Note [Move construction for RAII guards is tricky] for rationale.
Returns the most recent device that was set using this device guard, either from construction, or via set_device.
Definition at line 163 of file DeviceGuard.h.
|
inline |
Sets the device to the given one.
The specified device must be consistent with the device type originally specified during guard construction.
Definition at line 147 of file DeviceGuard.h.