pytorch/torch/csrc/generic/StorageMethods.cpp
Edward Yang 0a8c8c1dbe Rename real to scalar_t. (#11163)
Summary:
This is necessary to allow us to use the complex header
which defines real (and is very sad if real is macro'ed).

We should also fix accreal, ureal, Real and REAL, but
only 'real' is the real blocker.

```
codemod -d aten/src/TH --extensions c,cc,cpp,cu,cuh,h,TARGETS,py,hpp '\breal\b' scalar_t
codemod -d aten/src/THC --extensions c,cc,cpp,cu,cuh,h,TARGETS,py,hpp '\breal\b' scalar_t
codemod -d aten/src/THNN --extensions c,cc,cpp,cu,cuh,h,TARGETS,py,hpp '\breal\b' scalar_t
codemod -d aten/src/THCUNN --extensions c,cc,cpp,cu,cuh,h,TARGETS,py,hpp '\breal\b' scalar_t
```

Signed-off-by: Edward Z. Yang <ezyang@fb.com>
Pull Request resolved: https://github.com/pytorch/pytorch/pull/11163

Reviewed By: SsnL

Differential Revision: D9619906

Pulled By: ezyang

fbshipit-source-id: 922cb3a763c0bffecbd81200c1cefc6b8ea70942
2018-09-02 15:26:01 -07:00

321 lines
10 KiB
C++

#ifdef USE_CUDA
#include <cuda_runtime.h>
#endif
static PyObject * THPStorage_(size)(THPStorage *self)
{
HANDLE_TH_ERRORS
return PyLong_FromLong(THWStorage_(size)(LIBRARY_STATE self->cdata));
END_HANDLE_TH_ERRORS
}
#ifndef THD_GENERIC_FILE
static PyObject * THPStorage_(dataPtr)(THPStorage *self)
{
HANDLE_TH_ERRORS
return PyLong_FromVoidPtr(THWStorage_(data)(LIBRARY_STATE self->cdata));
END_HANDLE_TH_ERRORS
}
#endif
static PyObject * THPStorage_(copy_)(PyObject *self, PyObject *args, PyObject *kwargs)
{
HANDLE_TH_ERRORS
return THPStorageCopyMethod(THWStorage_(copy_functions), self, args, kwargs);
END_HANDLE_TH_ERRORS
}
#ifndef THD_GENERIC_FILE
static PyObject * THPStorage_(isPinned)(THPStorage *self)
{
HANDLE_TH_ERRORS
#if defined(USE_CUDA)
cudaPointerAttributes attr;
cudaError_t err = cudaPointerGetAttributes(&attr, THWStorage_(data)(LIBRARY_STATE self->cdata));
if (err != cudaSuccess) {
cudaGetLastError();
Py_RETURN_FALSE;
}
return PyBool_FromLong(attr.memoryType == cudaMemoryTypeHost);
#else
Py_RETURN_FALSE;
#endif
END_HANDLE_TH_ERRORS
}
#endif
static PyObject * THPStorage_(elementSize)(THPStorage *self)
{
HANDLE_TH_ERRORS
return PyLong_FromLong(THWStorage_(elementSize)(LIBRARY_STATE_NOARGS));
END_HANDLE_TH_ERRORS
}
static PyObject * THPStorage_(new)(THPStorage *self)
{
HANDLE_TH_ERRORS
THWStoragePtr new_storage(THWStorage_(new)(LIBRARY_STATE_NOARGS));
PyObject *_ret = THPStorage_(New)(new_storage);
new_storage.release();
return _ret;
END_HANDLE_TH_ERRORS
}
static PyObject * THPStorage_(resize_)(THPStorage *self, PyObject *number_arg)
{
HANDLE_TH_ERRORS
THPUtils_assert(THPUtils_checkLong(number_arg), "resize_ expects an int, "
"but got %s", THPUtils_typename(number_arg));
int64_t newsize = THPUtils_unpackLong(number_arg);
THWStorage_(resize)(LIBRARY_STATE self->cdata, newsize);
Py_INCREF(self);
return (PyObject*)self;
END_HANDLE_TH_ERRORS
}
static PyObject * THPStorage_(fill_)(THPStorage *self, PyObject *number_arg)
{
HANDLE_TH_ERRORS
THPUtils_assert(THPUtils_(checkReal)(number_arg), "fill_ expects %s, "
"but got %s", THPUtils_typeTraits<scalar_t>::python_type_str,
THPUtils_typename(number_arg));
THWStorage_(fill)(LIBRARY_STATE self->cdata, THPUtils_(unpackReal)(number_arg));
Py_INCREF(self);
return (PyObject*)self;
END_HANDLE_TH_ERRORS
}
#if !defined(THC_GENERIC_FILE) && !defined(THD_GENERIC_FILE)
static PyObject * THPStorage_(fromBuffer)(PyObject *_unused, PyObject *args, PyObject *keywds)
{
HANDLE_TH_ERRORS
PyObject *obj = nullptr;
const char* byte_order_str = nullptr;
Py_ssize_t count = -1, offset = 0;
Py_buffer buffer;
static char *kwlist[] = {"buffer", "byte_order", "count", "offset", nullptr};
const char* argtypes;
#if defined(TH_REAL_IS_BYTE) || defined(TH_REAL_IS_CHAR)
argtypes = "O|snn";
#else
argtypes = "Os|nn";
#endif
if (!PyArg_ParseTupleAndKeywords(args, keywds, argtypes, kwlist,
&obj, &byte_order_str, &count, &offset)) {
return nullptr;
}
#if !(defined(TH_REAL_IS_BYTE) || defined(TH_REAL_IS_CHAR))
THPByteOrder byte_order;
if (strcmp(byte_order_str, "native") == 0) {
byte_order = THP_nativeByteOrder();
} else if (strcmp(byte_order_str, "big") == 0) {
byte_order = THP_BIG_ENDIAN;
} else if (strcmp(byte_order_str, "little") == 0) {
byte_order = THP_LITTLE_ENDIAN;
} else {
PyErr_Format(PyExc_ValueError,
"invalid byte_order '%s' (expected 'big', 'little', or 'native')",
byte_order_str);
return nullptr;
}
#endif
if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0)
return nullptr;
if (offset < 0 || offset > buffer.len) {
PyErr_Format(PyExc_ValueError,
"offset must be non-negative and no greater than buffer length (%" PRId64 "), "
"but got %" PRId64, (int64_t)offset, (int64_t)buffer.len);
PyBuffer_Release(&buffer);
return nullptr;
}
if (count < 0) {
if ((buffer.len - offset) % sizeof(scalar_t) != 0) {
PyErr_Format(PyExc_ValueError, "buffer size (%" PRId64 ") must be a multiple "
"of element size (%" PRId64 ")", (int64_t)buffer.len, (int64_t)sizeof(scalar_t));
PyBuffer_Release(&buffer);
return nullptr;
}
count = (buffer.len - offset) / sizeof(scalar_t);
}
if (offset + (count * (Py_ssize_t)sizeof(scalar_t)) > buffer.len) {
PyErr_Format(PyExc_ValueError, "buffer has only %" PRId64 " elements after offset "
"%" PRId64 ", but specified a size of %" PRId64, (int64_t)(buffer.len - offset),
(int64_t)offset, (int64_t)count);
PyBuffer_Release(&buffer);
return nullptr;
}
uint8_t* src = (uint8_t*) buffer.buf;
THWStorage* storage = THWStorage_(newWithSize)(count);
#if defined(TH_REAL_IS_BYTE) || defined(TH_REAL_IS_CHAR)
memcpy(THWStorage_(data)(storage), src + offset, count);
#elif defined(TH_REAL_IS_SHORT)
THP_decodeInt16Buffer(THWStorage_(data)(storage), src + offset, byte_order, count);
#elif defined(TH_REAL_IS_INT)
THP_decodeInt32Buffer(THWStorage_(data)(storage), src + offset, byte_order, count);
#elif defined(TH_REAL_IS_LONG)
// TODO: remove the cast
THP_decodeInt64Buffer((int64_t*) THWStorage_(data)(storage), src + offset, byte_order, count);
#elif defined(TH_REAL_IS_HALF)
THP_decodeHalfBuffer(THWStorage_(data)(storage), src + offset, byte_order, count);
#elif defined(TH_REAL_IS_FLOAT)
THP_decodeFloatBuffer(THWStorage_(data)(storage), src + offset, byte_order, count);
#elif defined(TH_REAL_IS_DOUBLE)
THP_decodeDoubleBuffer(THWStorage_(data)(storage), src + offset, byte_order, count);
#else
#error "Unknown type"
#endif
PyBuffer_Release(&buffer);
return (PyObject*)THPStorage_(New)(storage);
END_HANDLE_TH_ERRORS
}
#endif
static PyObject * THPStorage_(fromFile)(PyObject *_unused, PyObject *args, PyObject *keywds)
{
HANDLE_TH_ERRORS
const char *filename;
Py_ssize_t size = 0;
int shared = 0;
static char *kwlist[] = {"filename", "shared", "size", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|in", kwlist,
&filename, &shared, &size)) {
return nullptr;
}
if (shared)
shared = TH_ALLOCATOR_MAPPED_SHARED;
THWStorage *storage = THWStorage_(newWithMapping)(LIBRARY_STATE filename, size, shared);
return (PyObject*)THPStorage_(New)(storage);
END_HANDLE_TH_ERRORS
}
#ifndef THD_GENERIC_FILE
PyObject * THPStorage_(writeFile)(THPStorage *self, PyObject *args)
{
HANDLE_TH_ERRORS
PyObject *file = PyTuple_GET_ITEM(args, 0);
bool is_real_file = PyTuple_GET_ITEM(args, 1) == Py_True;
if (!is_real_file) {
THPStorage_(writeFileRaw<PyObject*>)(self->cdata, file);
Py_RETURN_NONE;
}
int fd = PyObject_AsFileDescriptor(file);
THPUtils_assert(fd != -1, "_write_file couldn't retrieve a file descriptor "
"from given object");
THPStorage_(writeFileRaw)(self->cdata, fd);
Py_RETURN_NONE;
END_HANDLE_TH_ERRORS
}
PyObject * THPStorage_(newWithFile)(PyObject *_unused, PyObject *file)
{
HANDLE_TH_ERRORS
int fd = PyObject_AsFileDescriptor(file);
THPUtils_assert(fd != -1, "_new_with_file couldn't retrieve a file "
"descriptor from given object");
THWStorage *storage = THPStorage_(readFileRaw<int>)(fd, nullptr);
if (storage == nullptr)
return nullptr;
PyObject *result = THPStorage_(New)(storage);
return result;
END_HANDLE_TH_ERRORS
}
static PyObject *THPStorage_(setFromFile)(THPStorage *self, PyObject *args)
{
HANDLE_TH_ERRORS
PyObject *file = PyTuple_GET_ITEM(args, 0);
PyObject *offset = PyTuple_GET_ITEM(args, 1);
bool is_real_file = PyTuple_GET_ITEM(args, 2) == Py_True;
if (!is_real_file) {
// offset can be implemented with a call to the Python object's seek()
// but it is currently unnecessary to support this.
THPUtils_assert(offset == Py_None,
"_set_from_file: offset is NYI for filelike objects");
THWStorage *storage = THPStorage_(readFileRaw<PyObject*>)(file, self->cdata);
if (storage == nullptr) {
return nullptr;
}
Py_INCREF(self);
return (PyObject *) self;
}
// file is backed by a fd
int fd = PyObject_AsFileDescriptor(file);
if (offset != Py_None) {
lseek(fd, THPUtils_unpackLong(offset), SEEK_SET);
}
THPUtils_assert(fd != -1, "_set_from_file couldn't retrieve a file "
"descriptor from given object");
THWStorage *storage = THPStorage_(readFileRaw<int>)(fd, self->cdata);
if (storage == nullptr)
return nullptr;
Py_INCREF(self);
return (PyObject *) self;
END_HANDLE_TH_ERRORS
}
#endif // !defined(THD_GENERIC_FILE)
#ifdef THC_GENERIC_FILE
PyObject * THPStorage_(getDevice)(THPStorage *self)
{
HANDLE_TH_ERRORS
return PyLong_FromLong(THCStorage_(getDevice)(LIBRARY_STATE self->cdata));
END_HANDLE_TH_ERRORS
}
#endif
PyObject * THPStorage_(_setCdata)(THPStorage *self, PyObject *new_cdata)
{
HANDLE_TH_ERRORS
THPUtils_assert(THPUtils_checkLong(new_cdata), "given an invalid argument to "
"_set_cdata - expected an int or long, but got %s",
THPUtils_typename(new_cdata));
THWStorage *ptr = (THWStorage*)PyLong_AsVoidPtr(new_cdata);
THWStorage_(retain)(LIBRARY_STATE ptr);
THWStorage_(free)(LIBRARY_STATE self->cdata);
self->cdata = ptr;
Py_INCREF(self);
return (PyObject*)self;
END_HANDLE_TH_ERRORS
}
static PyMethodDef THPStorage_(methods)[] = {
{"copy_", (PyCFunction)THPStorage_(copy_), METH_VARARGS | METH_KEYWORDS, nullptr},
{"element_size", (PyCFunction)THPStorage_(elementSize), METH_NOARGS, nullptr},
{"fill_", (PyCFunction)THPStorage_(fill_), METH_O, nullptr},
{"new", (PyCFunction)THPStorage_(new), METH_NOARGS, nullptr},
{"resize_", (PyCFunction)THPStorage_(resize_), METH_O, nullptr},
{"size", (PyCFunction)THPStorage_(size), METH_NOARGS, nullptr},
#ifndef THD_GENERIC_FILE
{"data_ptr", (PyCFunction)THPStorage_(dataPtr), METH_NOARGS, nullptr},
{"is_pinned", (PyCFunction)THPStorage_(isPinned), METH_NOARGS, nullptr},
{"_write_file", (PyCFunction)THPStorage_(writeFile), METH_VARARGS, nullptr},
{"_new_with_file", (PyCFunction)THPStorage_(newWithFile), METH_O | METH_STATIC, nullptr},
{"_set_from_file", (PyCFunction)THPStorage_(setFromFile), METH_VARARGS, nullptr},
#endif // !defined(THD_GENERIC_FILE)
#if !defined(THC_GENERIC_FILE) && !defined(THD_GENERIC_FILE)
{"from_buffer", (PyCFunction)THPStorage_(fromBuffer), METH_VARARGS | METH_KEYWORDS | METH_STATIC, nullptr},
#endif
{"from_file", (PyCFunction)THPStorage_(fromFile), METH_VARARGS | METH_KEYWORDS | METH_STATIC, nullptr},
#ifdef THC_GENERIC_FILE
{"get_device", (PyCFunction)THPStorage_(getDevice), METH_NOARGS, nullptr},
#endif
{"_set_cdata", (PyCFunction)THPStorage_(_setCdata), METH_O, nullptr},
#ifndef THD_GENERIC_FILE
#endif
{nullptr}
};