xref: /aosp_15_r20/external/pytorch/torch/csrc/README.md (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1*da0073e9SAndroid Build Coastguard Worker# csrc
2*da0073e9SAndroid Build Coastguard Worker
3*da0073e9SAndroid Build Coastguard WorkerThe csrc directory contains all of the code concerned with integration
4*da0073e9SAndroid Build Coastguard Workerwith Python.  This is in contrast to lib, which contains the Torch
5*da0073e9SAndroid Build Coastguard Workerlibraries that are Python agnostic.  csrc depends on lib, but not vice
6*da0073e9SAndroid Build Coastguard Workerversa.
7*da0073e9SAndroid Build Coastguard Worker
8*da0073e9SAndroid Build Coastguard WorkerThere are a number of utilities for easing integration with Python which
9*da0073e9SAndroid Build Coastguard Workerare worth knowing about, which we briefly describe here.  But the most
10*da0073e9SAndroid Build Coastguard Workerimportant gotchas:
11*da0073e9SAndroid Build Coastguard Worker
12*da0073e9SAndroid Build Coastguard Worker* DO NOT forget to take out the GIL with `pybind11::gil_scoped_acquire`
13*da0073e9SAndroid Build Coastguard Worker  before calling Python API or bringing a `THPObjectPtr` into scope.
14*da0073e9SAndroid Build Coastguard Worker
15*da0073e9SAndroid Build Coastguard Worker* Make sure you include `Python.h` first in your header files, before
16*da0073e9SAndroid Build Coastguard Worker  any system headers; otherwise, you will get `error: "_XOPEN_SOURCE" redefined`
17*da0073e9SAndroid Build Coastguard Worker  error.  If you pay attention to warnings, you will see where you need to
18*da0073e9SAndroid Build Coastguard Worker  do this.
19*da0073e9SAndroid Build Coastguard Worker
20*da0073e9SAndroid Build Coastguard Worker## Notes
21*da0073e9SAndroid Build Coastguard Worker
22*da0073e9SAndroid Build Coastguard Worker### Note [Storage is not nullptr]
23*da0073e9SAndroid Build Coastguard Worker
24*da0073e9SAndroid Build Coastguard WorkerHistorically, Torch supported nullptr storage, as a minor optimization to
25*da0073e9SAndroid Build Coastguard Workeravoid having to allocate a storage object when it would be empty.
26*da0073e9SAndroid Build Coastguard WorkerHowever, this is actually a confusing special case to deal with, so
27*da0073e9SAndroid Build Coastguard Workerby-in-large, PyTorch assumes that, in fact, storage is never nullptr.
28*da0073e9SAndroid Build Coastguard Worker
29*da0073e9SAndroid Build Coastguard WorkerOne important case where this assumption is important is when tracking
30*da0073e9SAndroid Build Coastguard Workerthe CUDA device a tensor is stored in: this information is stored
31*da0073e9SAndroid Build Coastguard Workersolely in the storage, so if a storage is nullptr, we lose this information.
32*da0073e9SAndroid Build Coastguard Worker
33*da0073e9SAndroid Build Coastguard WorkerAlthough storage is never nullptr, the data field of c10::StorageImpl may be
34*da0073e9SAndroid Build Coastguard Workernullptr.  This
35*da0073e9SAndroid Build Coastguard Workermostly occurs when we want to pre-allocate an output tensor struct, but then
36*da0073e9SAndroid Build Coastguard Workerhave it be resized and filled with data by some operator: there's no point in
37*da0073e9SAndroid Build Coastguard Workerallocating data for it in this case!
38*da0073e9SAndroid Build Coastguard Worker
39*da0073e9SAndroid Build Coastguard Worker## Files
40*da0073e9SAndroid Build Coastguard Worker
41*da0073e9SAndroid Build Coastguard Worker### `Exceptions.h`
42*da0073e9SAndroid Build Coastguard Worker
43*da0073e9SAndroid Build Coastguard WorkerFrequently when working with the Python API, you may call a function
44*da0073e9SAndroid Build Coastguard Workerwhich returns an error.  In this case, we want to return directly to the
45*da0073e9SAndroid Build Coastguard WorkerPython interpreter, so that this exception can be propagated
46*da0073e9SAndroid Build Coastguard Workeraccordingly; however, because the Python API is C-based, what actually
47*da0073e9SAndroid Build Coastguard Workerwill happen is it will return control to whatever C++ code called it.
48*da0073e9SAndroid Build Coastguard WorkerSimilarly, if we raise a C++ exception, prior to returning to the Python
49*da0073e9SAndroid Build Coastguard Workerinterpreter, we must set the Python error flags, so it turns into a C++
50*da0073e9SAndroid Build Coastguard Workerexception.
51*da0073e9SAndroid Build Coastguard Worker
52*da0073e9SAndroid Build Coastguard WorkerMoreover, when using the following macros, the generated warnings
53*da0073e9SAndroid Build Coastguard Workerwill be converted into python warnings that can be caught by the user.
54*da0073e9SAndroid Build Coastguard Worker
55*da0073e9SAndroid Build Coastguard WorkerExceptions define helpers for two main cases:
56*da0073e9SAndroid Build Coastguard Worker* For code where you write the python binding by hand, `HANDLE_TH_ERRORS`,
57*da0073e9SAndroid Build Coastguard Worker`END_HANDLE_TH_ERRORS` and an exception class `python_error`.  You call them like this:
58*da0073e9SAndroid Build Coastguard Worker
59*da0073e9SAndroid Build Coastguard Worker```
60*da0073e9SAndroid Build Coastguard Worker// Entry point from Python interpreter
61*da0073e9SAndroid Build Coastguard WorkerPyObject* run(PyObject* arg) {
62*da0073e9SAndroid Build Coastguard Worker  HANDLE_TH_ERRORS
63*da0073e9SAndroid Build Coastguard Worker  ...
64*da0073e9SAndroid Build Coastguard Worker  if (!x) throw python_error();
65*da0073e9SAndroid Build Coastguard Worker  // From c10/Exception.h
66*da0073e9SAndroid Build Coastguard Worker  TORCH_CHECK(cond, "cond was false here");
67*da0073e9SAndroid Build Coastguard Worker  TORCH_WARN("Warning message");
68*da0073e9SAndroid Build Coastguard Worker  ...
69*da0073e9SAndroid Build Coastguard Worker  END_HANDLE_TH_ERRORS
70*da0073e9SAndroid Build Coastguard Worker}
71*da0073e9SAndroid Build Coastguard Worker```
72*da0073e9SAndroid Build Coastguard Worker
73*da0073e9SAndroid Build Coastguard WorkerThe `HANDLE_TH_ERRORS` macro will catch all exceptions and convert them
74*da0073e9SAndroid Build Coastguard Workerinto an appropriate Python signal.  `python_error` is a special
75*da0073e9SAndroid Build Coastguard Workerexception which doesn't contain any info, instead it says, "An error
76*da0073e9SAndroid Build Coastguard Workeroccurred in the Python API; if you return to the interpreter, Python
77*da0073e9SAndroid Build Coastguard Workerwill raise that exception, nothing else needs to be done."
78*da0073e9SAndroid Build Coastguard Worker
79*da0073e9SAndroid Build Coastguard Worker* For code that you bind using pybind, `HANDLE_TH_ERRORS` and `END_HANDLE_TH_ERRORS_PYBIND`
80*da0073e9SAndroid Build Coastguard Workercan be used. They will work jointly with pybind error handling to raise
81*da0073e9SAndroid Build Coastguard Workerpytorch errors and warnings natively and let pybind handle other errors. It can be used as:
82*da0073e9SAndroid Build Coastguard Worker
83*da0073e9SAndroid Build Coastguard Worker```
84*da0073e9SAndroid Build Coastguard Worker// Function given to the pybind binding
85*da0073e9SAndroid Build Coastguard Workerat::Tensor foo(at::Tensor x) {
86*da0073e9SAndroid Build Coastguard Worker  HANDLE_TH_ERRORS
87*da0073e9SAndroid Build Coastguard Worker  ...
88*da0073e9SAndroid Build Coastguard Worker  if (!x) throw python_error();
89*da0073e9SAndroid Build Coastguard Worker  // pybind native error
90*da0073e9SAndroid Build Coastguard Worker  if (!x) throw py::value_error();
91*da0073e9SAndroid Build Coastguard Worker  // From c10/Exception.h
92*da0073e9SAndroid Build Coastguard Worker  TORCH_CHECK(cond, "cond was false here");
93*da0073e9SAndroid Build Coastguard Worker  TORCH_WARN("Warning message");
94*da0073e9SAndroid Build Coastguard Worker  ...
95*da0073e9SAndroid Build Coastguard Worker  END_HANDLE_TH_ERRORS_PYBIND
96*da0073e9SAndroid Build Coastguard Worker}
97*da0073e9SAndroid Build Coastguard Worker```
98*da0073e9SAndroid Build Coastguard Worker
99*da0073e9SAndroid Build Coastguard Worker
100*da0073e9SAndroid Build Coastguard Worker### GIL
101*da0073e9SAndroid Build Coastguard Worker
102*da0073e9SAndroid Build Coastguard WorkerWhenever you make any calls to the Python API, you must have taken out
103*da0073e9SAndroid Build Coastguard Workerthe Python GIL, as none of these calls are thread safe.
104*da0073e9SAndroid Build Coastguard Worker`pybind11::gil_scoped_acquire` is a RAII struct which handles taking and
105*da0073e9SAndroid Build Coastguard Workerreleasing the GIL.  Use it like this:
106*da0073e9SAndroid Build Coastguard Worker
107*da0073e9SAndroid Build Coastguard Worker```
108*da0073e9SAndroid Build Coastguard Workervoid iWantToUsePython() {
109*da0073e9SAndroid Build Coastguard Worker  pybind11::gil_scoped_acquire gil;
110*da0073e9SAndroid Build Coastguard Worker  ...
111*da0073e9SAndroid Build Coastguard Worker}
112*da0073e9SAndroid Build Coastguard Worker```
113*da0073e9SAndroid Build Coastguard Worker
114*da0073e9SAndroid Build Coastguard WorkerIn general, the compiler will NOT warn you if you use Python
115*da0073e9SAndroid Build Coastguard Workerfunctionality without taking out the GIL, so DO NOT FORGET this call.
116*da0073e9SAndroid Build Coastguard Worker
117*da0073e9SAndroid Build Coastguard Worker### `utils/object_ptr.h`
118*da0073e9SAndroid Build Coastguard Worker
119*da0073e9SAndroid Build Coastguard Worker`THPPointer` is a smart pointer class analogous to `std::shared_ptr`,
120*da0073e9SAndroid Build Coastguard Workerbut which is overloaded to handle reference counting scheme of various
121*da0073e9SAndroid Build Coastguard Workerobjects which are not based on `shared_ptr`.  The most important overloads are:
122*da0073e9SAndroid Build Coastguard Worker
123*da0073e9SAndroid Build Coastguard Worker* `PyObject` (so important we've aliased it as `THPObjectPtr`), which
124*da0073e9SAndroid Build Coastguard Worker  hooks into Python reference counting.  (By the way, that means you
125*da0073e9SAndroid Build Coastguard Worker  MUST take out the GIL before bringing one of these into scope!)
126*da0073e9SAndroid Build Coastguard Worker
127*da0073e9SAndroid Build Coastguard Worker* The various TH tensor and storage types (e.g., `THTensor`), which
128*da0073e9SAndroid Build Coastguard Worker  hook into TH's reference counting.  (TH's reference counting
129*da0073e9SAndroid Build Coastguard Worker  IS thread safe, no locks necessary.)
130