问题描述
我遇到以下问题:
我想使用自动换行生成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)
$中的非虚拟rhs索引匹配p $ p>
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):参数数量的限制,数组形式的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!