mirror of
				https://github.com/pytorch/pytorch.git
				synced 2025-10-31 12:15:03 +08:00 
			
		
		
		
	Summary: * adds TORCH_API and AT_CUDA_API in places * refactor code generation Python logic to separate caffe2/torch outputs * fix hip and asan * remove profiler_cuda from hip * fix gcc warnings for enums * Fix PythonOp::Kind Pull Request resolved: https://github.com/pytorch/pytorch/pull/19554 Differential Revision: D15082727 Pulled By: kostmo fbshipit-source-id: 83a8a99717f025ab44b29608848928d76b3147a4
		
			
				
	
	
		
			249 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <torch/csrc/python_headers.h>
 | |
| #include <cstdarg>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| #include <sstream>
 | |
| #include <algorithm>
 | |
| #include <unordered_map>
 | |
| #include <torch/csrc/THP.h>
 | |
| #include <torch/csrc/utils/python_strings.h>
 | |
| #include <torch/csrc/utils/invalid_arguments.h>
 | |
| #include <torch/csrc/autograd/variable.h>
 | |
| #include <torch/csrc/DynamicTypes.h>
 | |
| 
 | |
| #include <torch/csrc/generic/utils.cpp>
 | |
| #include <TH/THGenerateAllTypes.h>
 | |
| 
 | |
| #include <torch/csrc/generic/utils.cpp>
 | |
| #include <TH/THGenerateHalfType.h>
 | |
| 
 | |
| #include <torch/csrc/WindowsTorchApiMacro.h>
 | |
| #include <torch/csrc/generic/utils.cpp>
 | |
| #include <TH/THGenerateBoolType.h>
 | |
| 
 | |
| int THPUtils_getCallable(PyObject *arg, PyObject **result) {
 | |
|   if (!PyCallable_Check(arg))
 | |
|     return 0;
 | |
|   *result = arg;
 | |
|   return 1;
 | |
| }
 | |
| 
 | |
| THLongStoragePtr THPUtils_unpackSize(PyObject *arg) {
 | |
|   THLongStoragePtr result;
 | |
|   if (!THPUtils_tryUnpackLongs(arg, result)) {
 | |
|     std::string msg = "THPUtils_unpackSize() expects a torch.Size (got '";
 | |
|     msg += Py_TYPE(arg)->tp_name;
 | |
|     msg += "')";
 | |
|     throw std::runtime_error(msg);
 | |
|   }
 | |
|   return result;
 | |
| }
 | |
| 
 | |
| bool THPUtils_tryUnpackLongs(PyObject *arg, THLongStoragePtr& result) {
 | |
|   bool tuple = PyTuple_Check(arg);
 | |
|   bool list = PyList_Check(arg);
 | |
|   if (tuple || list) {
 | |
|     int nDim = tuple ? PyTuple_GET_SIZE(arg) : PyList_GET_SIZE(arg);
 | |
|     THLongStoragePtr storage(THLongStorage_newWithSize(nDim));
 | |
|     for (int i = 0; i != nDim; ++i) {
 | |
|       PyObject* item = tuple ? PyTuple_GET_ITEM(arg, i) : PyList_GET_ITEM(arg, i);
 | |
|       if (!THPUtils_checkLong(item)) {
 | |
|         return false;
 | |
|       }
 | |
|       THLongStorage_set(storage, i, THPUtils_unpackLong(item));
 | |
|     }
 | |
|     result  = std::move(storage);
 | |
|     return true;
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| std::vector<int64_t> THPUtils_unpackLongs(PyObject *arg) {
 | |
|   bool tuple = PyTuple_Check(arg);
 | |
|   bool list = PyList_Check(arg);
 | |
|   if (tuple || list) {
 | |
|     int nDim = tuple ? PyTuple_GET_SIZE(arg) : PyList_GET_SIZE(arg);
 | |
|     std::vector<int64_t> sizes(nDim);
 | |
|     for (int i = 0; i != nDim; ++i) {
 | |
|       PyObject* item = tuple ? PyTuple_GET_ITEM(arg, i) : PyList_GET_ITEM(arg, i);
 | |
|       if (!THPUtils_checkLong(item)) {
 | |
|         std::ostringstream oss;
 | |
|         oss << "expected int at position " << i << ", but got: " << THPUtils_typename(item);
 | |
|         throw std::runtime_error(oss.str());
 | |
|       }
 | |
|       sizes[i] = THPUtils_unpackLong(item);
 | |
|     }
 | |
|     return sizes;
 | |
|   }
 | |
|   throw std::runtime_error("Expected tuple or list");
 | |
| }
 | |
| 
 | |
| bool THPUtils_tryUnpackLongVarArgs(PyObject *args, int ignore_first, THLongStoragePtr& result) {
 | |
|   Py_ssize_t length = PyTuple_Size(args) - ignore_first;
 | |
|   if (length < 1) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   PyObject *first_arg = PyTuple_GET_ITEM(args, ignore_first);
 | |
|   if (length == 1 && THPUtils_tryUnpackLongs(first_arg, result)) {
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   // Try to parse the numbers
 | |
|   result = THLongStorage_newWithSize(length);
 | |
|   for (Py_ssize_t i = 0; i < length; ++i) {
 | |
|     PyObject *arg = PyTuple_GET_ITEM(args, i + ignore_first);
 | |
|     if (!THPUtils_checkLong(arg)) {
 | |
|       return false;
 | |
|     }
 | |
|     THLongStorage_set(result, i, THPUtils_unpackLong(arg));
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool THPUtils_checkIntTuple(PyObject *arg)
 | |
| {
 | |
|   if (!PyTuple_Check(arg)) {
 | |
|     return false;
 | |
|   }
 | |
|   for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(arg); ++i) {
 | |
|     if (!THPUtils_checkLong(PyTuple_GET_ITEM(arg, i))) {
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| std::vector<int> THPUtils_unpackIntTuple(PyObject *arg)
 | |
| {
 | |
|   if (!THPUtils_checkIntTuple(arg)) {
 | |
|     throw std::runtime_error("Couldn't unpack int tuple");
 | |
|   }
 | |
|   std::vector<int> values(PyTuple_GET_SIZE(arg));
 | |
|   for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(arg); ++i) {
 | |
|     values[i] = (int)THPUtils_unpackLong(PyTuple_GET_ITEM(arg, i));
 | |
|   }
 | |
|   return values;
 | |
| }
 | |
| 
 | |
| void THPUtils_setError(const char *format, ...)
 | |
| {
 | |
|   static const size_t ERROR_BUFFER_SIZE = 1000;
 | |
|   char buffer[ERROR_BUFFER_SIZE];
 | |
|   va_list fmt_args;
 | |
| 
 | |
|   va_start(fmt_args, format);
 | |
|   vsnprintf(buffer, ERROR_BUFFER_SIZE, format, fmt_args);
 | |
|   va_end(fmt_args);
 | |
|   PyErr_SetString(PyExc_RuntimeError, buffer);
 | |
| }
 | |
| 
 | |
| void THPUtils_addPyMethodDefs(std::vector<PyMethodDef>& vector, PyMethodDef* methods)
 | |
| {
 | |
|   if (!vector.empty()) {
 | |
|     // remove nullptr terminator
 | |
|     vector.pop_back();
 | |
|   }
 | |
|   while (true) {
 | |
|     vector.push_back(*methods);
 | |
|     if (!methods->ml_name) {
 | |
|       break;
 | |
|     }
 | |
|     methods++;
 | |
|   }
 | |
| }
 | |
| 
 | |
| static const char* classOrTypename(PyObject* obj) {
 | |
|   if (PyType_Check(obj)) {
 | |
|     return ((PyTypeObject*)obj)->tp_name;
 | |
|   }
 | |
|   return Py_TYPE(obj)->tp_name;
 | |
| }
 | |
| 
 | |
| PyObject * THPUtils_dispatchStateless(
 | |
|     PyObject *tensor, const char *name, PyObject *args, PyObject *kwargs)
 | |
| {
 | |
|   THPObjectPtr methods(PyObject_GetAttrString(tensor, THP_STATELESS_ATTRIBUTE_NAME));
 | |
|   if (!methods) {
 | |
|     return PyErr_Format(
 | |
|         PyExc_TypeError,
 | |
|         "Type %s doesn't implement stateless methods",
 | |
|         classOrTypename(tensor));
 | |
|   }
 | |
|   THPObjectPtr method(PyObject_GetAttrString(methods, name));
 | |
|   if (!method) {
 | |
|     return PyErr_Format(
 | |
|         PyExc_TypeError,
 | |
|         "Type %s doesn't implement stateless method %s",
 | |
|         classOrTypename(tensor),
 | |
|         name);
 | |
|   }
 | |
|   return PyObject_Call(method.get(), args, kwargs);
 | |
| }
 | |
| 
 | |
| void THPUtils_invalidArguments(PyObject *given_args, PyObject *given_kwargs,
 | |
|         const char *function_name, size_t num_options, ...) {
 | |
|   std::vector<std::string> option_strings;
 | |
|   va_list option_list;
 | |
|   va_start(option_list, num_options);
 | |
|   for (size_t i = 0; i < num_options; i++)
 | |
|     option_strings.emplace_back(va_arg(option_list, const char*));
 | |
|   va_end(option_list);
 | |
| 
 | |
|   PyErr_SetString(PyExc_TypeError, torch::format_invalid_args(
 | |
|       given_args, given_kwargs, function_name, option_strings).c_str());
 | |
| }
 | |
| 
 | |
| template<>
 | |
| void THPPointer<THPGenerator>::free() {
 | |
|   if (ptr)
 | |
|     Py_DECREF(ptr);
 | |
| }
 | |
| 
 | |
| template class THPPointer<THPGenerator>;
 | |
| 
 | |
| static bool backCompatBroadcastWarn = false;
 | |
| 
 | |
| void setBackCompatBroadcastWarn(bool warn) {
 | |
|   backCompatBroadcastWarn = warn;
 | |
| }
 | |
| 
 | |
| bool getBackCompatBroadcastWarn() {
 | |
|   return backCompatBroadcastWarn;
 | |
| }
 | |
| 
 | |
| static bool backCompatKeepdimWarn = false;
 | |
| 
 | |
| void setBackCompatKeepdimWarn(bool warn) {
 | |
|   backCompatKeepdimWarn = warn;
 | |
| }
 | |
| 
 | |
| bool getBackCompatKeepdimWarn() {
 | |
|   return backCompatKeepdimWarn;
 | |
| }
 | |
| 
 | |
| bool maybeThrowBackCompatKeepdimWarn(char *func) {
 | |
|   if(getBackCompatKeepdimWarn()) {
 | |
|      std::ostringstream ss;
 | |
|      ss << "backwards compatibility: call to \"" << func
 | |
|         << "\" uses default value for keepdim which has changed default to False.  Consider passing as kwarg.",
 | |
|     PyErr_WarnEx(PyExc_UserWarning, ss.str().c_str(), 1);
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| template<>
 | |
| void THPPointer<THTensor>::free() {
 | |
|   if (ptr) {
 | |
|     THTensor_free(LIBRARY_STATE ptr);
 | |
|   }
 | |
| }
 | |
| 
 | |
| template<>
 | |
| void THPPointer<THPStorage>::free() {
 | |
|   if (ptr)
 | |
|     Py_DECREF(ptr);
 | |
| }
 | |
| 
 | |
| template class THPPointer<THPStorage>;
 |