提交 1ef3b616 authored 作者: Arnaud Bergeron's avatar Arnaud Bergeron

Add GpuKernelBase, a mixin class to help deal with kernels in C code for compyte.

上级 5bdeb8a3
......@@ -59,6 +59,87 @@ class HideC(object):
return self.c_code_cache_version()
class GpuKernelBase(object):
GpuKernelBase_version = 0
def c_kernel_code(self):
"""
Return the source code of the kernel.
"""
raise AttributeError("c_kernel_code", type(self))
def c_kernel_params(self):
"""
Return the list of typecodes for kernel parameters.
The list can contain strings ( "GA_BUFFER" ) or direct int values.
"""
raise AttributeError("c_kernel_params", type(self))
def c_kernel_name(self):
"""
Return the name of the kernel in the source.
"""
raise AttributeError("c_kernel_name", type(self))
def c_kernel_flags(self):
"""
Return a string representing the C flags for the kernel.
Example:
"GA_USE_CLUDA|GA_USE_DOUBLE"
self._get_kernel_flags(*dtypes) returns an appropritate string
for the result of this function.
"""
raise AttributeError("c_kernel_flags", type(self))
def c_kernel_codevar(self):
return 'kcode_' + type(self).__name__ + '_' + hex(hash(self))[2:]
def c_kernel_obj(self):
return 'k_' + type(self).__name__ + '_' + hex(hash(self))[2:]
def _get_kernel_flags(self, *dtypes):
dtypes = [numpy.dtype(d) for d in dtypes]
flags = ['GA_USE_CLUDA']
if any(d == numpy.float64 for d in dtypes):
flags.append('GA_USE_DOUBLE')
if any(d.itemsize < 4 for d in dtypes):
flags.append('GA_USE_SMALL')
return '|'.join(flags)
def c_headers(self):
return ['compyte/types.h']
def c_support_code(self):
kcode = self.c_kernel_code()
vname = self.c_kernel_codevar()
kname = self.c_kernel_obj()
code = '\\n'.join(l for l in kcode.split('\n'))
return """static const char *%(vname)s = "%(code)s";
static GpuKernel %(kname)s;""" % dict(vname=vname, kname=kname,code=code)
def c_init_code(self):
types = self.c_kernel_params()
numargs = len(types)
name = self.c_kernel_name()
vname = self.c_kernel_codevar()
kname = self.c_kernel_obj()
flags = self.c_kernel_flags()
# TODO: find a way to release the kernel once the module is unloaded
return ["""
int types[%(numargs)u] = {%(types)s};
if (GpuKernel_init(&%(kname)s, pygpu_default_context()->ops,
pygpu_default_context()->ctx, 1, &%(vname)s, NULL,
"%(name)s", %(numargs)s, types, %(flags)s) != GA_NO_ERROR) {
PyErr_SetString(PyExc_RuntimeError, "Error initializing kernel");
return;
}
""" % dict(types=','.join(types), numargs=numargs, kname=kname, name=name,
vname=vname, flags=flags)]
class HostFromGpu(Op):
def __eq__(self, other):
return type(self) == type(other)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论