提交 ac23069f authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Fix scalar C code to enable use of [u]int64 on 32-bits platforms.

上级 d78bce89
...@@ -94,6 +94,7 @@ class Scalar(Type): ...@@ -94,6 +94,7 @@ class Scalar(Type):
def c_headers(self): def c_headers(self):
l=['<math.h>'] l=['<math.h>']
l.append('<numpy/arrayscalars.h>')
if config.lib.amdlibm: if config.lib.amdlibm:
l+=['<amdlibm.h>'] l+=['<amdlibm.h>']
return l return l
...@@ -117,18 +118,19 @@ class Scalar(Type): ...@@ -117,18 +118,19 @@ class Scalar(Type):
def dtype_specs(self): def dtype_specs(self):
try: try:
return {'float32': (numpy.float32, 'npy_float32', 'PyFloat_Check', 'PyFloat_AsDouble', 'PyFloat_FromDouble'), return {# dtype: (py_type, c_type, cls_name)
'float64': (numpy.float64, 'npy_float64', 'PyFloat_Check', 'PyFloat_AsDouble', 'PyFloat_FromDouble'), 'float32': (numpy.float32, 'npy_float32', 'Float32'),
'complex128': (numpy.complex128, 'theano_complex128', 'PyComplex_Check', 'PyComplex_AsCComplex', 'PyComplex_FromCComplex'), 'float64': (numpy.float64, 'npy_float64', 'Float64'),
'complex64': (numpy.complex64, 'theano_complex64', None, None, None), 'complex128': (numpy.complex128, 'theano_complex128', 'Complex128'),
'uint8': (numpy.uint8, 'npy_uint8', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong'), 'complex64': (numpy.complex64, 'theano_complex64', 'Complex64'),
'int8': (numpy.int8, 'npy_int8', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong'), 'uint8': (numpy.uint8, 'npy_uint8', 'UInt8'),
'uint16': (numpy.uint16, 'npy_uint16', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong'), 'int8': (numpy.int8, 'npy_int8', 'Int8'),
'int16': (numpy.int16, 'npy_int16', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong'), 'uint16': (numpy.uint16, 'npy_uint16', 'UInt16'),
'uint32': (numpy.uint32, 'npy_uint32', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong'), 'int16': (numpy.int16, 'npy_int16', 'Int16'),
'int32': (numpy.int32, 'npy_int32', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong'), 'uint32': (numpy.uint32, 'npy_uint32', 'UInt32'),
'uint64': (numpy.uint64, 'npy_uint64', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong'), 'int32': (numpy.int32, 'npy_int32', 'Int32'),
'int64': (numpy.int64, 'npy_int64', 'PyInt_Check', 'PyInt_AsLong', 'PyInt_FromLong') 'uint64': (numpy.uint64, 'npy_uint64', 'UInt64'),
'int64': (numpy.int64, 'npy_int64', 'Int64')
}[self.dtype] }[self.dtype]
except KeyError: except KeyError:
raise TypeError("Unsupported dtype for %s: %s" % (self.__class__.__name__, self.dtype)) raise TypeError("Unsupported dtype for %s: %s" % (self.__class__.__name__, self.dtype))
...@@ -163,37 +165,36 @@ class Scalar(Type): ...@@ -163,37 +165,36 @@ class Scalar(Type):
def c_extract(self, name, sub): def c_extract(self, name, sub):
specs = self.dtype_specs() specs = self.dtype_specs()
#TODO: This is the wrong code, but we don't know what to change it to.
# For example, a numpy.uint8 is not a PyInt, so PyInt_Check
# is simply the wrong function to
# call.
# Look at PyArrayScalar api for how to cast to/from PyArrayScalar objects.
# numpy.uint* numpy.float* are all constructors of PyArrayScalar objects.
#
return """ return """
if (!%(check)s(py_%(name)s)) if (!PyObject_TypeCheck(py_%(name)s, &%(pyarr_type)s))
{ {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"Scalar check failed"); "Scalar check failed (%(dtype)s)");
%(fail)s %(fail)s
} }
%(name)s = (%(dtype)s)%(conv)s(py_%(name)s); PyArray_ScalarAsCtype(py_%(name)s, &%(name)s);
""" % dict(sub, """ % dict(sub,
name = name, name = name,
dtype = specs[1], dtype = specs[1],
check = specs[2], pyarr_type = 'Py%sArrType_Type' % specs[2])
conv = specs[3])
def c_sync(self, name, sub): def c_sync(self, name, sub):
specs = self.dtype_specs() specs = self.dtype_specs()
return """ return """
Py_XDECREF(py_%(name)s); Py_XDECREF(py_%(name)s);
py_%(name)s = %(conv)s((%(dtype)s)%(name)s); py_%(name)s = PyArrayScalar_New(%(cls)s);
if (!py_%(name)s) if (!py_%(name)s)
{
Py_XINCREF(Py_None);
py_%(name)s = Py_None; py_%(name)s = Py_None;
PyErr_Format(PyExc_MemoryError,
"Instantiation of new Python scalar failed (%(dtype)s)");
%(fail)s
}
PyArrayScalar_ASSIGN(py_%(name)s, %(cls)s, %(name)s);
""" % dict(name = name, """ % dict(name = name,
dtype = specs[1], dtype = specs[1],
conv = specs[4]) cls = specs[2])
def c_cleanup(self, name, sub): def c_cleanup(self, name, sub):
return "" return ""
...@@ -330,6 +331,7 @@ class Scalar(Type): ...@@ -330,6 +331,7 @@ class Scalar(Type):
return "" return ""
def c_code_cache_version(self): def c_code_cache_version(self):
return (10, numpy.__version__) # Use the correct type checking and conversion functions
return (9, numpy.__version__) # Make operators work with 64 and 128 arguments at the same time return (9, numpy.__version__) # Make operators work with 64 and 128 arguments at the same time
return (8, numpy.__version__) # put const around operators and added unary '-' operator return (8, numpy.__version__) # put const around operators and added unary '-' operator
# no need to put lib.amdlibm here as c_compile_args() are put in the key. # no need to put lib.amdlibm here as c_compile_args() are put in the key.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论