Skip to content

Commit 66402ef

Browse files
committed
Index array wrapper class to avoid premature Index destruction
1 parent fed169f commit 66402ef

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

arrayfire/array.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from .bcast import *
1818
from .base import *
1919
from .index import *
20+
from .index import _Index4
2021

2122
def _create_array(buf, numdims, idims, dtype):
2223
out_arr = ct.c_void_p(0)
@@ -152,9 +153,8 @@ def _get_info(dims, buf_len):
152153

153154
def _get_indices(key):
154155

155-
index_vec = Index * 4
156156
S = Index(slice(None))
157-
inds = index_vec(S, S, S, S)
157+
inds = _Index4(S, S, S, S)
158158

159159
if isinstance(key, tuple):
160160
n_idx = len(key)
@@ -874,7 +874,7 @@ def __getitem__(self, key):
874874
inds = _get_indices(key)
875875

876876
safe_call(backend.get().af_index_gen(ct.pointer(out.arr),
877-
self.arr, ct.c_longlong(n_dims), ct.pointer(inds)))
877+
self.arr, ct.c_longlong(n_dims), inds.pointer))
878878
return out
879879
except RuntimeError as e:
880880
raise IndexError(str(e))
@@ -903,7 +903,7 @@ def __setitem__(self, key, val):
903903
inds = _get_indices(key)
904904

905905
safe_call(backend.get().af_assign_gen(ct.pointer(out_arr),
906-
self.arr, ct.c_longlong(n_dims), ct.pointer(inds),
906+
self.arr, ct.c_longlong(n_dims), inds.pointer,
907907
other_arr))
908908
safe_call(backend.get().af_release_array(self.arr))
909909
if del_other:

arrayfire/index.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,29 @@ def __init__ (self, idx):
208208
else:
209209
self.idx.seq = Seq(idx)
210210

211-
# def __del__(self):
212-
# if not self.isSeq:
213-
# arr = self.idx.arr
214-
# backend.get().af_release_array(arr)
211+
def __del__(self):
212+
if not self.isSeq:
213+
# ctypes field variables are automatically
214+
# converted to basic C types so we have to
215+
# build the void_p from the value again.
216+
arr = ct.c_void_p(self.idx.arr)
217+
backend.get().af_release_array(arr)
218+
219+
class _Index4(object):
220+
def __init__(self, idx0, idx1, idx2, idx3):
221+
index_vec = Index * 4
222+
self.array = index_vec(idx0, idx1, idx2, idx3)
223+
# Do not lose those idx as self.array keeps
224+
# no reference to them. Otherwise the destructor
225+
# is prematurely called
226+
self.idxs = [idx0,idx1,idx2,idx3]
227+
@property
228+
def pointer(self):
229+
return ct.pointer(self.array)
230+
231+
def __getitem__(self, idx):
232+
return self.array[idx]
233+
234+
def __setitem__(self, idx, value):
235+
self.array[idx] = value
236+
self.idxs[idx] = value

0 commit comments

Comments
 (0)