From 7da501ceb4f070119999177a1cc85ae5b8517105 Mon Sep 17 00:00:00 2001 From: Keck Jean-Baptiste <jean-baptiste.keck@imag.fr> Date: Sun, 21 May 2017 01:40:41 +0200 Subject: [PATCH] codegen refactoring --- hysop/backend/device/codegen/base/codegen.py | 38 +- .../device/codegen/base/struct_codegen.py | 2 +- .../backend/device/codegen/base/variables.py | 511 ++++++++++-------- .../codegen/kernels/directional_remesh.py | 42 +- .../device/opencl/opencl_array_backend.py | 14 +- 5 files changed, 333 insertions(+), 274 deletions(-) diff --git a/hysop/backend/device/codegen/base/codegen.py b/hysop/backend/device/codegen/base/codegen.py index b548213af..a4b397e59 100644 --- a/hysop/backend/device/codegen/base/codegen.py +++ b/hysop/backend/device/codegen/base/codegen.py @@ -120,8 +120,6 @@ class CodeGenerator(object): pass return self - - def to_file(self,folder,filename): dst_file = folder + '/' + filename if not os.path.exists(folder): @@ -186,7 +184,6 @@ class CodeGenerator(object): if k>0: self.code = self.code[:k] return self - def _noop(self): @@ -206,9 +203,9 @@ class CodeGenerator(object): def define(self,what,prepend=True): code = '#define {}'.format(what) self.append(code,simple=True) - def include(self,*kargs): + def include(self,*args): code = [] - for k in kargs: + for k in args: code.append('#include {}'.format(k)) return self.append(code) @@ -252,24 +249,13 @@ class CodeGenerator(object): else: self.append(code) - def decl_vars(self,_type,_varnames,_inits=None,comment=None,cv_qualifier=None): - if not isinstance(_varnames,list): - _varnames = [_varnames] - if _inits is not None and not isinstance(_inits,list): - _inits = [_inits] - - declvar = '' - if cv_qualifier: - declvar+=cv_qualifier+' ' - declvar += '{} '.format(_type) - if _inits: - declvar += ','.join(['{}={}'.format(v,i) for v,i in zip(_varnames,_inits)]) - else: - declvar += ','.join(_varnames) - declvar += ';' - if comment is not None: - declvar += ' /* {} */'.format(comment) - self.append(declvar) + def decl_vars(self, *variables): + assert len(set(var.base_ctype() for var in variables))==1 + base= variables[0].base_ctype() + svars=[] + for var in variables: + svars.append(var.declare(multidecl=True)) + return '{} {};'.format(base, ', '.join(svars)) class VarBlock(object): @@ -354,7 +340,11 @@ class CodeGenerator(object): maxlen = lambda i: max([len(line[i]) for line in self._lines if len(line)>1]) line_str = '' for i in xrange(self._parts_count): - line_str+='{:'+str(maxlen(i))+'}' + ml = maxlen(i) + if ml==0: + line_str+='{}' + else: + line_str+='{:'+str(ml)+'}' code = [] for line in self._lines: if len(line)>1: diff --git a/hysop/backend/device/codegen/base/struct_codegen.py b/hysop/backend/device/codegen/base/struct_codegen.py index 12f6754de..3a058366b 100644 --- a/hysop/backend/device/codegen/base/struct_codegen.py +++ b/hysop/backend/device/codegen/base/struct_codegen.py @@ -59,7 +59,7 @@ class StructCodeGenerator(OpenClCodeGenerator): i+=1 def build_codegen_variable(self,name,**kargs): - return CodegenStruct(varname=name, struct=self, **kargs) + return CodegenStruct(name=name, struct=self, **kargs) if __name__ == '__main__': diff --git a/hysop/backend/device/codegen/base/variables.py b/hysop/backend/device/codegen/base/variables.py index e8f47f9fc..430840bc2 100644 --- a/hysop/backend/device/codegen/base/variables.py +++ b/hysop/backend/device/codegen/base/variables.py @@ -1,9 +1,10 @@ from hysop.deps import np, re, copy +from hysop.tools.types import to_list, check_instance import hysop.backend.device.opencl.opencl_types from hysop.backend.device.codegen.base.utils import VarDict -from hysop.backend.device.opencl.opencl_types import OpenClTypeGen +from hysop.backend.device.opencl.opencl_types import TypeGen, OpenClTypeGen # opencl extras from hysop.backend.device.opencl.opencl_types import cl_type_to_dtype @@ -35,7 +36,7 @@ _ctype_to_dtype = { 'half': np.float16, 'float' : np.float32, 'double': np.float64, - 'long doube': np.longdouble, + 'long double': np.longdouble, } @@ -60,18 +61,77 @@ def register_ctype_dtype(ctype,dtype): _ctype_to_dtype[ctype] = dtype class CodegenVariable(object): - def __init__(self,name,ctype,typegen, - value=None, svalue=None, - const=False, add_impl_const=False, - storage=None, nl=None, - ptr=False, restrict=False, volatile=False, - init=None, + def __init__(self, name, ctype, typegen, + storage=None, const=False, volatile=False, + add_impl_const=False, nl=None, + ptr=False, ptr_restrict=None, ptr_volatile=None, ptr_const=None, + value=None, svalue=None, init=None, symbolic_mode=False,struct_var=None): + + check_instance(typegen, TypeGen) + + check_instance(name, str) + check_instance(ctype, str) + check_instance(storage, str, allow_none=True) + assert len(name)>0 + assert len(ctype)>0 + assert (storage is None) or len(ctype)>0 + + check_instance(const, bool) + check_instance(volatile, bool) + check_instance(add_impl_const, bool) + check_instance(nl, bool, allow_none=True) + + if const and add_impl_const: + msg='Variable {} is const and add_impl_const has been specified!' + msg=msg.format(name) + raise ValueError(msg) + + self.name = name + self.ctype = ctype + self.typegen = typegen + self.const = const + self.volatile = volatile + self.add_impl_const = add_impl_const + self.storage = storage - self.name = name - self.ctype = ctype - self.typegen = typegen + self.nl = nl if (nl is not None) else (storage is not None) + self.struct_var = struct_var + self.symbolic_mode = symbolic_mode + + # pointer + if isinstance(ptr,bool): + is_ptr = ptr + ptr_level = int(ptr) + else: + check_instance(ptr, (int, long)) + is_ptr = True + ptr_level = ptr + del ptr + + if is_ptr: + ptr_restrict = to_list(ptr_restrict) + ptr_const = to_list(ptr_const) + ptr_volatile = to_list(ptr_volatile) + _len = max(len(ptr_restrict), len(ptr_const), len(ptr_volatile)) + assert _len <= ptr_level + + ptr_restrict = np.asarray(ptr_restrict + [False]*(ptr_level-len(ptr_restrict))) + ptr_volatile = np.asarray(ptr_volatile + [False]*(ptr_level-len(ptr_volatile))) + ptr_const = np.asarray(ptr_const + [False]*(ptr_level-len(ptr_const))) + else: + assert ptr_restrict is None + assert ptr_volatile is None + assert ptr_const is None + + self.is_ptr = is_ptr + self.ptr_level = ptr_level + self.ptr_restrict = ptr_restrict + self.ptr_const = ptr_const + self.ptr_volatile = ptr_volatile + + # value and svalue if value is None: value = None elif np.isscalar(value): @@ -94,82 +154,129 @@ class CodegenVariable(object): value = value.copy() else: pass - + self.value = value self.svalue = svalue - - self.storage = storage - self.volatile = volatile - self.nl = nl if (nl is not None) else (storage is not None) - self.ptr = ptr - self.struct_var = struct_var - self.symbolic_mode = symbolic_mode self.init=init - - const = [const] if isinstance(const,bool) else list(const) - add_impl_const = [add_impl_const] if isinstance(add_impl_const,bool) \ - else list(add_impl_const) - restrict = [restrict] if isinstance(restrict,bool) else list(restrict) - _len = max(max(len(const),len(add_impl_const)), len(restrict)) - const = np.asarray(const + (_len-len(const))*[False], dtype=bool) - add_impl_const = np.asarray(add_impl_const + (_len-len(add_impl_const))*[False], - dtype=bool) - restrict = np.asarray(restrict + (_len-len(restrict))*[False], dtype=bool) - if (const.size != add_impl_const.size) or (const.size != restrict.size): - raise ValueError('const, add_impl_const, restrict size mismatch!') - if not ptr and restrict.any(): - raise ValueError('Non pointer types cannot be aliased!') - if not ptr and (const.size>1 or add_impl_const.size>1): - raise ValueError('Non pointer types cannot have multiple const qualifiers!') - if not ptr and np.logical_and(const, add_impl_const).any(): - raise ValueError('Variable {} is const and add_impl_const has been specified!'\ - .format(name)) - #if (struct_var is not None) and (struct_var.const) and (not const[0]): - #raise ValueError('Variable {} declared in const struct {} is not const!'.format(name,struct_var.name)) - self.const = const - self.add_impl_const = add_impl_const - self.restrict = restrict - + + def newvar(name, nl=False, + storage=None, value=None, svalue=None, init=None, + ctype=None, const=None, volatile=None, add_impl_const=None, + ptr=None, ptr_restrict=None, ptr_volatile=None, ptr_const=None): - def full_ctype(self, const=None, impl=False): + ctype = self.ctype if (ctype is None) else ctype const = self.const if (const is None) else const - ctype = self.ctype + volatile = self.volatile if (volatile is None) else volatile + add_impl_const = self.add_impl_const if (add_impl_const is None) else add_impl_const + storage = self.storage if (storage is None) else storage + + if ptr is None: + ptr = self.ptr if (ptr is None) else ptr + ptr_const = self.ptr_const if (ptr_const is None) else ptr_const + ptr_volatile = self.ptr_volatile if (ptr_volatile is None) else ptr_volatile + ptr_restrict = self.ptr_restrict if (ptr_restrict is None) else ptr_restrict + + return CodegenVariable(name=name, nl=nl, + value=value, svalue=svalue, init=init, + ctype=ctype, storage=storage, + const=const, volatile=volatile, + add_impl_const=add_impl_const, + ptr=ptr, ptr_restrict=ptr_restrict, + ptr_volatile=ptr_volatile, ptr_const=ptr_const) + + def pointer_alias(self, name, ctype, **kargs): + handle = self.newvar(name=name, ctype=ctype, + const=const, volatile=volatile, restrict=restrict, + init='({})({})'.format( + handle.full_ctype(disable_ptr_cv_qualifiers=True), self), + **kargs) + return handle - if not self.ptr: - if const or (impl and self.add_impl_const): - const = 'const ' - else: - const = '' + def pointer(self, name, ptr_level, + ptr_const=None, ptr_volatile=None, ptr_restrict=None, + add_impl_const=False, with_init=True, **kargs): + ptr_const = [False]*ptr_level if (ptr_const is None) else to_list(ptr_const) + ptr_volatile = [False]*ptr_level if (ptr_volatile is None) else to_list(ptr_volatile) + ptr_restrict = [False]*ptr_level if (ptr_restrict is None) else to_list(ptr_restrict) + assert ptr_level>0 + assert len(ptr_const) == ptr_level + assert len(ptr_volatile) == ptr_level + assert len(ptr_restrict) == ptr_level + if self.is_ptr: + ptr_level = self.ptr_level + ptr_level + ptr_const = self.ptr_const + ptr_const + ptr_volatile = self.ptr_volatile + ptr_volatile + ptr_restrict = self.ptr_restrict + ptr_restrict + if with_init: + init = '&{}'.format(self.name) else: - const = ' const' if const else ''#' '*6 - ctype += '{} *'.format(const) - if impl and self.add_impl_const: - ctype += 'const ' - const='' + init = None + return self.newvar(name=name, ptr=ptr_level, + ptr_const=ptr_const, ptr_volatile=ptr_volatile, + ptr_restrict=ptr_restrict, init=init, + add_impl_const=add_impl_const, **kargs) + + + def base_ctype(self, storage=None, ctype=None, + const=None, volatile=False, + impl=True, align=False): + storage = self.storage if (storage is None) else storage + ctype = self.ctype if (ctype is None) else ctype + volatile = self.volatile if (volatile is None) else volatile - restrict = 'restrict' if self.restrict else '' - storage = ('volatile ' if self.volatile else '') - storage += (self.storage + ' ') if self.storage else '' - return '{storage}{const}{ctype}{restrict}'.format(storage=storage, - restrict=restrict,const=const,ctype=ctype) - - def argument(self,impl,const=None): - name = self.name - nl = '\n' if self.nl else '' - return '{} {name}{nl}'.format(self.full_ctype(impl=impl,const=const),name=name,nl=nl) - - - def alias(self, name, ctype, - const=None, volatile=None, restrict=None): - handle = copy.copy(self) - handle.ctype = ctype - handle.name=name - handle.const = const if (const is not None) else handle.const - handle.volatile = volatile if (volatile is not None) else handle.volatile - handle.restrict = restrict if (restrict is not None) else handle.restrict - handle.init='({})({})'.format(handle.full_ctype(), self) - return handle + if (const is None): + const = self.const + if impl and (not self.is_ptr) and (not const): + const = self.add_impl_const + + base_ctype = '{storage}${ctype}${const}${volatile}'.format( + storage='{} '.format(storage) if (storage is not None) else '', + const='const ' if const else '', + volatile='volatile ' if volatile else '', + ctype=ctype+' ') + if not align: + base_ctype = base_ctype.replace('$','') + return base_ctype.strip() + def full_ctype(self, storage=None, ctype=None, const=None, volatile=False, + impl=True, multidecl=False, align=False, cast=False): + + if multidecl: + base_ctype = '' + else: + base_ctype = self.base_ctype(storage,ctype,const,volatile,impl,align) + + if self.is_ptr: + ptrs=[] + for i, (c,v,r) in enumerate(zip(self.ptr_const, self.ptr_volatile, self.ptr_restrict)): + if i==self.ptr_level-1: + c = c or (impl and self.add_impl_const) + ptr=' $*{const}${volatile}${restrict}'.format( + const = 'const ' if (c and not cast) else '', + volatile = 'volatile ' if (v and not cast) else '', + restrict = 'restrict ' if (r and not cast) else '') + ptrs.append(ptr) + ptr_ctype = ''.join(ptrs) + else: + ptr_ctype='' + + full_ctype = '{}{}'.format(base_ctype, ptr_ctype) + if not align: + full_ctype = full_ctype.replace('$', '') + else: + full_ctype = full_ctype.replace('$ ', '$') + + return full_ctype.strip() + + def argument(self,impl, + nl=None, name=None, + **kargs): + name = self.name if (name is None) else name + nl = self.nl if (nl is None) else nl + return '{} {name}{nl}'.format( + self.full_ctype(impl=impl, **kargs), + name=name, + nl='\n' if self.nl else '') def is_symbolic(self): return (self.value is None) or self.symbolic_mode @@ -197,7 +304,8 @@ class CodegenVariable(object): elif self.value is not None: return self.typegen.dump(self.value) else: - raise NotImplementedError() + msg='value and svalue are not defined.' + raise RuntimeError(msg) def access_prefix(self,access): acc = '' @@ -205,55 +313,15 @@ class CodegenVariable(object): acc += self.struct_var.access_prefix(access=True) acc += self.name if access: - acc += '->' if self.ptr else '.' + acc += '->' if self.is_ptr else '.' return acc - def declare(self,codegen=None,align=False, - const=None,restrict=None, - storage=None,init=None): - - storage = storage if (storage is not None) else self.storage - storage = '{} '.format(storage) if (storage is not None) else '' - storage = '{}{}'.format('volatile ' if self.volatile else '', storage) - - if const is not None: - self.const = np.asarray(self.const,bool) - const = (const,)+(False,)*(self.const.size-1) if isinstance(const,bool) else const - const = np.asarray(const,dtype=bool) - const = np.logical_or(const, self.const) - else: - const = self.const + def declare(self, codegen=None, align=False, + multidecl=False, const=None, init=None): - if restrict is not None: - restrict = (restrict,)+(False,)*(self.restrict.size-1) \ - if isinstance(restrict,bool) else restrict - restrict = np.asarray(restrict,dtype=bool) - restrict = np.logical_or(restrict, self.restrict) - else: - restrict = self.restrict + ctype = self.full_ctype(align=align,multidecl=multidecl,const=const) - if self.ptr: - if hasattr(self, 'sshape'): - sshape = self.sshape - qualifiers = ['[{}{}{}]'.format( - s, - (' const' if c else ''), - (' restrict' if r else '' )) - for (s,c,r) in zip(sshape,const,restrict)] - array_qualifiers = ''.join(qualifiers) - else: - qualifiers = [('const' if c else '') + (' restrict' if r else '' ) \ - for (c,r) in zip(const,restrict)] - impl_const = ' const' if self.add_impl_const[0] else '' - array_qualifiers = '{} *'.format(impl_const)+' *'.join(qualifiers) - - ctype = '{}{}'.format(self.ctype, array_qualifiers) - modifiers = storage - else: - ctype = self.ctype - modifiers = '{}{}'.format(storage,'' if not const else 'const ') - - + # static array ctype needs to be split split = ctype.split('[',1) ctype = split[0] is_static_array = len(split)==2 @@ -261,14 +329,18 @@ class CodegenVariable(object): name = self.name+name_suffix init = init if (init is not None) else self.init - code = '{}{} ${}'.format(modifiers, ctype, name) + code = '{} ${}'.format(ctype, name) + if (init is not None): code = '{} $= {}'.format(code,init) elif self.known(): self.force_symbolic(False) sval = self.sval() code = '{} $= {}'.format(code,sval) - code+=';' + + if not multidecl: + code+=';' + self.force_symbolic() if not align: @@ -277,123 +349,121 @@ class CodegenVariable(object): codegen.append(code) return code - def __call__(self): - return self.sval() def __getitem__(self,ss): - if self.ptr: + if self.is_ptr: return '{}[{}]'.format(self.name,ss) elif ss==0: return self.__call__() else: assert self.ptr, '{} is not a pointer!'.format(self.name) + def __repr__(self): if self.is_symbolic(): return '{}({})'.format(self.name,self.ctype) else: return '{}({},{})'.format(self.name,self.ctype,self.value) + + def __call__(self): + return self.sval() def __str__(self): return self.sval() class CodegenArray(CodegenVariable): @staticmethod - def initialize_rec(name,dim, - ctype, typegen, - shape,sshape,value,svalue, - const, add_impl_const, restrict, - symbolic_mode): + def _initialize_rec(name, typegen, + storage, ctype, const, volatile, + shape, sshape, value, svalue, + ptr_dim, ptr_restrict, ptr_const, ptr_volatile, + symbolic_mode): if (value is None): return value, svalue s0 = shape[0] - if dim==1: - _name = name - _value = value + + if ptr_dim==1: + _name = name + _value = value if (svalue is not None): _svalue = '{ ' + ', '.join(svalue) + ' }' else: - _const = const[1:] - _add_impl_const= add_impl_const[1:] - _restrict=restrict[1:] _shape = shape[1:] _sshape = sshape[1:] + _ptr_dim = ptr_dim - 1 + _ptr_const = ptr_const[:-1] + _ptr_restrict = ptr_restrict[:-1] + _ptr_volatile = ptr_volatile[:-1] + _value = [None]*s0 _svalue = [None]*s0 for d in xrange(s0): - _name = name+'_{}'.format(d) - val, sval = CodegenArray.initialize_rec(_name, - dim-1, ctype, typegen, - _shape, _sshape, value[d], svalue[d], - _const, _add_impl_const, _restrict, + _name = '{}_{}'.format(name, d) + _value = value[d] + _svalue = svalue[d] + val, sval = CodegenArray.initialize_rec(_name, typegen, + storage, ctype, const, volatile, + _shape, _sshape, _value, _svalue, + _ptr_dim, _ptr_restrict, _ptr_const, _ptr_volatile, symbolic_mode) - var = CodegenArray(name=_name, - ctype=ctype, typegen=typegen, - dim=dim-1, - shape=_shape, sshape=_sshape, - value=val, svalue=sval, - symbolic_mode=False, struct_var=None,direct_init=True) + var = CodegenArray(name=_name, typegen=typegen, + storage=storage, ctype=ctype, const=const, volatile=volatile, + shape=_shape, sshape=_sshape, value=val, svalue=sval, + dim=_ptr_dim, ptr_const=_ptr_const, + ptr_volatile=_ptr_volatile, ptr_restrict=_ptr_restrict, + add_impl_const=False, + symbolic_mode=False, + struct_var=None, + _direct_init=True) _value[d] = var _svalue[d] = '\n\t'.join(sval.split('\n')) - if svalue is not None: - _svalue = '{\n\t'+',\n\t'.join(_svalue)+'\n}' - else: + + if svalue is None: _svalue=None + else: + _svalue = '{\n\t'+',\n\t'.join(_svalue)+'\n}' return _value, _svalue - def __init__(self, name, ctype, typegen, - dim=1, + def __init__(self, name, ctype, typegen, + storage=None, volatile=False, const=False, add_impl_const = False, + dim=1, ptr_const=None, ptr_volatile=None, ptr_restrict=None, shape=None, sshape=None, value=None, svalue=None, - const=None, add_impl_const=None, - restrict=None, storage=None, symbolic_mode=False, struct_var=None, - direct_init=False): + _direct_init=False): + + ptr_dim = dim + del dim - if direct_init: + if _direct_init: _value, _svalue = value, svalue else: - if const is None: - const = (False,)*dim - elif const in [True,False]: - const = (const,)*dim - elif len(const)!= dim: - raise ValueError('const dim mismatch!') - const = np.asarray(const) - - if add_impl_const is None: - add_impl_const = (False,)*dim - elif add_impl_const in [True,False]: - add_impl_const = (add_impl_const,)*dim - elif len(add_impl_const)!= dim: - raise ValueError('add_impl_const dim mismatch!') - add_impl_const = np.asarray(add_impl_const) - - if restrict is None: - restrict = (False,)*dim - elif restrict in [True,False]: - restrict = (restrict,)*dim - elif len(restrict)!= dim: - raise ValueError('restrict dim mismatch!') - restrict = np.asarray(restrict) + ptr_const = [] if (ptr_const is None) else to_list(ptr_const) + ptr_volatile = [] if (ptr_volatile is None) else to_list(ptr_volatile) + ptr_restrict = [] if (ptr_restrict is None) else to_list(ptr_restrict) + ptr_const += [False]*(ptr_dim-len(ptr_const)) + ptr_volatile += [False]*(ptr_dim-len(ptr_volatile)) + ptr_restrict += [False]*(ptr_dim-len(ptr_restrict)) if (value is not None): value = np.asarray(value) - if value.ndim != dim: - raise ValueError('value array dim mismatch!') + if value.ndim != ptr_dim: + raise ValueError('value array dim mismatch.') if shape is None: shape = value.shape + else: + assert value.shape == shape, 'shape mismatch.' if (svalue is not None): svalue = np.asarray(svalue) if value is None: raise ValueError('value cannot be None when svalue is not None.') - if svalue.ndim != dim: + if svalue.ndim != ptr_dim: raise ValueError('svalue input array dimension mismatch!') if svalue.shape != value.shape: raise ValueError('Input array shape mismatch between value and svalue.') - elif value is not None: + elif (value is not None): svalue = np.zeros_like(value,dtype=object) dtype = ctype_to_dtype(ctype) sview = svalue.flat @@ -401,48 +471,49 @@ class CodegenArray(CodegenVariable): sview[i] = typegen.dump(v) if (shape is not None): - if len(shape)!=dim: + if len(shape)!=ptr_dim: raise ValueError('shape dim mismatch!') else: - shape = (None,)*dim + shape = (None,)*ptr_dim shape = np.asarray(shape) if (sshape is None) and (shape[0] != None): - sshape = [s.__str__() for s in shape] + sshape = [str(s) for s in shape] elif (sshape is not None) and len(sshape)!=dim: raise ValueError('sshape dim mismatch!') else: - sshape = (None,)*dim + sshape = (None,)*ptr_dim sshape = np.asarray(sshape) - _value, _svalue = CodegenArray.initialize_rec(name,dim, - ctype, typegen, shape, sshape, value, svalue, - const, add_impl_const, restrict, + _value, _svalue = CodegenArray._initialize_rec(name, typegen, + storage, ctype, const, volatile, + shape, sshape, value, svalue, + ptr_dim, ptr_restrict, ptr_const, ptr_volatile, symbolic_mode) - super(self.__class__, self).__init__(name=name, - ctype=ctype, typegen=typegen, + super(CodegenArray, self).__init__(name=name, + storage=storage, ctype=ctype, typegen=typegen, value=_value, svalue=_svalue, - const=const, add_impl_const=add_impl_const, - ptr=True,restrict=restrict, - symbolic_mode=symbolic_mode, struct_var=struct_var, - storage=storage) + const=const, add_impl_const=add_impl_const, volatile=volatile, + ptr=ptr_dim, ptr_restrict=ptr_restrict, ptr_const=ptr_const, ptr_volatile=ptr_volatile, + symbolic_mode=symbolic_mode, struct_var=struct_var) self.shape = shape self.sshape = sshape class CodegenVector(CodegenVariable): - def __init__(self,name,ctype,dim,typegen, + def __init__(self, name, ctype, dim, typegen, value=None,svalue=None, - const=False, add_impl_const=False, - storage=None, nl=None, - ptr=False, restrict=False, + storage=None, const=False, volatile=False, + ptr=False, ptr_const=None, ptr_volatile=None, ptr_restrict=None, + add_impl_const=False, nl=None, symbolic_mode=False, struct_var=None, init=None): super(CodegenVector,self).__init__(name=name,ctype=ctype,value=value,typegen=typegen, - const=const, add_impl_const=add_impl_const, - storage=storage, nl=nl, ptr=ptr, restrict=restrict, + const=const, volatile=volatile, add_impl_const=add_impl_const, + storage=storage, nl=nl, + ptr=ptr, ptr_const=ptr_const, ptr_volatile=ptr_volatile, ptr_restrict=ptr_restrict, symbolic_mode=symbolic_mode,struct_var=struct_var,init=init) self.value = value @@ -592,14 +663,14 @@ class CodegenVectorClBuiltin(CodegenVector): else: raise TypeError, 'Invalid key type!' - def declare(self,codegen=None,align=False,const=None,storage=None,init=None): + def declare(self,codegen=None,align=False,const=None,init=None): if isinstance(init,int): init = ','.join([self.typegen.dump(init) for _ in xrange(self.dim)]) init = '({})({})'.format(self.ctype,init) elif init.__class__ in [list,tuple,np.ndarray]: init = ','.join([self.typegen.dump(init[i]) for i in xrange(self.dim)]) init = '({})({})'.format(self.ctype,init) - return super(CodegenVectorClBuiltin,self).declare(codegen=codegen,align=align,const=const,storage=storage,init=init) + return super(CodegenVectorClBuiltin,self).declare(codegen=codegen,align=align,const=const,init=init) class CodegenVectorClBuiltinFunc(CodegenVectorClBuiltin): def __init__(self,fname,name,btype,dim,typegen, @@ -618,34 +689,32 @@ class CodegenVectorClBuiltinFunc(CodegenVectorClBuiltin): assert i<self.dim return 'get_{}({})'.format(self.fname,i) - def declare(self,codegen=None,align=False,const=None,storage=None,init=None): + def declare(self,codegen=None,align=False,const=None,init=None): if init is False: init = None else: init = self.fval() if not self.known() else init - return super(CodegenVectorClBuiltinFunc,self).declare(codegen=codegen,align=align,const=const,storage=storage,init=init) + return super(CodegenVectorClBuiltinFunc,self).declare(codegen=codegen,align=align, + const=const, init=init) class CodegenStruct(CodegenVariable): - def __init__(self,varname,struct, - ptr=False, restrict=False, - const=False, add_impl_const=False, - storage=None, nl=None, + def __init__(self, name, struct, + storage=None, const=False, volatile=False, + ptr=False, ptr_const=None, ptr_volatile=None, ptr_restrict=None, + add_impl_const=False, nl=None, symbolic_mode=False, struct_var=None, value=None, var_overrides=None): super(CodegenStruct,self).__init__( - name=varname, + name=name, ctype=struct.ctype, typegen=struct.typegen, + storage=storage, const=const, volatile=volatile, + ptr=ptr, ptr_const=ptr_const, ptr_volatile=ptr_volatile, ptr_restrict=ptr_restrict, + add_impl_const=add_impl_const, nl=nl, value=value, - const=const, - add_impl_const=add_impl_const, - storage=storage, - nl=nl, - ptr=ptr, - restrict=restrict, symbolic_mode=symbolic_mode, struct_var=struct_var) diff --git a/hysop/backend/device/codegen/kernels/directional_remesh.py b/hysop/backend/device/codegen/kernels/directional_remesh.py index 955b449cf..2aee3c016 100644 --- a/hysop/backend/device/codegen/kernels/directional_remesh.py +++ b/hysop/backend/device/codegen/kernels/directional_remesh.py @@ -64,8 +64,7 @@ class DirectionalRemeshKernel(KernelCodeGenerator): return int(1+math.ceil(scalar_cfl)+remesh_kernel.n/2) def __init__(self, typegen, work_dim, direction, ftype, - nparticles, nscalars, sboundary, - is_inplace, + nparticles, nscalars, sboundary, is_inplace, scalar_cfl, remesh_kernel, remesh_criteria_eps=None, use_atomics = False, @@ -80,19 +79,19 @@ class DirectionalRemeshKernel(KernelCodeGenerator): check_instance(sboundary[0],BoundaryCondition) check_instance(sboundary[1],BoundaryCondition) check_instance(remesh_kernel, RemeshKernel) - - known_vars = known_vars or dict() - itype = 'int' - vftype = tg.vtype(ftype, nparticles) - vitype = tg.vtype(itype, nparticles) - + assert sboundary[0] in [BoundaryCondition.PERIODIC, BoundaryCondition.NONE] assert sboundary[1] in [BoundaryCondition.PERIODIC, BoundaryCondition.NONE] is_periodic = (sboundary[0]==BoundaryCondition.PERIODIC \ and sboundary[1]==BoundaryCondition.PERIODIC) - + + known_vars = known_vars or dict() local_size_known = ('local_size' in known_vars) + itype = 'int' + vftype = tg.vtype(ftype, nparticles) + vitype = tg.vtype(itype, nparticles) + name = DirectionalRemeshKernel.codegen_name(work_dim, direction, remesh_kernel, ftype, nparticles,nscalars, remesh_criteria_eps, @@ -155,28 +154,28 @@ class DirectionalRemeshKernel(KernelCodeGenerator): kargs = ArgDict() self.position = OpenClArrayBackend.build_codegen_argument(kargs, name='position', storage=self._global, ctype=ftype, typegen=typegen, - restrict=True, const=True) + ptr_restrict=True, ptr_const=True) if is_inplace: self.scalars_in = tuple( OpenClArrayBackend.build_codegen_argument(kargs, name=' s{}_in'.format(i), storage=self._global, ctype=ftype, typegen=typegen, - restrict=True, const=False) for i in xrange(nscalars)) + ptr_restrict=True, ptr_const=False) for i in xrange(nscalars)) self.scalars_out = self.scalars_in else: self.scalars_in = tuple( OpenClArrayBackend.build_codegen_argument(kargs, name='s{}_in'.format(i), storage=self._global, ctype=ftype, typegen=typegen, - restrict=True, const=True) for i in xrange(nscalars)) + ptr_restrict=True, ptr_const=True) for i in xrange(nscalars)) self.scalars_out = tuple( OpenClArrayBackend.build_codegen_argument(kargs, name='s{}_out'.format(i), storage=self._global, ctype=ftype, typegen=typegen, - restrict=True, const=False) for i in xrange(nscalars)) + ptr_restrict=True, ptr_const=False) for i in xrange(nscalars)) if debug_mode: kargs['dbg0'] = CodegenVariable(storage=self._global,name='dbg0',ctype=itype, - typegen=typegen, restrict=True,ptr=True,const=False,add_impl_const=True) + typegen=typegen, ptr_restrict=True,ptr=True,const=False,add_impl_const=True) kargs['dbg1'] = CodegenVariable(storage=self._global,name='dbg1',ctype=itype, - typegen=typegen, restrict=True,ptr=True,const=False,add_impl_const=True) + typegen=typegen, ptr_restrict=True,ptr=True,const=False,add_impl_const=True) kargs['position_mesh_info'] = kernel_reqs['MeshInfoStruct'].build_codegen_variable( const=True, name='position_mesh_info') @@ -187,7 +186,7 @@ class DirectionalRemeshKernel(KernelCodeGenerator): if not local_size_known: kargs['buffer'] = CodegenVariable(storage=self._local, ctype=ftype, - add_impl_const=True, name='buffer', ptr=True, restrict=True, + add_impl_const=True, name='buffer', ptr=True, ptr_restrict=True, typegen=typegen, nl=False) return kargs @@ -256,7 +255,7 @@ class DirectionalRemeshKernel(KernelCodeGenerator): line_index = CodegenVariable(name='line_index', ctype=itype, typegen=tg) line_offset = CodegenVariable(name='line_offset', ctype=itype, typegen=tg,const=True) line_velocity = CodegenVariable(name='line_velocity', ctype=ftype, ptr=True, - storage='__global', restrict=True, const=True, add_impl_const=True, typegen=tg) + storage='__global', ptr_restrict=True, ptr_const=True, const=True, typegen=tg) position_global_id = CodegenVectorClBuiltin('pos_gid', itype, work_dim, typegen=tg) scalars_global_id = tuple(CodegenVectorClBuiltin('S{}_gid'.format(i), @@ -283,7 +282,7 @@ class DirectionalRemeshKernel(KernelCodeGenerator): buf = self.vars['buffer'] for i in xrange(nscalars): Si = CodegenVariable(name='S{}'.format(i),ctype=ftype,typegen=tg, - restrict=True, ptr=True, storage=self._local, + ptr_restrict=True, ptr=True, storage=self._local, const=True, init='{} + {}*{}'.format(buf,i,cache_width)) cached_scalars.append(Si) @@ -380,9 +379,10 @@ class DirectionalRemeshKernel(KernelCodeGenerator): sgid.declare(al,align=True) s.jumpline() - with s._align_() as al: - for var in cached_scalars: - var.declare(al,align=True); + #with s._align_() as al: + #for var in cached_scalars: + #var.declare(al,align=True); + s.decl_vars(*cached_scalars) s.jumpline() diff --git a/hysop/backend/device/opencl/opencl_array_backend.py b/hysop/backend/device/opencl/opencl_array_backend.py index 3609031bb..d53ee9498 100644 --- a/hysop/backend/device/opencl/opencl_array_backend.py +++ b/hysop/backend/device/opencl/opencl_array_backend.py @@ -2985,20 +2985,20 @@ class OpenClArrayBackend(ArrayBackend): assert 'add_impl_const' not in kargs assert 'init' not in kargs - args[base] = CodegenVariable(name=base, - typegen=typegen, ctype=ctype, ptr=ptr, const=const, + args[base] = CodegenVariable(name=base, typegen=typegen, + ctype=ctype, ptr=ptr, const=const, add_impl_const=True, nl=False, **kargs) args[offset] = CodegenVariable(name=offset, typegen=typegen, ctype=itype, - add_impl_const=True,nl=True) + add_impl_const=True, nl=True) - char_alias = args[base].alias(None, ctype='char', restrict=False, volatile=False).full_ctype() - ctype_alias = args[base].alias(None, ctype=ctype, restrict=False, volatile=False).full_ctype() + char_alias = args[base].full_ctype(ctype='char', cast=True) + ctype_alias = args[base].full_ctype(cast=True) init = '({})(({})({})+{})'.format(ctype_alias, char_alias, base, offset) - var = CodegenVariable(name=name, - typegen=typegen, ctype=ctype, ptr=ptr, const=const, + var = CodegenVariable(name=name, typegen=typegen, + ctype=ctype, ptr=ptr, const=const, add_impl_const=True, nl=False, init=init, **kargs) -- GitLab