提交 31b7d309 authored 作者: Gabe Schwartz's avatar Gabe Schwartz

Updated CNDA to support the new C API in Python 3.

上级 0594b7f5
...@@ -294,10 +294,10 @@ static void ...@@ -294,10 +294,10 @@ static void
CudaNdarray_dealloc(CudaNdarray* self) CudaNdarray_dealloc(CudaNdarray* self)
{ {
if (0) std::cerr << "CudaNdarray dealloc " << self << " " << self->devdata << '\n'; if (0) std::cerr << "CudaNdarray dealloc " << self << " " << self->devdata << '\n';
if(self->ob_refcnt>1) if(Py_REFCNT(self) > 1)
printf("WARNING:CudaNdarray_dealloc called when there is still active reference to it.\n"); printf("WARNING:CudaNdarray_dealloc called when there is still active reference to it.\n");
CudaNdarray_uninit(self); CudaNdarray_uninit(self);
self->ob_type->tp_free((PyObject*)self); Py_TYPE(self)->tp_free((PyObject*)self);
--_outstanding_mallocs[1]; --_outstanding_mallocs[1];
if (0) if (0)
{ {
...@@ -461,9 +461,9 @@ PyObject* CudaNdarray_ZEROS(int n, int * dims) ...@@ -461,9 +461,9 @@ PyObject* CudaNdarray_ZEROS(int n, int * dims)
return (PyObject*) rval; return (PyObject*) rval;
} }
// declared as a static method (hence "dummy" is not used) // declared as a static method (hence 1st parameter is not used)
// Based on _Copy and _dimshuffle // Based on _Copy and _dimshuffle
PyObject* CudaNdarray_Zeros(PyObject* dummy, PyObject* shape) PyObject* CudaNdarray_Zeros(PyObject* _unused, PyObject* shape)
{ {
if(!shape) if(!shape)
{ {
...@@ -1226,7 +1226,7 @@ static PyMethodDef CudaNdarray_methods[] = ...@@ -1226,7 +1226,7 @@ static PyMethodDef CudaNdarray_methods[] =
(PyCFunction)CudaNdarray_DeepCopy, METH_O, (PyCFunction)CudaNdarray_DeepCopy, METH_O,
"Create a copy of this object"}, "Create a copy of this object"},
{"zeros", {"zeros",
(PyCFunction)CudaNdarray_Zeros, METH_STATIC, (PyCFunction)CudaNdarray_Zeros, METH_STATIC | METH_O,
"Create a new CudaNdarray with specified shape, filled with zeros."}, "Create a new CudaNdarray with specified shape, filled with zeros."},
{"copy", {"copy",
(PyCFunction)CudaNdarray_Copy, METH_NOARGS, (PyCFunction)CudaNdarray_Copy, METH_NOARGS,
...@@ -1817,6 +1817,49 @@ CudaNdarray_inplace_div(PyObject* py_self, PyObject * py_other) ...@@ -1817,6 +1817,49 @@ CudaNdarray_inplace_div(PyObject* py_self, PyObject * py_other)
return py_self; return py_self;
} }
// The PyNumberMethods struct layout changed in a non-trivial way from 2 to 3.
#if PY_MAJOR_VERSION == 3
static PyNumberMethods CudaNdarrayNumberMethods =
{
(binaryfunc)CudaNdarray_add, //binaryfunc nb_add; __add__
0, //binaryfunc nb_subtract;
0, //binaryfunc nb_multiply;
0, //binaryfunc nb_remainder;
0, //binaryfunc nb_divmod;
0, //ternaryfunc nb_power;
0, //unaryfunc nb_negative;
0, //unaryfunc nb_positive;
0, //unaryfunc nb_absolute;
0, //inquiry nb_bool;
0, //unaryfunc nb_invert;
0, //binaryfunc nb_lshift;
0, //binaryfunc nb_rshift;
0, //binaryfunc nb_and;
0, //binaryfunc nb_xor;
0, //binaryfunc nb_or;
0, //unaryfunc nb_int;
0, //void *nb_reserved;
0, //unaryfunc nb_float;
(binaryfunc)CudaNdarray_inplace_add, //binaryfunc nb_inplace_add; __iadd__
0, //binaryfunc nb_inplace_subtract;
0, //binaryfunc nb_inplace_multiply;
0, //binaryfunc nb_inplace_remainder;
0, //ternaryfunc nb_inplace_power;
0, //binaryfunc nb_inplace_lshift;
0, //binaryfunc nb_inplace_rshift;
0, //binaryfunc nb_inplace_and;
0, //binaryfunc nb_inplace_xor;
0, //binaryfunc nb_inplace_or;
0, //binaryfunc nb_floor_divide;
0, //binaryfunc nb_true_divide;
0, //binaryfunc nb_inplace_floor_divide;
(binaryfunc)CudaNdarray_inplace_div, //binaryfunc nb_inplace_true_divide; __idiv__
0, //unaryfunc nb_index
};
#else
static PyNumberMethods CudaNdarrayNumberMethods = static PyNumberMethods CudaNdarrayNumberMethods =
{ {
(binaryfunc)CudaNdarray_add, //binaryfunc nb_add; __add__ (binaryfunc)CudaNdarray_add, //binaryfunc nb_add; __add__
...@@ -1867,6 +1910,7 @@ static PyNumberMethods CudaNdarrayNumberMethods = ...@@ -1867,6 +1910,7 @@ static PyNumberMethods CudaNdarrayNumberMethods =
0 //unaryfunc nb_index; __index__ 0 //unaryfunc nb_index; __index__
#endif #endif
}; };
#endif
///////////////////// /////////////////////
...@@ -1970,7 +2014,7 @@ CudaNdarray_Subscript(PyObject * py_self, PyObject * key) ...@@ -1970,7 +2014,7 @@ CudaNdarray_Subscript(PyObject * py_self, PyObject * key)
int d_dim = CudaNdarray_HOST_DIMS(self)[0]; int d_dim = CudaNdarray_HOST_DIMS(self)[0];
Py_ssize_t start, stop, step, slen; Py_ssize_t start, stop, step, slen;
if (PySlice_GetIndicesEx((PySliceObject*)key, d_dim, &start, &stop, &step, &slen)) if (PySlice_GetIndicesEx(SLICE_CAST(key), d_dim, &start, &stop, &step, &slen))
{ {
if (verbose) if (verbose)
fprintf(stderr, "PySlice_GetIndicesEx failed\n"); fprintf(stderr, "PySlice_GetIndicesEx failed\n");
...@@ -2067,7 +2111,7 @@ CudaNdarray_Subscript(PyObject * py_self, PyObject * key) ...@@ -2067,7 +2111,7 @@ CudaNdarray_Subscript(PyObject * py_self, PyObject * key)
if (PySlice_Check(key_d)) if (PySlice_Check(key_d))
{ {
Py_ssize_t start, stop, step, slen; Py_ssize_t start, stop, step, slen;
if (PySlice_GetIndicesEx((PySliceObject*)key_d, CudaNdarray_HOST_DIMS(self)[d], &start, &stop, &step, &slen)) if (PySlice_GetIndicesEx(SLICE_CAST(key_d), CudaNdarray_HOST_DIMS(self)[d], &start, &stop, &step, &slen))
{ {
Py_DECREF(rval); Py_DECREF(rval);
return NULL; return NULL;
...@@ -2592,12 +2636,14 @@ static PyGetSetDef CudaNdarray_getset[] = { ...@@ -2592,12 +2636,14 @@ static PyGetSetDef CudaNdarray_getset[] = {
{NULL, NULL, NULL, NULL} /* Sentinel */ {NULL, NULL, NULL, NULL} /* Sentinel */
}; };
static PyTypeObject CudaNdarrayType = static PyTypeObject CudaNdarrayType =
{ {
#if PY_MAJOR_VERSION >= 3
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL) PyObject_HEAD_INIT(NULL)
0, /*ob_size*/ 0, /*ob_size*/
#endif
"CudaNdarray", /*tp_name*/ "CudaNdarray", /*tp_name*/
sizeof(CudaNdarray), /*tp_basicsize*/ sizeof(CudaNdarray), /*tp_basicsize*/
0, /*tp_itemsize*/ 0, /*tp_itemsize*/
...@@ -2616,7 +2662,12 @@ static PyTypeObject CudaNdarrayType = ...@@ -2616,7 +2662,12 @@ static PyTypeObject CudaNdarrayType =
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
#if PY_MAJOR_VERSION >= 3
// Py_TPFLAGS_CHECKTYPES is always true and was removed in Python 3.
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
#else
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
#endif
"CudaNdarray objects", /* tp_doc */ "CudaNdarray objects", /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
...@@ -3049,21 +3100,53 @@ static PyMethodDef module_methods[] = { ...@@ -3049,21 +3100,53 @@ static PyMethodDef module_methods[] = {
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void #define PyMODINIT_FUNC void
#endif #endif
#define CNDA_MOD_NAME "cuda_ndarray"
#define CNDA_DOCSTRING "CUDA implementation of a numpy ndarray-like object."
#if PY_MAJOR_VERSION == 3
static struct PyModuleDef cuda_ndarray_moduledef =
{
PyModuleDef_HEAD_INIT,
CNDA_MOD_NAME,
CNDA_DOCSTRING,
-1, /* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
module_methods
};
PyMODINIT_FUNC
PyInit_cuda_ndarray(void)
#else
PyMODINIT_FUNC PyMODINIT_FUNC
initcuda_ndarray(void) initcuda_ndarray(void)
#endif
{ {
import_array(); import_array();
PyObject* m; PyObject* m;
if (PyType_Ready(&CudaNdarrayType) < 0) if (PyType_Ready(&CudaNdarrayType) < 0) {
#if PY_MAJOR_VERSION == 3
return NULL;
#else
return; return;
#endif
}
m = Py_InitModule3("cuda_ndarray", module_methods, #if PY_MAJOR_VERSION == 3
"Example module that creates an extension type."); m = PyModule_Create(&cuda_ndarray_moduledef);
#else
m = Py_InitModule3(CNDA_MOD_NAME, module_methods, CNDA_DOCSTRING);
#endif
if (m == NULL) if (m == NULL) {
#if PY_MAJOR_VERSION == 3
return NULL;
#else
return; return;
#endif
}
Py_INCREF(&CudaNdarrayType); Py_INCREF(&CudaNdarrayType);
PyModule_AddObject(m, "CudaNdarray", (PyObject *)&CudaNdarrayType); PyModule_AddObject(m, "CudaNdarray", (PyObject *)&CudaNdarrayType);
...@@ -3088,6 +3171,10 @@ initcuda_ndarray(void) ...@@ -3088,6 +3171,10 @@ initcuda_ndarray(void)
std::cerr << "Error in SetDevice:" << cudaGetErrorString(err) << "\n"; std::cerr << "Error in SetDevice:" << cudaGetErrorString(err) << "\n";
} }
} }
#if PY_MAJOR_VERSION == 3
return m;
#endif
} }
...@@ -3106,7 +3193,7 @@ CudaNdarray_Check(const PyObject * ob) ...@@ -3106,7 +3193,7 @@ CudaNdarray_Check(const PyObject * ob)
int int
CudaNdarray_CheckExact(const PyObject * ob) CudaNdarray_CheckExact(const PyObject * ob)
{ {
return ((ob->ob_type == &CudaNdarrayType) ? 1 : 0); return ((Py_TYPE(ob) == &CudaNdarrayType) ? 1 : 0);
} }
PyObject * PyObject *
......
#ifndef _CUDA_NDARRAY_H #ifndef _CUDA_NDARRAY_H
#define _CUDA_NDARRAY_H #define _CUDA_NDARRAY_H
// Defines for Python 2/3 compatibility.
#if PY_MAJOR_VERSION == 3
// Py3k treats all ints as longs.
#define PyInt_Check PyLong_Check
#define PyInt_CheckExact PyLong_CheckExact
#define PyInt_AsLong PyLong_AsLong
#define PyInt_FromLong PyLong_FromLong
#define PyNumber_Int PyNumber_Long
// Py3k strings are unicode, these mimic old functionality.
#define PyString_Check PyUnicode_Check
#define PyString_FromString PyUnicode_FromString
#define PyString_AsString PyUnicode_AsUTF8
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
#define PyString_Size PyUnicode_GET_SIZE
#define PyCObject_AsVoidPtr NpyCapsule_AsVoidPtr
#define PyCObject_GetDesc NpyCapsule_GetDesc
#define PyCObject_Check NpyCapsule_Check
// Python 3 expects a PyObject* as the first argument to PySlice_GetIndicesEx().
#define SLICE_CAST(x) (x)
#else
// Python 2 expects a PySliceObject* as the first argument to PySlice_GetIndicesEx().
#define SLICE_CAST(x) ((PySliceObject*)(x))
#endif
#include <numpy/arrayobject.h> #include <numpy/arrayobject.h>
#include <stdio.h> #include <stdio.h>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论