Cython: Wie kann man große Objekte bewegen, ohne sie zu kopieren?

Ich verwende Cython, um C ++ - Code zu verpacken und ihn für die interaktive Arbeit in Python verfügbar zu machen. Mein Problem ist, dass ich große Graphen (mehrere Gigabyte) aus einer Datei lesen muss und sie zweimal im Speicher landen. Kann mir jemand bei der Diagnose und Lösung dieses Problems helfen?

Mein Cython-Wrapper für die Grafikklasse sieht folgendermaßen aus:

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()

Wenn ein Python-Diagramm zurückgegeben werden soll, muss es leer erstellt werden, und anschließend wird dassetThis Methode wird verwendet, um die native festzulegen_Graph Beispiel. Dies passiert zum Beispiel, wenn aGraph wird aus Datei gelesen. Das ist die Aufgabe dieser Klasse:

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))

Die interaktive Nutzung sieht folgendermaßen aus:

 >>> G = graphio.METISGraphReader().read("giant.metis.graph")

Nachdem das Lesen der Datei abgeschlossen ist und der X GB-Speicher verwendet wurde, wird in einer Phase offensichtlich kopiert und anschließend der 2X GB-Speicher verwendet. Der gesamte Speicher wird freigegeben, wenndel G wird genannt.

Wo ist mein Fehler, der dazu führt, dass das Diagramm kopiert wird und zweimal im Speicher vorhanden ist?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage