문제

I am writing a C++ library which can be called from both C++ and Python by using SWIG-Python interface. I would like to make a few functions in the library to return numpy array when they are used in Python.

The SWIG documentation [1] says that numpy.i located under numpy/docs/swig can be used for this purpose. But I cannot find this directory on the following systems.

  • Scientific Linux 6.4 (RHEL 6.4 clone) + Python 2.6 + NumPy 1.4 (installed via yum)
  • OS X Mavericks + Python 2.7 + NumPy 1.8 (via easy_install)
  • OS X Mavericks + Python 2.7 + NumPy 1.8 (built from the source python setup.py install)

There exists numpy.i under numpy-1.8.0/doc/swig if I get the .tar.gz source code from the NumPy site. But this file is not automatically installed when python setup.py install is executed.

So I would like to know what the best or recommended way to install numpy.i on my system is.

As I distribute this library to my colleagues, putting numpy.i in my code might be an easy solution. But I am concerning about version mismatch with their NumPy.

[1] http://docs.scipy.org/doc/numpy/reference/swig.interface-file.html

도움이 되었습니까?

해결책

The safest option is probably just to bundle a copy of numpy.i with your project, as the file is not currently installed by Numpy itself.

The numpy.i file is written using Numpy's C-API, so the backward compatibility questions are the same as if you wrote the corresponding C code by hand.

다른 팁

You can add the following code snippet to your setup.py file to download numpy.i from Github at build time:

import re
import requests
import numpy

np_version = re.compile(r'(?P<MAJOR>[0-9]+)\.'
                        '(?P<MINOR>[0-9]+)') \
                        .search(numpy.__version__)
np_version_string = np_version.group()
np_version_info = {key: int(value)
                   for key, value in np_version.groupdict().items()}

np_file_name = 'numpy.i'
np_file_url = 'https://raw.githubusercontent.com/numpy/numpy/maintenance/' + \
              np_version_string + '.x/tools/swig/' + np_file_name
if(np_version_info['MAJOR'] == 1 and np_version_info['MINOR'] < 9):
    np_file_url = np_file_url.replace('tools', 'doc')

chunk_size = 8196
with open(np_file_name, 'wb') as file:
    for chunk in requests.get(np_file_url,
                              stream=True).iter_content(chunk_size):
        file.write(chunk)

It downloads the suitable file depending on Numpy's version and works in both Python 2 and 3 with requests library installed.

Another possibility, similar to what was proposed by Alberto Marquez above, is to include a Makefile that automatically downloads the numpy.i file in case it is missing. Here is one example, cf. the line immediately below ${PROGRAM}: ${PROGRAM}.c:

# put here the root name of your code
PROGRAM = simple

CC  = gcc
CFLAGS  = -c -fPIC -O2  
LFLAGS  = -I/Users/nemmen/anaconda3/include/python3.5m -I/Users/nemmen/anaconda3/lib/python3.5/site-packages/numpy/core/include

all: ${PROGRAM}

${PROGRAM}: ${PROGRAM}.c
    [ -f ./numpy.i ] && echo "numpy.i already here, good" || wget https://raw.githubusercontent.com/numpy/numpy/master/tools/swig/numpy.i

    swig -python -o ${PROGRAM}_wrap.c ${PROGRAM}.i
    $(CC) ${CFLAGS} ${PROGRAM}.c -o ${PROGRAM}.o
    $(CC) ${CFLAGS} ${PROGRAM}_wrap.c -o ${PROGRAM}_wrap.o ${LFLAGS}
    ld -bundle -flat_namespace -undefined suppress -o _${PROGRAM}.so *.o

clean:
    rm -rf *.o *.mod *.so ${PROGRAM}_wrap.c numpy.i __pycache__

For an example of where this Makefile is adopted, check out this repo.

Download a copy of numpy.i from this GitHub page and put it in the local directory.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top