Skip to content

Commit

Permalink
npbackend: the target_bhc now ignore zero-sized operations. Fixes issue
Browse files Browse the repository at this point in the history
  • Loading branch information
madsbk committed Jun 8, 2015
1 parent 044f153 commit a045a54
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 29 deletions.
39 changes: 22 additions & 17 deletions bridge/npbackend/ndarray.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -180,23 +180,28 @@ def get_bhc(ary):
raise ValueError("Bohrium arrays must be aligned, writeable, and in machine byte-order")
if not dtype_equal(ary, base):
raise ValueError("Bohrium base and view must have same data type")
if not base.ctypes.data <= ary.ctypes.data < base.ctypes.data + base.nbytes:
raise ValueError("The view must point to data within the base array")

# Lets make sure that 'ary' has a Bohrium-C base array
if base.bhc_ary is None:
base._data_np2bhc()

offset = (ary.ctypes.data - base.ctypes.data) / base.itemsize
if (ary.ctypes.data - base.ctypes.data) % base.itemsize != 0:
raise TypeError("The view offset must be element aligned")
if not 0 <= offset < base.size:
raise TypeError("The view offset is greater than the total number of elements in the base!")
strides = []
for stride in ary.strides:
strides.append(stride / base.itemsize)
if stride % base.itemsize != 0:
raise TypeError("The strides must be element aligned")

if 0 in ary.shape:#Lets use a dummy strides and offset for zero-sized views
strides = [0]*ary.ndim
offset = 0
else:
if not base.ctypes.data <= ary.ctypes.data < base.ctypes.data + base.nbytes:
raise ValueError("The view must point to data within the base array")

# Lets make sure that 'ary' has a Bohrium-C base array
if base.bhc_ary is None:
base._data_np2bhc()

offset = (ary.ctypes.data - base.ctypes.data) / base.itemsize
if (ary.ctypes.data - base.ctypes.data) % base.itemsize != 0:
raise TypeError("The view offset must be element aligned")
if not 0 <= offset < base.size:
raise TypeError("The view offset is greater than the total number of elements in the base!")
strides = []
for stride in ary.strides:
strides.append(stride / base.itemsize)
if stride % base.itemsize != 0:
raise TypeError("The strides must be element aligned")

ndim = ary.ndim if ary.ndim > 0 else 1
shape = ary.shape if len(ary.shape) > 0 else (1,)
Expand Down
50 changes: 38 additions & 12 deletions bridge/npbackend/target/target_bhc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,25 @@
from .. import bhc
from .._util import dtype_name
from . import interface
import functools
import operator

class Base(interface.Base):
"""base array handle"""

def __init__(self, size, dtype, bhc_obj=None):
super(Base, self).__init__(size, dtype)
if size == 0:
return

if bhc_obj is None:
func = eval("bhc.bh_multi_array_%s_new_empty" % dtype_name(dtype))
bhc_obj = bhc_exec(func, 1, (size,))
bhc_obj = _bhc_exec(func, 1, (size,))
self.bhc_obj = bhc_obj

def __del__(self):
if self.size == 0:
return
exec("bhc.bh_multi_array_%s_destroy(self.bhc_obj)" %
dtype_name(self.dtype)
)
Expand All @@ -28,16 +34,21 @@ class View(interface.View):

def __init__(self, ndim, start, shape, strides, base):
super(View, self).__init__(ndim, start, shape, strides, base)
self.size = functools.reduce(operator.mul, shape, 1)
if self.size == 0:
return
dtype = dtype_name(self.dtype)
func = eval("bhc.bh_multi_array_%s_new_view" % dtype)
self.bhc_obj = func(base.bhc_obj, ndim, start, shape, strides)

def __del__(self):
if self.size == 0:
return
exec("bhc.bh_multi_array_%s_destroy(self.bhc_obj)" % dtype_name(
self.dtype
))

def bhc_exec(func, *args):
def _bhc_exec(func, *args):
"""execute the 'func' with the bhc objects in 'args'"""

args = list(args)
Expand All @@ -48,6 +59,8 @@ def bhc_exec(func, *args):

def get_data_pointer(ary, allocate=False, nullify=False):
"""Retrieves the data pointer from Bohrium Runtime."""
if ary.size == 0 or ary.base.size == 0:
return 0

dtype = dtype_name(ary)
ary = ary.bhc_obj
Expand Down Expand Up @@ -94,6 +107,9 @@ def ufunc(op, *args):
scalar_str = "_scalar" + ("_rhs" if len(args) > 2 else "")
elif i > 0:
in_dtype = arg.dtype#overwrite with a non-scalar input
#Do nothing on zero-sized arguments
if arg.size == 0 or arg.base.size == 0:
return

if op.info['name'] == "identity":#Identity is a special case
cmd = "bhc.bh_multi_array_%s_identity_%s" % (
Expand All @@ -105,19 +121,21 @@ def ufunc(op, *args):
dtype_name(in_dtype), op.info['name']
)
cmd += scalar_str
bhc_exec(eval(cmd), *args)
_bhc_exec(eval(cmd), *args)

def reduce(op, out, ary, axis):
"""
reduce 'axis' dimension of 'ary' and write the result to out
:op npbackend.ufunc.Ufunc: Instance of a Ufunc.
"""
if ary.size == 0 or ary.base.size == 0:
return

func = eval("bhc.bh_multi_array_%s_%s_reduce" % (
dtype_name(ary), op.info['name']
))
bhc_exec(func, out, ary, axis)
_bhc_exec(func, out, ary, axis)

def accumulate(op, out, ary, axis):
"""
Expand All @@ -129,11 +147,13 @@ def accumulate(op, out, ary, axis):
:in2 ?:
:rtype: None
"""
if ary.size == 0 or ary.base.size == 0:
return

func = eval("bhc.bh_multi_array_%s_%s_accumulate" % (
dtype_name(ary), op.info['name'])
)
bhc_exec(func, out, ary, axis)
_bhc_exec(func, out, ary, axis)

def extmethod(name, out, in1, in2):
"""
Expand All @@ -146,13 +166,15 @@ def extmethod(name, out, in1, in2):
:in2 ?:
:rtype: None
"""
if out.size == 0 or out.base.size == 0:
return

func = eval("bhc.bh_multi_array_extmethod_%s_%s_%s" % (
dtype_name(out),
dtype_name(in1),
dtype_name(in2)
))
ret = bhc_exec(func, name, out, in1, in2)
ret = _bhc_exec(func, name, out, in1, in2)

if ret != 0:
raise NotImplementedError("The current runtime system does not support "
Expand All @@ -167,10 +189,12 @@ def range(size, dtype):
:rtype: None
"""

func = eval("bhc.bh_multi_array_%s_new_range" % dtype_name(dtype))
bhc_obj = bhc_exec(func, size)
if size > 0:
func = eval("bhc.bh_multi_array_%s_new_range"%dtype_name(dtype))
bhc_obj = _bhc_exec(func, size)
else:
bhc_obj = None
base = Base(size, dtype, bhc_obj)

return View(1, 0, (size,), (dtype.itemsize,), base)

def random123(size, start_index, key):
Expand All @@ -180,9 +204,11 @@ def random123(size, start_index, key):
"""

dtype = numpy.dtype("uint64")
func = eval("bhc.bh_multi_array_uint64_new_random123")
bhc_obj = bhc_exec(func, size, start_index, key)
if size > 0:
func = eval("bhc.bh_multi_array_uint64_new_random123")
bhc_obj = _bhc_exec(func, size, start_index, key)
else:
bhc_obj = None
base = Base(size, dtype, bhc_obj)

return View(1, 0, (size,), (dtype.itemsize,), base)

17 changes: 17 additions & 0 deletions test/python/test_emptiness.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import numpy as np
import bohrium as bh
from numpytest import numpytest,gen_views,TYPES


class test_empty(numpytest):

def init(self):
a = {}
cmd = "a[0] = bh.array([]);a[1] = bh.array([])"
exec(cmd)
yield (a, cmd)

def test_add(self,a):
cmd = "res = a[0] + a[1]"
exec(cmd)
return (res,cmd)

0 comments on commit a045a54

Please sign in to comment.