forked from pytorch/pytorch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStreamGuard.h
126 lines (102 loc) · 5.29 KB
/
StreamGuard.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#pragma once
#include <c10/impl/InlineStreamGuard.h>
namespace c10 {
/**
* A StreamGuard is an RAII class that changes the current device
* to the device corresponding to some stream, and changes the
* default stream on that device to be this stream.
*
* Use of StreamGuard is HIGHLY discouraged in operator definitions. In
* a single operator, you probably don't know enough about the global
* state of the world to profitably decide how to set streams. Let
* the caller handle this appropriately, and just use the current stream
* in your operator code.
*
* This StreamGuard does NOT have an uninitialized state; it is guaranteed
* to reset the stream and device on exit. If you are in a situation
* where you *might* want to setup a stream guard, see OptionalStreamGuard.
*/
struct StreamGuard {
/// No default constructor, see Note [Omitted default constructor from RAII]
explicit StreamGuard() = delete;
/// Set the current device to the device associated with the passed stream,
/// and set the current stream on that device to the passed stream.
explicit StreamGuard(Stream stream) : guard_(stream) {}
/// Copy is disallowed
StreamGuard(const StreamGuard&) = delete;
StreamGuard& operator=(const StreamGuard&) = delete;
/// Move is disallowed, as StreamGuard does not have an uninitialized state,
/// which is required for moves on types with nontrivial destructors.
StreamGuard(StreamGuard&& other) = delete;
StreamGuard& operator=(StreamGuard&& other) = delete;
/// Resets the currently set stream to the original stream and
/// the currently set device to the original device. Then,
/// set the current device to the device associated with the passed stream,
/// and set the current stream on that device to the passed stream.
///
/// NOTE: this implementation may skip some stream/device setting if
/// it can prove that it is unnecessary.
///
/// WARNING: reset_stream does NOT preserve previously set streams on
/// different devices. If you need to set streams on multiple devices
/// on , use MultiStreamGuard instead.
void reset_stream(Stream stream) { guard_.reset_stream(stream); }
/// Returns the stream that was set at the time the guard was constructed.
Stream original_stream() const {
return guard_.original_stream();
}
/// Returns the most recent stream that was set using this device guard,
/// either from construction, or via set_stream.
Stream current_stream() const {
return guard_.current_stream();
}
/// Returns the most recent device that was set using this device guard,
/// either from construction, or via set_device/reset_device/set_index.
Device current_device() const { return guard_.current_device(); }
/// Returns the device that was set at the most recent reset_stream(),
/// or otherwise the device at construction time.
Device original_device() const { return guard_.original_device(); }
private:
c10::impl::InlineStreamGuard<impl::VirtualGuardImpl> guard_;
};
/**
* An OptionalStreamGuard is an RAII class that sets a device to some value on
* initialization, and resets the device to its original value on destruction.
* See OptionalDeviceGuard for more guidance on how to use this class.
*/
struct OptionalStreamGuard {
/// Create an uninitialized guard.
explicit OptionalStreamGuard() : guard_() {}
/// Set the current device to the device associated with the passed stream,
/// and set the current stream on that device to the passed stream.
explicit OptionalStreamGuard(Stream stream) : guard_(stream) {}
/// Set the current device to the device associated with the passed stream,
/// and set the current stream on that device to the passed stream,
/// if the passed stream is not nullopt.
explicit OptionalStreamGuard(optional<Stream> stream_opt) : guard_(stream_opt) {}
/// Copy is disallowed
OptionalStreamGuard(const OptionalStreamGuard&) = delete;
OptionalStreamGuard& operator=(const OptionalStreamGuard&) = delete;
// See Note [Move construction for RAII guards is tricky]
OptionalStreamGuard(OptionalStreamGuard&& other) = delete;
// See Note [Move assignment for RAII guards is tricky]
OptionalStreamGuard& operator=(OptionalStreamGuard&& other) = delete;
/// Resets the currently set stream to the original stream and
/// the currently set device to the original device. Then,
/// set the current device to the device associated with the passed stream,
/// and set the current stream on that device to the passed stream.
/// Initializes the guard if it was not previously initialized.
void reset_stream(Stream stream) { guard_.reset_stream(stream); }
/// Returns the stream that was set at the time the guard was most recently
/// initialized, or nullopt if the guard is uninitialized.
optional<Stream> original_stream() const { return guard_.original_stream(); }
/// Returns the most recent stream that was set using this stream guard,
/// either from construction, or via reset_stream, if the guard is initialized,
/// or nullopt if the guard is uninitialized.
optional<Stream> current_stream() const { return guard_.current_stream(); }
/// Restore the original device and stream, resetting this guard to uninitialized state.
void reset() { guard_.reset(); }
private:
c10::impl::InlineOptionalStreamGuard<impl::VirtualGuardImpl> guard_;
};
} // namespace c10