CUDA - это запатентованная технология NVIDIA, и единственная доступная, полезная и полностью функциональная реализация требует системы с поддерживаемым графическим процессором NVIDIA. Если у вас этого нет (а кажется, что у вас его нет), значит, у вашей проблемы нет решения.
Вы могли реализовать его сами, так же к тому, как Вы сделали, но с подклассом списка, который называет сброс () прежде, чем попытаться получить доступ к объекту.
Очевидно, Вы не хотите делать это на каждом доступе, но можно оптимизировать это путем установки обратного вызова на слабой ссылке для маркировки списка, грязного, когда что-то умирает. Затем только необходимо сбросить список, когда что-то умерло начиная с последнего доступа.
Вот реализованное использование класса списка этого метода. (Обратите внимание, что это не протестировало много, и некоторые методы не реализованы очень эффективно (например, те, которые просто преобразовывают в реальный список и называют метод на том), но это должна быть разумная начальная точка:
import weakref
class WeakList(list):
def __init__(self, seq=()):
list.__init__(self)
self._refs = []
self._dirty=False
for x in seq: self.append(x)
def _mark_dirty(self, wref):
self._dirty = True
def flush(self):
self._refs = [x for x in self._refs if x() is not None]
self._dirty=False
def __getitem__(self, idx):
if self._dirty: self.flush()
return self._refs[idx]()
def __iter__(self):
for ref in self._refs:
obj = ref()
if obj is not None: yield obj
def __repr__(self):
return "WeakList(%r)" % list(self)
def __len__(self):
if self._dirty: self.flush()
return len(self._refs)
def __setitem__(self, idx, obj):
if isinstance(idx, slice):
self._refs[idx] = [weakref.ref(obj, self._mark_dirty) for x in obj]
else:
self._refs[idx] = weakref.ref(obj, self._mark_dirty)
def __delitem__(self, idx):
del self._refs[idx]
def append(self, obj):
self._refs.append(weakref.ref(obj, self._mark_dirty))
def count(self, obj):
return list(self).count(obj)
def extend(self, items):
for x in items: self.append(x)
def index(self, obj):
return list(self).index(obj)
def insert(self, idx, obj):
self._refs.insert(idx, weakref.ref(obj, self._mark_dirty))
def pop(self, idx):
if self._dirty: self.flush()
obj=self._refs[idx]()
del self._refs[idx]
return obj
def remove(self, obj):
if self._dirty: self.flush() # Ensure all valid.
for i, x in enumerate(self):
if x == obj:
del self[i]
def reverse(self):
self._refs.reverse()
def sort(self, cmp=None, key=None, reverse=False):
if self._dirty: self.flush()
if key is not None:
key = lambda x,key=key: key(x())
else:
key = apply
self._refs.sort(cmp=cmp, key=key, reverse=reverse)
def __add__(self, other):
l = WeakList(self)
l.extend(other)
return l
def __iadd__(self, other):
self.extend(other)
return self
def __contains__(self, obj):
return obj in list(self)
def __mul__(self, n):
return WeakList(list(self)*n)
def __imul__(self, n):
self._refs *= n
return self
[Редактирование] Добавляет больше реализации полного списка.
Почему вы не можете сделать это вот так:
import weakref
class WeakList(list):
def append(self, item):
list.append(self, weakref.ref(item, self.remove))
А затем сделать аналогично для __iadd__
, extend
и т.д.
У меня работает.