def get_cpp_dtype(obj): return cpp_dtype[get_dtype_str(obj)]
def get_numpy_dtype(obj): return numpy_dtype[get_dtype_str(obj)]
def determine_keywords(self): from brian2.devices.device import get_device device = get_device() # load variables from namespace load_namespace = [] support_code = [] handled_pointers = set() user_functions = [] for varname, var in sorted(self.variables.items()): if isinstance(var, Variable) and not isinstance( var, (Subexpression, AuxiliaryVariable)): load_namespace.append( '_var_{0} = _namespace["_var_{1}"]'.format( varname, varname)) if isinstance(var, AuxiliaryVariable): line = "cdef {dtype} {varname}".format(dtype=get_cpp_dtype( var.dtype), varname=varname) load_namespace.append(line) elif isinstance(var, Subexpression): dtype = get_cpp_dtype(var.dtype) line = "cdef {dtype} {varname}".format(dtype=dtype, varname=varname) load_namespace.append(line) elif isinstance(var, Constant): dtype_name = get_cpp_dtype(var.value) line = 'cdef {dtype} {varname} = _namespace["{varname}"]'.format( dtype=dtype_name, varname=varname) load_namespace.append(line) elif isinstance(var, Variable): if var.dynamic: load_namespace.append('{0} = _namespace["{1}"]'.format( self.get_array_name(var, False), self.get_array_name(var, False))) # This is the "true" array name, not the restricted pointer. array_name = device.get_array_name(var) pointer_name = self.get_array_name(var) if pointer_name in handled_pointers: continue if getattr(var, 'ndim', 1) > 1: continue # multidimensional (dynamic) arrays have to be treated differently if get_dtype_str(var.dtype) == 'bool': newlines = [ "cdef _numpy.ndarray[char, ndim=1, mode='c', cast=True] _buf_{array_name} = _namespace['{array_name}']", "cdef {cpp_dtype} * {array_name} = <{cpp_dtype} *> _buf_{array_name}.data" ] else: newlines = [ "cdef _numpy.ndarray[{cpp_dtype}, ndim=1, mode='c'] _buf_{array_name} = _namespace['{array_name}']", "cdef {cpp_dtype} * {array_name} = <{cpp_dtype} *> _buf_{array_name}.data" ] if not var.scalar: newlines += [ "cdef int _num{array_name} = len(_namespace['{array_name}'])" ] if var.scalar and var.constant: newlines += [ 'cdef {cpp_dtype} {varname} = _namespace["{varname}"]' ] else: newlines += ["cdef {cpp_dtype} {varname}"] for line in newlines: line = line.format( cpp_dtype=get_cpp_dtype(var.dtype), numpy_dtype=get_numpy_dtype(var.dtype), pointer_name=pointer_name, array_name=array_name, varname=varname, ) load_namespace.append(line) handled_pointers.add(pointer_name) elif isinstance(var, Function): sc, ln, uf = self._add_user_function(varname, var) support_code.extend(sc) load_namespace.extend(ln) user_functions.extend(uf) else: # fallback to Python object load_namespace.append('{0} = _namespace["{1}"]'.format( varname, varname)) for varname, dtype in sorted(self.temporary_vars): cpp_dtype = get_cpp_dtype(dtype) line = "cdef {cpp_dtype} {varname}".format(cpp_dtype=cpp_dtype, varname=varname) load_namespace.append(line) return { 'load_namespace': '\n'.join(load_namespace), 'support_code_lines': support_code }
def get_numpy_dtype(obj): return numpy_dtype[get_dtype_str(obj)]
def get_cpp_dtype(obj): return cpp_dtype[get_dtype_str(obj)]
def determine_keywords(self): from brian2.devices.device import get_device device = get_device() # load variables from namespace load_namespace = [] support_code = [] handled_pointers = set() user_functions = [] for varname, var in self.variables.items(): if isinstance(var, Variable) and not isinstance(var, (Subexpression, AuxiliaryVariable)): load_namespace.append('_var_{0} = _namespace["_var_{1}"]'.format(varname, varname)) if isinstance(var, AuxiliaryVariable): line = "cdef {dtype} {varname}".format( dtype=get_cpp_dtype(var.dtype), varname=varname) load_namespace.append(line) elif isinstance(var, Subexpression): dtype = get_cpp_dtype(var.dtype) line = "cdef {dtype} {varname}".format(dtype=dtype, varname=varname) load_namespace.append(line) elif isinstance(var, Constant): dtype_name = get_cpp_dtype(var.value) line = 'cdef {dtype} {varname} = _namespace["{varname}"]'.format(dtype=dtype_name, varname=varname) load_namespace.append(line) elif isinstance(var, Variable): if var.dynamic: load_namespace.append('{0} = _namespace["{1}"]'.format(self.get_array_name(var, False), self.get_array_name(var, False))) # This is the "true" array name, not the restricted pointer. array_name = device.get_array_name(var) pointer_name = self.get_array_name(var) if pointer_name in handled_pointers: continue if getattr(var, 'dimensions', 1) > 1: continue # multidimensional (dynamic) arrays have to be treated differently if get_dtype_str(var.dtype) == 'bool': newlines = ["cdef _numpy.ndarray[char, ndim=1, mode='c', cast=True] _buf_{array_name} = _namespace['{array_name}']", "cdef {cpp_dtype} * {array_name} = <{cpp_dtype} *> _buf_{array_name}.data"] else: newlines = ["cdef _numpy.ndarray[{cpp_dtype}, ndim=1, mode='c'] _buf_{array_name} = _namespace['{array_name}']", "cdef {cpp_dtype} * {array_name} = <{cpp_dtype} *> _buf_{array_name}.data"] if not var.scalar: newlines += ["cdef int _num{array_name} = len(_namespace['{array_name}'])"] if var.scalar and var.constant: newlines += ['cdef {cpp_dtype} {varname} = _namespace["{varname}"]'] else: newlines += ["cdef {cpp_dtype} {varname}"] for line in newlines: line = line.format(cpp_dtype=get_cpp_dtype(var.dtype), numpy_dtype=get_numpy_dtype(var.dtype), pointer_name=pointer_name, array_name=array_name, varname=varname, ) load_namespace.append(line) handled_pointers.add(pointer_name) elif isinstance(var, Function): sc, ln, uf = self._add_user_function(varname, var) support_code.extend(sc) load_namespace.extend(ln) user_functions.extend(uf) else: # fallback to Python object load_namespace.append('{0} = _namespace["{1}"]'.format(varname, varname)) # delete the user-defined functions from the namespace and add the # function namespaces (if any) for funcname, func in user_functions: del self.variables[funcname] func_namespace = func.implementations[self.codeobj_class].get_namespace(self.owner) if func_namespace is not None: self.variables.update(func_namespace) return {'load_namespace': '\n'.join(load_namespace), 'support_code': '\n'.join(support_code)}
def determine_keywords(self): from brian2.devices.device import get_device device = get_device() # load variables from namespace load_namespace = [] support_code = [] handled_pointers = set() user_functions = [] for varname, var in self.variables.items(): if isinstance(var, Variable) and not isinstance( var, (Subexpression, AuxiliaryVariable)): load_namespace.append( '_var_{0} = _namespace["_var_{1}"]'.format( varname, varname)) if isinstance(var, AuxiliaryVariable): line = "{varname}".format(varname=varname) load_namespace.append(line) elif isinstance(var, Subexpression): dtype = get_numba_dtype(var.dtype) line = "{varname}".format(varname=varname) load_namespace.append(line) elif isinstance(var, Constant): dtype_name = get_numba_dtype(var.value) line = '{varname} = _namespace["{varname}"]'.format( varname=varname) load_namespace.append(line) elif isinstance(var, Variable): if var.dynamic: load_namespace.append('{0} = _namespace["{1}"]'.format( self.get_array_name(var, False), self.get_array_name(var, False))) # This is the "true" array name, not the restricted pointer. array_name = device.get_array_name(var) pointer_name = self.get_array_name(var) if pointer_name in handled_pointers: continue if getattr(var, 'dimensions', 1) > 1: continue # multidimensional (dynamic) arrays have to be treated differently if get_dtype_str(var.dtype) == 'bool': newlines = [ "_buf_{array_name} = _namespace['{array_name}']", "{array_name} = _buf_{array_name}.data" ] else: newlines = [ "_buf_{array_name} = _namespace['{array_name}']", "{array_name} = _buf_{array_name}.data" ] if not var.scalar: newlines += [ "_num{array_name} = len(_namespace['{array_name}'])" ] if var.scalar and var.constant: newlines += ['{varname} = _namespace["{varname}"]'] for line in newlines: line = line.format( numba_dtype=get_numba_dtype(var.dtype), numpy_dtype=get_numpy_dtype(var.dtype), pointer_name=pointer_name, array_name=array_name, varname=varname, ) load_namespace.append(line) handled_pointers.add(pointer_name) elif isinstance(var, Function): sc, ln, uf = self._add_user_function(varname, var) support_code.extend(sc) load_namespace.extend(ln) user_functions.extend(uf) else: # fallback to Python object load_namespace.append('{0} = _namespace["{1}"]'.format( varname, varname)) # delete the user-defined functions from the namespace and add the # function namespaces (if any) for funcname, func in user_functions: del self.variables[funcname] func_namespace = func.implementations[ self.codeobj_class].get_namespace(self.owner) if func_namespace is not None: self.variables.update(func_namespace) print "NAMESPACE IS" print load_namespace print "END NAMESPACE" #raise Exception return { 'load_namespace': '\n'.join(load_namespace), 'support_code': '\n'.join(support_code) }