2014-09-25 1 views
2

В библиотеке sympy есть этот классный метод ufuncify(), который преобразует символическое выражение в код C, компилирует его и затем выдает функцию lambda, которая вызывает этот метод.Предел параметра в sympy ufuncify

Я сделал простую демку, demo.py:

import sympy 
from sympy.utilities.autowrap import ufuncify 
import sys 

N = int(sys.argv[1]) 
theta = [] 
values = [] 
for n in range(N): 
    theta.append(sympy.symbols('x%s' % n)) 
    values.append(n) 

summation = sum(theta) 
f = ufuncify(theta, summation) 
print f(*values)[0] 

Он работает для малого N:

 
$ python demo.py 21 
210.0 

Но больше N, я получаю следующее сообщение об ошибке:

 
$ python demo.py 22 
Traceback (most recent call last): 
    File "demo.py", line 13, in 
    f = ufuncify(theta, summation) 
    File "/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/sympy/utilities/autowrap.py", line 485, in ufuncify 
    return autowrap(C.Equality(y[i], f(*args)), **kwargs) 
    File "/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/sympy/utilities/autowrap.py", line 403, in autowrap 
    return code_wrapper.wrap_code(routine, helpers=helps) 
    File "/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/sympy/utilities/autowrap.py", line 139, in wrap_code 
    self._process_files(routine) 
    File "/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/sympy/utilities/autowrap.py", line 158, in _process_files 
    " ".join(command), e.output)) 
sympy.utilities.autowrap.CodeWrapError: Error while executing command: f2py -m wrapper_module_0 -c wrapped_code_0.f90. Command output is: 
running build 
running config_cc 
unifing config_cc, config, build_clib, build_ext, build commands --compiler options 
running config_fc 
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options 
running build_src 
build_src 
building extension "wrapper_module_0" sources 
f2py options: [] 
f2py:> /tmp/tmpKbJQuO/src.linux-x86_64-2.7/wrapper_module_0module.c 
creating /tmp/tmpKbJQuO 
creating /tmp/tmpKbJQuO/src.linux-x86_64-2.7 
Reading fortran codes... 
     Reading file 'wrapped_code_0.f90' (format:free) 
Post-processing... 
     Block: wrapper_module_0 
         Block: autofunc 
Post-processing (stage 2)... 
Building modules... 
     Building module "wrapper_module_0"... 
       Constructing wrapper function "autofunc"... 
        y_15 = autofunc(x_16,x1,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x2,x20,x21,x3,x4,x5,x6,x7,x8,x9,[m_17]) 
     Wrote C/API module "wrapper_module_0" to file "/tmp/tmpKbJQuO/src.linux-x86_64-2.7/wrapper_module_0module.c" 
    adding '/tmp/tmpKbJQuO/src.linux-x86_64-2.7/fortranobject.c' to sources. 
    adding '/tmp/tmpKbJQuO/src.linux-x86_64-2.7' to include_dirs. 
copying /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c -> /tmp/tmpKbJQuO/src.linux-x86_64-2.7 
copying /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h -> /tmp/tmpKbJQuO/src.linux-x86_64-2.7 
build_src: building npy-pkg config files 
running build_ext 
customize UnixCCompiler 
customize UnixCCompiler using build_ext 
customize Gnu95FCompiler 
Found executable /opt/user/x86_64/gcc-4.7.2/bin/gfortran 
customize Gnu95FCompiler 
customize Gnu95FCompiler using build_ext 
building 'wrapper_module_0' extension 
compiling C sources 
C compiler: gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC 

creating /tmp/tmpKbJQuO/tmp 
creating /tmp/tmpKbJQuO/tmp/tmpKbJQuO 
creating /tmp/tmpKbJQuO/tmp/tmpKbJQuO/src.linux-x86_64-2.7 
compile options: '-I/tmp/tmpKbJQuO/src.linux-x86_64-2.7 -I/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include -I/opt/user/x86_64/Python-2.7.3/include/python2.7 -c' 
gcc: /tmp/tmpKbJQuO/src.linux-x86_64-2.7/wrapper_module_0module.c 
In file included from /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1728:0, 
       from /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17, 
       from /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h:15, 
       from /tmp/tmpKbJQuO/src.linux-x86_64-2.7/fortranobject.h:13, 
       from /tmp/tmpKbJQuO/src.linux-x86_64-2.7/wrapper_module_0module.c:18: 
/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/npy_deprecated_api.h:11:2: warning: #warning "Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp] 
/tmp/tmpKbJQuO/src.linux-x86_64-2.7/wrapper_module_0module.c:111:12: warning: âpy_sizeâefined but not used [-Wunused-function] 
gcc: /tmp/tmpKbJQuO/src.linux-x86_64-2.7/fortranobject.c 
In file included from /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1728:0, 
       from /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17, 
       from /opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h:15, 
       from /tmp/tmpKbJQuO/src.linux-x86_64-2.7/fortranobject.h:13, 
       from /tmp/tmpKbJQuO/src.linux-x86_64-2.7/fortranobject.c:2: 
/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include/numpy/npy_deprecated_api.h:11:2: warning: #warning "Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp] 
compiling Fortran sources 
Fortran f77 compiler: /opt/user/x86_64/gcc-4.7.2/bin/gfortran -Wall -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops 
Fortran f90 compiler: /opt/user/x86_64/gcc-4.7.2/bin/gfortran -Wall -fno-second-underscore -fPIC -O3 -funroll-loops 
Fortran fix compiler: /opt/user/x86_64/gcc-4.7.2/bin/gfortran -Wall -ffixed-form -fno-second-underscore -Wall -fno-second-underscore -fPIC -O3 -funroll-loops 
compile options: '-I/tmp/tmpKbJQuO/src.linux-x86_64-2.7 -I/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include -I/opt/user/x86_64/Python-2.7.3/include/python2.7 -c' 
gfortran:f90: wrapped_code_0.f90 
wrapped_code_0.f90:1.133: 

4, x15, x16, x17, x18, x19, x2, x20, x21, x3, x4, x5, x6, x7, x8, x9, y_15 
                      1 
Warning: Line truncated at (1) 
wrapped_code_0.f90:1.132: 

14, x15, x16, x17, x18, x19, x2, x20, x21, x3, x4, x5, x6, x7, x8, x9, y_15 
                      1 
Error: Unexpected junk in formal argument list at (1) 
wrapped_code_0.f90:33.3: 

end subroutine 
    1 
Error: Expecting END PROGRAM statement at (1) 
Error: Unexpected end of file in 'wrapped_code_0.f90' 
wrapped_code_0.f90:1.133: 

4, x15, x16, x17, x18, x19, x2, x20, x21, x3, x4, x5, x6, x7, x8, x9, y_15 
                      1 
Warning: Line truncated at (1) 
wrapped_code_0.f90:1.132: 

14, x15, x16, x17, x18, x19, x2, x20, x21, x3, x4, x5, x6, x7, x8, x9, y_15 
                      1 
Error: Unexpected junk in formal argument list at (1) 
wrapped_code_0.f90:33.3: 

end subroutine 
    1 
Error: Expecting END PROGRAM statement at (1) 
Error: Unexpected end of file in 'wrapped_code_0.f90' 
error: Command "/opt/user/x86_64/gcc-4.7.2/bin/gfortran -Wall -fno-second-underscore -fPIC -O3 -funroll-loops -I/tmp/tmpKbJQuO/src.linux-x86_64-2.7 -I/opt/user/x86_64/Python-2.7.3/lib/python2.7/site-packages/numpy/core/include -I/opt/user/x86_64/Python-2.7.3/include/python2.7 -c -c wrapped_code_0.f90 -o /tmp/tmpKbJQuO/wrapped_code_0.o" failed with exit status 1 

Как я могу заставить это работать?

+1

'Предупреждение: линия, усеченная в (1)' - звучит так, как можно обрабатывать только так много переменных. Я ожидаю, что это ошибка, которую вы должны поместить в sympy. – mdurant

+0

Похож на ошибку --- сгенерированный fortran-код имеет слишком длинные строки. ufuncify должен их обернуть, но, видимо, этого не происходит. –

ответ

0

Нет сомнений в том, что вы обнаружили ошибку в Sympy, но вы можете обойти ее, передав флаги на бэкэнд. Согласно документации по адресу http://docs.sympy.org/latest/modules/utilities/autowrap.html, ufuncify передает аргументы ключевого слова в autowrap. Аргумент ключевого слова flagsautowrap выглядит многообещающим. В свою очередь, f2py (бэкенд по умолчанию) имеет параметры, которые позволяют пересылать флаги компилятору.

Использование gfortran как компилятор, я хотел бы попробовать следующее:

f = ufuncify(theta, summation, flags='--f90flags="--ffree-line-length-none"') 

(Это в настоящее время не тестировалось.)

Для ясности: --f90flags является вариант f2py, который может быть использован для указания параметров для компилятора. Флаг --ffree-line-length-none отправляется компилятору и инструктирует gfortran никогда не обрезать строки в исходном коде.

1

Я отправил в список рассылки sympy и получил ответ. Это известная ошибка, которая была исправлена ​​в их ветке разработки. Вот исправление: https://github.com/sympy/sympy/pull/7968