clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name init.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-inlined-defensive-checks=false,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/pytorch/csa-scan,ctu-index-name=/tmp/pyrefcon/pytorch/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/pytorch/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fno-rounding-math -ffp-exception-behavior=ignore -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/pytorch/build -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem third_party/gloo -isystem ../cmake/../third_party/gloo -isystem ../cmake/../third_party/googletest/googlemock/include -isystem ../cmake/../third_party/googletest/googletest/include -isystem ../third_party/protobuf/src -isystem ../third_party/gemmlowp -isystem ../third_party/neon2sse -isystem ../third_party/XNNPACK/include -isystem ../third_party -isystem ../cmake/../third_party/eigen -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -isystem /usr/lib/python3/dist-packages/numpy/core/include -isystem ../cmake/../third_party/pybind11/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem ../third_party/ideep/mkl-dnn/include -isystem ../third_party/ideep/include -D BUILDING_TESTS -D FMT_HEADER_ONLY=1 -D HAVE_MALLOC_USABLE_SIZE=1 -D HAVE_MMAP=1 -D HAVE_SHM_OPEN=1 -D HAVE_SHM_UNLINK=1 -D MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS -D ONNXIFI_ENABLE_EXT=1 -D ONNX_ML=1 -D ONNX_NAMESPACE=onnx_torch -D THP_BUILD_MAIN_LIB -D USE_C10D -D USE_C10D_GLOO -D USE_C10D_MPI -D USE_DISTRIBUTED -D USE_EXTERNAL_MZCRC -D USE_NUMPY -D USE_RPC -D USE_TENSORPIPE -D USE_VALGRIND -D _FILE_OFFSET_BITS=64 -D torch_python_EXPORTS -I aten/src -I ../aten/src -I . -I ../ -I ../cmake/../third_party/benchmark/include -I caffe2/contrib/aten -I ../third_party/onnx -I third_party/onnx -I ../third_party/foxi -I third_party/foxi -I ../torch/.. -I ../torch/../aten/src -I ../torch/../aten/src/TH -I caffe2/aten/src -I third_party -I ../torch/../third_party/valgrind-headers -I ../torch/../third_party/gloo -I ../torch/../third_party/onnx -I ../torch/csrc -I ../torch/csrc/api/include -I ../torch/lib -I ../torch/lib/libshm -I ../torch/csrc/distributed -I ../torch/csrc/api -I ../c10/.. -I third_party/ideep/mkl-dnn/include -I ../third_party/ideep/mkl-dnn/src/../include -I ../torch/lib/libshm/../../../torch/lib -I ../third_party/fmt/include -D USE_PTHREADPOOL -D NDEBUG -D USE_KINETO -D LIBKINETO_NOCUPTI -D USE_FBGEMM -D USE_QNNPACK -D USE_PYTORCH_QNNPACK -D USE_XNNPACK -D SYMBOLICATE_MOBILE_DEBUG_HANDLE -D HAVE_AVX_CPU_DEFINITION -D HAVE_AVX2_CPU_DEFINITION -D NDEBUG -D NDEBUG -D CAFFE2_USE_GLOO -D HAVE_GCC_GET_CPUID -D USE_AVX -D USE_AVX2 -D TH_HAVE_THREAD -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-narrowing -Wall -Wextra -Werror=return-type -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-unused-local-typedefs -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-stringop-overflow -Wno-psabi -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -Wno-unused-but-set-variable -Wno-maybe-uninitialized -Werror=format -Werror=cast-function-type -Wno-stringop-overflow -Wno-write-strings -Wno-strict-aliasing -Wno-cast-function-type -w -std=gnu++14 -fdeprecated-macro -fdebug-compilation-dir=/tmp/pyrefcon/pytorch/build -ferror-limit 19 -fvisibility-inlines-hidden -fopenmp -fopenmp-cuda-parallel-target-regions -pthread -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -faligned-allocation -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/pytorch/csa-scan/reports -x c++ ../torch/csrc/distributed/autograd/init.cpp
| 1 | #include <torch/csrc/autograd/python_cpp_function.h> | 
| 2 | #include <torch/csrc/distributed/autograd/autograd.h> | 
| 3 | #include <torch/csrc/jit/python/pybind_utils.h> | 
| 4 | #include <torch/csrc/python_headers.h> | 
| 5 | #include <torch/csrc/utils/object_ptr.h> | 
| 6 | #include <torch/csrc/utils/pybind.h> | 
| 7 | #include <torch/types.h> | 
| 8 |   | 
| 9 | namespace torch { | 
| 10 | namespace distributed { | 
| 11 | namespace autograd { | 
| 12 |   | 
| 13 | namespace { | 
| 14 |   | 
| 15 | template <typename T> | 
| 16 | using shared_ptr_class_ = py::class_<T, std::shared_ptr<T>>; | 
| 17 |   | 
| 18 | PyObject* dist_autograd_init(PyObject* _unused, PyObject* noargs) { | 
| 19 |   auto autograd_module = | 
| 20 |       THPObjectPtr(PyImport_ImportModule("torch.distributed.autograd")); | 
 | 1  | Calling 'PyImport_ImportModule' |  |  
  | 
 | 3  |  | Returning from 'PyImport_ImportModule' |  |  
  | 
 | 8  |  | PyObject ownership leak with reference count of 1 |  
  | 
| 21 |   if (!autograd_module) { | 
 | 4  |  | Assuming the condition is false |  |  
  | 
 |  | 
| 22 |     throw python_error(); | 
| 23 |   } | 
| 24 |   | 
| 25 |   auto torch_C_module = THPObjectPtr(PyImport_ImportModule("torch._C")); | 
| 26 |   if (!torch_C_module) { | 
 | 6  |  | Assuming the condition is true |  |  
  | 
 |  | 
| 27 |     throw python_error(); | 
| 28 |   } | 
| 29 |   | 
| 30 |   auto torch_C_m = py::handle(torch_C_module).cast<py::module>(); | 
| 31 |   auto m = torch_C_m.def_submodule("_distributed_autograd", "distributed autograd bindings"); | 
| 32 |   | 
| 33 |   auto module = py::handle(m).cast<py::module>(); | 
| 34 |   | 
| 35 |   auto distAutogradContext = | 
| 36 |       shared_ptr_class_<DistAutogradContext>(module, "DistAutogradContext") | 
| 37 |           .def( | 
| 38 |               "_context_id", | 
| 39 |               &DistAutogradContext::contextId, | 
| 40 |               py::call_guard<py::gil_scoped_release>()) | 
| 41 |           .def( | 
| 42 |               "_recv_functions", | 
| 43 |               [](const DistAutogradContext& ctx) { | 
| 44 |                 std::map<int64_t, py::object> funcs; | 
| 45 |                 for (const auto& map_entry : ctx.recvFunctions()) { | 
| 46 |                   funcs.emplace( | 
| 47 |                       map_entry.first, | 
| 48 |                       py::reinterpret_steal<py::object>( | 
| 49 |                           torch::autograd::functionToPyObject( | 
| 50 |                               map_entry.second))); | 
| 51 |                 } | 
| 52 |                 return funcs; | 
| 53 |               }) | 
| 54 |           .def( | 
| 55 |               "_send_functions", | 
| 56 |               [](const ContextPtr& ctx) { | 
| 57 |                 std::map<int64_t, py::object> funcs; | 
| 58 |                 for (const auto& map_entry : ctx->sendFunctions()) { | 
| 59 |                   funcs.emplace( | 
| 60 |                       map_entry.first, | 
| 61 |                       py::reinterpret_steal<py::object>( | 
| 62 |                           torch::autograd::functionToPyObject( | 
| 63 |                               map_entry.second))); | 
| 64 |                 } | 
| 65 |                 return funcs; | 
| 66 |               }) | 
| 67 |           .def("_known_worker_ids", &DistAutogradContext::getKnownWorkerIds); | 
| 68 |   | 
| 69 |   module.def( | 
| 70 |       "_new_context", | 
| 71 |       []() -> const ContextPtr { | 
| 72 |         return DistAutogradContainer::getInstance().newContext(); | 
| 73 |       }, | 
| 74 |       py::return_value_policy::reference); | 
| 75 |   | 
| 76 |   module.def( | 
| 77 |       "_release_context", | 
| 78 |       [](int64_t context_id) { | 
| 79 |         return DistAutogradContainer::getInstance().releaseContext(context_id); | 
| 80 |       }, | 
| 81 |       py::call_guard<py::gil_scoped_release>()); | 
| 82 |   | 
| 83 |   module.def("_get_max_id", []() { | 
| 84 |     return DistAutogradContainer::getInstance().getMaxId(); | 
| 85 |   }); | 
| 86 |   | 
| 87 |   module.def( | 
| 88 |       "_is_valid_context", | 
| 89 |       [](int64_t worker_id) { | 
| 90 |         DistAutogradContainer::getInstance().isValidContext(worker_id); | 
| 91 |       }, | 
| 92 |       py::call_guard<py::gil_scoped_release>()); | 
| 93 |   | 
| 94 |   module.def( | 
| 95 |       "_retrieve_context", | 
| 96 |       [](int64_t context_id) -> const ContextPtr { | 
| 97 |         return DistAutogradContainer::getInstance().retrieveContext(context_id); | 
| 98 |       }, | 
| 99 |       py::return_value_policy::reference); | 
| 100 |   | 
| 101 |   module.def( | 
| 102 |       "_current_context", | 
| 103 |       []() -> const ContextPtr { | 
| 104 |         return DistAutogradContainer::getInstance().currentContext(); | 
| 105 |       }, | 
| 106 |       py::return_value_policy::reference); | 
| 107 |   | 
| 108 |   module.def( | 
| 109 |       "_init", | 
| 110 |       [](int64_t worker_id) { DistAutogradContainer::init(worker_id); }, | 
| 111 |       py::call_guard<py::gil_scoped_release>()); | 
| 112 |   | 
| 113 |   module.def( | 
| 114 |       "_get_debug_info", | 
| 115 |       []() { return DistEngine::getInstance().getDebugInfo(); }, | 
| 116 |       py::call_guard<py::gil_scoped_release>()); | 
| 117 |   | 
| 118 |   py::options options; | 
| 119 |   options.disable_function_signatures(); | 
| 120 |   | 
| 121 |   module.def( | 
| 122 |       "backward", | 
| 123 |       backward, | 
| 124 |       R"( | 
| 125 | backward(context_id: int, roots: List[Tensor], retain_graph = False) -> None | 
| 126 |   | 
| 127 | Kicks off the distributed backward pass using the provided roots. This | 
| 128 | currently implements the :ref:`fast-mode-algorithm` which | 
| 129 | assumes all RPC messages sent in the same distributed autograd context | 
| 130 | across workers would be part of the autograd graph during the backward pass. | 
| 131 |   | 
| 132 | We use the provided roots to discover the autograd graph and compute | 
| 133 | appropriate dependencies. This method blocks until the entire | 
| 134 | autograd computation is done. | 
| 135 |   | 
| 136 | We accumulate the gradients in the appropriate | 
| 137 | :class:`torch.distributed.autograd.context` on each of the nodes. The autograd | 
| 138 | context to be used is looked up given the ``context_id`` that is passed in when | 
| 139 | :meth:`torch.distributed.autograd.backward` is called. If there is no valid | 
| 140 | autograd context corresponding to the given ID, we throw an error. You can | 
| 141 | retrieve the accumulated gradients using the | 
| 142 | :meth:`~torch.distributed.autograd.get_gradients` API. | 
| 143 |   | 
| 144 | Arguments: | 
| 145 |     context_id (int): The autograd context id for which we should retrieve the gradients. | 
| 146 |     roots (list): Tensors which represent the roots of the autograd | 
| 147 |                   computation. All the tensors should be scalars. | 
| 148 |     retain_graph(bool, optional): If False, the graph used to compute the grad | 
| 149 |                   will be freed. Note that in nearly all cases setting this | 
| 150 |                   option to True is not needed and often can be worked around | 
| 151 |                   in a much more efficient way. Usually, you need to set this | 
| 152 |                   to True to run backward multiple times. | 
| 153 |   | 
| 154 | Example:: | 
| 155 |     >>> import torch.distributed.autograd as dist_autograd | 
| 156 |     >>> with dist_autograd.context() as context_id: | 
| 157 |     >>>     pred = model.forward() | 
| 158 |     >>>     loss = loss_func(pred, loss) | 
| 159 |     >>>     dist_autograd.backward(context_id, loss) | 
| 160 | )", | 
| 161 |       py::arg("contextId"), | 
| 162 |       py::arg("roots"), | 
| 163 |       py::arg("retain_graph") = false, | 
| 164 |       py::call_guard<py::gil_scoped_release>()); | 
| 165 |   | 
| 166 |   module.def( | 
| 167 |       "get_gradients", | 
| 168 |       [](int64_t contextId) -> py::dict { | 
| 169 |         const auto& autogradContext = | 
| 170 |             DistAutogradContainer::getInstance().retrieveContext(contextId); | 
| 171 |         return torch::jit::toPyObject(IValue(autogradContext->getGradients())); | 
| 172 |       }, | 
| 173 |       R"( | 
| 174 | get_gradients(context_id: int) -> Dict[Tensor, Tensor] | 
| 175 |   | 
| 176 | Retrieves a map from Tensor to the appropriate gradient for that Tensor | 
| 177 | accumulated in the provided context corresponding to the given ``context_id`` | 
| 178 | as part of the distributed autograd backward pass. | 
| 179 |   | 
| 180 | Arguments: | 
| 181 |     context_id(int): The autograd context id for which we should retrieve the | 
| 182 |                      gradients. | 
| 183 |   | 
| 184 | Returns: | 
| 185 |     A map where the key is the Tensor and the value is the associated gradient | 
| 186 |     for that Tensor. | 
| 187 |   | 
| 188 | Example:: | 
| 189 |     >>> import torch.distributed.autograd as dist_autograd | 
| 190 |     >>> with dist_autograd.context() as context_id: | 
| 191 |     >>>     t1 = torch.rand((3, 3), requires_grad=True) | 
| 192 |     >>>     t2 = torch.rand((3, 3), requires_grad=True) | 
| 193 |     >>>     loss = t1 + t2 | 
| 194 |     >>>     dist_autograd.backward(context_id, [loss.sum()]) | 
| 195 |     >>>     grads = dist_autograd.get_gradients(context_id) | 
| 196 |     >>>     print(grads[t1]) | 
| 197 |     >>>     print(grads[t2]) | 
| 198 | )", | 
| 199 |       py::arg("context_id")); | 
| 200 |   | 
| 201 |   Py_RETURN_TRUE; | 
| 202 | } | 
| 203 | }  | 
| 204 |   | 
| 205 | static PyMethodDef methods[] = {  | 
| 206 |     {"_dist_autograd_init", | 
| 207 |      dist_autograd_init, | 
| 208 |      METH_NOARGS, | 
| 209 |      nullptr}, | 
| 210 |     {nullptr, nullptr, 0, nullptr}}; | 
| 211 |   | 
| 212 | PyMethodDef* python_functions() { | 
| 213 |   return methods; | 
| 214 | } | 
| 215 |   | 
| 216 | }  | 
| 217 | }  | 
| 218 | }  |