@@ -81,6 +81,21 @@ signature.
81
81
- ` * ` is a special sentinel argument, which doesn't translate into an actual
82
82
argument, but indicates that in the Python bindings, any subsequent arguments
83
83
must be specified as keyword arguments (and cannot be provided positionally).
84
+ - ` ? ` is trailing question mark that annotate an argument to be an optional type, grep for
85
+ ` optional ` to find some example usages. In general, most functions will not need to use
86
+ this, but there are some cases that we want to use optional for the different types:
87
+ - You want to pass in a ` None ` to a ATen function/method from Python, and handles the
88
+ None type in the C++ side. For example, ` clamp(Tensor self, Scalar? min=None, Scalar? max=None) `
89
+ can take ` None ` for its ` min ` and ` max ` parameter, and do dispatch to different
90
+ backend if one of the parameters is ` None ` . Optional type can accept a ` None ` type
91
+ (` nullopt ` in C++) from Python and use the [ C++ Optional class] ( https://en.cppreference.com/w/cpp/utility/optional ) to interact with the parameters.
92
+ - You want a default value which is fine in Python but would cause ambiguity in C++.
93
+ For example, ` norm(Tensor self, Scalar p=2, int64_t dim, bool keepdim=false) ` would
94
+ cause ambiguity in C++ since it default args must be adjacent and ` p ` could not
95
+ have a default value when ` dim ` does not. Therefore, we need to make ` p ` as a
96
+ optional Scalar, and make ` p=2 ` when ` p ` is not passed in (nullopt).
97
+ - You want a value to default to the same value as another argument (this cannot be
98
+ expressed in C++ default arguments).
84
99
85
100
Functions with no tensor inputs are called * factory functions* , and
86
101
are handled specially by code generation. If your function is behaving
@@ -163,29 +178,6 @@ to unconditionally dispatch to a native function whose name is different than
163
178
the name in the public ATen API, but this is generally frowned upon (just name
164
179
them the same thing!)
165
180
166
- ### ` python_default_init `
167
-
168
- ```
169
- python_default_init:
170
- argument_name: initializing_expression
171
- ```
172
-
173
- A map from argument names to default initializing expressions written in C++. Such default
174
- expressions will only be used in Python API (in the C++ API, these arguments are
175
- mandatory).
176
-
177
- There are a few situations where you might like to use this functionality:
178
-
179
- - You want a default value which is fine in Python but would cause ambiguity in C++.
180
- For example, ` norm(Tensor self, real p=2, int64_t dim=1) ` would cause ambiguity
181
- with long tensors in C++. Therefore, we need to make ` p=2 ` a python only default
182
- initialization value.
183
-
184
- - You want a value to default to the same value as another argument (this cannot
185
- be expressed in C++ default arguments).
186
-
187
- If you grep for ` python_default_init ` , you can find examples of this being used;
188
- in general, most functions will not need to use this.
189
181
190
182
## Writing an implementation in C++
191
183
@@ -290,7 +282,7 @@ Tensor& s_add_(Tensor& self, const Tensor& other) {
290
282
291
283
By default, ` Tensor ` arguments to ATen functions are always defined, unless
292
284
you explicitly specified that an undefined tensor was permissible by writing
293
- ` Tensor? ` or ` Tensor x={} ` .
285
+ ` Tensor? ` or ` Tensor? x={} ` , the latter one is needed when you have to assign a default value in C++ (e.g. in the middle of other parameters with default values) .
294
286
295
287
The rules for returning undefined Tensors are a bit more subtle, but there
296
288
is only one case you have to remember:
0 commit comments