Beispiel #1
0
def _construct_native_attribute_struct(ext_type):
    attrs = dict((name, var.type) for name, var in ext_type.symtab.iteritems())
    if ext_type.attribute_struct is None:
        # No fields to inherit
        ext_type.attribute_struct = numba.struct(**attrs)
    else:
        # Inherit fields from parent
        fields = []
        for name, variable in ext_type.symtab.iteritems():
            if name not in ext_type.attribute_struct.fielddict:
                fields.append((name, variable.type))
                ext_type.attribute_struct.fielddict[name] = variable.type

        # Sort fields by rank
        fields = numba.struct(fields).fields
        ext_type.attribute_struct.fields.extend(fields)
Beispiel #2
0
def inherit_attributes(ext_type, class_dict):
    cls = ext_type.py_class
    if not is_numba_class(cls):
        # superclass is not a numba class
        return

    struct_type = cls.__numba_struct_type
    vtab_type = cls.__numba_vtab_type
    verify_base_class_compatibility(cls, struct_type, vtab_type)

    # Inherit attributes
    ext_type.attribute_struct = numba.struct(struct_type.fields)
    for field_name, field_type in ext_type.attribute_struct.fields:
        ext_type.symtab[field_name] = symtab.Variable(field_type,
                                                      promotable_type=False)

    # Inherit methods
    for method_name, method_type in vtab_type.fields:
        func_signature = method_type.base_type
        args = list(func_signature.args)
        if not (func_signature.is_class or func_signature.is_static):
            args[0] = ext_type
        func_signature = func_signature.return_type(*args)
        ext_type.add_method(method_name, func_signature)

    ext_type.parent_attr_struct = struct_type
    ext_type.parent_vtab_type = vtab_type
Beispiel #3
0
def compile_extension_methods(env, py_class, ext_type, class_dict, flags):
    """
    Compile extension methods:

        1) Process signatures such as @void(double)
        2) Infer native attributes through type inference on __init__
        3) Path the extension type with a native attributes struct
        4) Infer types for all other methods
        5) Update the ext_type with a vtab type
        6) Compile all methods
    """
    method_pointers = []
    lmethods = []

    class_dict['__numba_py_class'] = py_class

    _process_method_signatures(class_dict, ext_type)
    _type_infer_init_method(env, class_dict, ext_type, flags)
    _construct_native_attribute_struct(ext_type)
    _type_infer_methods(env, class_dict, ext_type, flags)

    # TODO: patch method call types

    # Set vtab type before compiling
    ext_type.vtab_type = numba.struct(
        [(field_name, field_type.pointer())
         for field_name, field_type in ext_type.methods])
    _compile_methods(class_dict, env, ext_type, lmethods, method_pointers,
                     flags)
    return method_pointers, lmethods
def _construct_native_attribute_struct(ext_type):
    attrs = dict((name, var.type) for name, var in ext_type.symtab.iteritems())
    if ext_type.attribute_struct is None:
        # No fields to inherit
        ext_type.attribute_struct = numba.struct(**attrs)
    else:
        # Inherit fields from parent
        fields = []
        for name, variable in ext_type.symtab.iteritems():
            if name not in ext_type.attribute_struct.fielddict:
                fields.append((name, variable.type))
                ext_type.attribute_struct.fielddict[name] = variable.type

        # Sort fields by rank
        fields = numba.struct(fields).fields
        ext_type.attribute_struct.fields.extend(fields)
def inherit_attributes(ext_type, class_dict):
    cls = ext_type.py_class
    if not is_numba_class(cls):
        # superclass is not a numba class
        return

    struct_type = cls.__numba_struct_type
    vtab_type = cls.__numba_vtab_type
    verify_base_class_compatibility(cls, struct_type, vtab_type)

    # Inherit attributes
    ext_type.attribute_struct = numba.struct(struct_type.fields)
    for field_name, field_type in ext_type.attribute_struct.fields:
        ext_type.symtab[field_name] = symtab.Variable(field_type,
                                                      promotable_type=False)

    # Inherit methods
    for method_name, method_type in vtab_type.fields:
        func_signature = method_type.base_type
        args = list(func_signature.args)
        args[0] = ext_type
        func_signature = func_signature.return_type(*args)
        ext_type.add_method(method_name, func_signature)

    ext_type.parent_attr_struct = struct_type
    ext_type.parent_vtab_type = vtab_type
Beispiel #6
0
def resolve_template_type(template_type, template_context):
    """
    After the template context is known, resolve functions on template types
    E.g.

        T[:]                -> ArrayType(dtype=T)
        void(T)             -> FunctionType(args=[T])
        Struct { T arg }    -> struct(fields={'arg': T})
        T *                 -> PointerType(base_type=T)

    Any other compound types?
    """
    r = lambda t: resolve_template_type(t, template_context)

    if template_type.is_template:
        template_type = template_type.resolve_template(template_context)
    elif template_type.is_array:
        template_type = template_type.copy()
        template_type.dtype = r(template_type.dtype)
    elif template_type.is_function:
        template_type = r(template_type.return_type)(*map(r, template_type.args))
    elif template_type.is_struct:
        S = template_type
        fields = []
        for field_name, field_type in S.fields:
            fields.append((field_name, r(field_type)))
        template_type = numba.struct(fields, name=S.name, readonly=S.readonly,
                                     packed=S.packed)
    elif template_type.is_pointer:
        template_type = r(template_type.base_type).pointer()

    return template_type
Beispiel #7
0
    def set_attributes(self, attribute_list):
        """
        Create the symbol table and attribute struct from a list of
        (varname, attribute_type)
        """
        import numba.symtab

        self.attribute_struct = numba.struct(attribute_list)
        self.symtab.update([(name, numba.symtab.Variable(type))
                               for name, type in attribute_list])
Beispiel #8
0
def from_ctypes_type(ctypes_type):
    """
    Convert a ctypes type to a numba type
    """
    if numba.utils.hashable(ctypes_type) and ctypes_type in ctypes_map:
        return ctypes_map[ctypes_type]
    elif isinstance(ctypes_type, _ctypes_pointer_type):
        return from_ctypes_type(ctypes_type._type_).pointer()
    elif isinstance(ctypes_type, _ctypes_array_type):
        base_type = from_ctypes_type(ctypes_type._type_)
        return minitypes.CArrayType(base_type, ctypes_type._length_)
    elif issubclass(ctypes_type, ctypes.Structure):
        fields = [(name, from_ctypes_type(field_type))
                  for name, field_type in ctypes_type._fields_]
        return numba.struct(fields)
    else:
        raise NotImplementedError(ctypes_type)
Beispiel #9
0
def from_ctypes_type(ctypes_type):
    """
    Convert a ctypes type to a numba type
    """
    if numba.utils.hashable(ctypes_type) and ctypes_type in ctypes_map:
        return ctypes_map[ctypes_type]
    elif isinstance(ctypes_type, _ctypes_pointer_type):
        return from_ctypes_type(ctypes_type._type_).pointer()
    elif isinstance(ctypes_type, _ctypes_array_type):
        base_type = from_ctypes_type(ctypes_type._type_)
        return minitypes.CArrayType(base_type, ctypes_type._length_)
    elif issubclass(ctypes_type, ctypes.Structure):
        fields = [(name, from_ctypes_type(field_type))
                      for name, field_type in ctypes_type._fields_]
        return numba.struct(fields)
    else:
        raise NotImplementedError(ctypes_type)
def build_vtab(vtab_type, method_pointers):
    assert len(method_pointers) == len(vtab_type.fields)

    vtab_ctype = numba.struct(
        [(vtab_name(field_name), field_type)
            for field_name, field_type in vtab_type.fields]).to_ctypes()

    methods = []
    for (method_name, method_pointer), (field_name, field_type) in zip(
                                        method_pointers, vtab_type.fields):
        assert method_name == field_name
        method_type_p = field_type.to_ctypes()
        cmethod = ctypes.cast(ctypes.c_void_p(method_pointer), method_type_p)
        methods.append(cmethod)

    vtab = vtab_ctype(*methods)
    return vtab, vtab_type
Beispiel #11
0
def build_vtab(vtab_type, method_pointers):
    assert len(method_pointers) == len(vtab_type.fields)

    vtab_ctype = numba.struct(
        [(vtab_name(field_name), field_type)
            for field_name, field_type in vtab_type.fields]).to_ctypes()

    methods = []
    for (method_name, method_pointer), (field_name, field_type) in zip(
                                        method_pointers, vtab_type.fields):
        assert method_name == field_name
        method_type_p = field_type.to_ctypes()
        cmethod = ctypes.cast(ctypes.c_void_p(method_pointer), method_type_p)
        methods.append(cmethod)

    vtab = vtab_ctype(*methods)
    return vtab, vtab_type
Beispiel #12
0
def map_type(cffi_type):
    "Map CFFI type to numba type"
    kind = getattr(cffi_type, 'kind', '')
    if kind in ('struct', 'union'):
        if kind == 'union':
            result = None
        else:
            result = numba.struct([(name, map_type(field.type))
                               for name, field in cffi_type.fields])
    elif kind == 'function':
        restype = map_type(cffi_type.result)
        argtypes = [map_type(arg) for arg in cffi_type.args]
        result = numba.function(restype, argtypes,
                                is_vararg=cffi_type.ellipsis).pointer()
    else:
        result = type_map.get(cffi_type)

    if result is None:
        raise TypeError(cffi_type)

    return result
Beispiel #13
0
def build_static_vtab(vtable, vtab_struct):
    """
    Create ctypes virtual method table.

    vtab_type: the vtab struct type (typesystem.struct)
    method_pointers: a list of method pointers ([int])
    """
    vtab_ctype = numba.struct(
        [(vtab_name(field_name), field_type)
            for field_name, field_type in vtab_struct.fields]).to_ctypes()

    methods = []
    for method, (field_name, field_type) in zip(vtable.methods,
                                                vtab_struct.fields):
        method_type_p = field_type.to_ctypes()
        method_void_p = ctypes.c_void_p(method.lfunc_pointer)
        cmethod = ctypes.cast(method_void_p, method_type_p)
        methods.append(cmethod)

    vtab = vtab_ctype(*methods)
    return vtab
Beispiel #14
0
def build_static_vtab(vtable, vtab_struct):
    """
    Create ctypes virtual method table.

    vtab_type: the vtab struct type (typesystem.struct)
    method_pointers: a list of method pointers ([int])
    """
    vtab_ctype = numba.struct(
        [(vtab_name(field_name), field_type)
            for field_name, field_type in vtab_struct.fields]).to_ctypes()

    methods = []
    for method, (field_name, field_type) in zip(vtable.methods,
                                                vtab_struct.fields):
        method_type_p = field_type.to_ctypes()
        method_void_p = ctypes.c_void_p(method.lfunc_pointer)
        cmethod = ctypes.cast(method_void_p, method_type_p)
        methods.append(cmethod)

    vtab = vtab_ctype(*methods)
    return vtab
Beispiel #15
0
def map_type(cffi_type):
    "Map CFFI type to numba type"
    kind = getattr(cffi_type, 'kind', '')
    if kind in ('struct', 'union'):
        if kind == 'union':
            result = None
        else:
            result = numba.struct([(name, map_type(field.type))
                                   for name, field in cffi_type.fields])
    elif kind == 'function':
        restype = map_type(cffi_type.result)
        argtypes = [map_type(arg) for arg in cffi_type.args]
        result = numba.function(restype,
                                argtypes,
                                is_vararg=cffi_type.ellipsis).pointer()
    else:
        result = type_map.get(cffi_type)

    if result is None:
        raise TypeError(cffi_type)

    return result
Beispiel #16
0
def build_vtab(vtab_type, method_pointers):
    """
    Create ctypes virtual method table.

    vtab_type: the vtab struct type (typesystem.struct)
    method_pointers: a list of method pointers ([int])
    """
    assert len(method_pointers) == len(vtab_type.fields)

    vtab_ctype = numba.struct(
        [(vtab_name(field_name), field_type)
            for field_name, field_type in vtab_type.fields]).to_ctypes()

    methods = []
    for (method_name, method_pointer), (field_name, field_type) in zip(
                                        method_pointers, vtab_type.fields):
        assert method_name == field_name
        method_type_p = field_type.to_ctypes()
        cmethod = ctypes.cast(ctypes.c_void_p(method_pointer), method_type_p)
        methods.append(cmethod)

    vtab = vtab_ctype(*methods)
    return vtab, vtab_type
Beispiel #17
0
 def to_struct(self):
     return numba.struct([(attr, self.attributedict[attr])
                          for attr in self.attributes])
Beispiel #18
0
    def wrap_vtable(self, vtable):
        return extension_types.StaticVtableWrapper(vtable)

#------------------------------------------------------------------------
# Hash-based virtual method tables
#------------------------------------------------------------------------

# ______________________________________________________________________
# Type Definitions

# TODO: Use something like CFFI + type conversion to get these
# TODO: types automatically

PyCustomSlots_Entry = numba.struct([
    ('id', uint64),
    ('ptr', void.pointer()),
])

PyCustomSlots_Table = numba.struct([
    ('flags', uint64),
    ('m_f', uint64),
    ('m_g', uint64),
    ('entries', PyCustomSlots_Entry.pointer()),
    ('n', uint16),
    ('b', uint16),
    ('r', uint8),
    ('reserved', uint8),
    # actually: uint16[b], 'b' trailing displacements
    # ('d', numba.carray(uint16, 0)), #0xffff)),
    # ('entries_mem', PyCustomSlot_Entry[n]), # 'n' trailing customslot entries
])
Beispiel #19
0
 def to_struct(self):
     return numba.struct([(m.name, m.signature.pointer())
                          for m in self.methods])
Beispiel #20
0
    """
    scalar = array[0, 0]
    return scalar

#------------------------------------------------------------------------
# Test type matching
#------------------------------------------------------------------------

T1 = numba.template("T1")
T2 = numba.template("T2")
T3 = numba.template("T3")
T4 = numba.template("T4")

A = T1[:, :]
F = void(T1)
S = numba.struct([('a', T1), ('b', T2.pointer()), ('c', T3[:]), ('d', void(T4))])
P = T2.pointer()

type_context1 = { T1: int_, T2: float_, T3: float64, T4: short, }
type_context2 = { T1: int_[:, :], T2: void(float32),
                  T3: numba.struct(a=float64, b=float_), T4: short.pointer(), }

def test_type_matching(array, func, struct, pointer):
    """
    >>> infer(test_type_matching, template_signature=void(A, F, S, P),
    ...       type_context=type_context1)
    [('array', int[:, :]), ('func', void (*)(int)), ('pointer', float32 *), ('struct', struct { int a, float32 * b, float64[:] c, void (*)(short) d })]
    """
    func(array[0, 0])
    struct.b = pointer
Beispiel #21
0
    scalar = array[0, 0]
    return scalar


#------------------------------------------------------------------------
# Test type matching
#------------------------------------------------------------------------

T1 = numba.template("T1")
T2 = numba.template("T2")
T3 = numba.template("T3")
T4 = numba.template("T4")

A = T1[:, :]
F = void(T1)
S = numba.struct([('a', T1), ('b', T2.pointer()), ('c', T3[:]),
                  ('d', void(T4))])
P = T2.pointer()

type_context1 = {
    T1: int_,
    T2: float_,
    T3: float64,
    T4: short,
}
type_context2 = {
    T1: int_[:, :],
    T2: void(float32),
    T3: numba.struct(a=float64, b=float_),
    T4: short.pointer(),
}
Beispiel #22
0
    scalar = array[0, 0]
    return scalar


#------------------------------------------------------------------------
# Test type matching
#------------------------------------------------------------------------

T1 = numba.template("T1")
T2 = numba.template("T2")
T3 = numba.template("T3")
T4 = numba.template("T4")

A = T1[:, :]
F = void(T1)
S = numba.struct(a=T1, b=T2.pointer(), c=T3[:], d=void(T4))
P = T2.pointer()

type_context1 = {
    T1: int_,
    T2: float_,
    T3: double,
    T4: short,
}
type_context2 = {
    T1: int_[:, :],
    T2: void(float_),
    T3: numba.struct(a=double, b=float_),
    T4: short.pointer(),
}
Beispiel #23
0
 def to_struct(self):
     return numba.struct([(attr, self.attributedict[attr])
                              for attr in self.attributes])
Beispiel #24
0
    def wrap_vtable(self, vtable):
        return extension_types.StaticVtableWrapper(vtable)

#------------------------------------------------------------------------
# Hash-based virtual method tables
#------------------------------------------------------------------------

# ______________________________________________________________________
# Type Definitions

# TODO: Use something like CFFI + type conversion to get these
# TODO: types automatically

PyCustomSlots_Entry = numba.struct([
    ('id', uint64),
    ('ptr', void.pointer()),
])

PyCustomSlots_Table = numba.struct([
    ('flags', uint64),
    ('m_f', uint64),
    ('m_g', uint64),
    ('entries', PyCustomSlots_Entry.pointer()),
    ('n', uint16),
    ('b', uint16),
    ('r', uint8),
    ('reserved', uint8),
    # actually: uint16[b], 'b' trailing displacements
    ('d', minitypes.CArrayType(uint16, 0)), #0xffff)),
    # ('entries_mem', PyCustomSlot_Entry[n]), # 'n' trailing customslot entries
])
Beispiel #25
0
import ctypes
import unittest
from collections import namedtuple
from functools import partial
import numba
from numba import *
from numba import ndarray_helpers
import llvm.core as lc

# ______________________________________________________________________

ArrayType = numba.struct([('data', double.pointer()),
                          ('shape', int64.pointer()),
                          ('strides', int64.pointer())])

Int32 = lc.Type.int(32)
const = partial(lc.Constant.int, Int32)
zero = const(0)
one = const(1)
two = const(2)


def ptr_at(builder, ptr, idx):
    return builder.gep(ptr, [const(idx)])


def load_at(builder, ptr, idx):
    return builder.load(ptr_at(builder, ptr, idx))


def store_at(builder, ptr, idx, val):
Beispiel #26
0
    """
    scalar = array[0, 0]
    return scalar

#------------------------------------------------------------------------
# Test type matching
#------------------------------------------------------------------------

T1 = numba.template("T1")
T2 = numba.template("T2")
T3 = numba.template("T3")
T4 = numba.template("T4")

A = T1[:, :]
F = void(T1)
S = numba.struct(a=T1, b=T2.pointer(), c=T3[:], d=void(T4))
P = T2.pointer()

type_context1 = { T1: int_, T2: float_, T3: double, T4: short, }
type_context2 = { T1: int_[:, :], T2: void(float_),
                  T3: numba.struct(a=double, b=float_), T4: short.pointer(), }

def test_type_matching(array, func, struct, pointer):
    """
    >>> infer(test_type_matching, template_signature=void(A, F, S, P),
    ...       type_context=type_context1)
    [('array', int[:, :]), ('func', void (*)(int)), ('pointer', float *), ('struct', struct { float * b, double[:] c, int a, void (*)(short) d })]
    """
    func(array[0, 0])
    struct.b = pointer
Beispiel #27
0
    scalar = array[0, 0]
    return scalar


# ------------------------------------------------------------------------
# Test type matching
# ------------------------------------------------------------------------

T1 = numba.template("T1")
T2 = numba.template("T2")
T3 = numba.template("T3")
T4 = numba.template("T4")

A = T1[:, :]
F = void(T1)
S = numba.struct([("a", T1), ("b", T2.pointer()), ("c", T3[:]), ("d", void(T4))])
P = T2.pointer()

type_context1 = {T1: int_, T2: float_, T3: float64, T4: short}
type_context2 = {T1: int_[:, :], T2: void(float32), T3: numba.struct(a=float64, b=float_), T4: short.pointer()}


def test_type_matching(array, func, struct, pointer):
    """
    >>> infer(test_type_matching, template_signature=void(A, F, S, P),
    ...       type_context=type_context1)
    [('array', int[:, :]), ('func', void (*)(int)), ('pointer', float32 *), ('struct', struct { int a, float32 * b, float64[:] c, void (*)(short) d })]
    """
    func(array[0, 0])
    struct.b = pointer
Beispiel #28
0
from numba import struct, jit, double
import numpy as np

record_type = struct([('x', double), ('y', double)])
record_dtype = record_type.get_dtype()
a = np.array([(1.0, 2.0), (3.0, 4.0)], dtype=record_dtype)

@jit(argtypes=[record_type[:]])
def hypot(data):
    # return types of numpy functions are inferred
    result = np.empty_like(data, dtype=np.float64) 
    # notice access to structure elements 'x' and 'y' via attribute access
    # You can also index by field name or field index:
    #       data[i].x == data[i]['x'] == data[i][0]
    for i in range(data.shape[0]):
        result[i] = np.sqrt(data[i].x * data[i].x + data[i].y * data[i].y)

    return result

print hypot(a)

# Notice inferred return type
print hypot.signature
# Notice native sqrt calls and for.body direct access to memory...
print hypot.lfunc
Beispiel #29
0
import ctypes
import unittest
from collections import namedtuple
from functools import partial
import numba
from numba import *
from numba import ndarray_helpers
import llvm.core as lc

# ______________________________________________________________________

ArrayType = numba.struct([('data', double.pointer()),
                          ('shape', int64.pointer()),
                          ('strides', int64.pointer())])

Int32 = lc.Type.int(32)
const = partial(lc.Constant.int, Int32)
zero = const(0)
one  = const(1)
two  = const(2)

def ptr_at(builder, ptr, idx):
    return builder.gep(ptr, [const(idx)])

def load_at(builder, ptr, idx):
    return builder.load(ptr_at(builder, ptr, idx))

def store_at(builder, ptr, idx, val):
    builder.store(val, ptr_at(builder, ptr, idx))

class MyArray(object):