提问者:小点点

sympy-ufuncify中的参数限制


symphy库有一个很酷的ufuncify()方法,它将符号表达式转换为C代码,对其进行编译,然后输出一个调用该C方法的lambda函数。

我做了这个简单的演示,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

我怎样才能让它工作?


共2个答案

匿名用户

我在Symphy邮件列表上发了帖子,得到了回复。这是一个已知的bug,已在其开发分支中修复。以下是修复方法:https://github.com/sympy/sympy/pull/7968

匿名用户

毫无疑问,您在Sympy中发现了一个错误,但是您可以通过向后端传递标志来解决它。根据http://docs.sympy.org/latest/modules/utilities/autowrap.html的留档,ufuncify将关键字参数传递给autowrap。autowrap标志关键字参数看起来很有希望。反过来,f2py(默认后端)具有允许您将标志转发到编译器的选项。

使用gfortran作为编译器,我会尝试以下方法:

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

(目前尚未测试。)

为清楚起见:--f90flags是f2py的一个选项,可用于指定编译器的选项。--ffree line length none标志将转发给编译器,并将指示gfortran永远不要截断源代码中的行。