Skip to content
This repository was archived by the owner on Jan 25, 2023. It is now read-only.

dparray integration #83

Open
wants to merge 25 commits into
base: pydppl
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
48213b4
Initial support for Numpy ndarray subclasses.
Aug 18, 2020
3a89799
PyType to py_type
DrTodd13 Aug 24, 2020
46a4b6f
Implementation of USM-backed ndarray as dparray.
DrTodd13 Sep 20, 2020
e12ea86
Initial implementation of custom allocator support.
DrTodd13 Sep 20, 2020
765d8fa
Add some testing code for dparray but this isn't integrated with the …
DrTodd13 Sep 20, 2020
42ff174
Initial support for Numpy ndarray subclasses.
Aug 18, 2020
f07879b
PyType to py_type
DrTodd13 Aug 24, 2020
fdab211
Implementation of USM-backed ndarray as dparray.
DrTodd13 Sep 20, 2020
390e679
Initial implementation of custom allocator support.
DrTodd13 Sep 20, 2020
9a271b2
Add some testing code for dparray but this isn't integrated with the …
DrTodd13 Sep 20, 2020
a2d6403
Remove debug prints.
DrTodd13 Sep 29, 2020
6f2bcf5
Move np.ones_like to decorator like empty_like and zeros_like.
DrTodd13 Sep 29, 2020
ea0747f
Define a module for the USM-allocator for dparray.
DrTodd13 Sep 29, 2020
547ae8d
Add an external_allocator options to the Numba runtime.
DrTodd13 Sep 29, 2020
d8fc51a
Compile the new dppl_rt extension module.
DrTodd13 Sep 29, 2020
d89b613
Most NumPy functions are now imported into dparray module and the typ…
DrTodd13 Sep 29, 2020
e1f9a9f
Merge branch 'numpy_subclass' of https://github.com/IntelPython/numba…
DrTodd13 Sep 29, 2020
55e61c3
Fix NRT_Allocate signature issue.
DrTodd13 Sep 30, 2020
3cbf1c6
Switch to dpctl.
DrTodd13 Sep 30, 2020
699a8bf
Switch to dpctl.
DrTodd13 Sep 30, 2020
aa945b9
Register dparray typing and lowering functions in a better spot so no…
DrTodd13 Sep 30, 2020
107f9c3
Give dparray's an empty dict for __array_interface. We can gradually…
DrTodd13 Oct 1, 2020
ccafc8e
Add support for attribute typing so things like array.T (transpose) n…
DrTodd13 Oct 3, 2020
f954be9
Don't redefine symbol if we specifically overloaded it prior.
DrTodd13 Nov 4, 2020
0ad853a
Merge remote-tracking branch 'origin' into numpy_subclass
DrTodd13 Nov 4, 2020
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
13 changes: 12 additions & 1 deletion numba/_typeof.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,7 @@ int
typeof_typecode(PyObject *dispatcher, PyObject *val)
{
PyTypeObject *tyobj = Py_TYPE(val);
int no_subtype_attr;
/* This needs to be kept in sync with Dispatcher.typeof_pyval(),
* otherwise funny things may happen.
*/
Expand All @@ -794,9 +795,19 @@ typeof_typecode(PyObject *dispatcher, PyObject *val)
return typecode_arrayscalar(dispatcher, val);
}
/* Array handling */
else if (PyType_IsSubtype(tyobj, &PyArray_Type)) {
else if (tyobj == &PyArray_Type) {
return typecode_ndarray(dispatcher, (PyArrayObject*)val);
}
/* Subtypes of Array handling */
else if (PyType_IsSubtype(tyobj, &PyArray_Type)) {
/* If the class has an attribute named __numba_no_subtype_ndarray then
don't treat it as a normal variant of a Numpy ndarray but as it's own
separate type. */
no_subtype_attr = PyObject_HasAttrString(val, "__numba_no_subtype_ndarray__");
if (!no_subtype_attr) {
return typecode_ndarray(dispatcher, (PyArrayObject*)val);
}
}

return typecode_using_fingerprint(dispatcher, val);
}
Expand Down
9 changes: 0 additions & 9 deletions numba/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,7 @@ def get_external_function_type(self, fndesc):
return fnty

def declare_function(self, module, fndesc):
#print("base.py: declare_function", module, "\n\targs:", fndesc.args, "\n\trestype:", fndesc.restype, "\n\targtypes:", fndesc.argtypes, fndesc.mangled_name, fndesc.noalias)
fnty = self.call_conv.get_function_type(fndesc.restype, fndesc.argtypes)
#print("fnty:", fnty)
fn = module.get_or_insert_function(fnty, name=fndesc.mangled_name)
self.call_conv.decorate_function(fn, fndesc.args, fndesc.argtypes, noalias=fndesc.noalias)
if fndesc.inline:
Expand Down Expand Up @@ -553,21 +551,14 @@ def get_function(self, fn, sig, _firstcall=True):
The return value is a callable with the signature (builder, args).
"""
assert sig is not None
# print("get_function", fn, sig, type(fn), type(sig))
sig = sig.as_function()
# print("get_function", sig, type(sig))
if isinstance(fn, (types.Function, types.BoundFunction,
types.Dispatcher)):
key = fn.get_impl_key(sig)
overloads = self._defns[key]
# print("function or boundfunction or dispatcher")
else:
key = fn
overloads = self._defns[key]
# print("other")
# print("overloads", overloads)
# print_overloads(overloads.versions)
# print_defns(self._defns)

try:
return _wrap_impl(overloads.find(sig.args), self, sig)
Expand Down
2 changes: 2 additions & 0 deletions numba/core/cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def load_additional_registries(self):
from numba.np import npyimpl
from numba.cpython import cmathimpl, mathimpl, printimpl, randomimpl
from numba.misc import cffiimpl
from numba.dppl.dparray import numba_register as dparray_register
self.install_registry(cmathimpl.registry)
self.install_registry(cffiimpl.registry)
self.install_registry(mathimpl.registry)
Expand All @@ -75,6 +76,7 @@ def load_additional_registries(self):

# load 3rd party extensions
numba.core.entrypoints.init_all()
dparray_register()

@property
def target_data(self):
Expand Down
2 changes: 1 addition & 1 deletion numba/core/extending.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
lower_setattr, lower_setattr_generic, lower_cast) # noqa: F401
from numba.core.datamodel import models # noqa: F401
from numba.core.datamodel import register_default as register_model # noqa: F401, E501
from numba.core.pythonapi import box, unbox, reflect, NativeValue # noqa: F401
from numba.core.pythonapi import box, unbox, reflect, NativeValue, allocator # noqa: F401
from numba._helperlib import _import_cython_function # noqa: F401
from numba.core.serialize import ReduceMixin

Expand Down
12 changes: 8 additions & 4 deletions numba/core/ir_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ def mk_alloc(typemap, calltypes, lhs, size_var, dtype, scope, loc):
out = []
ndims = 1
size_typ = types.intp
# Get the type of the array being allocated.
arr_typ = typemap[lhs.name]
if isinstance(size_var, tuple):
if len(size_var) == 1:
size_var = size_var[0]
Expand Down Expand Up @@ -108,11 +110,13 @@ def mk_alloc(typemap, calltypes, lhs, size_var, dtype, scope, loc):
typ_var_assign = ir.Assign(np_typ_getattr, typ_var, loc)
alloc_call = ir.Expr.call(attr_var, [size_var, typ_var], (), loc)
if calltypes:
calltypes[alloc_call] = typemap[attr_var.name].get_call_type(
cac = typemap[attr_var.name].get_call_type(
typing.Context(), [size_typ, types.functions.NumberClass(dtype)], {})
# signature(
# types.npytypes.Array(dtype, ndims, 'C'), size_typ,
# types.functions.NumberClass(dtype))
# By default, all calls to "empty" are typed as returning a standard
# Numpy ndarray. If we are allocating a ndarray subclass here then
# just change the return type to be that of the subclass.
cac._return_type = arr_typ
calltypes[alloc_call] = cac
alloc_assign = ir.Assign(alloc_call, lhs, loc)

out.extend([g_np_assign, attr_assign, typ_var_assign, alloc_assign])
Expand Down
9 changes: 8 additions & 1 deletion numba/core/pythonapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ def lookup(self, typeclass, default=None):
_boxers = _Registry()
_unboxers = _Registry()
_reflectors = _Registry()
# Registry of special allocators for types.
_allocators = _Registry()

box = _boxers.register
unbox = _unboxers.register
reflect = _reflectors.register
allocator = _allocators.register

class _BoxContext(namedtuple("_BoxContext",
("context", "builder", "pyapi", "env_manager"))):
Expand Down Expand Up @@ -1186,8 +1189,11 @@ def nrt_adapt_ndarray_to_python(self, aryty, ary, dtypeptr):
assert self.context.enable_nrt, "NRT required"

intty = ir.IntType(32)
# Embed the Python type of the array (maybe subclass) in the LLVM.
serial_aryty_pytype = self.unserialize(self.serialize_object(aryty.py_type))

fnty = Type.function(self.pyobj,
[self.voidptr, intty, intty, self.pyobj])
[self.voidptr, self.pyobj, intty, intty, self.pyobj])
fn = self._get_function(fnty, name="NRT_adapt_ndarray_to_python")
fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE)

Expand All @@ -1197,6 +1203,7 @@ def nrt_adapt_ndarray_to_python(self, aryty, ary, dtypeptr):
aryptr = cgutils.alloca_once_value(self.builder, ary)
return self.builder.call(fn, [self.builder.bitcast(aryptr,
self.voidptr),
serial_aryty_pytype,
ndim, writable, dtypeptr])

def nrt_meminfo_new_from_pyobject(self, data, pyobj):
Expand Down
37 changes: 35 additions & 2 deletions numba/core/runtime/_nrt_python.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ int MemInfo_init(MemInfoObject *self, PyObject *args, PyObject *kwds) {
return -1;
}
raw_ptr = PyLong_AsVoidPtr(raw_ptr_obj);
NRT_Debug(nrt_debug_print("MemInfo_init self=%p raw_ptr=%p\n", self, raw_ptr));

if(PyErr_Occurred()) return -1;
self->meminfo = (NRT_MemInfo *)raw_ptr;
assert (NRT_MemInfo_refcount(self->meminfo) > 0 && "0 refcount");
Expand Down Expand Up @@ -109,6 +111,27 @@ MemInfo_get_refcount(MemInfoObject *self, void *closure) {
return PyLong_FromSize_t(refct);
}

static
PyObject*
MemInfo_get_external_allocator(MemInfoObject *self, void *closure) {
void *p = NRT_MemInfo_external_allocator(self->meminfo);
printf("MemInfo_get_external_allocator %p\n", p);
return PyLong_FromVoidPtr(p);
}

static
PyObject*
MemInfo_get_parent(MemInfoObject *self, void *closure) {
void *p = NRT_MemInfo_parent(self->meminfo);
if (p) {
Py_INCREF(p);
return (PyObject*)p;
} else {
Py_INCREF(Py_None);
return Py_None;
}
}

static void
MemInfo_dealloc(MemInfoObject *self)
{
Expand Down Expand Up @@ -136,6 +159,13 @@ static PyGetSetDef MemInfo_getsets[] = {
(getter)MemInfo_get_refcount, NULL,
"Get the refcount",
NULL},
{"external_allocator",
(getter)MemInfo_get_external_allocator, NULL,
"Get the external allocator",
NULL},
{"parent",
(getter)MemInfo_get_parent, NULL,
NULL},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -286,7 +316,7 @@ PyObject* try_to_return_parent(arystruct_t *arystruct, int ndim,
}

NUMBA_EXPORT_FUNC(PyObject *)
NRT_adapt_ndarray_to_python(arystruct_t* arystruct, int ndim,
NRT_adapt_ndarray_to_python(arystruct_t* arystruct, PyTypeObject *retty, int ndim,
int writeable, PyArray_Descr *descr)
{
PyArrayObject *array;
Expand Down Expand Up @@ -324,10 +354,13 @@ NRT_adapt_ndarray_to_python(arystruct_t* arystruct, int ndim,
args = PyTuple_New(1);
/* SETITEM steals reference */
PyTuple_SET_ITEM(args, 0, PyLong_FromVoidPtr(arystruct->meminfo));
NRT_Debug(nrt_debug_print("NRT_adapt_ndarray_to_python arystruct->meminfo=%p\n", arystruct->meminfo));
/* Note: MemInfo_init() does not incref. This function steals the
* NRT reference.
*/
NRT_Debug(nrt_debug_print("NRT_adapt_ndarray_to_python created MemInfo=%p\n", miobj));
if (MemInfo_init(miobj, args, NULL)) {
NRT_Debug(nrt_debug_print("MemInfo_init returned 0.\n"));
return NULL;
}
Py_DECREF(args);
Expand All @@ -336,7 +369,7 @@ NRT_adapt_ndarray_to_python(arystruct_t* arystruct, int ndim,
shape = arystruct->shape_and_strides;
strides = shape + ndim;
Py_INCREF((PyObject *) descr);
array = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type, descr, ndim,
array = (PyArrayObject *) PyArray_NewFromDescr(retty, descr, ndim,
shape, strides, arystruct->data,
flags, (PyObject *) miobj);

Expand Down
1 change: 1 addition & 0 deletions numba/core/runtime/_nrt_pythonmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ declmethod(MemInfo_alloc);
declmethod(MemInfo_alloc_safe);
declmethod(MemInfo_alloc_aligned);
declmethod(MemInfo_alloc_safe_aligned);
declmethod(MemInfo_alloc_safe_aligned_external);
declmethod(MemInfo_alloc_dtor_safe);
declmethod(MemInfo_call_dtor);
declmethod(MemInfo_new_varsize);
Expand Down
Loading