Cython: Jak przenosić duże obiekty bez ich kopiowania?
Używam Cythona do zawijania kodu C ++ i udostępnienia go Pythonowi do pracy interaktywnej. Moim problemem jest to, że muszę odczytać duże wykresy (kilka gigabajtów) z pliku i kończą się dwa razy w pamięci. Czy ktoś może mi pomóc zdiagnozować i rozwiązać ten problem?
Mój wrapper Cython dla klasy graf wygląda tak:
cdef extern from "../src/graph/Graph.h":
cdef cppclass _Graph "Graph":
_Graph() except +
_Graph(count) except +
count numberOfNodes() except +
count numberOfEdges() except +
cdef class Graph:
"""An undirected, optionally weighted graph"""
cdef _Graph _this
def __cinit__(self, n=None):
if n is not None:
self._this = _Graph(n)
# any _thisect which appears as a return type needs to implement setThis
cdef setThis(self, _Graph other):
#del self._this
self._this = other
return self
def numberOfNodes(self):
return self._this.numberOfNodes()
def numberOfEdges(self):
return self._this.numberOfEdges()
Jeśli konieczne jest zwrócenie wykresu Pythona, należy go utworzyć pusty, a następniesetThis
metoda jest używana do ustawienia natywnego_Graph
instancja. Dzieje się tak na przykład, gdy aGraph
jest odczytywany z pliku. To jest zadanie tej klasy:
cdef extern from "../src/io/METISGraphReader.h":
cdef cppclass _METISGraphReader "METISGraphReader":
_METISGraphReader() except +
_Graph read(string path) except +
cdef class METISGraphReader:
""" Reads the METIS adjacency file format [1]
[1]: http://people.sc.fsu.edu/~jburkardt/data/metis_graph/metis_graph.html
"""
cdef _METISGraphReader _this
def read(self, path):
pathbytes = path.encode("utf-8") # string needs to be converted to bytes, which are coerced to std::string
return Graph(0).setThis(self._this.read(pathbytes))
Interaktywne użycie wygląda tak:
>>> G = graphio.METISGraphReader().read("giant.metis.graph")
Po zakończeniu odczytu z pliku i użyciu pamięci X GB, jest faza, w której następuje oczywiście kopiowanie, a następnie używana jest pamięć 2X GB. Cała pamięć zostaje uwolniona, kiedydel G
jest nazywany.
Gdzie jest mój błąd, który prowadzi do dwukrotnego skopiowania i istnienia wykresu w pamięci?