Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b0fcd32
Added rudimentary support for complex numbers (no arithmetic yet).
Jun 26, 2012
2aa4873
Reindent tabs to spaces (inconsistent indentation)
markflorisson Jun 26, 2012
358cdca
Add gitignore
markflorisson Jun 26, 2012
0316248
Add minivect as submodule to numba
markflorisson Jun 26, 2012
1be7392
Add type system with slicable types and LLVM conversion
markflorisson Jun 26, 2012
4bf3e3a
Add type conversion from Python to Numba and Numba to LLVM
markflorisson Jun 27, 2012
d05f9b5
Added type inference
markflorisson Jun 27, 2012
9568936
Adapt translater to use new type system and symbol table (not finished)
markflorisson Jun 28, 2012
2758807
Get example compiling and callable
markflorisson Jun 28, 2012
d7681ae
Create new Variable when assigning to variables
markflorisson Jun 29, 2012
eedcd85
Restore numba_compile default signature
markflorisson Jun 29, 2012
9e48690
Undo minivect symlink
markflorisson Jun 29, 2012
b80ad3a
Add submodule notice
markflorisson Jun 29, 2012
e248ff2
Compile for loops
markflorisson Jun 30, 2012
d554b85
Get for loops running
markflorisson Jun 30, 2012
1e6e639
Support Py_ssize_t type and PyObject_Length() for len(obj)
markflorisson Jun 30, 2012
f0b9932
Incorporate pymothoa
markflorisson Jul 4, 2012
65d59d5
Implement type inference on an AST
markflorisson Jul 4, 2012
5200b7f
Add type inference for numpy attributes (dtypes, *_like, arange)
markflorisson Jul 4, 2012
9491cde
Copy over ast code generator & numba translator
markflorisson Jul 5, 2012
f324e2c
Add slicing and indexing to type inference (tuples, slices, ellipsis,…
markflorisson Jul 5, 2012
f68f8f6
Start adapting code generation to ASTs
markflorisson Jul 5, 2012
993b9cc
Support None as newaxis index
markflorisson Jul 5, 2012
340e2a3
Continue translating code generator to ASTs
markflorisson Jul 5, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add type system with slicable types and LLVM conversion
Todo: actually use it :)
  • Loading branch information
markflorisson committed Jun 27, 2012
commit 1be73926d7d23f90471e8c25b3429fdd87df6c02
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ __pycache__
*.bak
*.pybackup

.idea/
build/
.gitrev
.coverage
Expand Down
1 change: 0 additions & 1 deletion numba/minivect
Submodule minivect deleted from 37a5ca
1 change: 1 addition & 0 deletions numba/minivect
238 changes: 0 additions & 238 deletions numba/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,49 +41,6 @@
#hasfree


# Convert llvm Type object to kind-bits string
def llvmtype_to_strtype(typ):
if typ.kind == lc.TYPE_FLOAT:
return 'f32'
elif typ.kind == lc.TYPE_DOUBLE:
return 'f64'
elif typ.kind == lc.TYPE_INTEGER:
return 'i%d' % typ.width
elif typ == _numpy_array: # NOTE: Checks for Numpy arrays need to
# happen before the more general
# recognition of pointer types,
# otherwise it won't ever be used.
# FIXME: Need to find a way to stash dtype somewhere in here.
return 'arr[]'
elif typ == _complex64:
return 'c64'
elif typ == _complex128:
return 'c128'
elif typ.kind == lc.TYPE_POINTER:
if typ.pointee.kind == lc.TYPE_FUNCTION:
return ['func'] + typ.pointee.args
else:
n_pointer = 1
typ = typ.pointee
while typ.kind == lc.TYPE_POINTER:
n_pointer += 1
typ = typ.pointee
return "%s%s" % (llvmtype_to_strtype(typ), "*" * n_pointer)
raise NotImplementedError("FIXME: LLVM type conversions for '%s'!" % (typ,))

# We don't support all types....
def pythontype_to_strtype(typ):
if issubclass(typ, float):
return 'f64'
elif issubclass(typ, int):
return 'i%d' % _plat_bits
elif issubclass(typ, complex):
return 'c128'
elif issubclass(typ, (types.BuiltinFunctionType, types.FunctionType)):
return ["func"]
elif issubclass(typ, tuple):
return 'tuple'

def map_to_function(func, typs, mod):
typs = [str_to_llvmtype(x) if isinstance(x, str) else x for x in typs]
INTR = getattr(lc, 'INTR_%s' % func.__name__.upper())
Expand Down Expand Up @@ -253,201 +210,6 @@ def is_phi(self):
def is_module(self):
return isinstance(self.val, types.ModuleType)

# Add complex, unsigned, and bool
def str_to_llvmtype(str):
if __debug__:
print("str_to_llvmtype(): str = %r" % (str,))
n_pointer = 0
if str.endswith('*'):
n_pointer = str.count('*')
str = str[:-n_pointer]
if str[0] == 'f':
if str[1:] == '32':
ret_val = lc.Type.float()
elif str[1:] == '64':
ret_val = lc.Type.double()
elif str[0] == 'i':
num = int(str[1:])
ret_val = lc.Type.int(num)
elif str[0] == 'c':
if str[1:] == '64':
ret_val = _complex64
elif str[1:] == '128':
ret_val = _complex128
elif str.startswith('arr['):
ret_val = _numpy_array
else:
raise TypeError, "Invalid Type: %s" % str
for _ in xrange(n_pointer):
ret_val = lc.Type.pointer(ret_val)
return ret_val

def _handle_list_conversion(typ):
assert isinstance(typ, list)
crnt_elem = typ[0]
dimcount = 1
while isinstance(crnt_elem, list):
crnt_elem = crnt_elem[0]
dimcount += 1
return dimcount, crnt_elem

def _dtypeish_to_str(typ):
n_pointer = 0
if typ.endswith('*'):
n_pointer = typ.count('*')
typ = typ[:-n_pointer]
dt = np.dtype(typ)
return ("%s%s%s" % (dt.kind, 8*dt.itemsize, "*" * n_pointer))

def convert_to_llvmtype(typ):
n_pointer = 0
if isinstance(typ, list):
return _numpy_array
return str_to_llvmtype(_dtypeish_to_str(typ))

def convert_to_ctypes(typ):
import ctypes
from numpy.ctypeslib import _typecodes
if isinstance(typ, list):
# FIXME: At some point we should add a type check to the
# wrapper code s.t. it ensures the given argument conforms to
# the following:
# np.ctypeslib.ndpointer(dtype = np.dtype(crnt_elem),
# ndim = dimcount,
# flags = 'C_CONTIGUOUS')
# For now, we'll just allow any Python objects, and hope for the best.
return ctypes.py_object
n_pointer = 0
if typ.endswith('*'):
n_pointer = typ.count('*')
typ = typ[:-n_pointer]
if __debug__:
print("convert_to_ctypes(): n_pointer = %d, typ' = %r" %
(n_pointer, typ))
dtype_str = np.dtype(typ).str
if dtype_str[1] == 'c':
if dtype_str[2:] == '8':
ret_val = Complex64
elif dtype_str[2:] == '16':
ret_val = Complex128
else:
raise NotImplementedError("Numba does not currently support "
"ctypes wrapping for type %r." % (typ,))
else:
ret_val = _typecodes[np.dtype(typ).str]
for _ in xrange(n_pointer):
ret_val = ctypes.POINTER(ret_val)
return ret_val

def convert_to_strtype(typ):
# FIXME: This current mapping preserves dtype information, but
# loses ndims.
arr = 0
if isinstance(typ, list):
arr = 1
_, typ = _handle_list_conversion(typ)
return '%s%s%s' % ('arr[' * arr, _dtypeish_to_str(typ), ']' * arr)

# Add complex, unsigned, and bool
def typcmp(type1, type2):
if type1==type2:
return 0
kind1 = type1[0]
kind2 = type2[0]
if kind1 == kind2:
return cmp(int(type1[1:]),int(type2[1:]))
if kind1 == 'f':
return 1
else:
return -1

def typ_isa_number(typ):
ret_val = ((not typ.endswith('*')) and
(typ.startswith(('i', 'f'))))
return ret_val

# Both inputs are Variable objects
# Resolves types on one of them.
# Won't work if both need resolving
# Currently delegates casting to Variable.llvm(), but only in the
# presence of a builder instance.
def resolve_type(arg1, arg2, builder = None):
if __debug__:
print("resolve_type(): arg1 = %r, arg2 = %r" % (arg1, arg2))
typ = None
typ1 = None
typ2 = None
if arg1._llvm is not None:
typ1 = arg1.typ
else:
try:
str_to_llvmtype(arg1.typ)
typ1 = arg1.typ
except TypeError:
pass
if arg2._llvm is not None:
typ2 = arg2.typ
else:
try:
str_to_llvmtype(arg2.typ)
typ2 = arg2.typ
except TypeError:
pass
if typ1 is None and typ2 is None:
raise TypeError, "Both types not valid"
# The following is trying to enforce C-like upcasting rules where
# we try to do the following:
# * Use higher precision if the types are identical in kind.
# * Use floats instead of integers.
if typ1 is None:
typ = typ2
elif typ2 is None:
typ = typ1
else:
# FIXME: What about arithmetic operations on arrays? (Though
# we'd need to support code generation for them first...)
if typ_isa_number(typ1) and typ_isa_number(typ2):
if typ1[0] == typ2[0]:
if int(typ1[1:]) > int(typ2[1:]):
typ = typ1
else:
typ = typ2
elif typ1[0] == 'f':
typ = typ1
elif typ2[0] == 'f':
typ = typ2
else:
# Fall-through case: just use the left hand operand's type...
typ = typ1
if __debug__:
print("resolve_type() ==> %r" % (typ,))
return (typ,
arg1.llvm(typ, builder = builder),
arg2.llvm(typ, builder = builder))

# This won't convert any llvm types. It assumes
# the llvm types in args are either fixed or not-yet specified.
def func_resolve_type(mod, func, args):
# already an llvm function
if func.val and func.val is func._llvm:
typs = [llvmtype_to_strtype(x) for x in func._llvm.type.pointee.args]
lfunc = func._llvm
else:
# we need to generate the function including the types
typs = [arg.typ if arg._llvm is not None else '' for arg in args]
# pick first one as choice
choicetype = None
for typ in typs:
if typ is not None:
choicetype = typ
break
if choicetype is None:
raise TypeError, "All types are unspecified"
typs = [choicetype if x is None else x for x in typs]
lfunc = map_to_function(func.val, typs, mod)

llvm_args = [arg.llvm(typ) for typ, arg in zip(typs, args)]
return lfunc, llvm_args

_compare_mapping_float = {'>':lc.FCMP_OGT,
'<':lc.FCMP_OLT,
Expand Down
Loading