2017-09-18 5 views
2

sympy을 사용하여 미분 방정식 시스템을 처리했습니다. 방정식을 기호식으로 작성하고 autowrap을 사용하여 cython으로 컴파일 한 다음 결과 함수를 scipy ODE 해석기로 전달합니다. 이 작업의 가장 큰 이점 중 하나는 sympy jacobian 함수를 사용하여 jacobian을 상징적으로 풀어 컴파일하고 ODE 해석기로도 해석 할 수 있다는 것입니다.대용량 행렬을 사용하는 sympy 컴파일 함수

약 30 개의 변수 시스템에서 효과적입니다. 최근에 나는 150 개의 변수로 그것을 시도했다. 그리고 무슨 일이 일어 났는가는 jacobian 함수를 컴파일 할 때 메모리가 부족하다는 것이었다. Windows에서 anaconda와 python 용 Microsoft Visual C++ 14 도구를 사용합니다. 기본적으로 22000 요소 벡터 인 jacobian을 컴파일하는 동안 링크 단계에서의 메모리 사용량이 8GB 노트북에서 약 7GB로 늘어났습니다.

메모리를 추가 한 컴퓨터를 사용하기 전에 누군가에게 몇 가지 제안 사항이 있습니까? 다른 운영 체제 또는 다른 C 컴파일러가 상황을 개선 할 가능성이 있습니까?

저는 많은 사람들이 이러한 유형의 작업을 수행한다는 것을 알고 있습니다. 따라서 답변이 있으면 커뮤니티의 좋은 덩어리에 도움이 될 것입니다.

편집 : 조나단의 발언 중 일부에 대한 응답 :

예, 이것이 N^2 문제가 있음을 충분히 알고 있어요. 자 코비안은 모든 부분 파생물의 행렬이므로 크기 N^2를 갖습니다. 이 스케일링을 둘러싼 실질적인 방법은 없습니다. 그러나 22000 요소 배열은 런타임 중에 메모리 문제를 일으킬 수준에 근접하지 않습니다. 컴파일하는 동안에 만 문제가 발생합니다.

기본적으로이 문제를 해결할 수있는 세 가지 수준이 있습니다.

1) 야 코비 행렬없이 ODE 문제를 해결하거나, 150x150 행렬을 갖지 않도록 자코비안을 분할합니다. 그게 근본을 말하지만, 내가 할 수있는 일을 확실히 제한하고, 아직 야코 비안 함수를 컴파일하는 것이 불가능하다고 확신하지는 않는다.

2) sympy은 자동으로 C 코드를 생성하여 분할한다. 여러 덩어리로 작성하고 중간 표현식에 더 많은 함수를 사용하며 어떻게 든 .c 파일을 작게 만듭니다. sympy 경험이 많은 사람들은 이에 대한 아이디어를 얻을 수 있습니다.

3) C가 컴파일되는 방식을 변경하여 메모리가 덜 필요합니다.

# 3 (literal referencing of large array -- compiler out of memory)을 중심으로 한 별도의 질문을 게시함으로써 다른 잠재 고객에게 답변 할 수 있다고 생각했습니다. 사실 그것은 정확하게 일어난 일입니다. 아마도 # 3에 대한 대답은 "할 수 없다"지만 유용한 정보이기도합니다.

+0

동일한 제한 사항에 구속됨에 따라이 질문을 두 번째해야합니다. 그러나, 나를 위해, 나는 "치명적인 오류 C1002 : 컴파일러는 패스 2의 힙 공간을 벗어났습니다"라는 메시지를받습니다. 동료의 컴퓨터에서 우분투 + gcc 컴파일러에 대한 빠른 시도가 불행히도 문제를 해결하지 못했습니다. 아무 것도 도움이되지 않는다면 자코 비안의 몇몇 서브 매트릭스에서 'autowrap'을 사용하여이 문제를 해결할 수 있고 파이썬에서 함수를 정의하여 다시 부품을 결합 할 수 있습니다. 그것은 물론 해결 방법이며 이상적인 방법은 아닙니다. – DavidP

+0

예, 죄송합니다. 다소 "느슨하게"사용했습니다. 같은 오류나 비슷한 오류가 발생합니다. –

+0

후속 질문 [메모리가 부족한 대형 배열 컴파일러의 리터럴 참조] (https://stackoverflow.com/questions/46380587)에 유의하십시오. 현재이 사본으로 닫혀 있습니다. 중복 된 상태가 변경되면이 댓글에 '더 이상 필요하지 않음'플래그를 지정하십시오. –

답변

0

http://www.sympy.org/scipy-2017-codegen-tutorial/에 게시 된 많은 예제를 따르면 나는 이것을 컴파일 할 수있었습니다.

핵심 항목은 입니다. autowrap을 사용하는 대신 1을 직접 제어하여 C 코드를 직접 작성하십시오. 무엇보다도 인수 목록을 확장하는 대신 벡터로 전달할 수 있습니다. 이것은 (distutils, etc, 등을 통해 컴파일러 플래그를 설정하는) 약간의 노력을 필요로했지만 결국에는 잘 작동했습니다. 예를 들어 위에 링크 된 코스의 레포를 갖는 것이 많은 도움이되었습니다.

2) 공통 하위 식 제거 (sympy.cse)를 사용하여 자 코비안 요소의 표현식 크기를 크게 줄입니다.

(1) 그 자체로는이 경우 도움이되지 못했습니다. (더 작은 모델의 성능을 대폭 향상시키기 위해 사용할 수는 있었지만). 코드는 여전히 원본 300MB 대신 200MB였습니다. 그러나 그것을 (2) (cse)와 결합하면 (14000 임시 변수에도 불구하고) 약 1.7MB로 줄일 수있었습니다.

cse은 내 랩톱에서 약 20-30 분 정도 소요됩니다. 그 후, 그것은 빨리 컴파일됩니다.