提交 95531c52 authored 作者: abalkin's avatar abalkin

More python 3.x fixes:

* Use PyCapsule instead of PyCObject. * Use Python 3 module initialization. * Prepend 'm' to code hash to avoid module names that start with a digit.
上级 fe50ef92
...@@ -9,7 +9,7 @@ import os ...@@ -9,7 +9,7 @@ import os
import StringIO import StringIO
import sys import sys
from itertools import izip from itertools import izip
from six import PY3
import numpy import numpy
...@@ -17,7 +17,9 @@ if sys.version_info[:2] >= (3, 0): ...@@ -17,7 +17,9 @@ if sys.version_info[:2] >= (3, 0):
import hashlib import hashlib
def hash_from_code(msg): def hash_from_code(msg):
return hashlib.md5(msg.encode()).hexdigest() # Python 3 does not like module names that start with
# a digit.
return 'm' + hashlib.md5(msg.encode()).hexdigest()
elif sys.version_info[:2] >= (2, 5): elif sys.version_info[:2] >= (2, 5):
import hashlib import hashlib
...@@ -1232,19 +1234,25 @@ class CLinker(link.Linker): ...@@ -1232,19 +1234,25 @@ class CLinker(link.Linker):
# Static methods that can run and destroy the struct built by # Static methods that can run and destroy the struct built by
# instantiate. # instantiate.
if PY3:
static = """
int {struct_name}_executor({struct_name} *self) {{
return self->run();
}}
void {struct_name}_destructor(PyObject *capsule) {{
{struct_name} *self = ({struct_name} *)PyCapsule_GetContext(capsule);
delete self;
}}
""".format(struct_name=self.struct_name)
else:
static = """ static = """
int %(struct_name)s_executor(%(struct_name)s* self) { int %(struct_name)s_executor(%(struct_name)s* self) {
return self->run(); return self->run();
} }
void %(struct_name)s_destructor(void* executor, void* self) { void %(struct_name)s_destructor(void* executor, void* self) {
//printf("doing cleanup\\n");
//fflush(stdout);
// ((%(struct_name)s*)self)->cleanup();
// free(self);
delete ((%(struct_name)s*)self); delete ((%(struct_name)s*)self);
//printf("done cleanup\\n");
//fflush(stdout);
} }
""" % dict(struct_name=self.struct_name) """ % dict(struct_name=self.struct_name)
...@@ -1310,6 +1318,16 @@ class CLinker(link.Linker): ...@@ -1310,6 +1318,16 @@ class CLinker(link.Linker):
print >> code, ' }' print >> code, ' }'
print >> code, ' %(struct_name)s* struct_ptr = new %(struct_name)s();' % locals() print >> code, ' %(struct_name)s* struct_ptr = new %(struct_name)s();' % locals()
print >> code, ' struct_ptr->init(', ','.join('PyTuple_GET_ITEM(argtuple, %i)' % n for n in xrange(n_args)), ');' print >> code, ' struct_ptr->init(', ','.join('PyTuple_GET_ITEM(argtuple, %i)' % n for n in xrange(n_args)), ');'
if PY3:
print >> code, """\
PyObject* thunk = PyCapsule_New((void*)(&{struct_name}_executor), NULL, {struct_name}_destructor);
if (thunk != NULL && PyCapsule_SetContext(thunk, struct_ptr) != 0) {{
PyErr_Clear();
Py_DECREF(thunk);
thunk = NULL;
}}
""".format(**locals())
else:
print >> code, ' PyObject* thunk = PyCObject_FromVoidPtrAndDesc((void*)(&%(struct_name)s_executor), struct_ptr, %(struct_name)s_destructor);' % locals() print >> code, ' PyObject* thunk = PyCObject_FromVoidPtrAndDesc((void*)(&%(struct_name)s_executor), struct_ptr, %(struct_name)s_destructor);' % locals()
print >> code, " return thunk; }" print >> code, " return thunk; }"
return code.getvalue() return code.getvalue()
......
...@@ -13,7 +13,7 @@ import subprocess ...@@ -13,7 +13,7 @@ import subprocess
import sys import sys
import tempfile import tempfile
import time import time
from six import b, next from six import PY3, b, next
import distutils.sysconfig import distutils.sysconfig
...@@ -165,6 +165,22 @@ class DynamicModule(object): ...@@ -165,6 +165,22 @@ class DynamicModule(object):
print >> stream, "};" print >> stream, "};"
def print_init(self, stream): def print_init(self, stream):
if PY3:
print >> stream, """\
static struct PyModuleDef moduledef = {{
PyModuleDef_HEAD_INIT,
"{name}",
NULL,
-1,
MyMethods,
}};
""".format(name=self.name)
print >> stream, "PyMODINIT_FUNC PyInit_%s(void) {" % self.name
for b in self.init_blocks:
print >> stream, ' ', b
print >> stream, " PyObject *m = PyModule_Create(&moduledef);"
print >> stream, " return m;"
else:
print >> stream, "PyMODINIT_FUNC init%s(void){" % self.name print >> stream, "PyMODINIT_FUNC init%s(void){" % self.name
for b in self.init_blocks: for b in self.init_blocks:
print >> stream, ' ', b print >> stream, ' ', b
...@@ -1639,6 +1655,7 @@ class GCC_compiler(object): ...@@ -1639,6 +1655,7 @@ class GCC_compiler(object):
if py_module: if py_module:
#touch the __init__ file #touch the __init__ file
open(os.path.join(location, "__init__.py"), 'w').close() open(os.path.join(location, "__init__.py"), 'w').close()
assert os.path.isfile(lib_filename)
return dlimport(lib_filename) return dlimport(lib_filename)
......
import os import os
import sys import sys
from six import PY3
from theano.gof.compilelock import get_lock, release_lock from theano.gof.compilelock import get_lock, release_lock
from theano import config from theano import config
...@@ -38,8 +39,29 @@ def compile_cutils(): ...@@ -38,8 +39,29 @@ def compile_cutils():
{"run_cthunk", run_cthunk, METH_VARARGS|METH_KEYWORDS, {"run_cthunk", run_cthunk, METH_VARARGS|METH_KEYWORDS,
"Run a theano cthunk."}, "Run a theano cthunk."},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
};"""
if PY3:
# This is not the most efficient code, but it is written this way to highlight
# the changes needed to make 2.x code compile under python 3.
code = code.replace("<Python.h>", '"numpy/npy_3kcompat.h"', 1)
code = code.replace("PyCObject", "NpyCapsule")
code += """
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"cutils_ext",
NULL,
-1,
CutilsExtMethods,
}; };
PyMODINIT_FUNC
PyInit_cutils_ext(void) {
return PyModule_Create(&moduledef);
}
}
"""
else:
code += """
PyMODINIT_FUNC PyMODINIT_FUNC
initcutils_ext(void) initcutils_ext(void)
{ {
...@@ -68,7 +90,7 @@ try: ...@@ -68,7 +90,7 @@ try:
if not os.path.exists(location): if not os.path.exists(location):
os.mkdir(location) os.mkdir(location)
if not os.path.exists(os.path.join(location, '__init__.py')): if not os.path.exists(os.path.join(location, '__init__.py')):
file(os.path.join(location, '__init__.py'), 'w').close() open(os.path.join(location, '__init__.py'), 'w').close()
try: try:
from cutils_ext.cutils_ext import * from cutils_ext.cutils_ext import *
......
...@@ -1023,7 +1023,8 @@ static struct PyModuleDef moduledef = { ...@@ -1023,7 +1023,8 @@ static struct PyModuleDef moduledef = {
#endif #endif
#if defined(NPY_PY3K) #if defined(NPY_PY3K)
#define RETVAL m #define RETVAL m
PyObject *PyInit_lazylinker_ext(void) { PyMODINIT_FUNC
PyInit_lazylinker_ext(void) {
#else #else
#define RETVAL #define RETVAL
PyMODINIT_FUNC PyMODINIT_FUNC
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论