1

尝试将 Python 代码移植到 cython 时,我收到以下链接器错误消息:

cls ~/workspace/Prototypes/PLPcython $ python3 setup.py build_ext --inplace
running build_ext
cythoning src/graph.pyx to src/graph.c
cythoning src/community.pyx to src/community.c
building 'PLPcython' extension
creating build
creating build/temp.macosx-10.8-x86_64-3.3
creating build/temp.macosx-10.8-x86_64-3.3/src
cc -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c src/graph.c -o build/temp.macosx-10.8-x86_64-3.3/src/graph.o
cc -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c src/community.c -o build/temp.macosx-10.8-x86_64-3.3/src/community.o
src/community.c:1414:19: warning: expression result unused [-Wunused-value]
    PyObject_INIT(o, t);
    ~~~~~~~~~~~~~~^~~~~
/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m/objimpl.h:163:69: note: expanded from macro 'PyObject_INIT'
    ( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
                                                                    ^
1 warning generated.
cc -bundle -undefined dynamic_lookup -L/usr/local/lib -L/usr/local/opt/sqlite/lib build/temp.macosx-10.8-x86_64-3.3/src/graph.o build/temp.macosx-10.8-x86_64-3.3/src/community.o -o /Users/cls/workspace/Prototypes/PLPcython/PLPcython.so
duplicate symbol _PyInit_PLPcython in:
    build/temp.macosx-10.8-x86_64-3.3/src/graph.o
    build/temp.macosx-10.8-x86_64-3.3/src/community.o
duplicate symbol ___pyx_module_is_main_PLPcython in:
    build/temp.macosx-10.8-x86_64-3.3/src/graph.o
    build/temp.macosx-10.8-x86_64-3.3/src/community.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: command 'cc' failed with exit status 1

显然会产生重复的符号。什么是_PyInit_*___pyx_module_is_main_

这些是我尝试 cythonize 的两个源文件:graph.pyx

class Graph:

    def __init__(self, n=0):
        self.n = n
        self.m = 0  
        self.z = n  # max node id
        self.adja = [[] for i in range(self.z)]
        self.deg = [0 for i in range(self.z)]

    def maxNodeId(self):
        return self.z

    def numberOfNodes(self):
        return self.n

    def numberOfEdges(self):
        return self.m

    def addEdge(self, u, v):
        if (u == v):
            self.adja[u].append(v)
            self.deg[u] += 1
        else:
            self.adja[u].append(v)
            self.adja[v].append(u)
            self.deg[u] += 1
            self.deg[v] += 1
        self.m += 1

    def hasEdge(self, u, v):
        for w in self.adja[u]:
            if w == v:
                return True
        return False 

    def degree(self, u):
        return self.deg[u]

    def forNodes(self, handle):
        # assumtion: all nodes exist
        for u in range(self.z):
            handle(u)

    def forEdges(self, handle):
        for u in range(self.z):
            for v in self.adja[u]:
                if v <= u:
                    handle(u, v)

    def forNeighborsOf(self, u, handle):
        for v in self.adja[u]:
            handle(v)

community.pyx

def numberOfCommunities(zeta, G):
    labels = set()
    for label in zeta:
        if label is not None:
            labels.add(label)
    return len(labels)


def coverage(zeta, G):
    intra = 0
    inter = 0
    m = G.numberOfEdges()

    def scan(u, v):
        nonlocal intra
        nonlocal inter
        if zeta[u] == zeta[v]:
            intra += 1
        else:
            inter += 1

    G.forEdges(scan)

    print("intra-community edges: ", intra)
    print("inter-community edges: ",inter)

    assert (inter + intra == m)
    coverage = intra / m
    return coverage
4

1 回答 1

1

我相信 Cython 只支持将单个源文件编译为单个模块。因此,要么将两个文件编译为两个单独的模块,要么使用包含语句(http://docs.cython.org/src/userguide/language_basics.html#the-include-statement)将它们组合在一个源文件中.

于 2013-07-19T11:57:26.760 回答