autowrap sympy (cython): limite de # de argumentos, argumentos em forma de matriz?

Eu tenho o seguinte problema:

Eu quero usar autowrap para gerar uma versão compilada de uma matriz sympy, com células contendo expressões sympy. Dependendo da especificação do meu problema, o número de argumentos pode ficar muito grande.

Encontrei os seguintes 2 problemas:

O número de argumentos aceitos pelo autowrap parece limitado a 509.

ou seja, isso funciona:

import sympy
from sympy.utilities.autowrap import autowrap

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

e isso falha ao compilar:

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

A mensagem que recebo não parece muito reveladora:

[...] (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

Existe alguma maneira de contornar isso? Eu gostaria de usar versões do meu programa que precisam de ~ 1000 variáveis de entrada. (Eu não entendo C / cython. Isso é uma limitação de autowrap, uma limitação de C ...?)

Parcialmente conectado ao acima:

Pode-se compilar funções que aceitam os argumentos como matriz.

Existe alguma maneira de gerar código que aceita uma matriz numpy como entrada? Quero dizer especificamente uma matriz para todos os argumentos, em vez de fornecer os argumentos como lista. (Semelhante ao lambdify usando um DeferredVector). O ufuncify suporta entrada de matriz, mas como eu entendo apenas para transmitir / vetorizar a função.

Espero que uma matriz como argumento possa contornar o primeiro problema acima, o que é mais urgente para mim. Além disso, eu preferiria a entrada da matriz de qualquer maneira, tanto porque parece mais rápido (não é necessário descompactar a matriz numpy que tenho como entrada em uma lista), como também mais direta e natural.

Alguém tem alguma sugestão do que eu posso fazer? Além disso, alguém poderia me dizer se o f2py tem limitações semelhantes? Isso também seria uma opção para mim, se possível, mas não o tenho configurado para funcionar atualmente e preferiria saber se isso ajuda de alguma forma antes de investir o tempo. Obrigado!

Editar:

Eu brinquei um pouco com os diferentes candidatos para contarautowrap que o argumento de entrada será algo em forma de matriz, em vez de uma lista de números. Vou documentar meus passos aqui para posteridade e também para aumentar as chances de obter alguma contribuição:

sympy.DeferredVector

É o que eu uso com o lambdify para o mesmo propósito, então pensei em experimentá-lo. Contudo,Aviso:

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

caiu completamente meu sistema operacional - a última instrução começou a ser executada (sem feedback), tudo ficou muito lento e não houve mais reações. (Só podemos especular, talvez isso tenha a ver com o fato de A não ter informações de forma, o que não parece incomodar a lambdificação, mas pode ser um problema aqui. De qualquer forma, parece não ser o caminho certo a seguir.)

Todos os tipos de objetos do tipo matriz preenchidos com os símbolos na expressão a ser quebrada.

por exemplo.

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

Ainda quer argumentos descompactados. Substituindo a última linha por

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

Dá a mensagem

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

Esse é um tema recorrente para essa abordagem: também acontece ao usar uma matriz sympy, uma tupla etc. na lista de argumentos.

sympy.IndexedBase

Isso é realmente usado nos exemplos de autowrap; no entanto, de uma maneira (para mim) não intuitiva, usando uma equação como a expressão a ser quebrada. Além disso, a maneira como é usada lá não parece realmente viável para mim: a expressão que eu quero cythonizar é uma matriz, mas suas células são expressões longas, que não posso obter por meio de operações de índice.

A vantagem é que eu tenho um exemplo mínimo para trabalhar:

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

realmente compila, e a função resultante avalia corretamente - quando passou um array 2d-np.array.

Portanto, essa parece a avenida mais promissora, mesmo que outras extensões dessa abordagem continuem tentando fracassar.

Por exemplo, isso

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

me pega

[...]\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]

mesmo que eu não veja como deve ser diferente do trabalho acima.

A mesma mensagem de erro ao aderir a duas dimensões, mas aumentando o tamanho deX:

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]

Tentei bisbilhotar o código paraautowrap, mas me sinto um pouco perdido por lá ...

Então, eu ainda estou procurando uma solução e feliz por qualquer entrada.

questionAnswers(1)

yourAnswerToTheQuestion