Skip to content

Commit

Permalink
Cache bf.ndarray.as_BFarray() to reduce overhead
Browse files Browse the repository at this point in the history
- The cost of the full call is quite significant on things like small memcopies
  • Loading branch information
benbarsdell committed Apr 27, 2017
1 parent de1d509 commit 56028d4
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions python/bifrost/ndarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import ctypes
import numpy as np
from memory import raw_malloc, raw_free, raw_get_space, space_accessible
from bifrost.libbifrost import _bf, _check
from bifrost.libbifrost import _bf, _check, _fast_call
import device
from DataType import DataType
from Space import Space
Expand Down Expand Up @@ -78,15 +78,16 @@ def copy_array(dst, src):
space_accessible(src_bf.bf.space, ['system'])):
np.copyto(dst_bf, src_bf)
else:
_check(_bf.ArrayCopy(dst_bf.as_BFarray(), src_bf.as_BFarray()))
_fast_call(_bf.ArrayCopy, dst_bf.as_BFarray(), src_bf.as_BFarray())
if dst_bf.bf.space != src_bf.bf.space:
# TODO: Decide where/when these need to be called
device.stream_synchronize()
return dst

def memset_array(dst, value):
dst_bf = asarray(dst)
_check(_bf.ArrayMemset(dst_bf.as_BFarray(), value))
#_check(_bf.ArrayMemset(dst_bf.as_BFarray(), value))
_fast_call(_bf.ArrayMemset, dst_bf.as_BFarray(), value)
return dst

# Stores Bifrost-specific metadata that augments Numpy's metadata
Expand Down Expand Up @@ -138,6 +139,7 @@ def __new__(cls, base=None, space=None, shape=None, dtype=None,
# Allow conjugated to be redefined
if conjugated is not None:
obj.bf.conjugated = conjugated
obj._update_BFarray()
else:
if not isinstance(base, np.ndarray):
# Convert base to np.ndarray
Expand Down Expand Up @@ -222,6 +224,7 @@ def __new__(cls, base=None, space=None, shape=None, dtype=None,
obj = np.ndarray.__new__(cls, shape, dtype_np,
data_buffer, offset, strides)
obj.bf = BFArrayInfo(space, dtype, native, conjugated, ownbuffer)
obj._update_BFarray()
return obj
def __array_finalize__(self, obj):
if obj is None:
Expand All @@ -241,10 +244,18 @@ def __array_finalize__(self, obj):
native = obj.dtype.isnative
conjugated = False
self.bf = BFArrayInfo(space, dtype, native, conjugated)
self._update_BFarray()
def __del__(self):
if hasattr(self, 'bf') and self.bf.ownbuffer:
raw_free(self.bf.ownbuffer, self.bf.space)
def _update_BFarray(self):
# (Re-)cache the BFarray structure
# Note: This must be called after any updates to self.bf.*
self._BFarray = None
self._BFarray = self.as_BFarray()
def as_BFarray(self):
if self._BFarray is not None:
return self._BFarray
a = _bf.BFarray()
a.data = self.ctypes.data
a.space = Space(self.bf.space).as_BFspace()
Expand Down Expand Up @@ -282,6 +293,7 @@ def view(self, dtype=None, type_=None):
dtype_np = np.dtype(dtype_bf.as_numpy_dtype())
v = super(ndarray, self).view(dtype_np)
v.bf.dtype = dtype_bf
v._update_BFarray()
return v
#def astype(self, dtype):
# dtype_bf = DataType(dtype)
Expand All @@ -304,6 +316,7 @@ def tofile(self, fid, sep="", format="%s"):
def byteswap(self, inplace=False):
if inplace:
self.bf.native = not self.bf.native
self._update_BFarray()
return super(ndarray, self).byteswap(True)
else:
return ndarray(self).byteswap(True)
Expand Down

0 comments on commit 56028d4

Please sign in to comment.