diff --git a/llvm_cbuilder/builder.py b/llvm_cbuilder/builder.py index 661c2b1..3fce585 100644 --- a/llvm_cbuilder/builder.py +++ b/llvm_cbuilder/builder.py @@ -149,6 +149,13 @@ class CBuilder(object): func = mod.add_function(functype, name=name) return CBuilder(func) + def depends(self, cdef, **kwargs): + try: + func = cdef.define(self.function.module, **kwargs) + except NameError as e: + (func,) = e + return CFunc(self, func) + def printf(self, fmt, *args): mod = self.function.module int_t = lc.Type.int() @@ -429,7 +436,7 @@ class CDefinition(CBuilder): functype = lc.Type.function(cls._retty_, [v for k, v in cls._argtys_]) func = module.get_or_insert_function(functype, name=cls._name_) if not func.is_declaration: # already defined? - raise NameError('Function %s has already been defined' % cls._name_) + raise NameError(func) # Name all arguments for i, (name, _) in enumerate(cls._argtys_): diff --git a/parallel_vectorize.py b/parallel_vectorize.py index 25176b8..42aea26 100644 --- a/parallel_vectorize.py +++ b/parallel_vectorize.py @@ -87,8 +87,15 @@ class Context(CStruct): ] class ParallelUFunc(CDefinition): + ''' + Platform dependent threading function is implemented in + + def _dispatch_worker(self, worker, contexts, num_thread): + ... + + which should be implemented in subclass or mixin. + ''' _name_ = 'parallel_ufunc' - _retty_ = C.void _argtys_ = [ ('func', C.void_p), ('worker', C.void_p), @@ -182,13 +189,7 @@ class ParallelUFunc(CDefinition): cur_ctxt.completed.assign( self.constant_null(cur_ctxt.completed.type)) - def _dispatch_worker(self, worker, contexts, num_thread): - ''' - Dispatch worker threads. - ''' - raise NotImplementedError - -class ParallelUFuncPosix(ParallelUFunc): +class ParallelUFuncPosixMixin(object): ''' Implements _dispatch_worker to use pthread. ''' @@ -316,6 +317,16 @@ class UFuncCore(CDefinition): ''' raise NotImplementedError +class _SpecializedParallelUFunc(ParallelUFunc, ParallelUFuncPosixMixin): + _argtys_ = [ + ('args', C.pointer(C.char_p)), + ('dimensions', C.pointer(C.intp)), + ('steps', C.pointer(C.intp)), + ('data', C.void_p), + ] + + def body(self, args, dimensions, steps, data, ThreadCount=1): + pass class PThreadAPI(CExternal): pthread_t = C.void_p diff --git a/test_parallel_vectorize.py b/test_parallel_vectorize.py index fd7cc52..4fde372 100644 --- a/test_parallel_vectorize.py +++ b/test_parallel_vectorize.py @@ -30,6 +30,8 @@ class UFuncCore_D_D(UFuncCore): res = ufunc_ptr(indata.load()) outdata.store(res) +class ParallelUFuncPosix(ParallelUFunc, ParallelUFuncPosixMixin): + pass class Tester(CDefinition): ''' @@ -45,10 +47,10 @@ class Tester(CDefinition): ArgCount = 2 WorkCount = 10000 - parallel_ufunc = CFunc(self, ParallelUFuncPosix.define(module, - ThreadCount=ThreadCount)) - ufunc_core = CFunc(self, UFuncCore_D_D.define(module)) - worker = CFunc(self, Work_D_D.define(module)) + parallel_ufunc = self.depends(ParallelUFuncPosix, + ThreadCount=ThreadCount) + ufunc_core = self.depends(UFuncCore_D_D) + worker = self.depends(Work_D_D) # real work NULL = self.constant_null(C.void_p)