本文介绍了sympy autowrap(cython):参数数量的限制,数组形式的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到以下问题:



我想使用自动换行生成sympy矩阵的编译版本,其中包含有sympy表达式的单元格。根据问题的具体说明,参数的数量会非常大。



我遇到了以下两个问题:




  • 自动换行接受的参数数量似乎限制为509。



ie ,它的工作原理是:

 从sympy.utilities.autowrap导入sympy 
导入autowrap

x = sympy.symbols( x:509)
exp = sum(x)
cyt = autowrap(exp,backend = cython,args = x)

,但无法编译:

  x = sympy.symbols( x:510)
exp = sum(x)
cyt = autowrap(exp,backend = cython,args = x)

我收到的消息似乎不太清楚:

  [...](根据要求提供完整输出)
生成代码
c:\users\ [classified] \appdata\local\temp\tmp2zer8vfe_sympy_compile\wrapper_module_17。 c(6293):致命错误C1001:c中发生内部错误ompiler。
(编译文件'f:\dd\vctools\compiler\utc\src\p2\hash.c',行884)
要变通解决此问题,请尝试简化或在上面列出的位置附近更改程序。
请在Visual C ++
帮助菜单上选择技术支持命令,或打开技术支持帮助文件以获取更多信息
链接:致命错误LNK1257:代码生成失败
错误:命令'C:\\ Program Files(x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\link.exe'失败,退出状态为1257

有什么解决办法吗?我想使用需要约1000个输入变量的程序版本。
(我不了解C / cython。这是自动换行限制,还是C限制...?)



部分与上述内容相关:




  • 可以编译一个将参数作为数组接受的函数。



有什么方法可以生成接受numpy数组作为输入的代码?我专门指的是所有参数的一个数组,而不是将参数作为列表提供。 (类似于使用DeferredVector lambdify)。 ufuncify支持数组输入,但据我了解,仅是对函数进行广播/向量化。



我希望数组作为参数可以绕过上面的第一个问题,这是最为我压迫。除此之外,无论如何我还是更喜欢数组输入,因为它看起来更快(不需要将我输入的numpy数组解压缩到列表中),而且也更加直接自然。



有人对我有什么建议吗?
另外,有人可以告诉我f2py是否有类似的限制吗?如果可行的话,这对我来说也是一种选择,但我目前尚未设置它可以使用,并且希望在投入时间之前先了解一下是否有帮助。
谢谢!






编辑:



I在告诉 autowrap 输入参数将是数组形式的东西,而不是数字列表时,与不同的候选者进行了一些比较。我将在此记录我的步骤以供后代使用,并增加获得输入的机会:




  • 符号。 DeferredVector



我是出于同一目的与lambdify配合使用的,所以我想尝试一下。但是,警告

  A = sympy.DeferredVector( A)
表达式= A [0] + A [1]
cyt = autowrap(表达式,backend = cython,args = A)

只是完全崩溃了我的操作系统-上一条语句开始执行,(没有反馈),一切真的很慢,然后没有更多反应了。 (只能推测,也许与A没有形状信息这一事实有关,它似乎不会打扰lambdify,但在这里可能是个问题。无论如何,这似乎不是正确的方法。)




  • 各种数组类型的对象,用要包装的表达式中的符号填充。



例如

  x0,x1 = sympy.symbols( x:2)
expression = x0 + x1
cyt = autowrap(expression,backend = cython,args = np.array([x0,x1]))

仍然希望解压缩参数。用$

  cyt = autowrap(expression,backend = cython,args = [np.array([x0 ,x1])])

给出消息

  CodeGenArgumentListError:(参数列表未指定:x0,x1,[InputArgument(x0),InputArgument(x1)])

这种方法经常出现:在参数列表中使用sympy矩阵,元组等时也会发生这种情况。




  • sympy.IndexedBase



这实际上在自动包装示例中使用;但是,以一种(对我来说)直观的方式,使用方程式作为要包装的表达式。另外,使用它的方式对我来说似乎并不切实可行:我想进行cythonize的表达式是一个矩阵,但是它的单元格本身却是冗长的表达式,我无法通过索引操作获得。



好处是我有一个简单的示例可以工作:

  X = sympy.IndexedBase( X ,shape =(1,1))
expression = 2 * X [0,0]
cyt = autowrap(expression,backend = cython,args = [X])

实际上已经编译,并且所生成的函数正确地求值-通过2d-np.array时。



所以这似乎是最有前途的途径,即使我继续尝试对该方法进行进一步扩展也会失败。



例如

  X = sympy.IndexedBase( X,shape =(1,))
expression = 2 * X [0]
cyt = autowrap(表达式,backend = cython,args = [X])

让我知道

  [...] \site-packages\sympy\printing\codeprinter.py,线258,在_get_expression_indices中%s中的rhs索引%expr)
ValueError:lhs索引必须与2 * X [0]


即使我不认为它与上面的工作方式有什么不同。



相同的错误坚持二维但增加 X 的大小时出现的消息:

  X = sympy.IndexedBase( X,shape =(2,2))
表达式= 2 * X [0,0] + X [0,1] + X [1,0] + X [ 1,1]
cyt = autowrap(expression,backend = cython,args = [X])

ValueError:lhs索引必须与2 * X中的非虚拟rhs索引相匹配[ 0,0] + X [0,1] + X [1,0] + X [1,1]

我尝试窥探 autowrap 的代码,但是我觉得在那儿有点迷路了……



因此,我仍在寻找解决方案,并希望获得任何输入。

解决方案

将参数作为数组传递似乎很有效OK

  x = sympy.MatrixSymbol('x', 520,1)i在范围(x.shape [0])中,

exp = 0

exp + = x [i]

cyt = autowrap(exp,backend ='cython')

arr = np.random.randn(520,1)
cyt(arr)
Out [48]: -42.59735861021934

arr.sum()
Out [49]:-42.597358610219345


I have the following issue:

I want to use autowrap to generate a compiled version of a sympy matrix, with cells containing sympy expressions. Depending on the specification of my problem, the number of arguments can get very large.

I ran into the following 2 issues:

  • The number of arguments that autowrap accepts seems to be limited to 509.

i.e., this works:

import sympy
from sympy.utilities.autowrap import autowrap

x = sympy.symbols("x:509")
exp = sum(x)
cyt = autowrap(exp, backend="cython", args=x)

and this fails to compile:

x = sympy.symbols("x:510")
exp = sum(x)
cyt = autowrap(exp, backend="cython", args=x)

The message I get seems not very telling:

[...] (Full output upon request)
Generating code
c:\users\[classified]\appdata\local\temp\tmp2zer8vfe_sympy_compile\wrapper_module_17.c(6293) : fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'f:\dd\vctools\compiler\utc\src\p2\hash.c', line 884)
 To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++
 Help menu, or open the Technical Support help file for more information
LINK : fatal error LNK1257: code generation failed
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\link.exe' failed with exit status 1257

Is there any way around this? I would like to use versions of my program that need ~1000 input variables.(I have no understanding of C/cython. Is this an autowrap limitation, a C limitation ...?)

Partly connected to the above:

  • Can one compile functions that accept the arguments as array.

Is there any way to generate code that accepts a numpy array as input? I specifically mean one array for all the arguments, instead of providing the arguments as list. (Similar to lambdify using a DeferredVector). ufuncify supports array input, but as I understand only for broadcasting/vectorizing the function.

I would hope that an array as argument could circumvent the first problem above, which is most pressing for me. Apart from that, I would prefer array input anyways, both because it seems faster (no need to unpack the numpy array I have as input into a list), and also more straightforward and natural.

Does anyone have any suggestions what I can do?Also, could anyone tell me whether f2py has similar limitations? This would also be an option for me if feasible, but I don't have it set up to work currently, and would prefer to know whether it helps at all before investing the time.Thanks!


Edit:

I played around a bit with the different candidates for telling autowrap that the input argument will be something in array form, rather than a list of numbers. I'll document my steps here for posterity, and also to increase chances to get some input:

  • sympy.DeferredVector

Is what I use with lambdify for the same purpose, so I thought to give it a try. However, warning:

A = sympy.DeferredVector("A")
expression = A[0]+A[1]
cyt = autowrap(expression, backend="cython", args=A)

just completely crashed my OS - last statement started executing, (no feedback), everything got really slow, then no more reactions. (Can only speculate, perhaps it has to do with the fact that A has no shape information, which does not seem to bother lambdify, but might be a problem here. Anyways, seems not the right way to go.)

  • All sorts of array-type objects filled with the symbols in the expression to be wrapped.

e.g.

x0 ,x1 = sympy.symbols("x:2")
expression = x0 + x1
cyt = autowrap(expression, backend="cython", args=np.array([x0,x1]))

Still wants unpacked arguments. Replacing the last row by

cyt = autowrap(expression, backend="cython", args=[np.array([x0,x1])])

Gives the message

CodeGenArgumentListError: ("Argument list didn't specify: x0, x1 ", [InputArgument(x0), InputArgument(x1)])

Which is a recurrent theme to this approach: also happens when using a sympy matrix, a tuple, and so on inside the arguments list.

  • sympy.IndexedBase

This is actually used in the autowrap examples; however, in a (to me) inintuitive way, using an equation as the expression to be wrapped. Also, the way it is used there seems not really feasible to me: The expression I want to cythonize is a matrix, but its cells are themselves longish expressions, which I cannot obtain via index operations.

The upside is that I got a minimal example to work:

X = sympy.IndexedBase("X",shape=(1,1))
expression = 2*X[0,0]
cyt = autowrap(expression, backend="cython", args=[X])

actually compiles, and the resulting function correctly evaluates - when passed a 2d-np.array.

So this seems the most promising avenue, even though further extensions to this approach I keep trying fail.

For example this

X = sympy.IndexedBase("X",shape=(1,))
expression = 2*X[0]
cyt = autowrap(expression, backend="cython", args=[X])

gets me

[...]\site-packages\sympy\printing\codeprinter.py", line 258, in _get_expression_indices " rhs indices in %s" % expr)
ValueError: lhs indices must match non-dummy rhs indices in 2*X[0]

even though I don't see how it should be different from the working one above.

Same error message when sticking to two dimensions, but increasing the size of X:

X = sympy.IndexedBase("X",shape=(2,2))
expression = 2*X[0,0]+X[0,1]+X[1,0]+X[1,1]
cyt = autowrap(expression, backend="cython", args=[X])

ValueError: lhs indices must match non-dummy rhs indices in 2*X[0, 0] + X[0, 1] + X[1, 0] + X[1, 1]

I tried snooping around the code for autowrap, but I feel a bit lost there...

So I'm still searching for a solution and happy for any input.

解决方案

Passing the argument as an array seems to work OK

x = sympy.MatrixSymbol('x', 520, 1)

exp = 0
for i in range(x.shape[0]):
    exp += x[i]

cyt = autowrap(exp, backend='cython')

arr = np.random.randn(520, 1)
cyt(arr)
Out[48]: -42.59735861021934

arr.sum()
Out[49]: -42.597358610219345

这篇关于sympy autowrap(cython):参数数量的限制,数组形式的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 19:26