Add specialize() for cleaner specialization of CDefinition.
This commit is contained in:
parent
b5893d4ebb
commit
01054c726f
3 changed files with 39 additions and 21 deletions
|
|
@ -95,7 +95,7 @@ class ParallelUFunc(CDefinition):
|
||||||
|
|
||||||
which should be implemented in subclass or mixin.
|
which should be implemented in subclass or mixin.
|
||||||
'''
|
'''
|
||||||
_name_ = 'parallel_ufunc_%(ThreadCount)d'
|
#_name_ = 'parallel_ufunc_%(ThreadCount)d'
|
||||||
_argtys_ = [
|
_argtys_ = [
|
||||||
('func', C.void_p),
|
('func', C.void_p),
|
||||||
('worker', C.void_p),
|
('worker', C.void_p),
|
||||||
|
|
@ -105,8 +105,18 @@ class ParallelUFunc(CDefinition):
|
||||||
('data', C.void_p),
|
('data', C.void_p),
|
||||||
]
|
]
|
||||||
|
|
||||||
def body(self, func, worker, args, dimensions, steps, data, ThreadCount=1):
|
@classmethod
|
||||||
|
def specialize(cls, num_thread):
|
||||||
|
name = 'parallel_ufunc_%d' % num_thread
|
||||||
|
newcls = type(name, (cls,), {
|
||||||
|
'_name_' : name,
|
||||||
|
'ThreadCount': num_thread,
|
||||||
|
})
|
||||||
|
return newcls
|
||||||
|
|
||||||
|
def body(self, func, worker, args, dimensions, steps, data):
|
||||||
# Setup variables
|
# Setup variables
|
||||||
|
ThreadCount = self.ThreadCount
|
||||||
common = self.var(ContextCommon, name='common')
|
common = self.var(ContextCommon, name='common')
|
||||||
workqueues = self.array(WorkQueue, ThreadCount, name='workqueues')
|
workqueues = self.array(WorkQueue, ThreadCount, name='workqueues')
|
||||||
contexts = self.array(Context, ThreadCount, name='contexts')
|
contexts = self.array(Context, ThreadCount, name='contexts')
|
||||||
|
|
@ -318,9 +328,7 @@ class UFuncCore(CDefinition):
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class SpecializedParallelUFunc(CDefinition):
|
class SpecializedParallelUFunc(CDefinition):
|
||||||
_name_ = 'specialized_parallel_ufunc_%(ThreadCount)d_%(FuncName)s'
|
|
||||||
_argtys_ = [
|
_argtys_ = [
|
||||||
('args', C.pointer(C.char_p)),
|
('args', C.pointer(C.char_p)),
|
||||||
('dimensions', C.pointer(C.intp)),
|
('dimensions', C.pointer(C.intp)),
|
||||||
|
|
@ -328,15 +336,27 @@ class SpecializedParallelUFunc(CDefinition):
|
||||||
('data', C.void_p),
|
('data', C.void_p),
|
||||||
]
|
]
|
||||||
|
|
||||||
def body(self, args, dimensions, steps, data,
|
def body(self, args, dimensions, steps, data,):
|
||||||
PUFuncDef, CoreDef, Func, FuncName, ThreadCount=1):
|
pufunc = self.depends(self.PUFuncDef)
|
||||||
pufunc = self.depends(PUFuncDef, ThreadCount=ThreadCount)
|
core = self.depends(self.CoreDef)
|
||||||
core = self.depends(CoreDef)
|
func = self.depends(self.FuncDef)
|
||||||
func = self.depends(Func)
|
|
||||||
to_void_p = lambda x: x.cast(C.void_p)
|
to_void_p = lambda x: x.cast(C.void_p)
|
||||||
pufunc(to_void_p(func), to_void_p(core), args, dimensions, steps, data)
|
pufunc(to_void_p(func), to_void_p(core), args, dimensions, steps, data)
|
||||||
self.ret()
|
self.ret()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def specialize(cls, pufunc_def, core_def, func_def):
|
||||||
|
name = 'specialized_%s_%s_%s'% (pufunc_def._name_,
|
||||||
|
core_def._name_,
|
||||||
|
func_def._name_)
|
||||||
|
newcls = type(name, (cls,), {
|
||||||
|
'_name_' : name,
|
||||||
|
'PUFuncDef': pufunc_def,
|
||||||
|
'CoreDef' : core_def,
|
||||||
|
'FuncDef' : func_def,
|
||||||
|
})
|
||||||
|
return newcls
|
||||||
|
|
||||||
class PThreadAPI(CExternal):
|
class PThreadAPI(CExternal):
|
||||||
pthread_t = C.void_p
|
pthread_t = C.void_p
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ class UFuncCore_D_D(UFuncCore):
|
||||||
'''
|
'''
|
||||||
Specialize UFuncCore for double input, double output.
|
Specialize UFuncCore for double input, double output.
|
||||||
'''
|
'''
|
||||||
|
_name_ = UFuncCore._name_ + '_d_d'
|
||||||
def _do_work(self, common, item, tid):
|
def _do_work(self, common, item, tid):
|
||||||
ufunc_type = Type.function(C.double, [C.double])
|
ufunc_type = Type.function(C.double, [C.double])
|
||||||
ufunc_ptr = CFunc(self, common.func.cast(C.pointer(ufunc_type)).value)
|
ufunc_ptr = CFunc(self, common.func.cast(C.pointer(ufunc_type)).value)
|
||||||
|
|
@ -47,12 +48,10 @@ class Tester(CDefinition):
|
||||||
ArgCount = 2
|
ArgCount = 2
|
||||||
WorkCount = 10000
|
WorkCount = 10000
|
||||||
|
|
||||||
sppufunc = self.depends(SpecializedParallelUFunc,
|
PUfuncDef = ParallelUFuncPosix.specialize(num_thread=2)
|
||||||
PUFuncDef = ParallelUFuncPosix,
|
SPUF = SpecializedParallelUFunc.specialize(
|
||||||
CoreDef = UFuncCore_D_D,
|
PUfuncDef, UFuncCore_D_D, Work_D_D)
|
||||||
Func = Work_D_D,
|
sppufunc = self.depends(SPUF)
|
||||||
FuncName = Work_D_D._name_,
|
|
||||||
ThreadCount = 2)
|
|
||||||
|
|
||||||
# real work
|
# real work
|
||||||
NULL = self.constant_null(C.void_p)
|
NULL = self.constant_null(C.void_p)
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,11 @@ import numpy as np
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = Module.new(__name__)
|
module = Module.new(__name__)
|
||||||
sppufunc = SpecializedParallelUFunc.define(module,
|
PUfuncDef = ParallelUFuncPosix.specialize(num_thread=2)
|
||||||
PUFuncDef = ParallelUFuncPosix,
|
SPUF = SpecializedParallelUFunc.specialize(
|
||||||
CoreDef = UFuncCore_D_D,
|
PUfuncDef, UFuncCore_D_D, Work_D_D)
|
||||||
Func = Work_D_D,
|
sppufunc = SPUF.define(module)
|
||||||
FuncName = Work_D_D._name_,
|
|
||||||
ThreadCount = 2)
|
|
||||||
module.verify()
|
module.verify()
|
||||||
|
|
||||||
mpm = PassManager.new()
|
mpm = PassManager.new()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue